first commit

This commit is contained in:
Jérôme Delacotte
2025-03-06 11:15:32 +01:00
commit 7b30d6e298
5276 changed files with 2108927 additions and 0 deletions

View File

@@ -0,0 +1,520 @@
/*
* 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 <Wire.h>
#include <Adafruit_BMP085.h>
#include <RCSwitch.h>
#include <Narcoleptic.h>
#define LED_PIN (13)
#define DEBUG TRUE
#define SEND_MESSAGE_DELAY 30000 // Ne pas dépasser 32000 !! Delay in ms between each value's extraction
#define SEND_433_PAUSE 160 // 16 multiple
const byte TRANSMITTER_PIN = 9;
// Init RCSwitch
RCSwitch mySwitch = RCSwitch();
//
float temperature = 0.0;
float pressure = 0.0;
float pression = 0.0;
float presiune = 0.0;
// ################# Barometre ####
Adafruit_BMP085 bmp;
// #####################
///////////////// OREGON //////////////////////////////////////
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, 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
}
/******************************************************************/
/******************************************************************/
/******************************************************************/
//////////////// FIN OREGON /////////////////////////////////
// =============================================================
void setup() {
mySwitch.enableTransmit(TRANSMITTER_PIN);
Serial.begin(9600);
// Sleep
/* Don't forget to configure the pin! */
pinMode(LED_PIN, OUTPUT);
// TEST SONDE BAROMETRE
//byte ID[] = {0x5A,0x5D};
#ifdef THN132N
// Create the Oregon message for a temperature only sensor (TNHN132N)
byte ID[] = {0xEA,0x4C};
#ifdef DEBUG
Serial.println("Def THN132");
#endif
#else
// Create the Oregon message for a temperature/humidity sensor (THGR2228N)
byte ID[] = {0x1A,0x2D};
#ifdef DEBUG
Serial.println("UnDef THN132");
#endif
#endif
setType(OregonMessageBuffer, ID);
setChannel(OregonMessageBuffer, 0x20);
// ATMEGA 1 = BC
// TEST OREGON BB
// TEST Luminosite BD
// Barometre BE
setId(OregonMessageBuffer, 0xBE); // ID BB BC BE
}
void loop()
{
digitalWrite(13, HIGH);
// Read Vcc value
long currentVcc = 5000; //readVcc();
barometre();
digitalWrite(13, LOW);
if (currentVcc > 5000) {
currentVcc = 5000;
}
#ifdef DEBUG
Serial.println(currentVcc);
#endif
byte ID[] = {0x1A,0x2D};
sendMyOregon( ID, 0x20, 0xBE, temperature, 58, currentVcc);
//sendMyOregon( ID, 0x20, 0xBC,temperature, 52);
//
// // Get Temperature, humidity and battery level from sensors
// // (ie: 1wire DS18B20 for température, ...)
// if (currentVcc < 3800) {
// setBatteryLevel(OregonMessageBuffer, 0); // 0 : low, 1 : high
// } else {
// setBatteryLevel(OregonMessageBuffer, 1); // 0 : low, 1 : high
// }
// // need addaptation here
//// Ajout perso
//
// setTemperature(OregonMessageBuffer,temperature);
//
//
//// setTemperature(OregonMessageBuffer, 11.2);
//
//#ifndef THN132N
// // Set Humidity
// setHumidity(OregonMessageBuffer, 52);
//#endif
//
// // Calculate the checksum
// calculateAndSetChecksum(OregonMessageBuffer);
//
// // Show the Oregon Message
// #ifdef DEBUG
// for (byte i = 0; i < sizeof(OregonMessageBuffer); ++i) {
// Serial.print(OregonMessageBuffer[i] >> 4, HEX);
// Serial.print(OregonMessageBuffer[i] & 0x0F, HEX);
//
// }
// Serial.println("");
// #endif
//
// // 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));
//
// Narcoleptic.delay(SEND_433_PAUSE);
//
// // Wait for 30 seconds before send a new message
// SEND_LOW();
// //delay(3000);
Narcoleptic.delay(SEND_MESSAGE_DELAY);
Narcoleptic.delay(SEND_MESSAGE_DELAY);
}
void barometre() {
/* See Example: TypeA_WithDIPSwitches */
// mySwitch.switchOn("00001", "10000");
// delay(1000);
// BMP
if (bmp.begin()) {
temperature = bmp.readTemperature();
pressure= bmp.readPressure() / 100.0;
pression = pressure / 101.325;
pression = pression * 0.760 * 100;
// http://en.wikipedia.org/wiki/Atmospheric_pressure#Mean_sea_level_pressure
// Serial.print("Presiure la nivelul marii (calculata) = ");
presiune = bmp.readSealevelPressure(19) / 101.325;
presiune = presiune * 0.760;
#ifdef DEBUG
Serial.print("Temperature="); Serial.println(temperature);
Serial.print("pressure="); Serial.println(pressure);
Serial.print("presiune="); Serial.println(presiune);
#endif
}
}
////--------------------------------------------------------------------------------------------------
//// Read current supply voltage
////--------------------------------------------------------------------------------------------------
// long readVcc() {
// bitClear(PRR, PRADC); ADCSRA |= bit(ADEN); // Enable the ADC
// long result;
// // Read 1.1V reference against Vcc
// #if defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
// ADMUX = _BV(MUX5) | _BV(MUX0); // For ATtiny84
// #elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
// ADMUX = _BV(MUX3) | _BV(MUX2);
// #else
// ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); // For ATmega328
// #endif
// delay(2); // Wait for Vref to settle
// ADCSRA |= _BV(ADSC); // Convert
// while (bit_is_set(ADCSRA,ADSC));
// result = ADCL;
// result |= ADCH<<8;
// result = 1126400L / result; // Back-calculate Vcc in mV
// // ADCSRA &= ~ bit(ADEN); bitSet(PRR, PRADC); // Disable the ADC to save power
// return result; // Vcc in millivolts
//}
void sendMyOregon(byte messageID[], byte channel, byte id, float temp, byte hum, int currentVcc) {
byte OregonMessageBuffer[9];
// Messages gérés par Domoticz
// 0xEA4C taille 8 bytes température et niveau de batterie
//0x1A2D taille 9 bytes température humidité et niveau de batterie (0 / 1)
//0xF824 3 températures 2 humidité
//0x1984 0x1994 Vent ?
//0x2914 Pluie
setType(OregonMessageBuffer, messageID);
setChannel(OregonMessageBuffer, channel);
// ATMEGA 1 = BC
// TEST OREGON BB
// TEST Luminosite BD
// Barometre BF
setId(OregonMessageBuffer, id); // ID BB BC BF
setBatteryLevel(OregonMessageBuffer, 1); // 0 : low, 1 : high
if (currentVcc < 3800) {
setBatteryLevel(OregonMessageBuffer, 0); // 0 : low, 1 : high
} else {
setBatteryLevel(OregonMessageBuffer, 1); // 0 : low, 1 : high
}
setTemperature(OregonMessageBuffer,temp);
setHumidity(OregonMessageBuffer, hum);
// Calculate the checksum
calculateAndSetChecksum(OregonMessageBuffer);
// 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));
}