Files
Arduino/Oregon433T_H_LED/Oregon433T_H_LED.ino
Jérôme Delacotte 7b30d6e298 first commit
2025-03-06 11:15:32 +01:00

667 lines
16 KiB
C++
Executable File

/*
* connectingStuff, Oregon Scientific v2.1 Emitter
* http://connectingstuff.net/blog/encodage-protocoles-oregon-scientific-sur-arduino
* and
* http://blog.idleman.fr/raspberry-pi-18-construire-une-sonde-de-temperature-radio-pour-7e/
*
* 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.
*/
#include <OneWire.h>
#include <DallasTemperature.h>
#include "DHT.h"
#define DHTPIN A3 // what pin we're connected to
#define DHTTYPE DHT11 // DHT 11
// ############################# LED
// Assign LED Output PWM Pins
int Red = 11;
int Green = 10;
int Blue = 6; // 9 déjà utilisé
//Set Initial Values
int RedVal = 0;
int GreenVal = 0;
int BlueVal = 0;
int fade = 10; // Delay Time
// Colour Value 1 as each colour intensity (0-255)
int RedVal1 = 186;
int GreenVal1 = 0;
int BlueVal1 = 255;
// Colour Value 2
int RedVal2 = 9;
int GreenVal2 = 239;
int BlueVal2 = 26;
//Colour Value 3
int RedVal3 = 255;
int GreenVal3 = 120;
int BlueVal3 = 0;
//Colour Value 4
int RedVal4 = 0;
int GreenVal4 = 255;
int BlueVal4 = 78;
//Set initial mode (Colour Value Mode) to Colour Value 1
int mode = 1;
int bcl = 0;
// ############################## FIN LED
//#define THN132N
const byte TEMPERATURE_1_PIN = 2;
const byte TRANSMITTER_PIN = 9;
// On crée une instance de la classe oneWire pour communiquer avec le materiel on wire (dont le capteur ds18b20)
OneWire oneWire(TEMPERATURE_1_PIN);
//On passe la reference onewire à la classe DallasTemperature qui vas nous permettre de relever la temperature simplement
DallasTemperature sensors(&oneWire);
// Initialize DHT sensor for normal 16mhz Arduino
DHT dht(DHTPIN, DHTTYPE);
const unsigned long TIME = 512;
const unsigned long TWOTIME = TIME*2;
#define SEND_HIGH() digitalWrite(TRANSMITTER_PIN, HIGH)
#define SEND_LOW() digitalWrite(TRANSMITTER_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, float hum)
{
int h = (int) hum;
data[7] = (int) h / 10; //(hum/10);
data[6] |= (h - data[7]*10) << 4;
Serial.print("Hum=");
Serial.println(h);
}
/**
* \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 setupLed() {
//----------------------- Assign outputs
pinMode(Red, OUTPUT);
pinMode(Green, OUTPUT);
pinMode(Blue, OUTPUT);
//----------------------- Write Initial Values of 0 to outputs
analogWrite(Red, RedVal);
analogWrite(Green, GreenVal);
analogWrite(Blue, BlueVal);
}
// #################################################
void setup()
{
setupLed();
pinMode(TRANSMITTER_PIN, OUTPUT);
Serial.begin(9600);
Serial.println("\n[Oregon V2.1 encoder]");
SEND_LOW();
//On initialise le capteur de temperature
sensors.begin();
#ifdef THN132N
// Create the Oregon message for a temperature only sensor (TNHN132N)
byte ID[] = {0xEA,0x4C};
Serial.println("Def THN132");
#else
// Create the Oregon message for a temperature/humidity sensor (THGR228N)
byte ID[] = {0x1A,0x2D};
// Rain jauge
//byte ID[] = {0x3A,0x0D};
Serial.println("UnDef THN132");
#endif
setType(OregonMessageBuffer, ID);
setChannel(OregonMessageBuffer, 0x20);
setId(OregonMessageBuffer, 0xBB);
// DHT
dht.begin();
}
void loop()
{
bcl++;
if (bcl >= 2) {
bcl = 0;
do433();
}
doLed();
}
void doLed() {
while(mode == 1){
if(RedVal < RedVal1){ // If RedVal is less than desired RedVal1
RedVal ++; // increment RedVal
} else if(RedVal > RedVal1){ // If RedVal is more than desired RedVal1
RedVal --; // decrement RedVal
} else if(RedVal == RedVal1){ // If RedVal is equal to desired RedVal1
//Do Nothing
}
// Repeated as above for BlueVal
if(BlueVal < BlueVal1){
BlueVal ++;
} else if(BlueVal > BlueVal1){
BlueVal --;
} else if(BlueVal == BlueVal1){
//Do Nothing
}
// Repeated as above for GreenVal
if(GreenVal < GreenVal1){
GreenVal ++;
} else if (GreenVal > GreenVal1){
GreenVal --;
} else if (GreenVal == GreenVal1){
// Do Nothing
}
// Now we have a new set of values, we write them to the PWM Pins.
analogWrite(Red, RedVal);
analogWrite(Green, GreenVal);
analogWrite(Blue, BlueVal);
delay(fade); // Implement a bit of delay to slow the change of colour down a bit
if(RedVal == RedVal1 && GreenVal == GreenVal1 && BlueVal == BlueVal1){ // If RedVal & GreenVal & BlueVal are all at the desired values
Serial.println("Pause mode 1");
delay(1500); // Delay to hold this colour for a little while
mode = 2; // Change the mode to the next colour. Exiting this while loop and into the next one
}
}
while(mode == 2){
if(RedVal < RedVal2){
RedVal ++;
} else if(RedVal > RedVal2){
RedVal --;
} else if(RedVal == RedVal2){
//Do Nothing
}
if(BlueVal < BlueVal2){
BlueVal ++;
} else if(BlueVal > BlueVal2){
BlueVal --;
} else if(BlueVal == BlueVal2){
//Do Nothing
}
if(GreenVal < GreenVal2){
GreenVal ++;
} else if (GreenVal > GreenVal2){
GreenVal --;
} else if (GreenVal == GreenVal2){
// Do Nothing
}
analogWrite(Red, RedVal);
analogWrite(Green, GreenVal);
analogWrite(Blue, BlueVal);
delay(fade);
if(RedVal == RedVal2 && GreenVal == GreenVal2 && BlueVal == BlueVal2){
Serial.println("Pause mode 2");
delay(1500);
mode = 3;
//break;
}
}
while(mode == 3){
if(RedVal < RedVal3){
RedVal ++;
} else if(RedVal > RedVal3){
RedVal --;
} else if(RedVal == RedVal3){
//Do Nothing
}
if(BlueVal < BlueVal3){
BlueVal ++;
} else if(BlueVal > BlueVal3){
BlueVal --;
} else if(BlueVal == BlueVal3){
//Do Nothing
}
if(GreenVal < GreenVal3){
GreenVal ++;
} else if (GreenVal > GreenVal3){
GreenVal --;
} else if (GreenVal == GreenVal3){
// Do Nothing
}
analogWrite(Red, RedVal);
analogWrite(Green, GreenVal);
analogWrite(Blue, BlueVal);
delay(fade);
if(RedVal == RedVal3 && GreenVal == GreenVal3 && BlueVal == BlueVal3){
Serial.println("Pause mode 3");
delay(1500);
mode = 4;
//break;
}
}
while(mode == 4){
if(RedVal < RedVal4){
RedVal ++;
} else if(RedVal > RedVal4){
RedVal --;
} else if(RedVal == RedVal4){
//Do Nothing
}
if(BlueVal < BlueVal4){
BlueVal ++;
} else if(BlueVal > BlueVal4){
BlueVal --;
} else if(BlueVal == BlueVal4){
//Do Nothing
}
if(GreenVal < GreenVal4){
GreenVal ++;
} else if (GreenVal > GreenVal4){
GreenVal --;
} else if (GreenVal == GreenVal4){
// Do Nothing
}
analogWrite(Red, RedVal);
analogWrite(Green, GreenVal);
analogWrite(Blue, BlueVal);
delay(fade);
if(RedVal == RedVal4 && GreenVal == GreenVal4 && BlueVal == BlueVal4){
Serial.println("Pause mode 4");
delay(1500);
mode = 1; // Set mode back to 1 to return to the original colour.
//break;
}
}
}
void do433() {
Serial.println("433 Start");
// Reading temperature or humidity takes about 250 milliseconds!
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
float h = dht.readHumidity();
// Read temperature as Celsius
float t = dht.readTemperature();
// Read temperature as Fahrenheit
float f = dht.readTemperature(true);
// Check if any reads failed and exit early (to try again).
if (isnan(h) || isnan(t) || isnan(f)) {
// Serial.println("Failed to read from DHT sensor!");
return;
} else {
// Compute heat index
// Must send in temp in Fahrenheit!
float hi = dht.computeHeatIndex(f, h);
Serial.print("Humidity: ");
Serial.print(h);
Serial.print(" %\t");
Serial.print("Temperature: ");
Serial.print(t);
Serial.print(" *C ");
Serial.print(f);
Serial.print(" *F\t");
Serial.print("Heat index: ");
Serial.print(hi);
Serial.println(" *F");
}
// ##########################################"
// Analogic read
// ------------------------------------------
int sensorValue = analogRead(A0);
int sensorValue2 = analogRead(A1);
int sensorValue3 = analogRead(A2);
// int sensorValue4 = digitalRead(10);
//vol = (float)sensorValue / 1024 * 5.0;
Serial.print("fumee=");
Serial.print(sensorValue);
Serial.print(" gaz=");
Serial.print(sensorValue2);
Serial.print(" photo=");
Serial.println((int) (sensorValue3 / 10.24));
// ##########################################
// Get Temperature, humidity and battery level from sensors
// (ie: 1wire DS18B20 for température, ...)
setBatteryLevel(OregonMessageBuffer, 0); // 0 : low, 1 : high
// need addaptation here
// Ajout perso
//Lancement de la commande de récuperation de la temperature
sensors.requestTemperatures();
setTemperature(OregonMessageBuffer,sensors.getTempCByIndex(0));
// setTemperature(OregonMessageBuffer, 11.2);
#ifndef THN132N
// Set Humidity
setHumidity(OregonMessageBuffer, h);
#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);
}
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();
// delay(30000);
}