Entry 1

A project log for Countdown Timer Blinky

A visual countdown timer, created for Macrofab's Blink an LED design contest.

charles-dean-modrichCharles Dean Modrich 09/06/2018 at 05:260 Comments

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. 

It's here!
The blinky in all of its blurry glory

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 8

int secondsToCountDown = 5;

void setup() {
  //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;


void loop() {
  countDown(secondsToCountDown); //I hope you know what this does

void countDown(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:

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.