Compare commits

...

3 Commits

Author SHA1 Message Date
r4
5728233bad add exit command 2022-04-18 19:33:41 +02:00
r4
580ba5e577 reset wait time after waiting 2022-04-18 19:32:11 +02:00
r4
232df37f5c fix watchdog + library independence 2022-04-18 19:31:51 +02:00

View File

@ -29,12 +29,12 @@
*/ */
#include <EEPROM.h> #include <EEPROM.h>
#include <LowPower.h> /* https://github.com/rocketscream/Low-Power */
#include <SD.h> #include <SD.h>
#include <SPI.h> #include <SPI.h>
#include <avr/interrupt.h> #include <avr/interrupt.h>
#include <avr/io.h> #include <avr/io.h>
#include <avr/wdt.h> #include <avr/wdt.h>
#include <avr/sleep.h>
/************************ /************************
BEGIN USER CONFIGURATION BEGIN USER CONFIGURATION
@ -61,6 +61,8 @@
END USER CONFIGURATION END USER CONFIGURATION
**********************/ **********************/
void (*full_reset)() = nullptr;
static int serial_putch(char c, FILE *f) { static int serial_putch(char c, FILE *f) {
(void)f; (void)f;
return Serial.write(c) == 1 ? 0 : 1; return Serial.write(c) == 1 ? 0 : 1;
@ -117,20 +119,40 @@ static bool fstreq(const char *a, const __FlashStringHelper *b_fsh) {
#define info(fmt, ...) { if (settings.serial_log) printf(fmt, ##__VA_ARGS__); } #define info(fmt, ...) { if (settings.serial_log) printf(fmt, ##__VA_ARGS__); }
#define info_special(x) { if (settings.serial_log) Serial.print(x); } #define info_special(x) { if (settings.serial_log) Serial.print(x); }
static void low_power_sleep_minutes(unsigned long t) { volatile bool wdt_int_sleep_mode = false;
for (unsigned long i = 0; 8ul * i < 60ul * t; i++) { ISR (WDT_vect) {
/* Power down for 8s. */ if (wdt_int_sleep_mode)
LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF); wdt_disable();
} else
full_reset();
} }
static void start_watchdog_with_full_reset() { /* Based on https://github.com/rocketscream/Low-Power. */
MCUSR &= ~B00001000; /* Clear reset flag. */ static void low_power_sleep_minutes(unsigned long t) {
WDTCSR |= B00011000; /* Prepare prescaler change. */ wdt_int_sleep_mode = true;
WDTCSR = B00100001; /* Set watchdog timeout to 8s. */ ADCSRA &= ~(1 << ADEN); /* Disable ADC. */
// Enable Watchdog Timer for (unsigned long i = 0; 8ul * i < 60ul * t; i++) {
WDTCSR |= B01000000; // Power Down for 8s
MCUSR = MCUSR & B11110111; wdt_enable(WDTO_8S); /* Start watchdog timer for 8s. */
WDTCSR |= (1 << WDIE); /* Enable watchdog interrupt. */
do {
set_sleep_mode(SLEEP_MODE_PWR_SAVE);
cli();
sleep_enable();
sleep_bod_disable();
sei();
sleep_cpu();
sleep_disable();
sei();
} while (0);
}
ADCSRA |= (1 << ADEN); /* Re-enable ADC. */
wdt_int_sleep_mode = false;
}
static void wdt_enable_with_full_reset() {
wdt_enable(WDTO_8S); /* Start watchdog timer for 8s. */
WDTCSR |= (1 << WDIE); /* Enable watchdog interrupt. */
} }
static inline void disable_recording_interrupts() { static inline void disable_recording_interrupts() {
@ -284,6 +306,7 @@ static void wav_write_header(uint32_t nsamples) {
void show_help() { void show_help() {
printf(F("Commands:\n")); printf(F("Commands:\n"));
printf(F(" help -- Display this page.\n")); printf(F(" help -- Display this page.\n"));
printf(F(" exit -- Leave command mode.\n"));
printf(F(" get wait -- Display current delay setting.\n")); printf(F(" get wait -- Display current delay setting.\n"));
printf(F(" set wait <number> [minutes|hours] -- Change current delay setting.\n")); printf(F(" set wait <number> [minutes|hours] -- Change current delay setting.\n"));
printf(F(" set serial [on|off] -- Write log to serial output.\n")); printf(F(" set serial [on|off] -- Write log to serial output.\n"));
@ -350,6 +373,10 @@ void command_loop() {
} }
} else if (fstreq(args[0], F("help"))) { } else if (fstreq(args[0], F("help"))) {
show_help(); show_help();
} else if (fstreq(args[0], F("exit"))) {
printf(F("Bye!\n"));
Serial.flush();
full_reset();
} else } else
printf(F("Invalid command: '%s'. Type 'help' for a list of commands.\n"), args[0]); printf(F("Invalid command: '%s'. Type 'help' for a list of commands.\n"), args[0]);
} else { } else {
@ -390,6 +417,9 @@ void setup() {
Serial.flush(); Serial.flush();
/* Using this function, an Arduino Nano (with its voltage regulator and TTL module removed) draws ~6μA. */ /* Using this function, an Arduino Nano (with its voltage regulator and TTL module removed) draws ~6μA. */
low_power_sleep_minutes(settings.recording_delay); low_power_sleep_minutes(settings.recording_delay);
/* Reset wait time. */
settings.recording_delay = 0;
save_settings();
} }
// Activate Components // Activate Components
#ifdef PIN_COMPONENT_SWITCH #ifdef PIN_COMPONENT_SWITCH
@ -397,7 +427,7 @@ void setup() {
delay(500); /* Wait for components to initialize. */ delay(500); /* Wait for components to initialize. */
#endif #endif
// Start Watchdog (wdt_enable() doesn't fully reset) // Start Watchdog (wdt_enable() doesn't fully reset)
start_watchdog_with_full_reset(); wdt_enable_with_full_reset();
// SD Card Setup // SD Card Setup
if (!SD.begin(PIN_SS)) if (!SD.begin(PIN_SS))
die(F("Error initializing SD card!\n")); die(F("Error initializing SD card!\n"));
@ -440,6 +470,7 @@ void setup() {
| _BV(OCIE1B); /* Enable "Output Compare B Match Interrupt". */ | _BV(OCIE1B); /* Enable "Output Compare B Match Interrupt". */
} }
void loop() { void loop() {
delay(2000); delay(2000);
wdt_reset(); /* Reset watchdog timer. */ wdt_reset(); /* Reset watchdog timer. */