Power Saving
This commit is contained in:
parent
8a977ceab9
commit
0cb9fb8ba1
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 192 KiB After Width: | Height: | Size: 392 KiB |
|
|
@ -7,9 +7,8 @@
|
||||||
https://git.cryhost.de/crycode/attiny85-radiohead-dht22-weather-sensor/-/tree/master
|
https://git.cryhost.de/crycode/attiny85-radiohead-dht22-weather-sensor/-/tree/master
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// pin with the transistor base (And LED) is connected
|
||||||
// pin with the LED connected
|
#define TRANSISTOR_BASE_PIN 4
|
||||||
#define LED_PIN 4
|
|
||||||
|
|
||||||
// blink time for the LED
|
// blink time for the LED
|
||||||
#define LED_TIME 200
|
#define LED_TIME 200
|
||||||
|
|
@ -33,10 +32,12 @@
|
||||||
*/
|
*/
|
||||||
#define WATCHDOG_WAKEUP 9
|
#define WATCHDOG_WAKEUP 9
|
||||||
|
|
||||||
|
// Sleep this many again before waging up. Sleep time in s = WATCHDOG_WAKEUP s * WATCHDOG_SLEEP_FURTHER, e.g. 8*8s = 64s
|
||||||
|
#define WATCHDOG_SLEEP_FURTHER 8
|
||||||
|
|
||||||
// pins for the radio hardware
|
// pins for the radio hardware
|
||||||
#define RH_RX_PIN 6 // not used, set to a non-existent pin
|
#define RH_RX_PIN 6 // not used, set to a non-existent pin
|
||||||
#define RH_TX_PIN 3
|
#define RH_TX_PIN 3 // Transmit Pin
|
||||||
#define RH_PTT_PIN 6 // not used, set to a non-existent pin
|
#define RH_PTT_PIN 6 // not used, set to a non-existent pin
|
||||||
|
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
|
|
@ -53,14 +54,13 @@
|
||||||
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
|
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// DHT22 lib
|
// DHT22 lib
|
||||||
// not using the current adafruit dht library, because it's too memory intensive
|
// not using the current adafruit dht library, because it's too memory intensive
|
||||||
#include "dht22.h"
|
#include "dht22.h"
|
||||||
dht22 dht;
|
dht22 dht;
|
||||||
|
|
||||||
#define RH_BUF_LEN 5
|
#define RH_BUF_LEN 5
|
||||||
uint8_t rh_buf[RH_BUF_LEN] = { 0x00, 0x00, 0x00, 0x00, 0x00 };
|
uint8_t rh_buf[RH_BUF_LEN] = {0x00, 0x00, 0x00, 0x00, 0x00};
|
||||||
|
|
||||||
// reduce the RadioHead max message length to save memory
|
// reduce the RadioHead max message length to save memory
|
||||||
#define RH_ASK_MAX_MESSAGE_LEN RH_BUF_LEN
|
#define RH_ASK_MAX_MESSAGE_LEN RH_BUF_LEN
|
||||||
|
|
@ -68,7 +68,6 @@ uint8_t rh_buf[RH_BUF_LEN] = { 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||||
// RadioHead
|
// RadioHead
|
||||||
#include <RH_ASK.h>
|
#include <RH_ASK.h>
|
||||||
|
|
||||||
|
|
||||||
// Message Headers:
|
// Message Headers:
|
||||||
#define MSG_START 0x00
|
#define MSG_START 0x00
|
||||||
#define MSG_TEMP 0x01
|
#define MSG_TEMP 0x01
|
||||||
|
|
@ -77,7 +76,6 @@ uint8_t rh_buf[RH_BUF_LEN] = { 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||||
#define MSG_SOIL 0x04
|
#define MSG_SOIL 0x04
|
||||||
#define MSG_ERR 0xee
|
#define MSG_ERR 0xee
|
||||||
|
|
||||||
|
|
||||||
RH_ASK rh_driver(RH_SPEED, RH_RX_PIN, RH_TX_PIN, RH_PTT_PIN);
|
RH_ASK rh_driver(RH_SPEED, RH_RX_PIN, RH_TX_PIN, RH_PTT_PIN);
|
||||||
|
|
||||||
// watchdog flag
|
// watchdog flag
|
||||||
|
|
@ -86,7 +84,6 @@ volatile boolean f_wdt = 1;
|
||||||
// temp / humid toggle
|
// temp / humid toggle
|
||||||
volatile uint8_t counter = 0;
|
volatile uint8_t counter = 0;
|
||||||
|
|
||||||
|
|
||||||
// prototypes:
|
// prototypes:
|
||||||
void gotoSleep(void);
|
void gotoSleep(void);
|
||||||
|
|
||||||
|
|
@ -98,94 +95,120 @@ void setup_watchdog(int ii);
|
||||||
|
|
||||||
void system_sleep();
|
void system_sleep();
|
||||||
|
|
||||||
void setup() {
|
void blink(uint8_t num);
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
// setup the LED pin
|
// setup the LED pin
|
||||||
pinMode(LED_PIN, OUTPUT);
|
pinMode(TRANSISTOR_BASE_PIN, OUTPUT);
|
||||||
|
|
||||||
pinMode(SOIL_PIN, INPUT);
|
pinMode(SOIL_PIN, INPUT);
|
||||||
|
|
||||||
// init the DHT22
|
// init the DHT22
|
||||||
dht_init(&dht, DHT_PIN);
|
dht_init(&dht, DHT_PIN);
|
||||||
|
|
||||||
|
|
||||||
uint8_t num_blink = 3;
|
uint8_t num_blink = 3;
|
||||||
|
|
||||||
if (!rh_driver.init()) {
|
if (!rh_driver.init())
|
||||||
|
{
|
||||||
num_blink = 5;
|
num_blink = 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
// blink 3 times
|
blink(num_blink);
|
||||||
for (uint8_t i = 0; i < num_blink; i++) {
|
|
||||||
digitalWrite(LED_PIN, HIGH);
|
|
||||||
_delay_ms(LED_TIME);
|
|
||||||
digitalWrite(LED_PIN, LOW);
|
|
||||||
_delay_ms(LED_TIME);
|
|
||||||
}
|
|
||||||
|
|
||||||
// send start message
|
// send start message
|
||||||
rh_buf[0] = MSG_START;
|
rh_buf[0] = MSG_START;
|
||||||
rh_send(1);
|
rh_send(1);
|
||||||
|
|
||||||
setup_watchdog(WATCHDOG_WAKEUP);
|
setup_watchdog(WATCHDOG_WAKEUP);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// main loop
|
// main loop
|
||||||
void loop() {
|
void loop()
|
||||||
|
{
|
||||||
|
|
||||||
if (f_wdt) {
|
if (f_wdt)
|
||||||
|
{
|
||||||
f_wdt = 0;
|
f_wdt = 0;
|
||||||
// turn on the LED
|
// turn on the LED and the transistor:
|
||||||
digitalWrite(LED_PIN, HIGH);
|
digitalWrite(TRANSISTOR_BASE_PIN, HIGH);
|
||||||
|
|
||||||
// temperature and humidity
|
// temperature and humidity
|
||||||
float t = 0;//float is 32bit = 4 byte
|
float t = 0; //float is 32bit = 4 byte
|
||||||
float h = 0;
|
float h = 0;
|
||||||
int soil = 0;
|
int soil = 0;
|
||||||
long battery = 0;
|
long battery = 0;
|
||||||
|
|
||||||
if (counter % 4 == 0) {
|
// wait for everything the transistor switched on:
|
||||||
rh_buf[0] = MSG_BAT;
|
delay(25);
|
||||||
battery = getVcc();
|
|
||||||
memcpy(&rh_buf[1], &battery, 4);
|
if (counter % 4 == 0)
|
||||||
rh_send(RH_BUF_LEN);
|
{
|
||||||
}else if (dht_read_data(&dht, &t, &h) == 1) {
|
rh_buf[0] = MSG_BAT;
|
||||||
if (counter % 3 == 0) {
|
battery = getVcc();
|
||||||
|
memcpy(&rh_buf[1], &battery, 4);
|
||||||
|
rh_send(RH_BUF_LEN);
|
||||||
|
}
|
||||||
|
else if (dht_read_data(&dht, &t, &h) == 1)
|
||||||
|
{
|
||||||
|
if (counter % 3 == 0)
|
||||||
|
{
|
||||||
rh_buf[0] = MSG_TEMP;
|
rh_buf[0] = MSG_TEMP;
|
||||||
memcpy(&rh_buf[1], &t, 4);
|
memcpy(&rh_buf[1], &t, 4);
|
||||||
} else if (counter % 3 == 1) {
|
}
|
||||||
|
else if (counter % 3 == 1)
|
||||||
|
{
|
||||||
rh_buf[0] = MSG_HUMID;
|
rh_buf[0] = MSG_HUMID;
|
||||||
memcpy(&rh_buf[1], &h, 4);
|
memcpy(&rh_buf[1], &h, 4);
|
||||||
} else if (counter % 3 == 2) {
|
}
|
||||||
|
else if (counter % 3 == 2)
|
||||||
|
{
|
||||||
rh_buf[0] = MSG_SOIL;
|
rh_buf[0] = MSG_SOIL;
|
||||||
soil = analogRead(SOIL_PIN);
|
soil = analogRead(SOIL_PIN);
|
||||||
memcpy(&rh_buf[1], &soil, 2);
|
memcpy(&rh_buf[1], &soil, 2);
|
||||||
}
|
}
|
||||||
rh_send(RH_BUF_LEN);
|
rh_send(RH_BUF_LEN);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// error message
|
// error message
|
||||||
|
blink(4);
|
||||||
|
digitalWrite(TRANSISTOR_BASE_PIN, HIGH);
|
||||||
|
delay(5);
|
||||||
rh_buf[0] = MSG_ERR;
|
rh_buf[0] = MSG_ERR;
|
||||||
rh_send(1);
|
rh_send(1);
|
||||||
|
|
||||||
}
|
}
|
||||||
counter++;
|
counter++;
|
||||||
|
|
||||||
// turn off the LED
|
// turn off the LED and transistor:
|
||||||
digitalWrite(LED_PIN, LOW);
|
digitalWrite(TRANSISTOR_BASE_PIN, LOW);
|
||||||
system_sleep();
|
// deep sleep
|
||||||
|
for (uint8_t i = 0; i < WATCHDOG_SLEEP_FURTHER; i++)
|
||||||
|
{
|
||||||
|
system_sleep();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void blink(uint8_t num)
|
||||||
|
{
|
||||||
|
// blink n times
|
||||||
|
for (uint8_t i = 0; i < num; i++)
|
||||||
|
{
|
||||||
|
digitalWrite(TRANSISTOR_BASE_PIN, HIGH);
|
||||||
|
_delay_ms(LED_TIME);
|
||||||
|
digitalWrite(TRANSISTOR_BASE_PIN, LOW);
|
||||||
|
_delay_ms(LED_TIME);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// function to send RadioHead messages from the buffer
|
// function to send RadioHead messages from the buffer
|
||||||
void rh_send(uint8_t len) {
|
void rh_send(uint8_t len)
|
||||||
|
{
|
||||||
rh_driver.send((uint8_t *)rh_buf, len);
|
rh_driver.send((uint8_t *)rh_buf, len);
|
||||||
rh_driver.waitPacketSent();
|
rh_driver.waitPacketSent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ISR(WDT_vect)
|
ISR(WDT_vect)
|
||||||
{
|
{
|
||||||
f_wdt = 1; // set global flag
|
f_wdt = 1; // set global flag
|
||||||
|
|
@ -194,28 +217,29 @@ ISR(WDT_vect)
|
||||||
/* set system into the sleep state
|
/* set system into the sleep state
|
||||||
system wakes up when watchdog is timed out
|
system wakes up when watchdog is timed out
|
||||||
*/
|
*/
|
||||||
void system_sleep() {
|
void system_sleep()
|
||||||
//cbi(ADCSRA, ADEN); // switch Analog to Digitalconverter OFF
|
{
|
||||||
|
|
||||||
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode is set here
|
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode is set here
|
||||||
sleep_enable();
|
sleep_enable();
|
||||||
|
|
||||||
sleep_mode(); // System sleeps here
|
sleep_mode(); // System sleeps here
|
||||||
|
|
||||||
sleep_disable(); // System continues execution here when watchdog timed out
|
sleep_disable(); // System continues execution here when watchdog timed out
|
||||||
//sbi(ADCSRA, ADEN); // switch Analog to Digitalconverter ON
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 0=16ms, 1=32ms,2=64ms,3=128ms,4=250ms,5=500ms
|
/* 0=16ms, 1=32ms,2=64ms,3=128ms,4=250ms,5=500ms
|
||||||
6=1 sec,7=2 sec, 8=4 sec, 9= 8sec
|
6=1 sec,7=2 sec, 8=4 sec, 9= 8sec
|
||||||
*/
|
*/
|
||||||
void setup_watchdog(int ii) {
|
void setup_watchdog(int ii)
|
||||||
|
{
|
||||||
|
|
||||||
byte bb;
|
byte bb;
|
||||||
int ww;
|
int ww;
|
||||||
if (ii > 9 ) ii = 9;
|
if (ii > 9)
|
||||||
|
ii = 9;
|
||||||
bb = ii & 7;
|
bb = ii & 7;
|
||||||
if (ii > 7) bb |= (1 << 5);
|
if (ii > 7)
|
||||||
|
bb |= (1 << 5);
|
||||||
bb |= (1 << WDCE);
|
bb |= (1 << WDCE);
|
||||||
ww = bb;
|
ww = bb;
|
||||||
|
|
||||||
|
|
@ -227,31 +251,33 @@ void setup_watchdog(int ii) {
|
||||||
WDTCR |= _BV(WDIE);
|
WDTCR |= _BV(WDIE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
From https://github.com/cano64/ArduinoSystemStatus/blob/master/SystemStatus.cpp
|
From https://github.com/cano64/ArduinoSystemStatus/blob/master/SystemStatus.cpp
|
||||||
*/
|
*/
|
||||||
int getVcc() {
|
int getVcc()
|
||||||
//reads internal 1V1 reference against VCC
|
{
|
||||||
#if defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny44__)
|
//reads internal 1V1 reference against VCC
|
||||||
ADMUX = _BV(MUX5) | _BV(MUX0); // For ATtiny84
|
#if defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny44__)
|
||||||
#elif defined(__AVR_ATtiny85__) || defined(__AVR_ATtiny45__)
|
ADMUX = _BV(MUX5) | _BV(MUX0); // For ATtiny84
|
||||||
ADMUX = _BV(MUX3) | _BV(MUX2); // For ATtiny85/45
|
#elif defined(__AVR_ATtiny85__) || defined(__AVR_ATtiny45__)
|
||||||
#elif defined(__AVR_ATmega1284P__)
|
ADMUX = _BV(MUX3) | _BV(MUX2); // For ATtiny85/45
|
||||||
ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); // For ATmega1284
|
#elif defined(__AVR_ATmega1284P__)
|
||||||
#else
|
ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); // For ATmega1284
|
||||||
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); // For ATmega328
|
#else
|
||||||
#endif
|
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); // For ATmega328
|
||||||
delay(2); // Wait for Vref to settle
|
#endif
|
||||||
|
delay(2); // Wait for Vref to settle
|
||||||
ADCSRA |= _BV(ADSC); // Convert
|
ADCSRA |= _BV(ADSC); // Convert
|
||||||
while (bit_is_set(ADCSRA, ADSC));
|
while (bit_is_set(ADCSRA, ADSC))
|
||||||
|
;
|
||||||
uint8_t low = ADCL;
|
uint8_t low = ADCL;
|
||||||
unsigned int val = (ADCH << 8) | low;
|
unsigned int val = (ADCH << 8) | low;
|
||||||
//discard previous result
|
//discard previous result
|
||||||
ADCSRA |= _BV(ADSC); // Convert
|
ADCSRA |= _BV(ADSC); // Convert
|
||||||
while (bit_is_set(ADCSRA, ADSC));
|
while (bit_is_set(ADCSRA, ADSC))
|
||||||
|
;
|
||||||
low = ADCL;
|
low = ADCL;
|
||||||
val = (ADCH << 8) | low;
|
val = (ADCH << 8) | low;
|
||||||
|
|
||||||
return ((long)1024 * 1100) / val;
|
return ((long)1024 * 1100) / val;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue