Décodage des protocoles Oregon Scientific sur Arduino (2/3)
Dans l’article précédant nous avons récupéré les trames brutes que les sondes Oregon Scientific émettent. Il nous reste maintenant à décoder celles-ci pour obtenir les informations que l’on attends.
[adsGrandRectangleTexte]
Décodage des trames Oregon Scientific
Selon le modèle de la sonde, les tailles de trames et les informations à récupérer sont différentes (température, humidité, vitesse et direction du vent, etc…). Il faut donc dans un premier temps identifier de quelle sonde provient la trame reçue.
De quel modèle de sonde s’agit’il ?
Le modèle de la sonde est codé dans les deux premiers octets de la trame. Ci-dessous, le tableau des correspondances sondes/codes :
Sensor name | Code | Type |
Oregon-THR128 Oregon-THR138 Oregon-THC138 |
0x0A4D | Inside Temperature |
Oregon-THC238 Oregon-THC268 Oregon-THN132N Oregon-THWR288A Oregon-THRN122N Oregon-THN122N Oregon-AW129 Oregon-AW131 |
0xEA4C | Outside/Water Temp |
Oregon-THWR800 | 0xCA48 | Water Temp |
Oregon-THGN122N Oregon-THGN123N Oregon-THGR122NX Oregon-THGR228N Oregon-THGR238 Oregon-THGR268 |
0x1A2D | Inside Temp-Hygro |
Oregon-THGR810 | 0xFA28 | Inside Temp-Hygro |
Oregon-RTGR328N | 0x*ACC | Outside Temp-Hygro |
Oregon-THGR328N | 0xCA2C | Outside Temp-Hygro |
Oregon-WTGR800 | 0xFAB8 | Outside Temp-Hygro |
Oregon-THGR918 Oregon-THGRN228NX Oregon-THGN500 |
0x1A3D | Outside Temp-Hygro |
Huger – BTHR918 | 0x5A5D | Inside Temp-Hygro-Baro |
Oregon-BTHR918N Oregon-BTHR968 |
0x5A6D | Inside Temp-Hygro-Baro |
Oregon-RGR126 Oregon-RGR682 Oregon-RGR918 |
0x2A1D | Rain Gauge |
Oregon-PCR800 | 0x2A19 | Rain Gauge |
Oregon-WTGR800 | 0x1A99 | Anemometer |
Oregon-WGR800 | 0x1A89 | Anemometer |
Huger-STR918 Oregon-WGR918 |
0x3A0D | Anemometer |
Oregon-UVN128 Oregon-UV138 |
0xEA7C | UV sensor |
Oregon-UVN800 | 0xDA78 | UV sensor |
Oregon-RTGR328N | 0x*AEC | Date & Time |
cent-a-meter OWL CM113 Electrisave |
0xEAC0 | Ampere meter |
OWL CM119 | 0x1A** 0x2A** 0x3A** |
Power meter |
Dans l’article précédent, il y a un exemple de trames produites par une sonde THN132N :
EA4C20369C200004
et une THGR228N :
1A2D20BB1C26008348A7
1A2D20BB8C2500834EE0
1A2D20BB6C2500834C24
1A2D20BB4C2500834A08
Si on regarde ces trames, on retrouve bien le code 0xEA4C pour la sonde THN132N et le code 0x1A2D pour la sonde THGR228N de Michael067, jusque là tout est bon 🙂
On voit aussi qu’elles n’ont pas la meme taille (cf les problèmes rencontrés lors du décodage)
On sait maintenant à quelle type de sonde on a à faire. Grace à cela, nous allons pouvoir connaitre la taille de la trame ainsi que les informations qu’elle contient.
Décodage des informations
Pour le décodage des informations, il faut savoir où aller les chercher dans la trame. Pour cela, autant faire confiance à un logiciel qui le fait déjà très bien. Je me suis basé sur les sources de xpl-perl, plus particulièrement le fichier lib/xPL/RF/Oregon.pm. Celui ci contient tout ce dont nous avons besoin pour décoder les différentes informations, à savoir :
- La longueur des trames pour chaque type de sonde
- le type d’informations envoyées pour chaque type de sonde
- et le décodage de chacune de ces informations
que demander de plus ? 🙂
Implémentation dans l’arduino
J’ai repris le code de l’article précédant auquel j’ai ajouté les fonctions de décodage de la température, humidité, niveau de batterie, canal et modifié la fonction reportSerial().
Dans cet exemple, on décode les trames envoyées par les sondes de température THN132N et les autres qui possèdent le meme code (0xEA4C), ainsi que les sondes de température/humidité qui possèdent le code 0x1A2D.
float temperature(const byte* data) { int sign = (data[6]&0x8) ? -1 : 1; float temp = ((data[5]&0xF0) >> 4)*10 + (data[5]&0xF) + (float)(((data[4]&0xF0) >> 4) / 10.0); return sign * temp; } byte humidity(const byte* data) { return (data[7]&0xF) * 10 + ((data[6]&0xF0) >> 4); } // Ne retourne qu'un apercu de l'etat de la baterie : 10 = faible byte battery(const byte* data) { return (data[4] & 0x4) ? 10 : 90; } byte channel(const byte* data) { byte channel; switch (data[2]) { case 0x10: channel = 1; break; case 0x20: channel = 2; break; case 0x40: channel = 3; break; } return channel; } void reportSerial (const char* s, class DecodeOOK& decoder) { byte pos; const byte* data = decoder.getData(pos); Serial.print(s); Serial.print(' '); for (byte i = 0; i < pos; ++i) { Serial.print(data[i] >> 4, HEX); Serial.print(data[i] & 0x0F, HEX); } // Outside/Water Temp : THN132N,... if(data[0] == 0xEA && data[1] == 0x4C) { Serial.print("[THN132N,...] Id:"); Serial.print(data[3], HEX); Serial.print(" ,Channel:"); Serial.print(channel(data)); Serial.print(" ,temp:"); Serial.print(temperature(data)); Serial.print(" ,bat:"); Serial.print(battery(data)); Serial.println(); } // Inside Temp-Hygro : THGR228N,... else if(data[0] == 0x1A && data[1] == 0x2D) { Serial.print("[THGR228N,...] Id:"); Serial.print(data[3], HEX); Serial.print(" ,Channel:"); Serial.print(channel(data)); Serial.print(" ,temp:"); Serial.print(temperature(data)); Serial.print(" ,hum:"); Serial.print(humidity(data)); Serial.print(" ,bat:"); Serial.print(battery(data)); Serial.println(); } decoder.resetDecoder(); }
Et voila ce que sort le nouveau sketch avec mes sondes THN132N et pour une des trames de la sonde THGR228N de Michael067:
OSV2 EA4C20369C200004[THN132N,...] Id:36 ,Channel:2 ,temp:20.90 ,bat:10 OSV2 EA4C20C55C2040D4[THN132N,...] Id:C5 ,Channel:2 ,temp:20.50 ,bat:10 OSV2 1A2D20BB1C26008348A7[THGR228N,...] Id:BB ,Channel:2 ,temp:26.10 ,hum:30.00 ,bat:10
Conclusion
Nous avons maintenant toutes les cartes en main pour réceptionner les données de nos sondes oregon.
Il me reste à tester le décodeur du protocol v3 mais il devrait fonctionner sans plus de soucis.
Il faut aussi revoir la contidion de sortie du décodeur qui ne semble pas correcte pour toutes les sondes (cf les commentaires de Michael067).
Dans le prochain article, je vous parlerai de la portée de réception. J’ai également commencé à écrire une librairie propre pour intégrer facilement le décodage des sondes Oregon dans la librairie connectingStuff ou dans un projet tier.
Merci de poster vos retours ou les résultats de vos tests sur d’autre type de sondes 🙂
Hello Olivier,
je viens de tester ton programme de decodage des differentes métriques avec mes sondes THN132N , voici la sortie console :
OSV2 1A2D103722189005368E[THGR228N,…] Id:37 ,Channel: ,temp:18.20 ,hum:; ,bat:Z
OSV2 1A2D103722189005368E[THGR228N,…] Id:37 ,Channel: ,temp:18.20 ,hum:; ,bat:Z
OSV2 1A2D103722189005368E[THGR228N,…] Id:37 ,Channel: ,temp:18.20 ,hum:; ,bat:Z
OSV2 1A2D103722189005368E[THGR228N,…] Id:37 ,Channel: ,temp:18.20 ,hum:; ,bat:Z
OSV2 1A2D103722189005368E[THGR228N,…] Id:37 ,Channel: ,temp:18.20 ,hum:; ,bat:Z
OSV2 1A2D20C46827500442D2[THGR228N,…] Id:C4 ,Channel: ,temp:27.60 ,hum:- ,bat:Z
OSV2 1A2D20C46827500442D2[THGR228N,…] Id:C4 ,Channel: ,temp:27.60 ,hum:- ,bat:Z
OSV2 1A2D2075782750043FC4[THGR228N,…] Id:75 ,Channel: ,temp:27.70 ,hum:- ,bat:Z
OSV2 1A2D2075782750043FC4[THGR228N,…] Id:75 ,Channel: ,temp:27.70 ,hum:- ,bat:Z
OSV2 1A2D10371218900535B4[THGR228N,…] Id:37 ,Channel: ,temp:18.10 ,hum:; ,bat:Z
OSV2 1A2D10371218900535B4[THGR228N,…] Id:37 ,Channel: ,temp:18.10 ,hum:; ,bat:Z
OSV2 1A2D10371218900535B4[THGR228N,…] Id:37 ,Channel: ,temp:18.10 ,hum:; ,bat:Z
OSV2 1A2D10371218900535B4[THGR228N,…] Id:37 ,Channel: ,temp:18.10 ,hum:; ,bat:Z
La température de 18.20 est ok c’est ma sonde extérieur, j’ai aussi du changer les piles de ma 2ème sonde (intérieur celle ci) on le voit avec les ID : C4 et 75 (bizzare que l’id change, c’est la même sonde pourtant, dans le temps l’id reste 75, C4 doit être le code pour signaler la découverte ? ou je sais ) Pour le taux d’humidité, le channel et la batterie c’est pas encore ca mais cela vient p-e car le programme détecte mon sonde comme une THGR228N au lieu d’une THN132N .
Par contre il faut vraiment attendre 5-10min avant d’avoir la première trame.
Après lecture de ton code, il semble que pour les deux sondes tu lise tableau data de la meme manière? c’est voulu ?
Je continuerai de bidouiller demain! Dans tous les cas ton programme marche 😉 Bravo et merci encore!
++Benny
Merci pour ton retour 🙂
L’Id change à chaque fois que la batterie est remplacée, sinon il reste fixe, du coup ca semble correspondre, l’id de la sonde ext ne change pas et l’autre à changé au changement de pile. L’id est généré aléatoirement par la sonde.
Ce que je ne comprends pas c’est que la trame envoyée par ta sonde (du moins celle reçue) commence par 0x1A2D, ce qui ne correspond pas à une THN132N ?
Je pencherai plutot pour un problème de réception car j’ai testé justement avec des sondes THN132N et des trames de THGR228N. Je vais retester sur un duemilanove pour voir (je n’ai pas de UNO)
Pour le temps de réception, normalement c’est rapide. Dès qu’une sonde emet c’est bon (en général j’enleve la pile et je la remet pour qu’elle émette de suite). Apres c’est peut etre à cause de la condition de sortie du décodeur que je dois revoir ? de la « polution » de la bande 433 ? ou encore de la portée (elle sont loin tes sondes) ?
Il faudrait aussi ajouter le control du CRC, ont verrai si tes trames sont correcte, je regarde ça dans la journée.
Oui ces deux types de sonde ont le meme codage, sauf que la THGR228N à l’humidité en plus. D’autres sonde ont des codages qui diffèrent un peu (cf les sources de xpl-perl).
Pas trop de réponses pour l’instant désolé 🙁 … à voir le résultat du CRC
Hello !
Ca fait un moment que je n’étais pas revenu xD navré, je me relance sur le sujet pour faire des cartes homemade à base de RFM69 qui se font passer pour des sonde Oregon, j’y suis presque.
J’en profite pour répondre au question de l’époque 😉
Ma sonde est une THGN132N qui semble se faire passer pour une THGR228N.
J’ai remis ton code et j’obtiens :
OSV2 1A2D101F611670063CF7[THGR228N,…] Id:1F ,Channel:1 ,temp:16.60 ,hum:67 ,bat:90
J’essaye de faire de même avec ma carte bricolé maison mais il me manque 2 « chiffre/lettre » j’ai 18 caractères au lieu de 20 et pourtant j’utilise ton code pour encoder (cf ton article : http://connectingstuff.net/encodage-protocoles-oregon-scientific-sur-arduino/)
Je vais voir pour rajouter ces caractères si la trames est bien reçue il me restera à envoyer la « vrai » température d’une sonde DS18B20 au lieu de la trame de test.
Merci pour tout ton taf c’est une mine d’or pour certains comme moi qui n’ont pas le niveau 🙂
Salut Benny,
Je suis en train de préparer le prochain article et j’ai pris une de tes trames pour tester, celle ci :
OSV2 1A2D10371218900535B4[THGR228N,…] Id:37 ,Channel: ,temp:18.10 ,hum:; ,bat:Z
sans toucher au code, j’obtiens :
OSV2 1A2D10371218900535B4[THGR228N,…] Id:37 ,Channel:1 ,temp:18.10 ,hum:59 ,bat:90
bizard ? je suis toujours sur mon mega, j’essaie de tester sur le duemilanove pour voir. Ca me parait improbable qu’il te sorte une trame correct de THGR228N si t’as sonde est une THN132N ???
J’ai même ajouté le calcul de la checksum et elle est bonne sur cette trame.
Je testerais en fin de semaine, pas le temps en ce moment.
j’ai egalement commandé une antenne 433 mhz
encore Merci Olivier 🙂
Bravo Olivier,
voici le resultat :
[ookDecoder]
OSV2 1A2D108E042310443964[THGR228N,…] Id:8E ,Channel:1 ,temp:23.00 ,hum:41 ,bat:10
OSV2 1A2D20BB642380834A78[THGR228N,…] Id:BB ,Channel:2 ,temp:23.60 ,hum:38 ,bat:10
OSV2 1A2D108E042310443964[THGR228N,…] Id:8E ,Channel:1 ,temp:23.00 ,hum:41 ,bat:10
OSV2 1A2D20BB7423104441A0[THGR228N,…] Id:BB ,Channel:2 ,temp:23.70 ,hum:41 ,bat:10
Content que ça fonctionne pour toi 🙂
Je vais essayer de trouver quelques autres sondes pour fiabiliser tout ça.
Je cherche un dernier conseil pour terminer ce projet, ou envoyer ces données ? rdtool, base de données, cosm …..
Quelles sont vos idées ?
Pour ma part, j’envois les données en xPL sur le réseau et un daemon les stocke dans des fichiers rrd. un script générent ensuite des graphs de temps en temps qui sont intégrer dans mon interface (web et XBMC).
Bonjour
j’ai essaye le prog suivant relié mon récepteur 433mhz a la pin 3 de l’arduino et je ne recois rien ??
Merci de votre aide.
// Oregon V2 decoder modfied – Olivier Lebrun
// Oregon V2 decoder added – Dominique Pierre
// New code to decode OOK signals from weather sensors, etc.
// 2010-04-11 http://opensource.org/licenses/mit-license.php
// $Id: ookDecoder.pde 5331 2010-04-17 10:45:17Z jcw $
class DecodeOOK {
protected:
byte total_bits, bits, flip, state, pos, data[25];
virtual char decode (word width) =0;
public:
enum { UNKNOWN, T0, T1, T2, T3, OK, DONE };
DecodeOOK () { resetDecoder(); }
bool nextPulse (word width) {
if (state != DONE)
switch (decode(width)) {
case -1: resetDecoder(); break;
case 1: done(); break;
}
return isDone();
}
bool isDone () const { return state == DONE; }
const byte* getData (byte& count) const {
count = pos;
return data;
}
void resetDecoder () {
total_bits = bits = pos = flip = 0;
state = UNKNOWN;
}
// add one bit to the packet data buffer
virtual void gotBit (char value) {
total_bits++;
byte *ptr = data + pos;
*ptr = (*ptr >> 1) | (value <= 8) {
bits = 0;
if (++pos >= sizeof data) {
resetDecoder();
return;
}
}
state = OK;
}
// store a bit using Manchester encoding
void manchester (char value) {
flip ^= value; // manchester code, long pulse flips the bit
gotBit(flip);
}
// move bits to the front so that all the bits are aligned to the end
void alignTail (byte max =0) {
// align bits
if (bits != 0) {
data[pos] >>= 8 – bits;
for (byte i = 0; i > bits) | (data[i+1] < 0 && pos > max) {
byte n = pos – max;
pos = max;
for (byte i = 0; i < pos; ++i)
data[i] = data[i+n];
}
}
void reverseBits () {
for (byte i = 0; i < pos; ++i) {
byte b = data[i];
for (byte j = 0; j < 8; ++j) {
data[i] = (data[i] <>= 1;
}
}
}
void reverseNibbles () {
for (byte i = 0; i < pos; ++i)
data[i] = (data[i] <> 4);
}
void done () {
while (bits)
gotBit(0); // padding
state = DONE;
}
};
class OregonDecoderV2 : public DecodeOOK {
public:
OregonDecoderV2() {}
// add one bit to the packet data buffer
virtual void gotBit (char value) {
if(!(total_bits & 0x01))
{
data[pos] = (data[pos] >> 1) | (value ? 0x80 : 00);
}
total_bits++;
pos = total_bits >> 4;
if (pos >= sizeof data) {
Serial.println(« sizeof data »);
resetDecoder();
return;
}
state = OK;
}
virtual char decode (word width) {
if (200 <= width && width = 700;
switch (state) {
case UNKNOWN:
if (w != 0) {
// Long pulse
++flip;
} else if (w == 0 && 24 = 2500 && pos >= 8) {
return 1;
} else {
return -1;
}
return 0;
}
};
OregonDecoderV2 orscV2;
volatile word pulse;
void ext_int_1(void)
{
static word last;
// determine the pulse length in microseconds, for either polarity
pulse = micros() – last;
last += pulse;
}
float temperature(const byte* data)
{
int sign = (data[6]&0x8) ? -1 : 1;
float temp = ((data[5]&0xF0) >> 4)*10 + (data[5]&0xF) + (float)(((data[4]&0xF0) >> 4) / 10.0);
return sign * temp;
}
byte humidity(const byte* data)
{
return (data[7]&0xF) * 10 + ((data[6]&0xF0) >> 4);
}
// Ne retourne qu’un apercu de l’etat de la baterie : 10 = faible
byte battery(const byte* data)
{
return (data[4] & 0x4) ? 10 : 90;
}
byte channel(const byte* data)
{
byte channel;
switch (data[2])
{
case 0x10:
channel = 1;
break;
case 0x20:
channel = 2;
break;
case 0x40:
channel = 3;
break;
}
return channel;
}
void reportSerial (const char* s, class DecodeOOK& decoder)
{
byte pos;
const byte* data = decoder.getData(pos);
Serial.print(s);
Serial.print(‘ ‘);
for (byte i = 0; i > 4, HEX);
Serial.print(data[i] & 0x0F, HEX);
}
// Outside/Water Temp : THN132N,…
if(data[0] == 0xEA && data[1] == 0x4C)
{
Serial.print(« [THN132N,…] Id: »);
Serial.print(data[3], HEX);
Serial.print( » ,Channel: »);
Serial.print(channel(data));
Serial.print( » ,temp: »);
Serial.print(temperature(data));
Serial.print( » ,bat: »);
Serial.print(battery(data));
Serial.println();
}
// Inside Temp-Hygro : THGR228N,…
else if(data[0] == 0x1A && data[1] == 0x2D)
{
Serial.print(« [THGR228N,…] Id: »);
Serial.print(data[3], HEX);
Serial.print( » ,Channel: »);
Serial.print(channel(data));
Serial.print( » ,temp: »);
Serial.print(temperature(data));
Serial.print( » ,hum: »);
Serial.print(humidity(data));
Serial.print( » ,bat: »);
Serial.print(battery(data));
Serial.println();
}
decoder.resetDecoder();
}
void setup ()
{
Serial.begin(115200);
Serial.println(« \n[ookDecoder] »);
attachInterrupt(1, ext_int_1, CHANGE);
//DDRE &= ~_BV(PE5); //input with pull-up
//PORTE &= ~_BV(PE5);
}
void loop () {
static int i = 0;
cli();
word p = pulse;
pulse = 0;
sei();
if (p != 0)
{
if (orscV2.nextPulse(p))
reportSerial(« OSV2 », orscV2);
}
}
Bonsoir,
Quelle sonde utilises tu ?
Il faudrait modifier le code pour prendre le code le l’article suivant je pense car la condition de sortie du décodeur ne semble pas fonctionner pour toutes les type de sondes. La version dans l’article suivant corrige ce problème.
J’essaie de mettre un lien vers le bon sketch complet demain matin.
ma sonde est une THGR228N
ah oui j’utilise une uno.
J’ai laissé le programme tourné 20 mn environ et j’ai recu une info THGR228N id etc mais qu’une info en 20 mn??
D’ou peut venir le problème?
j’utilise ce rx ; module de gauche : <A HREF="http://image.dhgate.com/albu_261635291_00-1.0×0/5sets-433mhz-wireless-rf-transmitter-and.jpg"
http://image.dhgate.com/albu_261635291_00/1.0×0.jpg
ca y est ca marche !!
sur la pin 3 de mon arduino il y avait mauvais contact!!
par contre la portée est faible 2 à 3m max avec un fil de 15cm branché sur la sortie antenne!!!
Bonjour,
D’abord merci pour cet article et le précédent, ça fonctionne super chez moi.
J’ai juste une sonde RTGR328N qui n’est pas « traduite » correctement:
OSV2 AACC13783419008250AD[RTGR328N,…] Id:78 ,Channel:0 ,temp:19.30 ,hum:20 ,bat:10
Hors cette sonde à le canal 1 et non le 0. Que faut-il changer dans le code pour corriger ce petit écart ?
Par ailleurs cette sonde me renvoie aussi la trame suivante:
8AEA1378077214924242C16CBD
Une idée pour la décoder ? Je pense qu’il s’agit de la transmission de la date et l’heure (21:49 le 29/04/2014 pour la trame ci-dessus).
Merci par avance
Salut,
Le mieux serait de jeter un œil aux source de xpl-perl (ancienne version) ici : http://cpansearch.perl.org/src/BEANZ/Device-RFXCOM-1.110800/lib/Device/RFXCOM/Decoder/Oregon.pm , la trame 8AEA1378077214924242C16CBD correspond bien à l’envoi de la date/heure. Il y a la fonction dans le source (reste à la traduire en C), elle utilise une autre fonction checksum également.
Par contre concernant le canal, je ne vois pas trop ce qui peut provoquer ce problème.
cf mon commentaire plus bas, tu peux convertir ta trame en:
year: 14 month:4 week day: 2 (donc mardi) mday:29 hour:21 min:47 sec:20
Par contre, pas encore calculé le checksum. Et je n’avais pas trouvé le code sur le lien que tu as fourni.
J’utilise un spark.io, équivalent à l’Arduino, un récepteur Aurel. J’utilise une alimentation en 5V externe car le spark.io est en 3.3V. Mais 5V tolerant pour les pins digitaux.
Je reçois bien des trames mais aucune ne peut être décodée. J’ai plusieurs sondes de plusieurs types et une base qui envoie l’heure également.
Voici ce que j’ai après quelques minutes. Une idée d’où peut venir le problème?
OSV2 184F60E07E137BC7
OSV2 2E8D9F0018BE6EE9
OSV2 A082FC38829C5CB3
OSV2 E69A23C7FF1A4890
OSV2 ACD1F806F35F79C0
OSV2 060078DCC7C707F1
OSV2 F833387E883F2280
OSV2 783B30EE0B6604F1
OSV2 40CC1294E00F1F58
OSV2 4AF8C1DFFBFFEC94
OSV2 EEE7339E1DFE18DF34
OSV2 BEF4184FBA00C782
OSV2 02F415FEF8A727FB
OSV2 C0C9831FB71FD720
OSV2 3C205C41F83C7E00
OSV2 36BDFC03C077107C
OSV2 E0F50FF2C70700B0
OSV2 6E7E0CFCE1077E87
OSV2 06BCFD62D90E40E0
OSV2 06FE0E85038780FF
OSV2 10E0BB7B098CE171
OSV2 F8131BFFFFFFFFEB
OSV2 E8E10F00C0BF8B0F
OSV2 F21F7C747F38F838
OSV2 062EFCF94C2BEBEE
OSV2 1E1F87D06F44FA00
OSV2 84E581B37E603EF0
OSV2 E8399E3E30FC4160
OSV2 CAFFC00185F313E0
OSV2 A27D037EC7704078
OSV2 7C30CF9D383E87F7
OSV2 6A0F207C1BE00700
Je m’auto réponds… Ca a fini par fonctionner. J’ai déconnecté la fonction « cloud » du spark.io et j’ai fini par avoir des trames compatibles. Je pense que je vais acheter un arduino dédié pour cela, ce sera certainement plus simple. J’ai une sonde RTGR328N et plusieurs THGR228N. Et en plus, je capte celles de mes voisins… Le calcul du canal pour la RTGR328N est le suivant:
byte channel2(const byte* data)
{
byte channel;
channel = (data[2] >> 4) & 0x0f;
return channel;
}
Salut Laurent,
Merci pour ton retour
Pour compléter, j’ai fini par réussir à décoder les trames 8AEA. Merci Excel pour le coup de main 🙂
J’ai récupéré suffisamment de trames pour comparer avec l’heure réelle (ok, pas vraiment pour les secondes mais ça ç l’air de fonctionner par déduction).
La trame
8AEA434253031412624651584E
peut se convertir en:
Id:42 ,year:14 ,month:6 ,mday:21 ,wday:6 ,hour:21 ,min:40 ,sec:35
Voici le code:
struct otimedate
{
byte sec;
byte min;
byte hour;
byte mday;
byte mon;
byte wday;
byte year;
};
void decodetimedate(const byte *data, struct otimedate *otd)
{
otd->sec = (data[4] >> 4) + 10 * (data[5] & 0xf);
otd->min = (data[5] >> 4) + 10 * (data[6] & 0xf);
otd->hour = (data[6] >> 4) + 10 * (data[7] & 0xf);
otd->mday = (data[7] >> 4) + 10 * (data[8] & 0xf);
otd->mon = (data[8] >> 4);
otd->wday = (data[ 9] & 0x7);
otd->year = (data[9] >> 4) + 10 * (data[10] & 0xf);
}
pour tester:
if (((data[0] & 0x8A ) == 0x8A) && data[1] == 0xEA)
{
Serial.print(« [RTGR328N date time] Id: »);
Serial.print(data[3], HEX);
decodetimedate(data, &mytm);
//if (checksum2(data))
//{
Serial.print( » ,year: »);
Serial.print(mytm.year);
Serial.print( » ,month: »);
Serial.print(mytm.mon);
Serial.print( » ,day: »);
Serial.print(mytm.mday);
Serial.print( » ,week day: »);
Serial.print(mytm.wday);
Serial.print( » ,hour: »);
Serial.print(mytm.hour);
Serial.print( » ,min: »);
Serial.print(mytm.min);
Serial.print( » ,sec: »);
Serial.print(mytm.sec);
Serial.println();
//} else
//{ Serial.println(« Bad checksum »); }
}
Je n’ai pas calculer le checksum car je ne sais pas encore comment faire.
Ca peut être intéressant pour récupérer la date et l’heure sur des arduino ou équivalents non connectés à Internet. Le spak.io est connecté donc pas vraiment d’intérêt pour moi. Mais bon, j’ai décodé par plaisir 🙂
Salut,
Merci pour les infos 🙂
Et voici la fonction de checksum. Elle renvoie 0 si tout est OK
byte checksum3(const byte *data )
{
short ssum;
ssum = Sum(11, data) – data[11] ;
return ((byte)(ssum & 0xff) – 0x0Au);
}
PS: l’ID, la batterie et le channel fonctionnent. Attention, pour le channel, il faut utiliser la fonction suivante:
byte channel2(const byte* data)
{
byte channel;
channel = (data[2] >> 4) & 0x0f;
return channel;
}
Olivier, ton mail sur la page à propos ne fonctionne pas.
Ah oui tiens merci, c’est corrigé je pense.
bonjour,
je suis peut être un peu hors sujet mais votre expertise peut sens doute me renseigner.
je possède une station Oregon RMR500 qui est fournie avec des sondes THGR122N et THGN132N et non une THGN500.
or cette dernière est une sonde extérieure spécifique 1 seul canal qui doit s’afficher sur l’écran de la station dans le cadre « out ».
les sondes THGN132N qui la remplacent sont des 3 canaux et s’affichent dans les autres écrans. je perd donc l’affichage de ma sonde extérieure et n’ai plus que 4 sondes affichées au lieu de 5. Auriez vous une solution a ce problème car Oregon fait la sourde oreille, me disant que 4 c’est très bien…
merci d’avance
sylvain
Hello,
bravo pour ce boulot. Et merci 😉
Moi j’ai essayé, et ça marche du tonnerre… Ou presque
OSV2 EA4C101360193023
OSV2 EA4C101360193023
OSV2 EA4C101360193023
OSV2 EA4C101360193023
Pendant tout le premier essai, nickel. J’ai même pu capter tous mes trucs et j’ai implémenté ton deuxsième code qui m’a donné la batterie, tout, nickel.
Ensuite, pour identifier les EA4CXXXXXXX de mes 4 senseurs, j’ai voulu revenir au premier code et depuis, je ne capte plus qu’une seule sonde parmi les 4, toujours la même alors qu’au premier coup, je les voyais toutes.
J’ai changé la PIN de 3 à 2 (interrupt 0), mais c’est kif.
Qu’est ce qui peut se passer à ton avis ?
Merci encore pour tout
Je crois que j’ai compris.
J’ai branché l’arduino sur l’USB 5V et, dans mon esprit, j’avais branché l’alimentation sur une pile 9V. Mais je crois que la pile était has been, du coup, défaut de puissance (pas de relais automatique par l’USB sur duino).
Perso si vous voulez un décodeur ultra puissant pour vos sonde et prise télécommandé regarder ici :
https://github.com/Cactusbone/ookDecoder
Le dernier lien de la conclusion semble non relatif au sujet de l’article.
Volontaire ou pas ?
Salut,
Non effectivement.
J’ai eu une « intrusion » sur le serveur il y a quelque temps à cause d’un autre site … je vais vérifier le reste du site, merci pour l’info.
Magnifique !
Merci encore pour ce travail remarquable.
Après quelques heures passées à comprendre le code, il suffit de changer les paramètres pour « filtrer » sa sonde et ça marche.
J’ai une Oregon qui a maintenant quelques années et une sonde RTGR328N.
Mon projet : utiliser la sonde Oregon pour retravailler la régulation du plancher chauffant d’une chambre.
Actuellement , la T° du circuit d’eau « plancher » de la chaudière est gérée à partir de la sonde principale située dans le salon.
La T° de la chambre est obtenue par une simple vanne à pointeau qui vient agir sur le débit du circuit « chambre ». Ce qui pose problème car on a besoin ici d’à peine 1/10e de puissance… Ce qui se traduit par un étranglement très important au niveau du passage et donc une précision relevant pratiquement d’une régulation « tout ou rien ».
La suite : travailler, à partir d’une consigne (~18°C) et du retour de la sonde, dans un Arduino nano, et réguler en MLI (PWM) sur une électro-vanne qui laissera passer 100% du débit pendant un temps donné.
Évite aussi l’encrassement (embouage) du circuit concerné du fait d’un très faible débit dans les tuyaux.
Voilà, merci encore, car le décodage n’était pas à la portée du premier venu…..