Power Saving

This commit is contained in:
Stefan Ostermann 2021-04-12 23:52:04 +02:00
parent 8a977ceab9
commit 0cb9fb8ba1
3 changed files with 98 additions and 72 deletions

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 192 KiB

After

Width:  |  Height:  |  Size: 392 KiB

View File

@ -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,7 +54,6 @@
#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"
@ -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,45 +95,43 @@ 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
@ -144,48 +139,76 @@ void loop() {
int soil = 0; int soil = 0;
long battery = 0; long battery = 0;
if (counter % 4 == 0) { // wait for everything the transistor switched on:
delay(25);
if (counter % 4 == 0)
{
rh_buf[0] = MSG_BAT; rh_buf[0] = MSG_BAT;
battery = getVcc(); battery = getVcc();
memcpy(&rh_buf[1], &battery, 4); memcpy(&rh_buf[1], &battery, 4);
rh_send(RH_BUF_LEN); rh_send(RH_BUF_LEN);
}else if (dht_read_data(&dht, &t, &h) == 1) { }
if (counter % 3 == 0) { 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);
// deep sleep
for (uint8_t i = 0; i < WATCHDOG_SLEEP_FURTHER; i++)
{
system_sleep(); 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,11 +251,11 @@ 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 //reads internal 1V1 reference against VCC
#if defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny44__) #if defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny44__)
ADMUX = _BV(MUX5) | _BV(MUX0); // For ATtiny84 ADMUX = _BV(MUX5) | _BV(MUX0); // For ATtiny84
@ -244,12 +268,14 @@ int getVcc() {
#endif #endif
delay(2); // Wait for Vref to settle 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;