door mvdbro » 22 jul 2012, 10:31
Ik werk al enkele maanden zonder problemen met remote Oregon Scientific sensoren (1 binnen en 1 buiten) van het tyoe THN132N. Het protocol is heel goed beschreven op internet. Temperaturen staan bij mij nu ook in de Nodo webapp. Code voor de Nodo r386:
unsigned long Oregon_Decode(void)
{
int y = 1;
int c = 1;
int startpulses = 0;
unsigned long rfbit = 1;
unsigned long id = 0;
unsigned long channel = 0;
unsigned long rc = 0;
unsigned long flags = 0;
unsigned long data = 0;
unsigned long sign = 0;
unsigned long checksum = 0;
byte checksumcalc = 0;
byte digit1, digit2, digit3;
byte var;
int datavalue = 0;
// valid messages are between 196-206 pulses
if ((RawSignal.Number < 196) | (RawSignal.Number > 206)) return 0L;
// should start with minimum of 30 long pulses
for(byte x=1;x<=32;x++) if(RawSignal.Pulses[x] > 500) startpulses++;
if (startpulses < 30) return 0L;
for(byte x=1;x<=RawSignal.Number;x++)
{
if(RawSignal.Pulses[x] < 500)
{
rfbit = rfbit ^ 1;
x++;
}
if (y%2 == 1)
{
if ((c>=21) && (c<=36)) id = (id >> 1) | (rfbit << 15);
if ((c>=37) && (c<=40)) channel = (channel >> 1) | (rfbit << 3);
if ((c>=41) && (c<=48)) rc = (rc >> 1) | (rfbit << 7);
if ((c>=49) && (c<=52)) flags = (flags >> 1) | (rfbit << 3);
if ((c>=53) && (c<=64)) data = (data >> 1) | (rfbit << 11);
if ((c>=65) && (c<=68)) sign = (sign >> 1) | (rfbit << 3);
if ((c>=69) && (c<=76)) checksum = (checksum >> 1) | (rfbit << 7);
c++;
}
y++;
}
digit3 = data & 0xf;
digit2 = (data >> 4) & 0xf;
digit1 = (data >> 8) & 0xf;
checksumcalc = ((id & 0xf000) >> 12) + ((id & 0x0f00) >> 8) + ((id & 0x00f0) >> 4) + (id & 0x000f) + ((rc & 0xf0) >> 4) + (rc & 0x0f) + channel + flags + digit1 + digit2 + digit3 + sign;
if (checksum != checksumcalc)
{
return 0L;
}
// if valid type (1230), update user variable and process event
if (id == 1230)
{
var = 10 + channel;
if (var == 14) var = 13;
if ((var >= 11) & (var <= 13))
{
datavalue = ((1000 * digit1) + (100 * digit2) + (10 * digit3));
if ((sign & 0x8) == 8) datavalue = -1 * datavalue;
UserVar[var-1] = datavalue;
ProcessEvent(AnalogInt2event(UserVar[var-1], var, CMD_VARIABLE_EVENT), VALUE_DIRECTION_INTERNAL, VALUE_SOURCE_VARIABLE, 0, 0);
}
}
// send result to terminal as a string 'RawSignal=<id>,<channel>,<value>
sprintf(TempString,"%s","RawSignal=");
strcat(TempString,int2str(id));
strcat(TempString,",");
strcat(TempString,int2str(channel));
strcat(TempString,",");
if ((sign & 0x8) == 8) strcat(TempString,"-");
strcat(TempString,int2str(digit1));
strcat(TempString,int2str(digit2));
strcat(TempString,".");
strcat(TempString,int2str(digit3));
PrintTerminal(TempString);
lcdprint(TempString);
return 1L;
}
Sensoren van Alecto, Hama, Auriol, Ventus (gebruiken waarschijnlijk allemaal hetzelfde protocol) zijn ook goed gedocumenteerd, echter heb ik die niet, dus kan ook niet testen. Ik heb wel al eens een stukje code gemaakt om de signalen te herkennen. (74 pulsen, 36 bits). Hieruit komt dan een 32 bit code waaruit we alleen nog maar de temperatuur en humidity uit hoeven te halen. De weerstations zijn volgens mij ook relatief eenvoudig uit te lezen, maar die heb ik ook niet...
Waarom ik hiervoor kies en niet een dedicated nodoslave oid:
1) Werkt maandenlang op batterij, de Nodo is daar standaard niet voor geschikt, vereist 'low power mode en wake interrupts e.d.)
2) Goedkoop, 19,95 alles compleet. (je krijgt er zelfs een ontvanger bij, maar die gebruik ik niet)
3) Voorzien van net kastje, geschikt om buiten te monteren, spatwaterdicht
4) Geen gaten in je kozijn boren voor een losse buitensensor, de gehele unit hangt buiten
5) Geen calibratie nodig van de sensor.
Er is ook wel een nadeel, ze zenden ong elke 35 seconden. Ik vindt dat nogal overdreven, maar dat is dus niet aan te passen.
gr
Martinus