Protocoles Oregon Scientific et Arduino : Encodage
Maintenant que l’on décode les protocoles Oregon Scientific (le v2 du moins car n’ayant pas de sonde en v3, je n’ai pas pu tester mais certains commentaires laissent à penser que ça fonctionne 🙂 ), on va s’attaquer à l’émission de trames Oregon Scientific v2 depuis un arduino. Je pense que ça va en intéresser plus d’un et vous aurez compris l’idée derrière cela … réaliser des sondes pas chères et surtout compatibles avec les équipements du marché tel que le RFXCom ou la Zibase.
MAJ 10/02/2013 : suite à un problème avec l’éditeur de wordpress, le code était foireux à la ligne 264, c’est corrigé. Merci à catalin.
Note: Je parle de protocole version 2, il s’agit du 2.1 à réalité.
[adsGrandRectangleTexte]
Le protocole Oregon Scientific v2
Codage
Je suis parti des specs que l’on trouve ici: http://wmrx00.sourceforge.net/Arduino/OregonScientific-RF-Protocols.pdf.
Note : Il y a des différences entre la spec et ce que fait le décodeur des articles précédant, notamment au niveau des ID des sondes.
En effet, si on prend l’exemple d’une sonde THN132N, la spec indique qu’elle renvoie 0xEC40 comme ID, alors que nous on attend 0xEA4C. le « A » de 0xEA4C semble venir en fait de 4bits de syncho envoyés par toutes les sondes. Du coup, même si le décodeur fonctionne, je pense qu’il ne doit pas reconnaitre toutes les sondes correctement (à tester, maintenant que l’on peut simuler n’importe qu’elle sonde).
Les protocoles 2 et 3 transmettent à un débit d’environ 1024Hz et utilisent un codage manchester. Un bit 0 est représenté par une transition du niveau bas vers le niveau haut et un bit 1 par une transition du niveau haut vers le niveau bas. La transition se produit au milieu d’une pulsation.
Particularités du protocole Oregon Scientific 2
La version 2 du protocole Oregon Scientific présente quelques particularités. Chaque bit est envoyé 4 fois. D’abords, les bits sont doublés. Pour un bit 1, on envoie « 01 » et pour un bit 0, « 10 ». Puis le message complet est envoyé 2 fois.
Structure d’une trame Oregon Scientific
Les protocoles v2 et v3 ont une structure similaire :
[ Préambule (16/24) ] [ Sync (4) ] [ Data (taille variable) ] [ Postambule (taille variable) ]
- Un préambule qui permet de reconnaitre une trame Oregon. Elle consiste en une série de 24bits « 1 » pour la version 3 et 16bits « 1 » pour la version 2. N’oubliez pas que dans la version 2, chaque bit est doublé par son inverse. On se retrouve donc pour la v2 avec 32bits « 01010101… » .
- 4 bits de synchronisation : 0101, le fameux « A » (voir note plus haut). Les bits sont envoyés bit de poids faible en premier (A = 1010 -> tramis à l’envers : 0101). Pour la v2 : 10011001, Vous suivez toujours ?
- Les datas (voir plus bas)
- un postambule variable.
Analyse de la trame à « l’oscilloscope »
Forcement, ça n’a pas fonctionné du premier coup et pour vérifier ce que mon émetteur envoyait et le comparer avec une vrai sonde un oscilloscope aurait été bien pratique. Il y a plusieurs méthodes pour se dépatouiller sans oscillo.
On peut brancher un récepteur RF433 sur l’entrée ligne d’une carte son et utiliser un soft comme audacity pour afficher le signal comme le « ferait » un oscillo. Malheureusement je n’ai pas d’entrée ligne sur mon portable.
J’ai trouvé une autre méthode à base d’arduino : xoscillo. C’est un oscilloscope logiciel. Le signal reçu par un Arduino équipé d’un récepteur RF est envoyé via l’USB sur le PC qui fait tourner le soft xoscillo et qui affiche une représentation graphique du signal. Ca ne remplace pas un vrai oscillo bien sûr mais dans notre cas c’est suffisant et en tout cas, ça m’a bien dépanné 🙂
Sur l’image, une trame Oregon complète (le deuxième envoi) en haut. En bas, On voit clairement les 16 bits du préambule par exemple et les 4bits de synchro.
Simulation d’une sonde Oregon Scientific V2 avec un Arduino
Le sketch ci dessous permet de simuler une sonde de température Oregon Scientific THN132N ou une sonde de température/humidité THGR2228N.
Le code envoie la même trame toutes les 30 secondes. Libre à vous ensuite d’ajouter un capteur de température et/ou d’humidité pour envoyer de vrais informations.
Je me suis inspiré du code de skyduino pour l’envoi de trame blyss. Je l’ai testé sur Arduino Duemilanove et l’IDE 1.0.1 (linux).
/* * connectingStuff, Oregon Scientific v2.1 Emitter * http://connectingstuff.net/encodage-protocoles-oregon-scientific-sur-arduino/ * * Copyright (C) 2013 olivier.lebrun@gmail.com * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #define THN132N const byte TX_PIN = 4; const unsigned long TIME = 512; const unsigned long TWOTIME = TIME*2; #define SEND_HIGH() digitalWrite(TX_PIN, HIGH) #define SEND_LOW() digitalWrite(TX_PIN, LOW) // Buffer for Oregon message #ifdef THN132N byte OregonMessageBuffer[8]; #else byte OregonMessageBuffer[9]; #endif /** * \brief Send logical "0" over RF * \details azero bit be represented by an off-to-on transition * \ of the RF signal at the middle of a clock period. * \ Remenber, the Oregon v2.1 protocol add an inverted bit first */ inline void sendZero(void) { SEND_HIGH(); delayMicroseconds(TIME); SEND_LOW(); delayMicroseconds(TWOTIME); SEND_HIGH(); delayMicroseconds(TIME); } /** * \brief Send logical "1" over RF * \details a one bit be represented by an on-to-off transition * \ of the RF signal at the middle of a clock period. * \ Remenber, the Oregon v2.1 protocol add an inverted bit first */ inline void sendOne(void) { SEND_LOW(); delayMicroseconds(TIME); SEND_HIGH(); delayMicroseconds(TWOTIME); SEND_LOW(); delayMicroseconds(TIME); } /** * Send a bits quarter (4 bits = MSB from 8 bits value) over RF * * @param data Source data to process and sent */ /** * \brief Send a bits quarter (4 bits = MSB from 8 bits value) over RF * \param data Data to send */ inline void sendQuarterMSB(const byte data) { (bitRead(data, 4)) ? sendOne() : sendZero(); (bitRead(data, 5)) ? sendOne() : sendZero(); (bitRead(data, 6)) ? sendOne() : sendZero(); (bitRead(data, 7)) ? sendOne() : sendZero(); } /** * \brief Send a bits quarter (4 bits = LSB from 8 bits value) over RF * \param data Data to send */ inline void sendQuarterLSB(const byte data) { (bitRead(data, 0)) ? sendOne() : sendZero(); (bitRead(data, 1)) ? sendOne() : sendZero(); (bitRead(data, 2)) ? sendOne() : sendZero(); (bitRead(data, 3)) ? sendOne() : sendZero(); } /******************************************************************/ /******************************************************************/ /******************************************************************/ /** * \brief Send a buffer over RF * \param data Data to send * \param size size of data to send */ void sendData(byte *data, byte size) { for(byte i = 0; i < size; ++i) { sendQuarterLSB(data[i]); sendQuarterMSB(data[i]); } } /** * \brief Send an Oregon message * \param data The Oregon message */ void sendOregon(byte *data, byte size) { sendPreamble(); //sendSync(); sendData(data, size); sendPostamble(); } /** * \brief Send preamble * \details The preamble consists of 16 "1" bits */ inline void sendPreamble(void) { byte PREAMBLE[]={0xFF,0xFF}; sendData(PREAMBLE, 2); } /** * \brief Send postamble * \details The postamble consists of 8 "0" bits */ inline void sendPostamble(void) { #ifdef THN132N sendQuarterLSB(0x00); #else byte POSTAMBLE[]={0x00}; sendData(POSTAMBLE, 1); #endif } /** * \brief Send sync nibble * \details The sync is 0xA. It is not use in this version since the sync nibble * \ is include in the Oregon message to send. */ inline void sendSync(void) { sendQuarterLSB(0xA); } /******************************************************************/ /******************************************************************/ /******************************************************************/ /** * \brief Set the sensor type * \param data Oregon message * \param type Sensor type */ inline void setType(byte *data, byte* type) { data[0] = type[0]; data[1] = type[1]; } /** * \brief Set the sensor channel * \param data Oregon message * \param channel Sensor channel (0x10, 0x20, 0x30) */ inline void setChannel(byte *data, byte channel) { data[2] = channel; } /** * \brief Set the sensor ID * \param data Oregon message * \param ID Sensor unique ID */ inline void setId(byte *data, byte ID) { data[3] = ID; } /** * \brief Set the sensor battery level * \param data Oregon message * \param level Battery level (0 = low, 1 = high) */ void setBatteryLevel(byte *data, byte level) { if(!level) data[4] = 0x0C; else data[4] = 0x00; } /** * \brief Set the sensor temperature * \param data Oregon message * \param temp the temperature */ void setTemperature(byte *data, float temp) { // Set temperature sign if(temp < 0) { data[6] = 0x08; temp *= -1; } else { data[6] = 0x00; } // Determine decimal and float part int tempInt = (int)temp; int td = (int)(tempInt / 10); int tf = (int)round((float)((float)tempInt/10 - (float)td) * 10); int tempFloat = (int)round((float)(temp - (float)tempInt) * 10); // Set temperature decimal part data[5] = (td << 4); data[5] |= tf; // Set temperature float part data[4] |= (tempFloat << 4); } /** * \brief Set the sensor humidity * \param data Oregon message * \param hum the humidity */ void setHumidity(byte* data, byte hum) { data[7] = (hum/10); data[6] |= (hum - data[7]*10) << 4; } /** * \brief Sum data for checksum * \param count number of bit to sum * \param data Oregon message */ int Sum(byte count, const byte* data) { int s = 0; for(byte i = 0; i<count;i++) { s += (data[i]&0xF0) >> 4; s += (data[i]&0xF); } if(int(count) != count) s += (data[count]&0xF0) >> 4; return s; } /** * \brief Calculate checksum * \param data Oregon message */ void calculateAndSetChecksum(byte* data) { #ifdef THN132N int s = ((Sum(6, data) + (data[6]&0xF) - 0xa) & 0xff); data[6] |= (s&0x0F) << 4; data[7] = (s&0xF0) >> 4; #else data[8] = ((Sum(8, data) - 0xa) & 0xFF); #endif } /******************************************************************/ /******************************************************************/ /******************************************************************/ void setup() { pinMode(TX_PIN, OUTPUT); Serial.begin(9600); Serial.println("\n[Oregon V2.1 encoder]"); SEND_LOW(); #ifdef THN132N // Create the Oregon message for a temperature only sensor (TNHN132N) byte ID[] = {0xEA,0x4C}; #else // Create the Oregon message for a temperature/humidity sensor (THGR2228N) byte ID[] = {0x1A,0x2D}; #endif setType(OregonMessageBuffer, ID); setChannel(OregonMessageBuffer, 0x20); setId(OregonMessageBuffer, 0xBB); } void loop() { // Get Temperature, humidity and battery level from sensors // (ie: 1wire DS18B20 for température, ...) setBatteryLevel(OregonMessageBuffer, 0); // 0 : low, 1 : high setTemperature(OregonMessageBuffer, 11.2); #ifndef THN132N // Set Humidity setHumidity(OregonMessageBuffer, 52); #endif // Calculate the checksum calculateAndSetChecksum(OregonMessageBuffer); // Show the Oregon Message for (byte i = 0; i < sizeof(OregonMessageBuffer); ++i) { Serial.print(OregonMessageBuffer[i] >> 4, HEX); Serial.print(OregonMessageBuffer[i] & 0x0F, HEX); } // Send the Message over RF sendOregon(OregonMessageBuffer, sizeof(OregonMessageBuffer)); // Send a "pause" SEND_LOW(); delayMicroseconds(TWOTIME*8); // Send a copie of the first message. The v2.1 protocol send the // message two time sendOregon(OregonMessageBuffer, sizeof(OregonMessageBuffer)); // Wait for 30 seconds before send a new message SEND_LOW(); delay(30000); }
Compatibilité et conclusion
J’ai testé avec succès la réception avec le décodeur des articles précédant et avec un ancien RFXCom USB (2010). J’attends vos retours pour savoir si ça passe bien sur les nouveaux RFXcom ou sur une Zibase, voir sur une station Oregon Scientific directement.
J’avais commencé une librairie Oregon pour Arduino que je vais du coup essayer de terminer et de publier.
[adsGrandRectangleHTexte]
Bonsoir,
Je viens du forum touteladomotique.com qui m’a conseillé votre site.
J’ai des sondes Oregon, un Arduino Uno.
Pensez vous qu’il soit possible de lire les températures des sondes avec l’Arduino et ensuite de récupérer les données sous forme de courbe depuis un navigateur web (Pc, Mac, tablette, iPhone)?
En vous remerciant pour le temps que vous prendrez à me répondre 🙂
Salut,
C’est moi qui t’es laissé le message sur le forum 😉
Oui tout a fait c’est le but de cette série d’article. Si tu regarde ici : décodage oregon sur arduino 3/3 tu auras déjà le code pour réceptionner et décoder les infos des sondes 2.1 (quel modèle de sonde possèdes tu ?). Il faudra ensuite coder le transfert des données vers ton serveur. Il existe plein de moyen pour le faire (ethernet, usb, serie, rf …) et plein de façons différentes de le faire (http, xpl, …)
Si tu es patient, je ferai un article avec cette partie là.
Je saurait faire preuve de patience dans ce cas 😉
Mes sondes sont des THGR122N et la dernière est une THGR122NX, je sais pas où ce trouve la différence?
Par contre je ne sais pas si ce sont des V2 ou V3?
Pour commencer avec les trois premier articles, il me manque donc un récepteur 433Mhz, j’en est trouvé mais pas à deux euros 😉
Lequel prendre?
http://www.planete-domotique.com/module-slave-recepteur-rf-433-92mhz-antenne-rfxcom.html
http://www.lextronic.fr/P865-recepteur-43392-mhz-rrq3-433.html
Tu as dit:
« Il faudra ensuite coder le transfert des données vers ton serveur. Il existe plein de moyen pour le faire (ethernet, usb, serie, rf …) et plein de façons différentes de le faire (http, xpl, …) »
L’Arduino ne peu pas faire office de serveur?
Je pensais qu’il suffisait de lui adjoindre un shield Ethernet pour qu’il soit accessible via un navigateur internet.
Mon serveur actuel, qui me sert pour les sauvegardes, bibliothéques iTunes est un Mac mini server avec OSX 10.6.
Je ne sais pas si il peu être utilisé pour faire sa?
Salut Frank,
Je t’ai déjà répondu sur le forum de touteladomotique mais je partage les réponse ici aussi du coup.
Je dirai que tu devrais pouvoir utiliser le code que j’ai fournis dans les articles précédant puisqu’elles partagent le même codage que les THGR228N pour lesquels j’ai fournis les fonctions nécessaires.
J’ai acheté le mien ici (ce n’est pas le même que sur la photo par contre) : http://www.watterott.com/en/RF-Link-2400bps-Receiver-434MHz il me semblait l’avoir payé moins cher à l’époque.
Si l’arduino peut faire office de serveur. On pourrait stocker les données sur la carte SD par exemple mais pour générer des graphs ça risque d’être limité. Je préfère utiliser l’arduino juste comme « passerelle », il s’occupe de la réception/décodage et renvoi les données décodées au serveur, chacun son boulot 🙂
Oui tu peux utiliser ton MAc mini, pas de soucis.
Je suppose qu’il faudra un module Rfx com pour lire les sondes Oregon?
Tu peux le faire avec le rfxcom mais aussi avec un arduino + un module récepteur RF433 à 2€. Cf le commentaire au dessus: jette un oeil sur les trois articles précédant à propos du décodage du protocole oregon.
Hi,
there is a problem in your code and iit will not compile, the problem relates to the sum byte part there is something missing in the code and it will not compile on line 264..
Thank you
Please rectify the code on the page, I have found the problem.
this is the correct code:
int Sum(byte count, const byte* data)
{
int s = 0;
for(byte i = 0; i> 4;
s += (data[i]&0xF);
}
if(int(count) != count)
s += (data[count]&0xF0) >> 4;
return s;
}
Hi,
Thanks. The code should be ok now, I think it’s a wordpress editor’s bug when I have copy/paste from the arduino IDE :/
Je viens de trouver sa:
http://www.mon-club-elec.fr/pmwiki_reference_arduino/pmwiki.php?n=Main.DebuterModuleArduinoEthernet
Dans le cas où mon Mac Mini Server ne pourrais pas être utilisé, mais j’attend ta réponse à mon précédent post 😉
Effectivement il te faudra un shield Ethernet pour relier l’arduino au réseau. Regarde sur Ebay, tu en trouveras des pas cher 🙂
Thank you for all your work, I have managed to use your code together with an 433.92 rf transmitter and an ShT22 sensor and i have a fully working replica of an Oregon Scientific sensor now, I am using it in Homeseer with RFXCom.
I plan to have it ported outside arduino on a separate AVR platform with atmega 8 and make my own compatible temperature sensors.
Great 🙂 I’m glad it’s working for you !
I plan to use a ATtiny or something like that too to reduce cost. I’ll write a post when it’s ok.
Share with us if you do it ! 🙂
sure it will be shared 🙂
Bonjour,
J’ai une série de thermomètres THR128 Oregon.
Aucuns des décodeurs que j’ai pu tester ne fonctionne. Il semble qu’ils utilisent le protocole V1.
Je n’ai pas trouvé de sketch Arduino pour cette version. Il y a-t-il une quelqu’un qui a réalisé un décodeur pour la version 1.
Merci d’avance
Robert
Bonjour Robert,
Désolé pour le tps de réponse :/
Oui j’en ai vu un il y a un moment (cf lien en bas de page ici : http://jeelabs.net/projects/cafe/wiki/Decoding_the_Oregon_Scientific_V2_protocol ) mais malheureusement la page n’est plus accessible et je ne l’ai pas conservée.
Mais avec les spec il doit être possible de modifier le décodeur actuel pour le faire fonctionner avec la version 1.0 du protocole.
Bonjour,
Try to play with your sketch (including bufix line 264) to emulate sensor.
I have at serial output 1A2D20BB0C500006F6, and nothing on Oregon screen.
Could you please specify where is problem?
Many thanks in advance for reply.
Data from my real Oregon sensor
OSV2 1A2D408E700870834B41
Bonjour, et merci pour cet excellent article, néanmoins je m’interroge… dans le document que vous citez en référence : http://wmrx00.sourceforge.net/Arduino/OregonScientific-RF-Protocols.pdf , les ID’s sont différents des votres, est-ce lié à un encodage particulier de vos données ?
désolé la réponse était dans l’article…
Hi,
the code works fine with rfxcom but it is not recognised by any Oregon Scientific stations, i have tested it with BAR800U and BAR206.
I believe there is an issue with the checksum or postamble, hard to say..
Hi,
Are they oregonv2.1 sensors ?
If yes, you can have a look to xpl-perl source code (old version) to see if the checksum code is correct.
I’ll check when I have some time.
bonjour,
j’ai fait quelques essais avec ma station wmr86 et des capteurs en version 3. Il semble que le postamble soit en fait le crc 8 des données placées avant le cheksum, je n’ai pas de transmetteur RF 433 pour tester mais en ajoutant le crc, je pense que l’on devrait pouvoir afficher les données sur la station.
Un petit sketch pour vérifier, ( les paquets RF sont ceux enregistrés depuis mes capteurs ).
#include
#define mByte(i) (RFPacket[i])
#define NIBBLE(i) ((mByte((i)>>1) >> (((i)&1)<<2))&0xf)
// WGR800
// 1A8904BBA0C004000046E2 Anemo = Sync + longueur utile (17) + CheckSum + CRC = 22 nibbles
//uint8_t RFPacket[]={0x1A, 0x89, 0x04, 0xBB, 0xA0, 0xC0, 0x04, 0x00, 0x00, 0x46, 0xE2};
// PCR800
//2A19047D0000204500F05208 Pluvio Sync + longueur utile (18) + CheckSum + CRC = 23 nibbles
//uint8_t RFPacket[]={0x2A, 0x19, 0x04, 0x7D, 0x00, 0x00, 0x20, 0x45, 0x00, 0xF0, 0x52, 0x08};
// THGN800
//AF8241750570028CC4054 thermo Hygro = Sync + longueur utile (15) + CheckSum + CRC = 20 nibbles
uint8_t RFPacket[]={0xFA, 0x28, 0x14, 0x57, 0x50, 0x07, 0x20, 0xC8, 0x4C, 0x50};
void checkSumAndCRC(const uint8_t len)
{
uint8_t i,j,c,CRC,SUM;
CRC =0x00;
SUM =0x00;
uint8_t CCIT_POLY = 0x07;
for (j=1; j<=len; j++)
{
c = NIBBLE(j);
Serial.print(c, HEX);Serial.print(" ");
SUM += c;
CRC ^= c;
for(i = 0; i<4; i++)
if(CRC & 0x80 )
CRC = (CRC << 1) ^ CCIT_POLY;
else
CRC <<= 1;
CRC &= 0xff;
}
for(i = 0; i<4; i++)
if(CRC & 0x80 )
CRC = (CRC << 1) ^ CCIT_POLY;
else
CRC <<= 1;
Serial.print("SUM: ");Serial.print(SUM, HEX); Serial.print(" CRC:"); Serial.print(CRC, HEX);Serial.println("");
}
void setup()
{
Serial.begin(38400,4);
Serial.print("Start\n");
}
void loop()
{
checkSumAndCRC(15);
delay(10000);
}
bonjour engel,
j’essaye de comprendre votre code de calcul du post-ambul
mais je bloque sur la compréhension
ne manque t il pas de { } pour les boucles for(i = 0; i<4; i++)?
car sans eux, le for ne sert a rien?
pour le SUM , pas de probleme, j'ai bien compris et il est bien corroboré par mes trames brutes issus de capteur V2 (non via un recepteur UHF)
ex : A1D3015717220418 73 8B
le SUM vaut bien 37
mais j'arrive pas a calculé le B8
merci de votre aide
Les accolades ne sont pas nécessaires, le for est exécuté sur l’instruction if suivante,( l’indentation n’a pas été préservée ). enfin bon je reconnais que l’on peut les mettre, ca ne gâche rien 🙂
je n’ai pas de capteurs V2. mais un truc intéressant à faire à mon avis c’est de calculer le CRC en excluant le rolling Code du capteur 0x57 dans votre cas.
bon j’ai testé en enlevant le 57 , mais c’est pas ça 😀
ou alors c’est mon code qui ne colle pas au votre
voila ce que j’ai ecrit sous visualbasic en m’inspirant du votre
ai je bon ?
plainText recupere chaque nibble de la trame
dans la trame du dessus
plainText[0] = 1
plainText[1] = D
plainText[2] = 3
etc…
********************************************************
Dim i, j, c, CRC, SUM As UInteger
CRC = &H0
SUM = &H0
Dim CCIT_POLY As UInteger = &H7
For j = 0 To (Input1.TextLength – 1)
c = plainText(j)
SUM = SUM + c
CRC = CRC Xor c
For i = 0 To 3
If CRC And &H80 Then
CRC = (CRC << 1) Xor CCIT_POLY
Else
CRC = CRC << 1
End If
Next i
CRC = CRC And &HFF
Next j
For i = 0 To 3
If CRC And &H80 Then
CRC = (CRC << 1) Xor CCIT_POLY
Else
CRC = CRC << 1
End If
Next i
********************************************************
bonjour engel,
j’essaye de comprendre votre code de calcul du CRC8
ni connaissant rien en arduino, j’essaye de faire la translation du code en C pour tenter de le comprendre
dans votre code , ne manque t il pas de { } pour la boucle for(i = 0; i<4; i++)?
car sans eux , la boucle for tourne sur elle meme?
merci de votre aide pour avoir quelques explications sur le calcul du CRC
merci
Bonjour engel
Avez vous pu confirmer qu’il s’agit bien d’un CRC 8 ? Si oui avec quel polynome ?
J’ai testé avec 0x07 comme indiqué dans votre code mais ca ne fonctionne pas. Je vais en tester d’autres mais si je peux éviter de partir sur une mauvaise piste c’est aussi bien…
Si vous avez d’autres informations qui expliquent ce préambule vous me seriez d’une grande aide.
Si je trouve quelque chose de mon coté je publierai le résultat.
Merci d’avance
Hi engel, I am willing to send you a free RF 433 transmitter to test your code, if you continue to share the code, get in touch with me and send me your details.
I will buy a RF emitter this evening and do a few test, I will post the results here.
quelqu’un a t’il reussi a faire reconnaitre une sonde simulé sur une station oregon?
Bonjour Olivier et quel super travail réalisé.
J’arrive à capter toutes les infos de mes sondes (THN132N & THGR228N) 🙂
Par contre ma THN132N étant en train de lacher, je souhaite la remplacer par un montage à base d’Arduino + sonde DS18B20.
En récupérant ce code, je capte bien les messages sur un Arduino + récepteur RF mais ma station Oregon ne capte pas le message.
Quelqu’un a-t’il déjà réussi à émuler une sonde et faire afficher la température sur une station Oregon?
Par avance, merci de vos réponses
j’ai testé , mais helas sans le post-ambule
impossible qu’une station oregon reconnaisse la trame 🙁
faut reussir à trouver le calcul du post-ambul sur un capteur V2
Salut,
Je n’ai pas de station oregon, le rfxcom doit être est plus permissif (?)
J’essaierai de regarder de ce coté à l’occasion mais pour le moment le tps me manque un peut :/
disons que le rfxcom se moque complétement du post-ambule vu qu’il a deja toutes les infos dont il a besoin avant (meme si elles peuvent etre erroné suite à un parasite, quoique y’a un minimum avec le CRC ^_^ )
Bonjour,
oui j’ai reussi a simuler une sonde THGN801 pour qu elle s affiche sur ma station wmr86.
C’est une sonde qui utilise le protocole version 3
J’utilise ce script que j ai trouver sur le net :
https://github.com/barnybug/arduino-sous-vide
il fonctionne en ce moment et me permet d’afficher la temperature de ma piscine du la canal 2 (il faut changer le channel a la ligne : 51 du fichier sous vide.ino.
Bonsoir,
Merci pour ce retour sur le protocole v3, c’est intéressant.
Je suis justement en train de faire une sonde avec le code que j’avais publié ici (v2 donc), je vais regarder ça de plus près.
Salut,
Merci beaucoup pour ce code ! C’est cool ! Je n’ai pas pour habitude de laisser des messages sur internet, mais je voulais faire partager mes expériences. Tout cela me paraissait assez compliqué, si bien que je doutais de l’efficacité de toutes ces lignes…
Je viens tout juste de programmer un Atmega328 muni d’une sonde temp/hygro DHT22 et d’un émetteur 433MHz (les moins chers sur eBay). J’avais déjà essayé ces deux petits objets pour d’autres projets et ça marchait très bien. Pour le DHT22, j’utilise la librairie du même nom.
Ce qui m’intéressait, c’était que la zibase capte toute seule les ondes et que je n’aie pas à passer par le port série branché sur un Raspberry (je lance un script PHP à l’aide de php_serial.class pour récupérer ce que le récepteur 433 a lui-même récupéré sur le Uno). D’une part, c’est plus pratique (et ça soulage la Zibase et le Raspberry), et d’autre part, je vais enfin pouvoir utiliser de manière optimale la librairie LowPower pour mettre en powerDown en boucle et ne réveiller la bête que toutes les tant de minutes… Cela m’économisera les piles. A vrai dire, c’est surtout pour le montage d’une sonde à ultrasons HC-SR04 que j’ai placée dans ma cuve de récupération d’eau de pluie, qui est au fond du jardin, que tout ceci m’intéressait… Mais je vais en profiter pour me faire une autre sonde temp/hygro sans fil, une « Oregon fake » !
Merci encore !
(Donc ça marche super bien avec la Zibase ! Voici ce qu’elle m’envoie : Received radio ID (433Mhz Noise=2004 Level=5.0/5 Oregon Generic Temp-Hygro/THGR228N Ch=2 T=+27.5°C (+81.5°F) Humidity=49% Batt=Ok): OS439204610
Autant dire que c’est parfait : avec un petit fil de 17,3cm, je capte à 100% alors que je suis à l’étage…)
NB : pour le code, j’ai remplacé #ifndef THN132N par #ifdef THGR2228N
Salut,
Merci pour le retour, ça fait plaisir 🙂
Salut,
Can you share your code here? Merci.
Le code pour la sonde Temp/hygro : (pour le byte ID 0x1A,0x2D, on peut le remplacer par 0xCA,0x2C (THGR328N), il y aura peut-être moins de risques sur la limitation des canaux s’il y a plusieurs sondes) (j’ai aussi celui de l’ultrason pour ceux qui veulent)
#include "LowPower.h" // Appel pour la maise en veille
#include
// Data wire is plugged into port 7 on the Arduino
// Connect a 4.7K resistor between VCC and the data pin (strong pullup)
#define DHT22_PIN 2
// Setup a DHT22 instance
DHT22 myDHT22(DHT22_PIN);
#define THGR228N
const byte TX_PIN = 12;
const unsigned long TIME = 512;
const unsigned long TWOTIME = TIME*2;
#define SEND_HIGH() digitalWrite(TX_PIN, HIGH)
#define SEND_LOW() digitalWrite(TX_PIN, LOW)
// Buffer for Oregon message
#ifdef THN132N
byte OregonMessageBuffer[8];
#else
byte OregonMessageBuffer[9];
#endif
/**
* \brief Send logical "0" over RF
* \details azero bit be represented by an off-to-on transition
* \ of the RF signal at the middle of a clock period.
* \ Remenber, the Oregon v2.1 protocol add an inverted bit first
*/
inline void sendZero(void)
{
SEND_HIGH();
delayMicroseconds(TIME);
SEND_LOW();
delayMicroseconds(TWOTIME);
SEND_HIGH();
delayMicroseconds(TIME);
}
/**
* \brief Send logical "1" over RF
* \details a one bit be represented by an on-to-off transition
* \ of the RF signal at the middle of a clock period.
* \ Remenber, the Oregon v2.1 protocol add an inverted bit first
*/
inline void sendOne(void)
{
SEND_LOW();
delayMicroseconds(TIME);
SEND_HIGH();
delayMicroseconds(TWOTIME);
SEND_LOW();
delayMicroseconds(TIME);
}
/**
* Send a bits quarter (4 bits = MSB from 8 bits value) over RF
*
* @param data Source data to process and sent
*/
/**
* \brief Send a bits quarter (4 bits = MSB from 8 bits value) over RF
* \param data Data to send
*/
inline void sendQuarterMSB(const byte data)
{
(bitRead(data, 4)) ? sendOne() : sendZero();
(bitRead(data, 5)) ? sendOne() : sendZero();
(bitRead(data, 6)) ? sendOne() : sendZero();
(bitRead(data, 7)) ? sendOne() : sendZero();
}
/**
* \brief Send a bits quarter (4 bits = LSB from 8 bits value) over RF
* \param data Data to send
*/
inline void sendQuarterLSB(const byte data)
{
(bitRead(data, 0)) ? sendOne() : sendZero();
(bitRead(data, 1)) ? sendOne() : sendZero();
(bitRead(data, 2)) ? sendOne() : sendZero();
(bitRead(data, 3)) ? sendOne() : sendZero();
}
/******************************************************************/
/******************************************************************/
/******************************************************************/
/**
* \brief Send a buffer over RF
* \param data Data to send
* \param size size of data to send
*/
void sendData(byte *data, byte size)
{
for(byte i = 0; i < size; ++i)
{
sendQuarterLSB(data[i]);
sendQuarterMSB(data[i]);
}
}
/**
* \brief Send an Oregon message
* \param data The Oregon message
*/
void sendOregon(byte *data, byte size)
{
sendPreamble();
//sendSync();
sendData(data, size);
sendPostamble();
}
/**
* \brief Send preamble
* \details The preamble consists of 16 "1" bits
*/
inline void sendPreamble(void)
{
byte PREAMBLE[]={
0xFF,0xFF };
sendData(PREAMBLE, 2);
}
/**
* \brief Send postamble
* \details The postamble consists of 8 "0" bits
*/
inline void sendPostamble(void)
{
#ifdef THN132N
sendQuarterLSB(0x00);
#else
byte POSTAMBLE[]={
0x00 };
sendData(POSTAMBLE, 1);
#endif
}
/**
* \brief Send sync nibble
* \details The sync is 0xA. It is not use in this version since the sync nibble
* \ is include in the Oregon message to send.
*/
inline void sendSync(void)
{
sendQuarterLSB(0xA);
}
/******************************************************************/
/******************************************************************/
/******************************************************************/
/**
* \brief Set the sensor type
* \param data Oregon message
* \param type Sensor type
*/
inline void setType(byte *data, byte* type)
{
data[0] = type[0];
data[1] = type[1];
}
/**
* \brief Set the sensor channel
* \param data Oregon message
* \param channel Sensor channel (0x10, 0x20, 0x30)
*/
inline void setChannel(byte *data, byte channel)
{
data[2] = channel;
}
/**
* \brief Set the sensor ID
* \param data Oregon message
* \param ID Sensor unique ID
*/
inline void setId(byte *data, byte ID)
{
data[3] = ID;
}
/**
* \brief Set the sensor battery level
* \param data Oregon message
* \param level Battery level (0 = low, 1 = high)
*/
void setBatteryLevel(byte *data, byte level)
{
if(!level) data[4] = 0x0C;
else data[4] = 0x00;
}
/**
* \brief Set the sensor temperature
* \param data Oregon message
* \param temp the temperature
*/
void setTemperature(byte *data, float temp)
{
// Set temperature sign
if(temp < 0)
{
data[6] = 0x08;
temp *= -1;
}
else
{
data[6] = 0x00;
}
// Determine decimal and float part
int tempInt = (int)temp;
int td = (int)(tempInt / 10);
int tf = (int)round((float)((float)tempInt/10 - (float)td) * 10);
int tempFloat = (int)round((float)(temp - (float)tempInt) * 10);
// Set temperature decimal part
data[5] = (td << 4);
data[5] |= tf;
// Set temperature float part
data[4] |= (tempFloat << 4);
}
/**
* \brief Set the sensor humidity
* \param data Oregon message
* \param hum the humidity
*/
void setHumidity(byte* data, byte hum)
{
data[7] = (hum/10);
data[6] |= (hum - data[7]*10) << 4;
}
/**
* \brief Sum data for checksum
* \param count number of bit to sum
* \param data Oregon message
*/
int Sum(byte count, const byte* data)
{
int s = 0;
for(byte i = 0; i> 4;
s += (data[i]&0xF);
}
if(int(count) != count)
s += (data[count]&0xF0) >> 4;
return s;
}
/**
* \brief Calculate checksum
* \param data Oregon message
*/
void calculateAndSetChecksum(byte* data)
{
#ifdef THN132N
int s = ((Sum(6, data) + (data[6]&0xF) - 0xa) & 0xff);
data[6] |= (s&0x0F) <> 4;
#else
data[8] = ((Sum(8, data) - 0xa) & 0xFF);
#endif
}
/******************************************************************/
/******************************************************************/
/******************************************************************/
void setup()
{
pinMode(TX_PIN, OUTPUT);
Serial.begin(9600);
Serial.println("\n[Oregon V2.1 encoder]");
SEND_LOW();
#ifdef THN132N
// Create the Oregon message for a temperature only sensor (TNHN132N)
byte ID[] = {
0xEA,0x4C };
#else
// Create the Oregon message for a temperature/humidity sensor (THGR228N)
byte ID[] = {
0x1A,0x2D };
#endif
setType(OregonMessageBuffer, ID);
setChannel(OregonMessageBuffer, 0x20);
setId(OregonMessageBuffer, 0xBB);
}
void loop()
{
// Get Temperature, humidity and battery level from sensors
// (ie: 1wire DS18B20 for température, ...)
DHT22_ERROR_t errorCode;
// The sensor can only be read from every 1-2s, and requires a minimum
// 2s warm-up after power-on.
delay(2000);
float t = myDHT22.getTemperatureC();
float h = myDHT22.getHumidity();
int hum = h * 10;
int temp = t * 10;
errorCode = myDHT22.readData();
switch(errorCode)
{
case DHT_ERROR_NONE:
// Alternately, with integer formatting which is clumsier but more compact to store and
// can be compared reliably for equality:
//
char buf[128];
sprintf(buf, "T%03hi%03hi ", temp, hum);
Serial.println(buf);
// vw_send((uint8_t *)buf, strlen(buf));
// vw_wait_tx(); // Wait until the whole message is gone
break;
case DHT_ERROR_CHECKSUM:
Serial.print("check sum error ");
Serial.print(myDHT22.getTemperatureC());
Serial.print("C ");
Serial.print(myDHT22.getHumidity());
Serial.println("%");
break;
case DHT_BUS_HUNG:
Serial.println("BUS Hung ");
break;
case DHT_ERROR_TOOQUICK:
Serial.println("Polled to quick ");
break;
}
setBatteryLevel(OregonMessageBuffer, 1); // 0 : low, 1 : high
setTemperature(OregonMessageBuffer, t);
#ifdef THGR228N
// Set Humidity
setHumidity(OregonMessageBuffer, h);
#endif
// Calculate the checksum
calculateAndSetChecksum(OregonMessageBuffer);
// Show the Oregon Message
for (byte i = 0; i > 4, HEX);
Serial.print(OregonMessageBuffer[i] & 0x0F, HEX);
}
Serial.println();
// Send the Message over RF
sendOregon(OregonMessageBuffer, sizeof(OregonMessageBuffer));
// Send a "pause"
SEND_LOW();
delayMicroseconds(TWOTIME*8);
// Send a copie of the first message. The v2.1 protocol send the
// message two time
sendOregon(OregonMessageBuffer, sizeof(OregonMessageBuffer));
// Wait for 30 seconds before send a new message
SEND_LOW();
int i =0;
while (i++ < 70) {
// Sleep for 8 s with ADC module and BOD module off x 70 = 560 s
LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
}
}
Bonjour,
petit déterrage de topic, cependant je suis fortement intéressé par le code pour le capteur à ultrason si toujours disponible 😀
Merci d’avance 😉
Bonjour,
Super, je suis en train de faire un capteur de niveau ultra son pour ma cuve a eau idem que toi, si tu as le code pour l’ultrason je suis preneur.
encore merci,
Benjamin
Hi, many thanks for this code.
I have a comment, after working out what follows, I’ve found my discovery is something that is well known, but I’ll repeat it here to save others effort.
I got Ook_OSV2 from Jee Labs Cafe, written by Dominique Pierre. Worked well with my Oregon sensors.
I then set up this encoder – would not work. The Ook code demands 32 bits in the preamble, and this code seems to generate 31..
I have found that subsequent versions of the Ook code drop the preamble requirement to 24 bits, so the problem goes away if you’re using the latest version.
Hi, you’re welcome 🙂
Yes, Dominique Pierre explain me that sometimes the OokDecoder doesn’t « see » all 32 bits of the preamble. I have this problem with my THN132N sensors (31bits only are reported).
However, if my encoder send only 31 bits, It’s a mistake … I need to check, thanks for pointing that out.
Salut,
Peut-on créer des sondes à bas cout en utilisant seulement la puce de l’Ardui (Atmega328) comme le montre Idleman , pour les utiliser sur Domoticz via RFXcom.
merci d’avance.
Salut,
Oui c’est possible et c’était le but à l’origine des articles. Je ne m’en suis pas encore occupé mais j’ai tout ce qu’il faut pour le faire.
J’aimerai être sous les 5€ boitier compris.
il semble que erwan ai déjà tenté l’expérience 🙂
http://labalec.fr/erwan/?p=1489
https://forum.jeedom.fr/viewtopic.php?f=36&t=1832
hormis la conso électrique qui me semble a optimiser pour se rapprocher de celle des oregons officielles cela semble être un bon plan 🙂
Apres va falloir que je potasse sérieusement l’arduino 🙂
Salut,
Oui j’ai vu le post d’Erwan, il ne reste plus qu’à supprimer l’arduino pour être un peut moins cher et plus petit 🙂
Le coté conso n’est pas un problème je pense. Les sondes officielles émettent environ toutes les 30s mais tu peux monter à 1min, 5 min voir plus pour monitorer la température d’une pièce c’est largement suffisant. Ensuite, il suffit de mettre l’atmega en veille le reste du temps.
On doit pouvoir tenir facilement plus d’un 1an à ce rythme avec une ou deux piles LR6.
C’est clair que les 30-40 secondes d’origine ne sont pas nécessaires 🙂
Merci pour la réponse rapide
Je viens de voir un lien vers mon site, Merci 🙂
Ce site et cette page en particulier est une référence pour moi et m’a bcp aidé dans mes projets domotiques : un grand merci donc à Olivier !
Pour info, oui un arduino ca consomme encore top.
Donc, je suis passé sur un attiny85.
Voir ici .
Je passe 5ua en veille et 18ma en lecture : de quoi tenir longtemps, très longtemps sur une pile 3.7v / 1800 ma !
Salut Erwan,
Heureux de t’avoir été utile 🙂
J’ai fais un test aussi avec un ATtiny et j’ai un article en préparation mais je n’arrive pas à le terminer, je cherche un petit boitier joli et pas cher, tu n’en aurais pas trouvé un ?
++
Pour le boitier je me suis pas embête, je fais du strap sur une plaque mini de prototypage : ça me coûte pas cher et ma sonde est planqué derrière un meuble donc …
voir photo ici
Salut,
merci a Erwan pour son site et pour le boitier moi j’ai pris ca http://img15.hostingpics.net/pics/354568sondeo.jpg
http://img15.hostingpics.net/pics/144889sondef.jpg
1.5€ chez aliexpress
Bonjour à tous,
Je souhaite faire un répéteur pour les sondes oregon dans le but d’augmenter la portée à partir d’un Uno. La partie réception fonctionne. Par contre la partie émission, j’ai plus de pb et en plus je débute avec Arduino.
Si j’utilise le sketch d’Olivier, pas d’erreur de compilation par contre la zibase ne reçoit pas les ordres.
En utilisant la correction de catalin, j’ai une erreur de compilation.
int Sum(byte count, const byte* data)
{
int s = 0;
for(byte i = 0; i> 4;
s += (data[i]&0xF);
}
if(int(count) != count)
s += (data[count]&0xF0) >> 4;
return s;
}
Si quelqu’un pouvait m’aider…
Merci
Salut,
Le code de l’article est correct, je l’avais corrigé suite au commentaire de catalin. Par contre dans son commentaire il y a une erreur (due à wordpress qui à supprimé un bout de code à l’enregistrement du commentaire :/) c’est pour cela que tu as une erreur de compilation.
salut,
Tout d’abord merci pour ton boulot de reverse.
J’ai réussi à faire un module avec un DHT22+ Microview (arduino like)+Emetteur. ça fonctionne à merveille et est reconnu par domoticz comme un « THGN122/123, THGN132, THGR122/228/238/268 ».
j’ai essayé d’y ajouter un capteur BMP180 pour la pression et du coup, j’ai essayé de trouver quelle sonde Oregon faisait ça pour pouvoir l’émuler.
il semble que la BTHR968/BTHR918N fait ça.
J’ai essayé de l’émuler mais sans succès et même en émettant la trame soit disant de test du site http://www.mattlary.com/2012/06/23/weather-station-project/ ça ne fonctionne pas. le RFXCOM ne la voit pas.
une idée sur le codage de cette sonde ?
Bonjour Olivier, bonjour à tous,
Vraiment un grand bravo et un grand merci pour ce travail et cette mise à dispo, ça marche du tonnerre en réception comme en émission.
Juste une petite remarque pour la partie réception, à l’intégration de la partie 3/3 j’ai eu une erreur de compilation avec « max_bits = 160; »que j’ai du déclarer ainsi « int max_bits; » en début du sketch.
J’utilise un Tx/RX 433 vraiment pas cher (ce modèle : avec un fil de 17,5cm comme antenne, je me ballade dans toute la maison).
Reste à traiter les infos, j’aimerais pouvoir interfacer avec Domoticz, à suivre…
Merci encore
Cordialement
Michel
Bonjour
deja bravo pour toute ces realisations qui font rever des novice comme moi 🙂
je souhaite poser une petite question 🙂
j’ai commencé a me pencher sur la domotique il y a peut et au regard du prix d’un z-wave et d’un rfxcom je trouve ca bete de mettre peux cher dans un rasp pour devoir payer a prix d’or une interface 🙂
le module avec l’arduino presenté dans le post est-il compatible avec le logiciel domoticz?
est ce que par exemple les prises radiocommandé d’idleman sont compatible avec par exemple?
j’ai une sonde de temperature exterieure en 433mhz (vendu avec une horloge de base) est ce que ca peut etre compatible?
merci d’avance de vos reponses
DD91
Bonsoir,
Ces explications remontent un peu et font ma joie aujourd’hui j’ai pu moi aussi simuler des sondes « oregon » avec un Arduino ! et pour bien moins cher qu’une sonde « originale ».
Un grand merci pour votre article.
Par contre je serait à la recherche de l’encodage de sonde styles SD18, WD18,… (detecteurs de fumée, gaz, eau, …) et OWL (mesure de conso electyrique), quelqu’un aurait leurs protocoles ?
Merci.
Salut F1MVP , je suis F1 JSH
je suis comme toi à la recherche du protocole pour les OWL et autres sondes RFX as tu trouvé ces infos. J’ai cherché en vain…
As tu trouvé quelques choses à ce sujet
73 !!!
Olivier
Bonjour,
Non pas de réponse, un collègue m’a donné un morceau de code pour le décodage des trames, mais c’est à partir d’un récepteur RFX qui met déjà en forme ce qu’il a reçu. Donc je ne sais si la trame est complète (au niveau HF) et en plus il faut faire du rétro-engenering pour retrouver le contenu exact…
73’s
Thierry.
Bonjour,
Je cherche aussi les informations sur le protocole owl : mon objectif est de simuler un compteur owl cm180 (micro+) en émettant en 433mhz les infos de comptage provenant de ma carte arduino branchée sur la prise teleinfo de mon compteur électrique ERDF. (J’ai une installation domotique basée sur domoticz + rfxcom USB).
Le mieux que j’ai trouvé ce jour est sur http://forum.jeelabs.net/node/1038.html ou un forumeur disposant d’un owl cm119 signale que ce dernier utilise un protocole très proche d’0regon v3 et donne 2 trames capturees. Des que j’ai un peu de temps j’essaie de reconstituer le protocole du owl cm180 qui doit être proche.
Bonjour,
Pour le décodage des trames CMR180 j’ai mis à dispo le code sur un repo github (https://github.com/onlinux/OWL-CMR180)
avec qq exemples d’appli pour arduino et raspberry pi.
OSV3 62803C2801A0BE0313000020B5[CMR180,…] Id:6280, size:13 ,Flags:8 ,power:288 ,total:318946976 ,total kWh:88.60
OSV2 1A2D10867018100535A6[THGR228N,…] Id:86 ,Channel:1 ,temp:18.70 ,hum:51 ,bat:90
OSV2 1A2D20BB1C0940054700[THGR228N,…] Id:BB ,Channel:2 ,temp:9.10 ,hum:54 ,bat:10
OSV2 1A2D10222017100424F4[THGR228N,…] Id:22 ,Channel:1 ,temp:17.20 ,hum:41 ,bat:90
OSV2 1A2D10867018100535A6[THGR228N,…] Id:86 ,Channel:1 ,temp:18.70 ,hum:51 ,bat:90
OSV3 62803C2801E0020413000000E4[CMR180,…] Id:6280, size:13 ,Flags:8 ,power:288 ,total:319029984 ,total kWh:88.62
OSV2 1A2D40EC4120304440E6[THGR228N,…] Id:EC ,Channel:3 ,temp:20.40 ,hum:43 ,bat:90
OSV2 1A2D10867018100535A6[THGR228N,…] Id:86 ,Channel:1 ,temp:18.70 ,hum:51 ,bat:90
OSV2 1A2D20BB1C0940054700[THGR228N,…] Id:BB ,Channel:2 ,temp:9.10 ,hum:54 ,bat:10
OSV3 62823CD800B0[CMR180,…] Id:6282, size:6 ,Flags:8 ,power:208
OSV3 62813CE80040[CMR180,…] Id:6281, size:6 ,Flags:8 ,power:224
Merci onlinux !
Encore merci onlinux,
j’ai pu « rejouer » les trames que vous avez données pour faire croire à ma carte RFXCOM-USB que la carte arduino est un OWL CM180.
Pour info : il faut absolument un « postamble » à 4 pulses « 0 » pour que RFXCOM reconnaisse la trame (par contre il est peu sensible au preamble : j’ai fait un test de 10 pulses à 32 pulses « 1 » de preamble et ca passe à chaque fois).
Bonjour,
Serait-il possible d’avoir un exemple de code Arduino pour simuler un compteur owl cm180.
merci
Je mettrai le bout de code des que c’est déverminé, peut être le we prochain.
Je vois que cela à avancé, j’ai trouvé aujourd’hui cet article :
http://www.baghli.com/dspic_x10rf.php
Ou il y a une explication du protocole X10, mais cela ne ressemble pas aux transmissions OWL et SD18.
Merci pour vos infos.
Comme promis ci-dessous le bout de code (pas du tout optimisé ni propre) pour simuler un CM180 (OWL micro+) vis à vis d’un RFXCOM-Usb.
il réutilise largement le code de M. Olivier LEBRUN ele travail d’Onlinux ci-dessus.
P.S. j’ai couplé ce code avec le code « Teléinfo » d’un montage arduino branché sur mon compteur électrique pour transmettre en 433Mhz la puissance apparente et les index compteurs HC et HP à mon RFXCOM-usb couplé à Domoticz.
Je remercie l’auteur de ce Blog, Onlinux (ci-dessus) et M. Pascal Cardon (téléinfo : http://www.domotique-info.fr/2014/05/recuperer-teleinformation-arduino/).
—————————————————–
Le code est téléchargeable ici ->
http://connectingstuff.net/dw/encodeur_CM180.ino
Il faut apporter un correctif au programme ino ci-dessus.
La séquence de « postamble » consistant à faire 4 « SendZero » est incomplète ce qui peut faire planter le RFXCOM (je viens de le comprendre). Il faut y ajouter juste après un SEND_LOW() pendant une durée de 488 microsecondes (au moins).
Donc dans la fonction « void sendPostamble(void) » après l’exécution de la boucle « for », à la fin, il faut ajouter les 2 lignes suivantes et cela marchera bien mieux :
SEND_LOW();
delayMicroseconds(TIME);
J’ai apporté la modif dans le fichier à télécharger
Bonjour,
Super ton article. J’ai réutilisé ton code ( qui marche parfaitement d’ailleurs 😉 pour communiquer à mon serveur domotique la température / humidité de mon garage et aussi la consommation de gaz de la maison.
https://github.com/equinoxefr/gasMonitor
Encore merci.
Pierre
Bonjour Pierre.
Je suis aussi utilisateur de Domoticz et ton capteur de compteur gaz m interesse fortement.
Comment est ton compteur gaz ? il a un emplacement prevu pour recevoir une telereleve ou c est le bete compteur blanc ?
J’ai deja réaliser une copie de sonde osv3 (thgr810) visible par ma station meteo et par un soft utilisant un dongle usb tnt (rtl_433).
Bon, le copier et coller fait sauter les bouts de code…. notamment les signes les comparateurs et « ». Désolé.
snips, envoie le moi par mail je vais essayer de le remplacer dans ton commentaire via l’interface d’admin
@snips, merci pour le partage du code encodage CM180.
Malheureusement la copie pose effectivement problème, il manque aussi des des accolades, il me semble.
Possible de le partager sur une plateforme comme http://paste.debian.net qui permet de copier du texte/code pour une période limitée.
merci
Bonsoir Domos,
Olivier a mis le code/le fichier en ligne : http://connectingstuff.net/dw/encodeur_CM180.ino
Merci à lui !
Merci à vous deux.
Il faut apporter un correctif au programme ino ci-dessus.
La séquence de « postamble » consistant à faire 4 « SendZero » est incomplète ce qui peut faire planter le RFXCOM (je viens de le comprendre). Il faut y ajouter juste après un SEND_LOW() pendant une durée de 488 microsecondes (au moins).
Donc dans la fonction « void sendPostamble(void) » après l’exécution de la boucle « for », à la fin, il faut ajouter les 2 lignes suivantes et cela marchera bien mieux :
SEND_LOW();
delayMicroseconds(TIME);
J’ai apporté la modif dans le fichier à télécharger
Merci !
Snips
Je viens d’essayer ton code pour la simulation du cm180, cela fonction nickel.
Comment transmettre en valeur réel s’il te plait ?
Bonsoir,
Tu as déjà monté une carte électronique du type http://www.domotique-info.fr/2014/05/recuperer-teleinformation-arduino/ fonctionnelle et branchée sur les prises téléinfo de ton compteur électrique ?
Tu as bien vérifié que ton compteur renvoie bien les données téléinfo ?
La teleinfo fonctionne sans probleme, en direct sur mon PI, et en parrallele sur mon arduino.
Ton code lui aussi fonctionne avec les valeurs fixe que tu as determiner 60000kw et 1000w
J’ai essayer de commenté tes valeurs « test » forcement tout revient a 0
Quand tu ecris que tu as couplé ton code avec celui de la teleinfo :
– est ce que le code telechargeable ici est « complet » et l’accouplement est déja fait ?
– est ce que je dois faire l’assemblage moi meme ?
– en cas d assemblage maison, je prends quel code de teleinfo ? le test ou le final avec mise a jour du serveur web php ?.
Ton code doit il envoyer les info d’heure pleines et d’heures creuses ?
Merci de tes réponses
Parfait, j’ai déjà un code accouplé (encodeur + téléinfo) qui tourne chez moi depuis 2 semaines avec domoticz. Il faut que je nettoie le code et je demanderai a Olivier de publier sur le site (dans les jours qui viennent)
Pour les heures creuses et heures pleines : j’ai opté pour la solution sous domoticz de créer 2 compteurs differents: 1 pour les heures pleines et un pour les heures creuses. La carte arduino va donc émuler 2 compteurs distincts (2 identifiants différents) qui retourne chacun l’index heure creuse ou pleine suivan la periode tarifaire retournee par teleinfo. J’envisage aussi d’émuler un troisième compteur où je cumulerai les index heures pleines et creuses mais ce n’est pas encore fait.
Bonjour et merci à tous pour ce travail.
J’ai pu grâce aux codes partagés simuler 2 sonde oregon avec un capteur DHT22 et un DS18B20 waterproof (pour une piscine) sur un atmega 328 en standalone le tout interfacer avec domoticz.
Je suis actuellement en train de mettre en place la simulation OWL 180.
A la différence des autres post je n’utilise pas le teleinfo mais un capteur CT SENSOR.
J’arrive à intégrer dans le code OWL 180 la lecture de mon capteur en Watt, mais je ne sais pas comment faire pour envoyer correctement les bonnes infos à domoticz.
compteur totale
consommation « aujourd’hui »
Si vous avez des idées.
merci.
Ok, j’ai nettoyé le code et débogué, je viens de l’envoyer à Olivier.
Salut Snips, je n’ai rien reçu ?
merci snips.
Tu as la possibilité de le mettre à dispo ?
Olivier doit être occupé.
Le voila : http://connectingstuff.net/dw/my_teleinfo_CM180_clean.ino
matyoo,
je ne sais pas si ce lien vous sera utile : http://openenergymonitor.org/emon/node/58
L’encodeur OWL Cm180 retourne à Domoticz une puissance (pour teleinfo = puissance apparente) et un « total usage » (pour télinfo = index compteur).
Domoticz affiche la puissance et se sert de la variation du total usage (variation d’index compteur) pour calculer la consommation journalière.
Donc votre carte arduino doit retourner a minima un total usage (index compteur) pour que cela fonctionne. Le lien ci-dessus devrait vous être utile.
Merci je vais regarder ça et je vous fais un retour.
Bonsoir snips,
pour le lien j’utilise juste le current only je n’ai pas le dispositif AC voltage sur mon montage.
Je multiplie A (current) *230 pour avoir la puissance en WATT.
J’utilise donc qu’un seul PIN de mon arduino pour récupérer l’information.
Pour revenir au code, Il faudrait donc que j’incrémente un total usage dans mon code.
Je me pose la question s’il faut enregistrer ce totale dans l’eeprom en cas de coupure de courant. Sinon mon totale deviendra faux ?
Sinon j’ai en ma possession un « vrai » OWL 180, il n’utilise pas le telinfo il a un CT SENSOR. C’est pour ça que je ne comprend pas que dans le code fourni on parle de teleinfo.
voici le montage que j’utilise ainsi que le code qui fonctionne :
http://openenergymonitor.org/emon/buildingblocks/how-to-build-an-arduino-energy-monitor-measuring-current-only
Hello matyoo, pour répondre à votre question :
>Télinfo : en France les compteurs électroniques ERDF comportent la plupart du temps des borniers téléinfo (I1, I2). Le compteur envoie des données en série 1200 bauds : puissance apparente, les index compteurs etc…..
Donc quand on a la chance d’avoir un compteur de ce type, on a des mesures très précises (le compteur = instrument de mesure pour transaction) et on fait l’économie d’un OWL ou d’une pince ampèremétrique.
>SI vous avez un OWL CM180, c’est reconnu directement par domoticz ! pourquoi ne pas l’utiliser !
>Bon, si vous voulez utiliser votre CT SENSOR (je comprends ! c’est un défi, un challenge) effectivement pour Domoticz il me semble qu’il faut à partir de la puissance approximée A(t) * 230 multiplier par la durée entre 2 mesures puis ajouter cela au total pour avoir un total de consommation (énergie WH = index compteur). Ce chiffre devrait être mémorisé sur arduino d’une manière ou d’une autre. Après ce n’est pas catastrophique non plus si de temps temps le total compteur est « réinitialisé » car domoticz procède par différence (fin journée – début de journée il me semble) pour calculer la conso d’une journée. Une éventuelle anomalie sur Domoticz survient seulement pour le jour où le total compteur est réinitialisé (il suffit de corriger la base de données à la main avec sqlite manager par exemple….).
P.S. : attention l’approximation A(t)* 230 V marche bien si vous avez des « résistances » chez vous genre chauffage électrique…. par contre si vous avez des plaques à induction (>> puissance réactive, cosphi <1) vous allez avoir une valeur A(t)* 230 V qui est supérieure à la puissance acive consommée réelle. Idem quand vous n'avez rien d'allumé chez vous, et vous n'avez que les appareils en veille… vous allez avoir un cosphi <1 et de la puissance réactive… C'est pour cela que, pour une mesure précise, il faut pouvoir mesurer la tension en plus de l'intensité.
Je viens d’essaye le code « cleaner » et il ne fonctionne pas chez moi alors que le pas clean oui, j’ai l impression que rien n’est envoyer, et je n ai aucun retour dans la console de serial
bien entendu le montage est le meme,, une idee ?
Bonsoir Snips,
J’utilise mon owl 180 dailleurs il marche très bien avec domoticz.
Mais comme tu l’as dis c’est un challenge de réussir à en émuler un.
Avec les infos que tu m’as donné « multiplié la valeur par la durée entre 2 mesures » + compteur totale je penses que je peux y arriver.
Je vais alléger le code des entrées pour le teleinfo.
deennoo,
-j’ai re-téléchargé l’ino en lien ci-dessus, recompilé et déversé sur ma carte arduino et tout fonctionne chez moi.
-si le programme encodeur_CM180.ino fonctionne chez vous : c’est que l’émetteur 433 mhz est ok
-donc la conclusion c’est que la partie téléinfo qui a un problème. pour vérifier sur la console (PC branché sur l’USB) que tout est ok : dans la boucle loop il faut virer tout en bas les // devant la ligne // displayTeleInfo(); ce qui va activer le module d’affichage displayTeleInfo();
Sur la console vous devez voir les data téléinfo. si vous ne voyez rien, c’est normal qu’il n’y a pas d’émission 433 Mhz car celle ci n’est activé que si une trame téléinfo a été correctement reçue.
Si c’est le cas je vous suggère de vérifier si qqch n’a pas bougé (contact, cable; composant sur partie électronique teleinfo.
Bon courage !
Bonsoir,
j’ai réussi à avoir les bonnes informations remontées dans domoticz.
Ci-dessous le code utilisé
http://matyoo.free.fr/owl_180.txt
Il faudrait envoyé aussi la valeur de la batterie dans le code, car dans domoticz la sonde remonte en batterie faible (en tête en jaune). Mais je ne sais pas quel numéro de byte utiliser car ceux utilisés ci-dessous ne correspondent pas au code qu’on utilise.
J’ai trouvé le code ci-dessous pour le rfxcom et le owl 180.
Je ne sais pas si vous le connaissiez déjà.
http://rfxcom.readthedocs.org/en/latest/_modules/rfxcom/protocol/elec.html
« » »The Elec protocol is a 17 byte packet used by energy sensors. The
sensors transmit this packet periodically and the key data it provides is
the current watt usage and total watt usage. It is used for example by the
Owl energy monitors.
==== ====
Byte Meaning
==== ====
0 Packet Length, 0x11 (excludes this byte)
1 Packet Type, 0x5A
2 Sub Type
3 Sequence Number
4 ID 1
5 ID 2
6 Count (?)
7 Current Watts 1
8 Current Watts 2
9 Current Watts 3
10 Current Watts 4
11 Total Watts 1
12 Total Watts 2
13 Total Watts 3
14 Total Watts 4
15 Total Watts 5
16 Total Watts 6
17 Battery Level and RSSI
==== ====
« » »
Et encore merci pour l’aide.
Je vais m’attaquer maintenant au compteur d’eau, je viens de recevoir mes modules CNY 70
Oui il s’agit du format des trames retournées par rfxcom mais cela ne correspond pas aux trames émises pas le owl cm180 (rfxcom reformate les trames suivant son standard). J’avais fait varier quelques valeurs des octets/quartets de la trame de l’owl non encore décodés (,on ne sait pas a quoi ils servent) pour essayer de voir si cela change l’etat des batteries dans domoticz mais ça restait toujours a faible. J’ai laisse tomber si j’ai le courage je m’y remets (balayer toutes les valeurs et voir sur la console rfxcom ou domoticz si ça change qqch… C’est super pénible !).
Je renvoie tout de suite par mail il y a du avoir un problème avec ma messagerie.
Mea culpa, le message était bloqué dans ma boîte, je viens de renvoyer.
Ok merci cela fonctionne nickel !! (petit probleme de breadborad)
Bonjour,
Un grand merci pour tout ce travail.
J’ai repris le code pour faire un répétiteur et
Je voudrais ajouter des infos en queue du message.
Cela fonctionne bien jusqu’à 5 octets mais au-dessus, le message n’est pas reçu.
J’ai augmenté un peu sauvagement la valeur max_bits mais cela ne l’a pas impressionné.
Comme je ne comprends pas bien le fonctionnement du décodeur, je suis bloqué.
Quelle serait la manipulation à faire pour allonger les messages simulant les sondes 0xEA4C ou 0x1A2D.
Mon admiration pour l’ensemble du sujet !
Tout d’abord merci pour ce code très complet.
Je viens juste de coder et tester le calcul de CRC pour les sondes THGR122NX.
C’est bien un CRC8, pour le calcul duquel il faut supprimer l’ID et initialiser à 0x3C.
voici le code complet : (à appeler à la place de calculateAndSetChecksum(OregonMessageBuffer, false) par checkSumAndCRC(OregonMessageBuffer,8) )
void checkSumAndCRC(byte * data, const uint8_t len)
{
#define mByte(i) (data[i])
#define NIBBLE(i) ((mByte(i>>1) >> (((i)&1)<<2))&0xf)
uint8_t i,j,c,CRC,SUM;
CRC =0x3C;
SUM =0x00;
uint8_t CCIT_POLY = 0x07;
for (j=1; j<2*len; j++)
{
c = NIBBLE(j);
SUM += c;
if ( j != 6 && j != 7){ // place for ID
CRC ^= c;
for(i = 0; i<4; i++)
if(CRC & 0x80 )
CRC = (CRC << 1) ^ CCIT_POLY;
else
CRC <<= 1;
CRC &= 0xff;
}
}
for(i = 0; i<4; i++)
if(CRC & 0x80 )
CRC = (CRC << 1) ^ CCIT_POLY;
else
CRC <<= 1;
data[len] = (SUM & 0xFF);
data[len+1]= CRC;
}
Super merci 🙂
Bonjour,
merci pour cet article c’est vraiment super !
Je voudrais installer un dizaine de sondes dans ma maison et je ne vois pas comment mon récepteur va les distinguer.
Peut-être ceci est-il lié au paramètre channel ? et dans ce cas on est limité à 3 sondes. N’y a t’il pas un identifiant de sonde que l’on peut faire varier (par des micro switch par exemple) ?
merci pour votre aide car je suis un peut perdu !
Cordialement
Salut,
Si, l’identifiant c’est le code hexa que tu renseigne via la fonction : (ici 0xBB)
setId(OregonMessageBuffer, 0xBB);
Dans les trames que tu vas récupérer, soit avec un arduino récepteur (voir les articles sur la réception), soit avec un rfxcom, tu auras ce code comme identifiant.
Tu peux donc le modifier pour chaque sonde ou brancher un dip switch et récupérer le code configuré.
merci beaucoup
depuis j’ai ajouté un dizaine de sondes chez moi, 3 avec humidité + temp (avec un dht22) et 7 avec juste la température (avec une ds18b20) et je constate que de temps en temps les sondes vont et viennent ! Certaines ne fonctionnent qu’au démarrage (quand on branche la pile) et après plus rien. je ne sais pas si qqu’un a déjà rencontré ce problème et s’il y a une solution!
pour info mon montage est alimenté par une pile 3.6v 1/2AA
Salut,
Il est possible qu’il y est des collisions de paquets. Si elles sont programmées pour toutes émettre toutes les 30s par exemple et que tu les branche en même temps (peut probable) elles vont toutes émettre en même temps et tu ne recevras rien. Dans les sondes Oregon, l’intervalle de temps entre chaque émission est aléatoire (30s +- quelques secondes a chaque tour) ce qui permet de « désynchroniser » les émissions de chaque sonde et d’éviter d’avoir tjs les mêmes collisions. Bon après ce n’est peut être pas ça, à tester.
Bonjour Olivier,
Merci pour cet article génial!
Base sur ton excellent boulot et quelques infos à droite à gauche, j’ai pu réaliser le codage de la sonde BTHR918N, qui rajoute la pression!
Le code est là, si tu veux tester et l’intégrer 🙂
https://gist.github.com/RouquinBlanc/5cb6ff88cd02e68d48ea#file-bthr918n_arduinosender-ino
J’aurais aimé que la pression soit au dixième près par contre, car j’utilise un MPL3115A2 pour obtenir température et pression, qui est très précis. Le capteur réveille l’arduino par une interrupt, qui par la suite lis les données (I2C) et les transmet. Avec l’arduino nano je suis à 5mA en sommeil et 15mA en transmission. J’attends de recevoir un atmega328 standalone pour faire descendre encore plus la conso!
Tu peux regarder ce lien si ça t’intéresse: http://www.gammon.com.au/forum/?id=11497
Le mec fait miroiter une conso de moins de 350µA!!!!!
Je partage mon code Arduino+MPL3115A2+OregonRFSender dès que c’est plus propre.
Cheers
Jonathan
Salut Jonathan,
Merci pour ton partage! j’ai également fais une sonde (température et humidité pour l’instant) en standalone avec un attiny. J’ai préparer un article dessus mais je cherche désespérément un joli boitier pour encapsuler le tout :/
Super boulot !!!
J’ai besoin d’aide… je n’arrive pas à faire reconnaitre une simulation de sonde THGR228N ou même THN132 sur une station oregon : BAR988 ou même sur WMR928.
philippe hervier j’ai appliqué ça modif pour le calcul de CRC pour les sondes THGR122NX, rien à faire… les stations ne me remonte aucune information :(. par contre si je branche un 2em arduino, la trame est bien émise et complète. J’ai besoin d’aide j’y suis depuis 2 jours …merci :o)
Dsl petit complément d’info, quand je parle d’un 2em arduino. Il est en lecture et il me restitue bien les trames émissent par le 1er arduino.
Hello
je ne comprend pas ;
if(int(count) != count) …
count is a byte 8bit . Int(count) = 16bit ..;
A quoi cela sert il ?
Bonjour Olivier,
Je souhaite remplacer ma sonde de temperature exterieur (THN123N) qui est connectée à une centrale meteo oregon.
Je voulais savoir si le sketch que tu as présenté etait compatible avec le matériel oregon (j’ai testé et sans succès).
Cordialement,
Erwan
Salut Erwanlb,
Tel quel, non car il me semble qu’il y a un pb avec la checksum mais si tu regarde dans les commentaires, certains en parlent.
Bonsoir olivier,
Super ton script, je l’ai installé sur un arduino uno, testé, et bien sur il fonctionne parfaitement.
J’ai intégrer la lecture de capteur, et bien sur, je me retrouve avec une sonde oregon fonctionnant parfaitement.
Je te remercie
continue à partagé, c’est super.
cordialement
bouda25
Salut,
Merci pour ton retour, c’est sympa 🙂
Hi all and congratulations for the project, it’s very interesting :). I’m writing because I’m trying to simulate an Orengon scientif temperature sensor and anemometer with 3.0 protocol, and the base is a wmr200 console.
I studied the protocol, I got the hexadecima strings from THGR810 sensor (using one of the many programs that are found on the network), I rebuilt the signal with the preable (0xFF, 0xFF, 0xFF ….), and I retransmitted (without modification) without receiving from the console (using an additional arduino programmed, I can receive the string without problems) and I do not understand why. The transmission software that I have used is a revised version of http://shuhy.com/esi/osv3_dock_sensor.htm.
Can you help me?
Thanks so much!
Federico
No one knows how to help me? I can’t believe it 🙂
Hi!
Can you help me?
I loaded your code to arduino uno and nothing happened.
My Oregon base not print data.
Another arduino reviewer print transmitted data
Transmiter:
[Oregon V2.1 encoder]
1A2D20BB2C2220023E
Receiver:
Wed Sep 28 21:33:43 2016 – :1A:2D:20:BB:2C:22:20:02:3E:00: 2 187 22.2 22.0 12
Wed Sep 28 21:33:43 2016 – :1A:2D:20:BB:2C:22:20:02:3E:00: 2 187 22.2 22.0 12
But Oregon base not print this data in search mode.
Whats wrong with my base or your code?…
Hi,
I don’t have an Oregon base, but it’s probably a CRC error (we don’t check the CRC in the receiver, this is why you get results with it)
You should check the comments, some Guys have post CRC functions.
I did check CRC in the receiver, ‘3E’ byte in that packet is correct checksum, i think.
I checked CRC from my THGN122N, it sends correct data, checksum code is correct.
I will did Oregon repeater, but it doesn’t work 🙁
I overcame it! 🙂
1) tune length (485ms in real time world, my Arduino has сhinese timer 😉
const unsigned long TIME = 482;
2) send 17 bit, not 16… and remove postamble
void sendOregon(byte *data, byte size)
{
sendPreamble();
sendOne();
//sendSync();
sendData(data, size);
//sendPostamble();
}
3) replace calculateAndSetChecksum with checkSumAndCRC and rise message buffer from 9 to 10 bytes.
4) rise timeout between packets (i used DSO201 for trace real Oregon THGN122N )
delayMicroseconds(TWOTIME*10);
Very important time fine-tuning, to within microseconds.
All my three Oregon bases print data from arduino’s only if i set TWOTIME == 980us external real time (not arduino timer).
Each board has to be adjusted on the testimony of an oscilloscope 🙁
Hi Alex,
Very interesting ! I am also currently trying to transmit Oregon data from my Odroid-C2 with a RF433 transmitter to a BAR386 Oregon station. The data emitted are well decoded by my RF 433 receiver but I am unable to get anything on the Oregon station.
I send the following message with the emitter:
1a2d10bb202220023175
and I get on the following messages on the receiver :
Sensor::getRightSensor – create of (OSV2 1A2D10BB202220023175)
OSV2 – decode : id(1D20)(0x1D20)
OSV2 – decode : id(EC40) ch(1) bat(0) temp(222) sign(0) humid(220) cksum(31) crc(75)
Validate OOK – SUM : 0x31(0x31) CRC : 0x75(0x75)
So, everithing seems OK…
Could you confirm that my CRC is good ? and where do you connect your scope to get the external real time ? because it seems the delays are very important.
Thanks a lot !
DomPaul,
I used DSO201 oscilloscope to view length the first bit of transmission from sensor. I opened my sensor and view data from radio transmitter pin.
It has 980us. Where 1/2 = 490us.
I tune scetch code to set TIME == 490us. On my arduino’s it has TIME 485-487, all other numbers does not working.
You can cycle through all the values from 480 to 490.
But also you should protect code from interfering interruptions:
void sendOregon(byte *data, byte size)
{
cli(); // off inerrupts
sendPreamble();
sendData(data, size);
//sendPostamble();
sei(); // on interrupts
}
DomPau,
yes, CRC code is OK.
Hi Alex,
Thanks a lot for your feedback ! I tried with different values of TIME parameter and I switched my Odroid-C2 to realtime mode but with no success for this THGN122N sensor. I suppose there is still some delay issues…
I also tried with a THN132ES (Solar sensor) and I got the following informations on my RF433 Receiver :
Sensor::getRightSensor – create of (OSV2 EA4C20704021E0520B00)
Sensor::getRightSensor – create OregonSensorV2
OSV2 – decode : id(EC40)(0xEC40)
LEN=20
OSV2 – decode : id(EC040) ch(2) bat(0) temp(214) sign(0) cksum(2E)
OSV2 – decode : id(0xEC40) ch(2) bat(0) temp(21.400000) sign(0) cksum(0x2E) _chksum(0x2E)
Unfortunatly I am not able to calculate the CRC with this type of sensor which is very similar to a THN132N sensor but with a length of 2O nibbles. Probably the CRC initilization is’nt 0x3c but something else…
So, I will buy a THN122NX Sensor to check the real delays.
Could you tell me what type of Oregon Station you are using ? Perhaps my BAR386 station is a little bit different from your station.
Best Regards.
DomPaul
I’m using BAR388HG, RMR203HG, BAR628HG.
Thanks for this answer I will compare to see what is going wrong with my BAR386.
I have finaly solved the CRC initialization problem for the THN132N and THN132ES sensors. After many many tests I can say that the CRC must be initialized with oxD6 value and not with ox3C.
Moreover for this type of sensor it is necessary to modify the buffer to calculate the CRC :
checkSumAndCRC(OregonMessageBuffer,7);
and then it is also necessary to modify the loop for the CRC calculation :
for (j=1; j<(2*len) – 1; j++) instead of for (j=1; j<2*len ; j++)
For THN132ES OregonMessageBuffer has to be set to 10 (like for THGR122)
Now for example, when I emit :
ea4c40cd502020240300 (for a THN132ES sensor)
I receive :
Sensor::getRightSensor – create of (OSV2 EA4C40CD502020240300)
Sensor::getRightSensor – create OregonSensorV2
OSV2 – decode : id(EC40)(0xEC40)
LEN=20
OSV2 – decode : id(EC040) ch(4) bat(0) temp(205) sign(0) cksum(42)
OSV2 – decode : id(0xEC40) ch(4) bat(0) temp(20.500000) sign(0) cksum(0x42) _chksum(0x42)
with the right CRC (=32)
My Odroid and my Pi are reading the temperature value correctly but the BAR386 is still not able to display the temperature value. So now I am sure at 100% that it is a delay problem (or perhaps a postamble problem).
Thanks again for your help !
DomPaul
Hi all,
I also overcame it ! it was a delay problem and not a postamble problem. Now the temperature values are well displayed on my BAR386 ! As Alex said an oscilloscope is necessary to do a fine tuning of the real delays. I used a DSO nanoV3 and after some tests I put the following values in the C programme : TIME = 392 and TWOTIME = 996. I also reduced the delay between the two frames at only TWOTIME*2.
What i also discovered, is that the Oregon bases don’t read the temperatures immediately if they are not in search mode. So sometimes it’s necessary to wait until 1.5 minute before having the right temperature displayed on the screen of the base.
I hope those complementary informations will help…
Thanks again to all and particularly to Olivier for his great work on Oregon decoding/encoding
DomPaul
Hi DomPaul,
I also have a BAR386 and I would like to replace my broken THN132N with a cheap custom sensor. Can you please post a sample code with your modifications to send data to BAR386?
Hello
J’essaye, depuis un arduino Atmega 328 couplé à une puce RFM69, d’envoyé une trame de sonde oregon mais rien n’arrive sur mon recepteur 433Mhz.
Pourtant, je récupère bien les trames d’une sonde oregon THGN132N et aussi celle d’un arduino + emetteur RFM433mhz avec le même code que celui sur mon arduino + RFM69.
Des idées ?
Certains ont essayé?
Je suis parti d’un projet, avec un collègue, d’une sonde homemade basse conso, détails ici : https://github.com/Oliv4945/NoteRF-Elec
Merci d’avance
Benny
Bonjour,
Félicitation pour ce site,
En ce qui me concerne je souhaiterais faire l’inverse c’est à dire utiliser une station WMR918N pour afficher les informations de mes propres capteurs. Les originaux extérieurs sont morts seul le capteur BTHR918N fonctionne encore.
Pour info je suis de base électronicien et je fais évidemment un peu de programmation. J’ai réalisé une centrale domotique pour une résidence secondaire qui me permet de récupérer la température et l’humidité intérieure comme extérieure à partir d’une sonde THGR228N pour l’intérieur et THGN132N pour l’extérieur. Pour ces 2 sondes pas de soucis ma centrale WMR918N affiche les valeurs.
Maintenant je souhaiterais compléter mon système pour avoir les autres informations (vitesse et sens du vent +cumul pluie voire soleil…) Comme mes capteurs sont morts je pense en bidouiller a ma sauce éventuellement en utilisant les parties mécaniques de mes anciens capteurs. J’arrive déjà parfaitement à récupérer les infos de mes sondes THGR228 et BTHR918N avec ma centrale domotique. Afin de me faire la main sur l’émission du protocole oregon j’essaie de simuler en premier celui d’une sonde THGR228 que je maitrise bien avec un PIC et un module AUREL. Ma centrale domotique capte bien mais pas ma station WMR918N. J’ai fait une multitude d’essais mais ma station ne veut toujours rien savoir. Je sais qu’il y a sans doute un CRC8 à la fin de la trame certainement utilisée par la station mais j’ai simulé une trame intégrale (avec le CRC) que j’ai récupérée sur la vraie sonde THGR228 qui elle fonctionne sur ma station.
Il y a obligatoirement quelque chose que je ne dois pas respecter dans le protocole mais je n’arrive pas à voir quoi.
C’est pourquoi je vous sollicite. Je vous remercie d’avance et j’espère avoir été clair dans mes explications.
Cordialement