Skip to content

Instantly share code, notes, and snippets.

@PhirePhly
Created July 30, 2021 03:02
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save PhirePhly/1a329c39aea1494428af5eed86ea2c24 to your computer and use it in GitHub Desktop.
Save PhirePhly/1a329c39aea1494428af5eed86ea2c24 to your computer and use it in GitHub Desktop.
// Kenneth Finnegan, 2021
//
// Atmega328P on breadboard with 8MHz crystal. Use the mini pro 3.3V 8MHz board
//
// Pin 11 is the LED output
// Digital Pins 2-5 are DIP switch for time config on boot
// Reset button restarts the timer
// Using https://github.com/LowPowerLab/LowPower
#include <LowPower.h>
#define LED_OUTPUT 11
#define CONFIG_SW1 2
#define CONFIG_SW2 3
#define CONFIG_SW3 4
#define CONFIG_SW4 5
// Read in the DIP switches on boot to select the timer length from the config table
int timer_select;
// Config multiplier is the number of seconds in each unit of the config table
unsigned long config_multiplier_s = 24UL * 60UL * 60UL;
// How much SOONER than the full multipler do we want to advance?
// This is to prevent the event from slipping a few minutes later every time
unsigned long config_routine_phase_gain_s = 10 * 60;
// List of the 16 different time interval options starting at 0000, 1000, 0100, ... ,1111
static unsigned long config_table[] = {1, 2, 3, 4, 5, 6, 7, 10, 14, 18, 21, 24, 28, 31, 35, 42};
// derivative calculation used to compare against the running time.
unsigned static long target_event_s = (config_table[timer_select] * config_multiplier_s) - config_routine_phase_gain_s;
void setup() {
pinMode(LED_OUTPUT, OUTPUT);
pinMode(CONFIG_SW1, INPUT);
digitalWrite(CONFIG_SW1, HIGH); // Enable internal pullup
pinMode(CONFIG_SW2, INPUT);
digitalWrite(CONFIG_SW2, HIGH); // Enable internal pullup
pinMode(CONFIG_SW3, INPUT);
digitalWrite(CONFIG_SW3, HIGH); // Enable internal pullup
pinMode(CONFIG_SW4, INPUT);
digitalWrite(CONFIG_SW4, HIGH); // Enable internal pullup
LowPower.powerDown(SLEEP_500MS, ADC_OFF, BOD_OFF);
timer_select = !digitalRead(CONFIG_SW1) + \
!digitalRead(CONFIG_SW2) * 2 + \
!digitalRead(CONFIG_SW3) * 4 + \
!digitalRead(CONFIG_SW4) * 8;
// Disable pullups to save power
digitalWrite(CONFIG_SW1, LOW);
digitalWrite(CONFIG_SW2, LOW);
digitalWrite(CONFIG_SW3, LOW);
digitalWrite(CONFIG_SW4, LOW);
blink_cnt(config_table[timer_select] / 10);
// Good morning!
digitalWrite(LED_OUTPUT, HIGH);
LowPower.powerDown(SLEEP_500MS, ADC_OFF, BOD_OFF);
digitalWrite(LED_OUTPUT, LOW);
LowPower.powerDown(SLEEP_500MS, ADC_OFF, BOD_OFF);
blink_cnt(config_table[timer_select] % 10);
}
void loop() {
LowPower.idle(SLEEP_8S, ADC_OFF, TIMER2_OFF, TIMER1_OFF, TIMER0_ON,
SPI_OFF, USART0_OFF, TWI_OFF);
if (millis() > target_event_s * 1000UL) {
need_water();
}
}
void need_water() {
unsigned long time_since_blink_start = 0;
while (1) {
time_since_blink_start += 16;
int numofblink = (time_since_blink_start / config_multiplier_s) + 1;
blink_cnt(numofblink);
LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
blink_cnt(numofblink/2);
LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
}
}
void blink_cnt(int blink_total) {
int i;
for (i=0; i < blink_total; i++) {
digitalWrite(LED_OUTPUT, HIGH);
LowPower.powerDown(SLEEP_30MS, ADC_OFF, BOD_OFF);
digitalWrite(LED_OUTPUT, LOW);
LowPower.powerDown(SLEEP_500MS, ADC_OFF, BOD_OFF);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment