Cette station est sans doute un peu passée de mode, mais est-ce une raison pour la mettre à la poubelle?
Je cherche un code fonctionnel permettant de simuler une sonde de température (Oregon, 433Mhz, V1).
J'ai trouvé une doc assez complète sur internet, mais, malgré l'avoir suivie, à priori, scrupuleusement, je n'arrive toujours pas à afficher une température :-(.
L'objet final est d'obtenir différentes températures (processeur ou autre sondes) et de les afficher sur ce tableau de bord.
On trouve pléthore de décodeur, surtout V2 et V3, mais, même si le sujet est évoqué parfois, pas de code d'émetteur.
Aussi, si l'un de vous avait cela dans son tiroir, quelle aubaine
Etonnant !
/*
* 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.
*
* based on
* https://github.com/skywodd/arduino_blyss_hack/blob/master/Blyss_arduino_code/RF_Blyss_Spoofer/RF_Blyss_Spoofer.ino
*/
#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);
}
Merci pour ce code, mais cela concerne le protocole V2... Qui est très différent du V1 (même la fréquence d’échantillonnage est différente ;-)).
Le lien vers la doc est http://wmrx00.sourceforge.net/Arduino/OregonScientific-RF-Protocols.pdf
Bref, je veux toujours bien une réponse qui correspond à la V1...
OK
J'avais cru lire que tu ne trouvais pas de programme TX pour aucune des versions oregon
çà bouge pas mal en ce moment sur le portage RFLINK vers de l'esp32
tu à jeté un oeil ? là
Super merci, c'est exactement ce que je cherchais!
Au début j'ai pensé que la lib ne fonctionnait pas bien, mais en me replongeant dans la doc de la station, j'ai noté une chose importante qui accélère pas mal le processus: il faut, après démarrage de la nouvelle sonde, appuyer simultanément sur memory et channel pour que la station considère rapidement la nouvelle sonde.
Ensuite, je ne sais pas si cela vient du arduino pas cher (instable?), de la station vieillissante (sourde?), de perturbation locale (je n'ai pas non plus un analyseur de spectre sous la main ) ou de mon code (nan, je ne crois pas ), mais pour avoir un affichage stable, je dois en fait émettre toutes les 10s pour chacune des sondes simulées. Si je n'émets que toutes les 30s je perds souvent l'affichage sur une journée... Je n'ai pas fait de test pour connaitre la limite précise entre 10 et 30.
En tout cas, le résultat est une sonde multiple que je renseigne, sur le pseudo port série USB, à partir d'une machine linux qui récupère sur internet la température mesurée de mon patelin ainsi que la température ressentie (le genre de truc incalculable ). J'ai un canal pour chacune des données. Et je suis bien trop loin des fenêtres pour avoir une sonde à portée...
Dans l'absolu, je peux maintenant afficher 3* n'importe qu'elle température depuis mon PC .