He estado haciendo un programa para recibir la transmisión de un termómetro inalámbrico. Ya lo tengo funcionando pero como he visto que no hay mucha información al respecto, y que este tipo de termómetros parecen bastante comunes porque son muy baratos, les paso a continuación el programa final y un link a la descripción completa que he puesto en internet. Espero que les resulte útil:
#include <PinChangeInt.h>
#include <ByteBuffer.h>
#define DATA 8
#define BUFLEN 20
#define MAXBITS 32
ByteBuffer buffer;
unsigned long paquete=0L;
byte bits_paquete=0;
//////////////////////////////////////////////////
void cambio() {
unsigned long m;
static unsigned long dur_low;
static unsigned long dur_high;
static bool recibiendo=0;
static unsigned long lmicros=0;
static unsigned long hmicros=0;
m=micros();
if (digitalRead(DATA)==HIGH){ //flanco de subida
hmicros=m;
dur_low=m-lmicros;
//si el ultimo pulso alto duro 1ms, es un separador de pulsos y hay que procesar este dato
if (recibiendo){
if (dur_low<1800L) return; //tiene que tener por lo menos 1,8ms
if (dur_low>8000L) { //si es un pulso de 10ms, es un fin de paquete
digitalWrite(13,HIGH);
procesar_paquete();
return;
}
digitalWrite(13,LOW);
agregar_pulso(dur_low>3000L); //si el pulso es de 5ms, es un 1, si es de 2 ms es un 0
}
return;
}
//flanco de bajada
lmicros=m;
dur_high=m-hmicros;
//si es un pulso de 0,5ms estamos recibiendo datos
if (dur_high>400L && dur_high<900L) {
recibiendo=1;
}
else {
bits_paquete=0;
recibiendo=0;
paquete=0L;
}
}
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
void agregar_pulso(bool valor){
paquete=(paquete<<1) | valor;
bits_paquete++;
}
////////////////////////////////////////////////////////////////////////////
void procesar_paquete(){
buffer.put(bits_paquete);
buffer.putLong(paquete);
paquete=0L;
bits_paquete=0;
}
////////////////////////////////////////////////////////////////////////////
void setup() {
buffer.init(20);
buffer.clear();
pinMode(DATA, INPUT);
pinMode(13, OUTPUT);
digitalWrite(13,LOW);
pinMode(12, OUTPUT);
PCintPort::attachInterrupt(DATA, &cambio, CHANGE);
Serial.begin(115200);
Serial.println("---------------------------------------");
}
/////////////////////////////////////////////////////////////////////////////////////
void mostrar_dato(unsigned long p){
float temp;
bool bot;
byte canal=0;
byte a;
word b;
byte c;
Serial.print("datos:");
Serial.println(p,BIN);
/*
4 bits ???? (va variando)
8 bits ? (fijo)
12 bits temperatura en celsius
2 bits canal
2 bits ?? (fijo)
*/
a=(p & 0b1110000000000000000000000000) >> 25;
b=(p & 0b0000111111110000000000000000) >> 16;
a=(p & 0b0000000000000000000000000011);
bot=(p & 0b0001000000000000000000000000 !=0);
temp=(0.0+((p & 0b0000000000001111111111110000) >> 4)) /10;
if (temp>204.8) temp-=409.6;
canal=(p & 0b0000000000000000000000001100) >> 2;
Serial.print("temp:");
Serial.println(temp);
Serial.print("boton:");
Serial.println(bot);
Serial.print("canal:");
Serial.println(canal);
Serial.print(a,BIN);
Serial.print(" ");
Serial.print(b,HEX);
Serial.print(" ");
Serial.println(c,BIN);
}
/////////////////////////////////////////////////////////////////////////////////////
unsigned long p;
unsigned long ant=0;
unsigned long rep=0;
unsigned long tiempo=0,m=0;
byte l;
byte estado=0;
void loop() {
if (buffer.getSize()>4){
l=buffer.get();
p=buffer.getLong();
if (l==28){
tiempo=millis()-m;
m=millis();
if (estado==0){ //esperando repeticiones
if(ant==p) rep++;
else rep=0;
if (rep>4) {
estado=1;
mostrar_dato(p);
}
}
else if(estado==1){ //al menos 4 repeticiones
if(ant!=p || tiempo>1000) estado=0;//ya no se repite
}
ant=p;
} //l==28
}//buffer con datos
}