Datalogger arduino. Adquisición de datos de los sensores
Se va a definir una función que recibe peticiones del subsistema linux mediante Bridge, y también del puerto serie para depuración. Tendrá la siguiente funcionalidad básica:
- parámetros de entrada: numero de señal, número de repeticiones, tiempo entre repeticiones, filtrado de extremos (SI o NO), tipo de cálculo (media, min, max, acum)
- parámetros de salida: estadístico solicitado según los parámetros de entrada
- si se coloca un RTC, hay que dotar de las funciones de lectura y escritura de la hora.
ACTUALIZADO (parte2): Lo más correcto es emplear los servicios web al modo del ejemplo: http://arduino.cc/en/Tutorial/Bridge
Cada señal será de un sensor diferente y en cada caso se tratará así mismo de forma diferente. No pretendemos desarrollar un datalogger genérico sino simplemente hacer un interfaz común de la comunicación de las medidas realizadas por el arduino hacia un elemento superior.
Probamos inicialmente las posibilidades de Brigde y Console con el siguiente sketch y una función de adquisición de datos simple:
/* ConsoleDataCom Sistema de adquisicion de datos Arduino. To see the Console, pick your Yún's name and IP address in the Port menu then open the Port Monitor. You can also see it by opening a terminal window and typing ssh root@ yourYunsName.local 'telnet localhost 6571' */ #include <Console.h> // para depuracion desde Console, siempre es posible depurar desde Serial #define DEBUG 0 #define CODIGO_ERROR -9999 char incomingByte; // a variable to read incoming Console data into int numSen=0,numRep=0,tiempoRep=1000,filtrar=1,calculo=1; // para lectura de sensor de ultrasonidos #include <Ultrasonic.h> Ultrasonic ultrasonic(5,6); // (Trig PIN,Echo PIN) void setup() { Bridge.begin(); // Initialize Bridge Console.begin(); // Initialize Console // Wait for the Console port to connect // while(!Console); Console.println("Funciones de adquisicion de datos:\n\t 1-> tomar medida señal\n\t\t Params:(Num Señal, Num Repeticiones,Tiempo entre Repeticiones, filtrar Extremos, calculo: med,max,min,suma)"); Console.println("\t\t\t ejemplo de uso: 1,3,8,1000,1 (funcin 1, señal 3, 8 repeticiones, intervalo de 1000 ms entre rep., eliminar extremos, calculo Media)"); Console.println("Funciones de tiempo: T->"); Serial.begin(9600); // while (!Serial) // wait for serial port to connect. Needed for Leonardo only Serial.println("Funciones de adquisicion de datos:\n\t 1-> tomar medida señal\n\t\t Params:(Num Repeticiones,Tiempo entre Repeticiones, filtrar Extremos, calculo: med,max,min,suma)"); Serial.println("Funciones de tiempo: T->"); // inicializar sensor ultrasonidos pinMode(4, OUTPUT); // VCC pin pinMode(7, OUTPUT); // GND ping digitalWrite(4, HIGH); // VCC +5V mode digitalWrite(7, LOW); // GND mode } void loop() { // see if there's incoming Console data: if (Console.available() > 0) { // read the oldest byte in the Console buffer: incomingByte = Console.read(); if (DEBUG) Console.println(incomingByte); //parse commands and functions: if (incomingByte == '1') { if (DEBUG){ Console.println("1-> tomar medida señal"); } // read the next byte in the Console buffer, coma incomingByte = Console.read(); if (incomingByte == ',') { // read the next byte in the Console buffer like Integer numSen = Console.parseInt(); if (DEBUG){ Console.print("numSen "); Console.println(numSen); } } // read the next byte in the Console buffer, coma incomingByte = Console.read(); if (incomingByte == ',') { // read the next byte in the Console buffer like Integer numRep = Console.parseInt(); if (DEBUG){ Console.print("numRep "); Console.println(numRep); } } // read the next byte in the Console buffer, coma incomingByte = Console.read(); if (incomingByte == ',') { // read the next byte in the Console buffer like Integer tiempoRep = Console.parseInt(); if (DEBUG){ Console.print("tiempoRep "); Console.println(tiempoRep); } } // read the next byte in the Console buffer, coma incomingByte = Console.read(); if (incomingByte == ',') { // read the next byte in the Console buffer like Integer filtrar = Console.parseInt(); if (DEBUG){ Console.print("filtrar "); Console.println(filtrar); } } // read the next byte in the Console buffer, coma incomingByte = Console.read(); if (incomingByte == ',') { // read the next byte in the Console buffer like Integer calculo = Console.parseInt(); if (DEBUG){ Console.print("calculo "); Console.println(calculo); } } Console.println(medidaSensor()); } else if(incomingByte == '\n'){ }else{ if (DEBUG){ Console.println(incomingByte); Console.println("funcion desconocida"); } Console.println(CODIGO_ERROR); } } // see if there's incoming Console data: if (Serial.available() > 0) { // read the oldest byte in the Serial buffer: incomingByte = Serial.read(); Serial.println(incomingByte); //parse comandas and functions: if (incomingByte == '1') { Serial.println("1-> tomar medida señal"); // read the next byte in the Serial buffer, coma incomingByte = Serial.read(); if (incomingByte == ',') { // read the next byte in the Serial buffer like Integer numSen = Serial.parseInt(); Serial.print("numSen "); Serial.println(numSen); } // read the next byte in the Serial buffer, coma incomingByte = Serial.read(); if (incomingByte == ',') { // read the next byte in the Serial buffer like Integer numRep = Serial.parseInt(); Serial.print("numRep "); Serial.println(numRep); } // read the next byte in the Serial buffer, coma incomingByte = Serial.read(); if (incomingByte == ',') { // read the next byte in the Serial buffer like Integer tiempoRep = Serial.parseInt(); Serial.print("tiempoRep "); Serial.println(tiempoRep); } // read the next byte in the Serial buffer, coma incomingByte = Serial.read(); if (incomingByte == ',') { // read the next byte in the Serial buffer like Integer filtrar = Serial.parseInt(); Serial.print("filtrar "); Serial.println(filtrar); } // read the next byte in the Serial buffer, coma incomingByte = Serial.read(); if (incomingByte == ',') { // read the next byte in the Serial buffer like Integer calculo = Serial.parseInt(); Serial.print("calculo "); Serial.println(calculo); } Serial.println(medidaSensor()); } else{ Serial.println(incomingByte); Serial.println("funcion desconocida"); Serial.println(CODIGO_ERROR); } } } // metodo encargado de las diferentes medidas double medidaSensor(){ double medida=CODIGO_ERROR,maximo,minimo; double medidas[numRep]; int indiceMax=0,indiceMin=0,indiceAux=0; boolean iniciadosValores=false; switch (numSen){ // ultrasonidos case 1: for (int rep=0;rep<numRep;rep++){ double medida=ultrasonic.Ranging(CM); if (DEBUG) Console.println(medida); medidas[rep] = medida; if(medida>medidas[indiceMax]) indiceMax=rep; if(medida<medidas[indiceMin]) indiceMin=rep; // intervalo de espera entre medidas delay(tiempoRep); } // si los indices coinciden es que todas las medidas son iguales if(indiceMax==indiceMin) indiceMax=indiceMin++; if (DEBUG){ Console.println("Indices extremos"); Console.println(indiceMax); Console.println(indiceMin); } Serial.println("Indices extremos"); Serial.println(indiceMax); Serial.println(indiceMin); // filtro de extremos: if(filtrar){ for (int rep=0;rep<numRep;rep++){ if(rep==indiceMax) continue; if(rep==indiceMin) continue; if(!iniciadosValores){ maximo=medidas[rep]; minimo=medidas[rep]; medida=0; if (DEBUG){ Console.println("inicializar medida"); Console.println(medida); } Serial.println("inicializar medida"); Serial.println(medida); iniciadosValores=true; } switch (calculo){ case 2: // max if(medidas[rep]>maximo) maximo=medidas[rep]; break; case 3: //min if(medidas[rep]<minimo) minimo=medidas[rep]; break; default: medida=medida+medidas[rep]; } } if (DEBUG){ Console.println("medida final"); Console.println(medida); } Serial.println("medida final"); Serial.println(medida); //calculo final switch (calculo){ case 1: // med medida=medida/(numRep-2); break; case 2: // max medida=maximo; break; case 3: //min medida=minimo; break; default: medida=medida; } }else{ for (int rep=0;rep<numRep;rep++){ if(!iniciadosValores){ maximo=medidas[rep]; minimo=medidas[rep]; medida=0; if (DEBUG){ Console.println("inicializar medida"); Console.println(medida); } Serial.println("inicializar medida"); Serial.println(medida); iniciadosValores=true; } switch (calculo){ case 2: // max if(medidas[rep]>maximo) maximo=medidas[rep]; break; case 3: //min if(medidas[rep]<minimo) minimo=medidas[rep]; break; default: medida=medida+medidas[rep]; } } if (DEBUG){ Console.println("medida final"); Console.println(medida); } Serial.println("medida final"); Serial.println(medida); //calculo final switch (calculo){ case 1: // med medida=medida/(numRep); break; case 2: // max medida=maximo; break; case 3: //min medida=minimo; break; default: medida=medida; } } break; default: break; } return medida; }
Desde el monitor serie siempre se muestra información de depuración. Desde Console, sólo se muestra información de depuración si se define DEBUG a 1, al inicio del sketch.
Por ejemplo una vez conectado el sensor de ultrasonidos podemos lanzar la consola del siguiente modo:
[adan@adan ~]$ ssh root@yun 'telnet localhost 6571' root@yun's password: sh: /usr/bin/X11/xauth: not found 1,1,5,1000,1,1 13.00
Desde el monitor serie se ve la información de depuración:
Básicamente la función 1 y sus parámetros:
1-> tomar medida señal
numSen 1
numRep 5
tiempoRep 1000
filtrar 1
calculo 1
Para cada numSen se adquirirán los datos según el sensor correspondiente. En el ejemplo actual sólo se está midiendo con el sensor de ultrasonidos.