Stap 2: Code
Veel testen en opnieuw controleren is er gebeurd met de code te maken wat het nu is. Dingen anders zou kunnen werken voor uw sanitaire systemen of als u verschillende apparatuur gedurende het gehele proces. Deze code werkte voor ons project met behulp van de apparatuur en de methoden die we gebruikt.
Het beeld is louter ter demonstratie. Afbeelding bron http://apcmag.com/arduino-masterclass-part-3-tv-w...
Voor deze specifieke code downloadden wij meerdere 'bibliotheken' voor hoe te programmeren van een arduino aan onze computers.
Software voor het kalibreren van de Arduino
5-gallon emmer vullen met water en het nummer op het scherm aflezen. Dit getal delen door 5 en u hebt uw conversie factor (con)
#include <LiquidCrystal.h>#include "RunningMedian.h" #define sensor 0 LiquidCrystal lcd(9, 8, 7, 6, 5, 4);
const float lowlim = 3000; // use this to differentiate between background noise and water flowing
float val =0; // Current reading for analog pin float ave; // Running average of the wave amplitude used in calculating Median float RMSAVE = 0; // Running RMS average used in calculating Median float start = 0; // Counter for how long the program runs at each calculation float interval = 0; // Used in calculating the length of the 6 sec calculation float RMStot = 0;
RunningMedian Median = RunningMedian(5); float sum = 0; boolean flag = 0;
void setup() { pinMode(sensor, INPUT); pinMode(17, OUTPUT); // Activated onboard LED (yellow) lcd.begin(8,2); ave = 530; // set average at midpoint }
// Compute 1000 averages, then print final value to a file. void loop(){ start = millis(); for (int j=0; j < 5; j++){ digitalWrite(17, LOW); // Has yellow LED light up when calculating for (int i=0; i <= 5000; i++){ val = (float) analogRead(sensor); ave = (ave * 0.999) + (val * 0.001); RMSAVE = (RMSAVE * 0.998) + .002*(abs((ave-val))); delayMicroseconds (50); //Modulates the sampling rate (now sampling at ~ 1000 Hz?) }
// Calcuulates the average for the 6-second period interval = millis()-start; RMStot = interval*RMSAVE; Median.add(RMStot); } digitalWrite(17, HIGH); // Has yellow LED light up off when resetting
if(Median.getMedian()>lowlim){ sum = sum + Median.getMedian(); flag = 0; TXLED1; }
if (Median.getMedian()
//Print output to LCD-display for calibration lcd.clear(); lcd.setCursor(0, 0); lcd.print(Median.getMedian()); lcd.setCursor(0, 1); lcd.print(sum); }
Software voor de follow-up proces (slaat de gegevens van de douche aan EEPROM [vluchtig geheugen op Arduino]):
Het installeren van de bibliotheek uitgevoerd mediaan van Arduino.cc voor het uploaden van deze code. Empirische kalibratieprogramma gebruiken om te bepalen "lowlim" en "con" (lowlim wordt gebruikt om te scheiden van achtergrondgeluiden uit water lopen in de pijp, en "con" is de omrekeningsfactor gebruikt voor het berekenen van watergebruik):
// include the library code:#include<EEPROM.h> #include "RunningMedian.h" #include <LiquidCrystal.h> #define sensor 0 // initialize the library with the numbers of the interface pins - this is lines up with how we soldered the Arduino to the LCD LiquidCrystal lcd(9, 8, 7, 6, 5, 4);
const float con = 234862; //Test-value for non-screen unit
const float lowlim = 7000; // use this to differentiate between background noise and water flowing
RunningMedian Average = RunningMedian(10); //Running out of memory (SRAM) when this is around 19 - leave plenty space, so no more then 10 adviced I think... RunningMedian Median = RunningMedian(5);
float val =0; // Current reading for analog pin float ave; // Running average of the wave amplitude used in calculating Median float RMSAVE = 0; // Running RMS average used in calculating Median float start = 0; // Counter for how long the program runs at each calculation float interval = 0; // Used in calculating the length of the 6 sec calculation float RMStot = 0; float volume = 0; float sum = 0;
int numshowers = EEPROM.read(0); int k = numshowers*4; //Use this to update the number of showers as stored in the zero-index EEPROM float time = 0;
boolean flag = 0; // Flag for storing when shower is turned off boolean flag2 = 0; // Flag for switching between "H20 used" and "Average use"
void setup() { pinMode(sensor, INPUT); pinMode(17, OUTPUT); // Activated onboard LED (yellow)
lcd.begin(8,2); ave = 530; // set average at midpoint Serial.begin(9600); // Need to write function to put what's in EEPROM memory into the RunningAverage function int l = 0; // Counter for copying from EEPROM to RunningAverage int m = 1; // Counter for finding memory-location in EEPROM to RunningAverage float TempAve = 0; while (l < EEPROM.read(0)) { int ReadAve[3]; ReadAve[0] = EEPROM.read(m)*100; ReadAve[1] = EEPROM.read(m+1)*10; ReadAve[2] = EEPROM.read(m+2); TempAve=ReadAve[0]+ReadAve[1]+ReadAve[2]; Average.add(TempAve/10); m = m + 4; l++; delay(50); }
}
1000 gemiddelden berekenen, waarna de verkoopcommissie naar een bestand afdrukken. void loop {start = millis(); voor (int j = 0; j < 5; j ++) {TXLED1; / / groene LED light uo bij de berekening voor (int ik = 0; ik < = 5000; i ++) {val = (float) analogRead(sensor), ave = (ave * 0.999) + (val * 0.001); RMSAVE = (RMSAVE * 0.998) + .002*(abs((ave-val))); delayMicroseconds (50); Moduleert de sampling-snelheid (nu bemonstering bij 1000 Hz?) // Compute 1000 averages, then print final value to a file. void loop(){ start = millis(); for (int j=0; j < 5; j++){ TXLED1; // Green LED light uo when calculating for (int i=0; i <= 5000; i++){ val = (float) analogRead(sensor); ave = (ave * 0.999) + (val * 0.001); RMSAVE = (RMSAVE * 0.998) + .002*(abs((ave-val))); delayMicroseconds (50); //Modulates the sampling rate (now sampling at 1000 Hz?) } // Calcuulates the average for the 6-second period interval = millis()-start; RMStot = interval*RMSAVE; Median.add(RMStot); } TXLED0; if(Median.getMedian()>lowlim){ sum = sum + Median.getMedian(); //Updates the "sum", amount used (non-converted) if the varlue is over the threshold flag = 1; time = time+interval/60000; // Updates how long the shower was digitalWrite(17, LOW); // Lights up the yellow LED if above threshold } // The following section saves the data from the shower into the EEPROM memory after the Median drops below the threshold, and then resents the "sum". // Total number of showers recorded is stored in the EEPROM memory location 0 [EEPROM.read(0)] if (Median.getMedian() Calcuulates het gemiddelde voor de periode 6-seconde interval = millis ()-start; RMStot = interval * RMSAVE; Median.Add(RMStot); #include<EEPROM.h> void setup(){ Serial.begin(9600); delay(10000); // Gives you 10 seconds to open serial port after uploading sketch Serial.println("Initializing the Serial port"); }int numshowers = EEPROM.read(0); //Records number of showers from the first index in the EEEPROM memory int i = 0; ///Counter that will update how many shower have been printed out to the serial port int k = 1; // Counter that shows which memory address in to get the shower number from int gal;void loop(){ while (i < numshowers) { delay(100); // Keeps serial port from overloading gal = EEPROM.read(k)*100 + EEPROM.read(k+1)*10+EEPROM.read(k+2); Serial.println(gal); Serial.print("Length of Shower: "); Serial.println(EEPROM.read(k+3)); k = k + 4; i++; } Serial.print("Showers taken: "); Serial.println(numshowers); Serial.print("Data points printed: "); Serial.println(i); delay(10000); // Means that the "Showers taken" & "Data points printed" only is repeated every 10 seconds } TXLED0; if(Median.getMedian() > lowlim) {som = som + Median.getMedian(); //Updates de "som", de gebruikte hoeveelheid (niet-geconverteerde) als de varlue is over de drempel vlag = 1; tijd = tijd + interval/60000; / / Updates hoe lang de douche was digitalWrite (17, laag); / / de gele LED brandt als boven drempelDe volgende sectie worden de gegevens opgeslagen uit de douche in het EEPROM geheugen na de mediaan zakt tot onder de drempel, en dan de "som" kwalijk. Totale aantal douches opgenomen wordt opgeslagen in de EEPROM geheugenlocatie 0 [EEPROM.read(0)]
Software douche gegevens ophaalt uit de EEPROM op Arduino:
Het programma uploaden naar de Arduino en seriële monitor om data te lezen in seriële monitorvenster openen
#include < EEPROM.h > void setup {Serial.begin(9600); delay(10000); / / geeft je 10 seconden seriële poort openen nadat uploaden schets Serial.println ("initialiseren van de seriële poort");} int numshowers = EEPROM.read(0); Records aantal douches van de eerste index in het EEEPROM geheugen int i = 0; Teller die zal bijwerken hoeveel douche zijn afgedrukt uit tot de seriële poort int k = 1; Teller die laat zien welke geheugen adres om het nummer van de douche van int gal; void loop {terwijl (ik < numshowers) {delay(100); / / seriële poort weerhoudt overbelading gal = EEPROM.read (k) * 100 + EEPROM.read(k+1)*10+EEPROM.read(k+2); Serial.println(GAL); Serial.Print ("lengte van douche:"); Serial.println(EEPROM.Read(k+3)); k = k + 4; i ++;Serial.Print ("douches genomen:"); Serial.println(numshowers); Serial.Print ("gegevenspunten afgedrukt:"); Serial.println(i); delay(10000); Betekent dat de "Douches genomen" & "gegevenspunten gedrukt" alleen elke 10 seconden wordt herhaald