├── README.md ├── low_power_sensor.ino └── low_power_sensor_inside.ino /README.md: -------------------------------------------------------------------------------- 1 | # low_power_sensor 2 | Low power node - ATMega328p standalone based environment sensor 3 | 4 | low_power_sensor.ino is dedicated to outside house measurement it measures humidity, temperature, hygrometry and battery voltage 5 | Tutorial: http://1technophile.blogspot.fr/2016/08/low-cost-low-power-6ua-garden-433mhz.html 6 | 7 | low_power_sensor_inside.ino is dedicated to inside house measurement it measures humidity, temperature and battery voltage 8 | Tutorial: http://1technophile.blogspot.fr/2016/12/low-cost-low-power-room-sensor-with.html 9 | 10 | This program enables to send sensor data with low power: 11 | - send sensor data to a 433Mhz gateway 12 | - with 3 AA batteries measured at 5V the current consumption in sleep mode is around 6uA 13 | 14 | Contributors: 15 | - 1technophile 16 | 17 | Based on the libraries: 18 | - RCSwitch 19 | - LowPower 20 | 21 | Based on the work of: 22 | Nick Gammon : http://www.gammon.com.au/power 23 | Rocketscream: https://github.com/rocketscream/Low-Power 24 | Tinkerit: https://code.google.com/archive/p/tinkerit/wikis/SecretVoltmeter.wiki 25 | 26 | Documentation: 27 | Project home: https://github.com/1technophile/low_power_sensor 28 | 29 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software 30 | and associated documentation files (the "Software"), to deal in the Software without restriction, 31 | including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 32 | and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, 33 | subject to the following conditions: 34 | 35 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 36 | 37 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 38 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 39 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 40 | CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 41 | -------------------------------------------------------------------------------- /low_power_sensor.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Low power node - ATMega328p program to send humidity, temperature, hygrometry and battery voltage 3 | 4 | This program enables to send sensor data with low power: 5 | - send sensor data to a 433Mhz gateway 6 | - with 3 AA batteries measured at 5V the current consumption in sleep mode is around 5uA 7 | Contributors: 8 | - 1technophile 9 | Based on the libraries: 10 | - RCSwitch 11 | - LowPower 12 | Based on the work of: 13 | Nick Gammon : http://www.gammon.com.au/power 14 | Rocketscream: https://github.com/rocketscream/Low-Power 15 | Tinkerit: https://code.google.com/archive/p/tinkerit/wikis/SecretVoltmeter.wiki 16 | Documentation: 17 | Project home: https://github.com/1technophile/low_power_sensor 18 | Blog: http://1technophile.blogspot.fr/2016/08/low-cost-low-power-6ua-garden-433mhz.html 19 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software 20 | and associated documentation files (the "Software"), to deal in the Software without restriction, 21 | including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 22 | and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, 23 | subject to the following conditions: 24 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 25 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 26 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 27 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 28 | CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 29 | */ 30 | 31 | #include "DHT.h" 32 | #include "LowPower.h" 33 | #include 34 | #include 35 | 36 | #define DHTTYPE DHT11 37 | 38 | RCSwitch mySwitch = RCSwitch(); 39 | 40 | //Time used to wait for an interval before resending data 41 | unsigned long time; 42 | 43 | //Pin on which the sensors are connected 44 | const int PresencePin = 8; 45 | const int LedPin = 9; 46 | const int DhtPin = 3; 47 | const int DhtPowerPin = 4; 48 | const int HygPowerPin = 10; 49 | const int EmitPin = 6; 50 | const int EmitPowerPin = 7; 51 | 52 | const int TimeToSleep = 3000; // set time to sleep (approx) in seconds 53 | 54 | DHT dht(DhtPin,DHTTYPE); 55 | 56 | int presenceState = 0; 57 | 58 | // define humidity variable to hold the final value 59 | int humidity = 0; 60 | 61 | //Do we want to see trace for debugging purposes 62 | #define TRACE 0 // 0= trace off 1 = trace on 63 | 64 | /*These values define the RF code value sent if the sensor values are 65 | equals to 0, for example, if the sensor value of temperature is 24°C, the 66 | program is going to send 33240, this resulting value can be interpreted 67 | either at gateway level or better at domotic software level (example openhab)*/ 68 | #define HUM "31000" 69 | #define TEMP "33000" 70 | #define HYGRO "34000" 71 | #define VOLT "35000" 72 | #define ERRORCODE "99999" 73 | 74 | // define humidity variable to hold the final value 75 | int hygro = 0; 76 | 77 | void setup() 78 | { 79 | Serial.begin(9600); 80 | // initialize the input for presence detection 81 | pinMode(HygPowerPin,INPUT); 82 | pinMode(DhtPowerPin,INPUT); 83 | pinMode(EmitPowerPin,INPUT); 84 | // start led signal 85 | pinMode(LedPin,OUTPUT); 86 | digitalWrite(LedPin, HIGH); 87 | delay(500); 88 | digitalWrite(LedPin, LOW); 89 | pinMode(LedPin,INPUT); 90 | 91 | // Launch traces for debugging purposes 92 | trc("Start of the program"); 93 | 94 | } 95 | 96 | void loop() 97 | { 98 | // begin emitting 99 | pinMode(EmitPowerPin,OUTPUT); 100 | digitalWrite(EmitPowerPin, HIGH); 101 | mySwitch.enableTransmit(EmitPin); // Using Pin #6 102 | mySwitch.setRepeatTransmit(10); //increase transmit repeat to avoid lost of rf sendings 103 | 104 | // send battery voltage 105 | sendData(vccVoltage(), atol(VOLT)); 106 | 107 | // send temp and hum 108 | pinMode(DhtPowerPin,OUTPUT); 109 | digitalWrite(DhtPowerPin, HIGH); 110 | dht.begin(); 111 | TempAndHum(); 112 | digitalWrite(DhtPowerPin, LOW); 113 | pinMode(DhtPin,INPUT);//disable the internal pullup resistor enable by dht.begin 114 | pinMode(DhtPowerPin,INPUT); 115 | 116 | //send soil hygro 117 | pinMode(HygPowerPin,OUTPUT); 118 | digitalWrite(HygPowerPin, HIGH); 119 | Hygro(); 120 | digitalWrite(HygPowerPin, LOW); 121 | pinMode(HygPowerPin,INPUT); 122 | 123 | //deactivate the transmitter 124 | mySwitch.disableTransmit(); 125 | pinMode(EmitPowerPin,INPUT); 126 | 127 | // sleep for x seconds 128 | sleepSeconds(TimeToSleep); 129 | 130 | } 131 | 132 | void sleepSeconds(int seconds) 133 | { 134 | for (int i = 0; i < seconds; i++) { 135 | LowPower.powerDown(SLEEP_1S, ADC_OFF, BOD_OFF); 136 | } 137 | } 138 | 139 | void TempAndHum(){ 140 | delay(500); 141 | //retreiving value of temperature and humidity from DHT 142 | float h = dht.readHumidity(); 143 | float t = dht.readTemperature(); 144 | if (isnan(h) || isnan(t)) { 145 | trc("Failed to read from DHT sensor!"); 146 | sendData(atol(ERRORCODE), atol(HUM));//send error code 147 | sendData(atol(ERRORCODE), atol(TEMP));//send error code 148 | } else { 149 | sendData(int(h*10), atol(HUM)); 150 | sendData(int(t*10), atol(TEMP)); 151 | } 152 | } 153 | 154 | void Hygro(){ 155 | // read soil moisture from sensor 156 | delay(500); 157 | int sensorValue = analogRead(A0); 158 | sensorValue = constrain (sensorValue, 300,1023); 159 | int hygro = map (sensorValue, 0, 1023, 100, 0); 160 | sendData(hygro, atol(HYGRO)); 161 | } 162 | 163 | void sendData(long dataTosend, long dataType){ 164 | long sum = atol(ERRORCODE); 165 | 166 | trc(String(dataTosend)); 167 | trc(String(dataType)); 168 | 169 | if (dataTosend == sum) { 170 | // nothing to do sending error code 171 | } else { 172 | sum = dataTosend + dataType; // sending value added to topic offset 173 | } 174 | 175 | trc("Sum"); 176 | trc(String(sum)); 177 | 178 | //sending value by RF 179 | mySwitch.send(sum,24); 180 | 181 | } 182 | 183 | // https://code.google.com/archive/p/tinkerit/wikis/SecretVoltmeter.wiki 184 | long vccVoltage() { 185 | long result = 0; 186 | // Read 1.1V reference against AVcc 187 | ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); 188 | delay(10); // Wait for Vref to settle 189 | ADCSRA |= _BV(ADSC); // Convert 190 | while (bit_is_set(ADCSRA,ADSC)); 191 | result = ADCL; 192 | result |= ADCH<<8; 193 | result = 1126400L / result; // Back-calculate AVcc in mV 194 | return result; 195 | } 196 | 197 | 198 | //trace function 199 | void trc(String msg){ 200 | if (TRACE) { 201 | Serial.println(msg); 202 | } 203 | } 204 | -------------------------------------------------------------------------------- /low_power_sensor_inside.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Low power node - ATMega328p program to send humidity, temperature and battery voltage 3 | 4 | This program enables to send sensor data with low power: 5 | - send sensor data to a 433Mhz gateway 6 | - with 3 AA batteries measured at 5V the current consumption in sleep mode is around 5uA 7 | Contributors: 8 | - 1technophile 9 | Based on the libraries: 10 | - RCSwitch 11 | - LowPower 12 | Based on the work of: 13 | Nick Gammon : http://www.gammon.com.au/power 14 | Rocketscream: https://github.com/rocketscream/Low-Power 15 | Tinkerit: https://code.google.com/archive/p/tinkerit/wikis/SecretVoltmeter.wiki 16 | Documentation: 17 | Project home: https://github.com/1technophile/low_power_sensor 18 | Blog: http://1technophile.blogspot.com/2016/12/low-cost-low-power-room-sensor.html 19 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software 20 | and associated documentation files (the "Software"), to deal in the Software without restriction, 21 | including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 22 | and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, 23 | subject to the following conditions: 24 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 25 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 26 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 27 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 28 | CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 29 | */ 30 | 31 | 32 | #include 33 | #include "LowPower.h" 34 | #include 35 | #include 36 | 37 | #define DHTTYPE DHT22 38 | 39 | RCSwitch mySwitch = RCSwitch(); 40 | 41 | //Time used to wait for an interval before resending data 42 | unsigned long time; 43 | 44 | //Pin on which the sensors are connected 45 | const int LedPin = 9; 46 | const int DhtPin = 3; 47 | const int DhtPowerPin = 4; 48 | const int EmitPin = 6; 49 | const int EmitPowerPin = 7; 50 | 51 | const int TimeToSleep = 3000; // set time to sleep (approx) in seconds 52 | 53 | DHT dht(DhtPin,DHTTYPE); 54 | 55 | // define humidity variable to hold the final value 56 | int humidity = 0; 57 | 58 | //Do we want to see trace for debugging purposes 59 | #define TRACE 0 // 0= trace off 1 = trace on 60 | 61 | /*These values define the RF code value sent if the sensor values are 62 | equals to 0, for example, if the sensor value of temperature is 24°C, the 63 | program is going to send 33240, this resulting value can be interpreted 64 | either at gateway level or better at domotic software level (example openhab)*/ 65 | #define HUM "61000" 66 | #define TEMP "63000" 67 | #define VOLT "65000" 68 | #define ERRORCODE "99999" 69 | 70 | void setup() 71 | { 72 | Serial.begin(9600); 73 | // initialize the input for presence detection 74 | pinMode(DhtPowerPin,INPUT); 75 | pinMode(EmitPowerPin,INPUT); 76 | // start led signal 77 | pinMode(LedPin,OUTPUT); 78 | digitalWrite(LedPin, HIGH); 79 | delay(500); 80 | digitalWrite(LedPin, LOW); 81 | pinMode(LedPin,INPUT); 82 | 83 | // Launch traces for debugging purposes 84 | trc("Start of the program"); 85 | 86 | } 87 | 88 | void loop() 89 | { 90 | // begin emitting 91 | pinMode(EmitPowerPin,OUTPUT); 92 | digitalWrite(EmitPowerPin, HIGH); 93 | mySwitch.enableTransmit(EmitPin); // Using Pin #6 94 | mySwitch.setRepeatTransmit(10); //increase transmit repeat to avoid lost of rf sendings 95 | 96 | // send battery voltage 97 | sendData(vccVoltage(), atol(VOLT)); 98 | 99 | // send temp and hum 100 | pinMode(DhtPowerPin,OUTPUT); 101 | digitalWrite(DhtPowerPin, HIGH); 102 | dht.begin(); 103 | TempAndHum(); 104 | digitalWrite(DhtPowerPin, LOW); 105 | pinMode(DhtPin,INPUT);//disable the internal pullup resistor enable by dht.begin 106 | pinMode(DhtPowerPin,INPUT); 107 | 108 | //deactivate the transmitter 109 | mySwitch.disableTransmit(); 110 | pinMode(EmitPowerPin,INPUT); 111 | 112 | // sleep for x seconds 113 | sleepSeconds(TimeToSleep); 114 | 115 | } 116 | 117 | void sleepSeconds(int seconds) 118 | { 119 | for (int i = 0; i < seconds; i++) { 120 | LowPower.powerDown(SLEEP_1S, ADC_OFF, BOD_OFF); 121 | } 122 | } 123 | 124 | void TempAndHum(){ 125 | delay(500); 126 | //retreiving value of temperature and humidity from DHT 127 | float h = dht.readHumidity(); 128 | float t = dht.readTemperature(); 129 | if (isnan(h) || isnan(t)) { 130 | trc("Failed to read from DHT sensor!"); 131 | sendData(atol(ERRORCODE), atol(HUM));//send error code 132 | sendData(atol(ERRORCODE), atol(TEMP));//send error code 133 | } else { 134 | sendData(int(h*10), atol(HUM)); 135 | sendData(int(t*10), atol(TEMP)); 136 | } 137 | } 138 | 139 | 140 | void sendData(long dataTosend, long dataType){ 141 | long sum = atol(ERRORCODE); 142 | 143 | trc(String(dataTosend)); 144 | trc(String(dataType)); 145 | 146 | if (dataTosend == sum) { 147 | // nothing to do sending error code 148 | } else { 149 | sum = dataTosend + dataType; // sending value added to topic offset 150 | } 151 | 152 | trc("Sum"); 153 | trc(String(sum)); 154 | 155 | //sending value by RF 156 | mySwitch.send(sum,24); 157 | 158 | } 159 | 160 | // https://code.google.com/archive/p/tinkerit/wikis/SecretVoltmeter.wiki 161 | long vccVoltage() { 162 | long result = 0; 163 | // Read 1.1V reference against AVcc 164 | ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); 165 | delay(10); // Wait for Vref to settle 166 | ADCSRA |= _BV(ADSC); // Convert 167 | while (bit_is_set(ADCSRA,ADSC)); 168 | result = ADCL; 169 | result |= ADCH<<8; 170 | result = 1126400L / result; // Back-calculate AVcc in mV 171 | return result; 172 | } 173 | 174 | 175 | //trace function 176 | void trc(String msg){ 177 | if (TRACE) { 178 | Serial.println(msg); 179 | } 180 | } 181 | --------------------------------------------------------------------------------