Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * connectingStuff, Oregon Scientific v2.1 Emitter
- * http://www.connectingstuff.net/blog/encodage-protocoles-oregon-scientific-sur-arduino/
- *
- * Copyright (C) 2013 [email protected]
- * Modified by Jonathan Martin <[email protected]>, August 2015
- *
- * 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.
- *
- * 2017 04 11
- * LeOS modification to get data from DHT11 sensor connected to PIN7
- * Tested working great on Domoticz environment
- */
- #include <dht11.h>
- dht11 DHT;
- #define DHT11_PIN 7
- #define MODE_0 0 // Temperature only [THN132N]
- #define MODE_1 1 // Temperature + Humidity [THGR2228N]
- #define MODE_2 2 // Temperature + Humidity + Baro() [BTHR918N]
- #define MODE MODE_1
- const byte TX_PIN = 6;
- 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
- #if MODE == MODE_0
- byte OregonMessageBuffer[8];
- #elif MODE == MODE_1
- byte OregonMessageBuffer[9];
- #elif MODE == MODE_2
- byte OregonMessageBuffer[11];
- #else
- #error mode unknown
- #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)
- {
- #if MODE == MODE_0
- 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 Set the sensor temperature
- * \param data Oregon message
- * \param temp the temperature
- */
- void setPressure(byte *data, float pres)
- {
- if ((pres > 850) && (pres < 1100)) {
- data[8] = (int)round(pres) - 856;
- data[9] = 0xC0;
- }
- }
- /**
- * \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)
- {
- #if MODE == MODE_0
- int s = ((Sum(6, data) + (data[6]&0xF) - 0xa) & 0xff);
- data[6] |= (s&0x0F) << 4; data[7] = (s&0xF0) >> 4;
- #elif MODE == MODE_1
- data[8] = ((Sum(8, data) - 0xa) & 0xFF);
- #else
- data[10] = ((Sum(10, data) - 0xa) & 0xFF);
- #endif
- }
- /******************************************************************/
- /******************************************************************/
- /******************************************************************/
- void setup()
- {
- pinMode(TX_PIN, OUTPUT);
- //Serial.begin(9600);
- //Serial.println("\n[Oregon V2.1 encoder]");
- SEND_LOW();
- #if MODE == MODE_0
- // Create the Oregon message for a temperature only sensor (THN132N)
- byte ID[] = {0xEA,0x4C};
- #elif MODE == MODE_1
- // Create the Oregon message for a temperature/humidity sensor (THGR2228N)
- byte ID[] = {0x1A,0x2D};
- #else
- // Create the Oregon message for a temperature/humidity/barometer sensor (BTHR918N)
- byte ID[] = {0x5A, 0x6D};
- #endif
- setType(OregonMessageBuffer, ID);
- setChannel(OregonMessageBuffer, 0x20);
- setId(OregonMessageBuffer, 0xCB);
- }
- void loop()
- {
- // Get Temperature, humidity and battery level from sensors
- // (ie: 1wire DS18B20 for température, ...)
- setBatteryLevel(OregonMessageBuffer, 1); // 0 : low, 1 : high
- float temp=(DHT.temperature,1);
- setTemperature(OregonMessageBuffer, temp);
- #if MODE != MODE_0
- // Set Humidity
- //setHumidity(OregonMessageBuffer, 52);
- float hum=(DHT.humidity,1);
- setHumidity(OregonMessageBuffer, hum);
- #endif
- #if MODE == MODE_2
- // Set Pressure
- setPressure(OregonMessageBuffer, 1013);
- #endif
- // Calculate the checksum
- calculateAndSetChecksum(OregonMessageBuffer);
- // Show the Oregon Message
- //Serial.println("Oregon -> ");
- //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);
- }
Advertisement
Add Comment
Please, Sign In to add comment