SDR. Usar rtl_433 para obtener los datos de las estaciones meteorológicas de tus vecinos.

Podemos usar nuestro receptor SDR para captar señales usadas en dispositivos domóticos que trabajan en la frecuencia de 433Mhz y 868Mhz entre ellos algunas estaciones meteorológicas que muchas personas instalan en su casa. En lugar de comprar nuestra propia estación vamos a usar nuestro receptor SDR y el software rtl_433 para capturar datos que luego algún sistema nuestro pueda consumir y mostrar.

Empecemos con lo básico usaremos el comando rtl_433 para obtener datos de los dispositivos de IoT cercanos:

rtl_433 

Por defecto escucha en la frecuencia de 433 Mhz, si queremos usar otra frecuencia habitual como 868 Mhz

rtl_433 -f 868M

En los datos que se obtendrán hay todo tipo de dispositivos. El primer paso es filtrar los que nos interesan. Podemos buscar aquellos que tengan campos propios de las estaciones meteorológicas como temperatura y humedad y usar el campo «model» para buscar si es una estación meteorológica o algo que nos pueda servir.

Otro truco es verificar que los datos tienen que cuadrar. Si hace frío y la temperatura es de más de 20 grados es posible que sea un sensor interno. Hay dispositivos que devuelven valores sin sentido seguramente porque no tiene ese sensor. Por ejemplo entre los datos que leo hay un medidor de humedad del suelo que devuelve una temperatura de -88°C.


Cada dispositivo envía los valores de temperatura en grados Celsius o Farenheit. Por suerte podemos convertirlo a Celsius usando el parámetro «-C si» que convierte los valores al sistema internacional. 

rtl_433 -C si

Por ejemplo yo puedo aprovecharme del siguientes dispositivos:

time      : ############
brand     : OS
model     : Oregon-THGR122N                        
House Code: 155
Channel   : 1            
Battery   : 0             
Temperature: 3.90 C       
Humidity  : 70 %

time      : ############
model     : AlectoV1-Rain 
House Code: 139
Channel   : 0            
Battery   : 1             
Total Rain: 286.75 mm     
Integrity : CHECKSUM

Ahora que ya sabes que dispositvos podemos fiarnos y como identificarlos por el campo model tenemos el problema de leer los datos, por suerte rtl_433 permite formatear la salida en varios formatos como: kv, json, csv, mqtt, influx, syslog. Para ello bastacon usar el parámetro -F seguido del formato que queremos y si deseamos guardarlo en un fichero hay que indicarlo con -F formato:nombre_fichero

 rtl_433 -C si -F json:output.json

Cada vez que se lanza sobrescribe el fichero de datos con los nuevos datos.

Hay un último parámetro que puede ser útil para este caso en «-T segundos» que indica cuanto tiempo estará capturando datos rtl_433 antes de cerrarse. Por ejemplo:

 rtl_433 -C si -F json:output.json -T 30

Estará durante 30 segundo capturado datos en formato json y almacenándolos en el fichero «output.json»

Podríamos usar cron para planificar cada cuanto tiempo se lanza ese comando y se actualizan los datos del archivo.

Desventajas:

  • Depende de lo que tengan tus vecinos que puede ser la mejor estación del mercado como la peor del mundo.
  • Cuidado con confundir fuentes de datos (sensores internos y externos)
  • Aunque sea legal hay gente no le gusta que «escuches» sus sensores.

Ventajas:

  • Tienes múltiples fuentes de datos por lo que puede cruzar sus datos
  • Puedes aprovechar datos que no vienen de estaciones meteorológicas, por ejemplo anemómetros colocados en toldos para pleglarlos cuando sopla el viento.
  • Si alguno de los sensores «cae» puedes usar los datos de otros.

Puedes ver un vídeo practico sobre este mismo tema en mi canal de Youtube:

Haz click para ver el vídeo en mi canal de Youtube

Arduino. Volcado de la memoria RAM, flash y EEPROM usando Dump

Ya hemos visto como leer un byte de los distintos tipos de memoria de la placa Arduino. Sabiendo leer un byte podemos recorriendo y mostrando todos los bytes entre dos direcciones para conseguir un volcado. Pero si queremos algo con «mejor aspecto» podemos usar la librería Dump .

Tenemos dos funciones, una devuelve un volcado de la SRAM y otra un volcado de la memoria flash.

Volcado de la SRAM: dumpRam(out, addr, size);

Volcado de la memoria flash: dumpPgm(out, addr, size);

Los parámetros que se les pasa son los siguientes:

  • out: Serial al que enviar los datos
  • addr: dirección en la que comenzar el volcado
  • size: cantidad de bytes que se mostraran

Faltaría un volcado de la memoria EEPROM, por suerte es sencillo crear nuestra propia función fijándonos en el código de las que ya tiene:

unsigned char memByteEeprom(const void* x) {
  return EEPROM[int(x)];
}

void dumpEeprom(Print& out, void const* at, int sz) {
  return dump(out,at,sz,memByteEeprom);
}

Veamos un ejemplo completo de su uso:

#include <Dump.h>
#include <EEPROM.h>

const unsigned int* ramTest = (unsigned int*) 0x100;
const unsigned int* pgmTest = (unsigned int*) 0x100;

void setup() {
  Serial.begin(9600);
  while(!Serial);
  Serial.println("Dump SRAM");
  dumpRam(Serial,ramTest,64);
  Serial.println("Dump Flash");
  dumpPgm(Serial,pgmTest,64);
  Serial.println("Dump EEPROM");
  dumpEeprom(Serial,0,64);
}

void loop(){}

unsigned char memByteEeprom(const void* x) {
  return EEPROM[int(x)];
}

void dumpEeprom(Print& out, void const* at, int sz) {
  return dump(out,at,sz,memByteEeprom);
}

La salida obtenida:

Dump SRAM
0x0100: ......e. ..R..... 00 00 00 00 05 01 65 00  92 00 52 01 C3 00 A1 00 
0x0110: .....000 .0x.: .D B5 00 0D 0A 00 30 30 30  00 30 78 00 3A 20 00 44 
0x0120: ump SRAM .Dump Fl 75 6D 70 20 53 52 41 4D  00 44 75 6D 70 20 46 6C 
0x0130: ash.Dump  EEPROM. 61 73 68 00 44 75 6D 70  20 45 45 50 52 4F 4D 00 
Dump Flash
0x0100: ...-.... .+y..... F0 81 E0 2D C6 01 09 95  89 2B 79 F7 C5 01 DF 91 
0x0110: ........ ........ CF 91 1F 91 0F 91 FF 90  EF 90 DF 90 CF 90 BF 90 
0x0120: ......S. D.%/0../ AF 90 08 95 FC 01 53 8D  44 8D 25 2F 30 E0 84 2F 
0x0130: ......T. ........ 90 E0 82 1B 93 0B 54 17  10 F0 CF 96 08 95 01 97 
Dump EEPROM
0x0000: ........ ...._... A3 00 BE BF BF 00 00 00  00 00 36 00 5F 00 0E 00 
0x0010: ...... . ..J.0... 00 00 00 00 01 00 20 08  18 00 4A 01 30 00 1E 00 
0x0020: ........ ........ B8 B8 B8 1F 00 00 02 00  00 01 00 00 B8 B8 B8 B8 
0x0030: ....5... ........ B8 B8 B8 B8 B8 06 07 07  B8 B8 B8 00 00 00 00 00 

Este texto mejorado y ampliado forma parte de mi libro sobre como mejorar tus programas en Arduino. Puedes echarle un vistazo aquí.

Tienes el vídeo donde explico este post en mi canal de Youtube:

Haz click para el vídeo en mi canal de Youtube