/* * 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 #include #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> 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); }