The boards showed up, and they look great! After a quick test sketch and a fresh battery the blinky is pretty much good to go.
Here it is in action:
Here's the code:
#include<avr/sleep.h> // library for sleep#include<avr/power.h> // library for power control#include<Adafruit_SleepyDog.h>#define LED0 5#define LED1 4#define LED2 2#define LED3 A2#define LED4 10#define SWpin 6#define J0 7#define J1 8int secondsToCountDown = 5;
voidsetup(){
//Initialize the pins and set them low
pinMode(LED0, OUTPUT);
pinMode(LED1, OUTPUT);
pinMode(LED2, OUTPUT);
pinMode(LED3, OUTPUT);
pinMode(LED4, OUTPUT);
digitalWrite(LED0, LOW);
digitalWrite(LED1, LOW);
digitalWrite(LED2, LOW);
digitalWrite(LED3, LOW);
digitalWrite(LED4, LOW);
pinMode(SWpin, INPUT_PULLUP);
pinMode(J0, INPUT_PULLUP);
pinMode(J1, INPUT_PULLUP);
//There are two solder junctions available just above the button.//This can control how long the timer is set for without the need to reprogram.//Make sure to take the battery out to reset the device after setting the jumper!if (digitalRead(J0) == HIGH && digitalRead(J1) == HIGH) {
secondsToCountDown = 5;
}
if (digitalRead(J0) == HIGH && digitalRead(J1) == LOW) {
secondsToCountDown = 10;
}
if (digitalRead(J0) == LOW && digitalRead(J1) == HIGH) {
secondsToCountDown = 30;
}
if (digitalRead(J0) == LOW && digitalRead(J1) == LOW) {
secondsToCountDown = 60;
}
}
voidloop(){
countDown(secondsToCountDown); //I hope you know what this does
}
voidcountDown(byte seconds){
if (digitalRead(SWpin) == LOW) { //If the button is pushed, do the thing
digitalWrite(LED0, HIGH);
digitalWrite(LED1, HIGH);
digitalWrite(LED2, HIGH);
digitalWrite(LED3, HIGH);
digitalWrite(LED4, HIGH);
//So really the delay time should be 1000 * seconds / 5, but I think the //crystal frequency is half of what it 'should' be so millis() is thrown off//I'll fix the crystal frequency issue later, but in the meantime this'll work
delay(1000 * seconds / 10);
digitalWrite(LED4, LOW);
delay(1000 * seconds / 10);
digitalWrite(LED3, LOW);
delay(1000 * seconds / 10);
digitalWrite(LED2, LOW);
delay(1000 * seconds / 10);
digitalWrite(LED1, LOW);
delay(1000 * seconds / 10);
digitalWrite(LED0, LOW);
}
else {
Watchdog.sleep(1000); //If the button isn't pushed, go to sleep.//This is much worse than using a wake interrupt since the device has to wake up//every second to see if a button is being pushed, but what are you gonna do
}
}
A few things that can be improved in the future:
Actually use the external clock crystal rather than the internal oscillator. (fuses are scary)
Modify the circuit board to use pins 2 or 3 for the switch, since apparently those are the only two digital pins with interrupt capability on the 328p-au. Consequently, the chip is forced to use a suboptimal sleep scheme, which is less energy efficient and offers poor responsiveness to a button press.
Use higher resistance values for the current limiting resistors on the leds. As they are, they're probably too bright and so some energy can be saved limiting their intensity.
In the meantime though I'm pretty sure the battery is going to last a good long while and the timing will be reasonably accurate, so I'm quite happy at the end of the day.
Special thanks to MacroFab for the fast and cheap service, without which this project would never have happened.