Paso 2: código
Un montón de pruebas y verificar de nuevo pasó a hacer el código lo que es ahora. Cosas pueden funcionar diferentemente para los sistemas de plomería o utiliza diferentes equipos durante todo el proceso. Este código trabaja para nuestro proyecto utilizando el equipo y los métodos que utilizamos.
La imagen es puramente para la demostración. Fuente de imagen http://apcmag.com/arduino-masterclass-part-3-tv-w...
Para este código específico descargamos varios 'bibliotecas' de cómo programar un arduino a nuestros ordenadores.
Software para la calibración de la Arduino
Llenar el cubo de 5 galones con agua y leer el número en la pantalla. Divida este número por 5 y tiene su factor de conversión (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 para control de proceso (guarda los datos de la ducha en EEPROM [memoria volátil en Arduino]):
Instalar la biblioteca de mediana corriente de Arduino.cc antes de subir este código. Utilizar programa de calibración empírica para determinar la "lowlim" y "con" (lowlim se utiliza para separar el ruido de fondo de agua en el tubo y "con" es el factor de conversión para calcular el uso del agua):
// 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); }
}
Calcular promedios de 1000, luego el valor final en un archivo de impresión. void loop() {iniciar = millis(); para (int j = 0; j < 5; j ++) {TXLED1; / / LED verde luz uo en el cálculo de (int i = 0; me < = 5000; i ++) {val = analogRead(sensor) (flotador), ave = (ave * 0.999) + (val * 0.001); RMSAVE = (RMSAVE * 0.998) + .002*(abs((ave-val))); delayMicroseconds (50); Modula la frecuencia de muestreo (muestreo ahora a 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 la media para el intervalo de período 6 segundos = millis ()-Inicio; RMStot = intervalo * 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) {suma = suma + Median.getMedian(); //Updates la "suma", cantidad usada (no convertido) si la varlue es la bandera de umbral = 1; tiempo = tiempo + intervalo/60000; / / actualizaciones cuánto la ducha fue digitalWrite (17, LOW); / / el LED amarillo se ilumina si por encima del umbralLa sección siguiente guarda los datos de la ducha en la memoria EEPROM, después de que la mediana cae por debajo del umbral y entonces resiente la "suma". Número total de duchas grabado se almacena en la memoria EEPROM 0 [EEPROM.read(0)]
Software de recuperación de datos de la ducha de EEPROM en Arduino:
Cargar el programa en el Arduino y abrir monitor de serie para leer datos en la ventana de monitor serial
#include < EEPROM.h > void setup() {Serial.begin(9600); delay(10000); / / le da 10 segundos para abrir el puerto serie después de subir sketch Serial.println ("inicialización puerto serie");} int numshowers = EEPROM.read(0); Número de expedientes de duchas del primer índice en el EEEPROM memoria int i = 0; Contador que se actualizará la ducha cuántos se han impreso hacia fuera para el puerto serie int k = 1; Contador que muestra qué memoria dirección en obtener el número de ducha de int gal; void loop() {mientras que (< numshowers) {delay(100); / / guarda puerto serie de sobrecarga gal = EEPROM.read (k) * 100 + EEPROM.read(k+1)*10+EEPROM.read(k+2); Serial.println(GAL); Serial.Print ("longitud de ducha:"); Serial.println(EEPROM.Read(k+3)); k = k + 4; i ++;Serial.Print ("duchas tomados:"); Serial.println(numshowers); Serial.Print ("puntos de datos impreso:"); Serial.println(i); Delay(10000); Significa que la "Ducha tomada" y "puntos de datos impresión" sólo se repite cada 10 segundos