Arduino Yun – Sistema de Adquisición de Datos – Datalogger (parte 1)

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:
Pantallazo--dev-ttyACM0

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.

Deja un comentario