Here's some code I threw together to make your watch snazzy for NYE.
Bottom right button: Set time (hold this while pressing top left for hour and bottom left for minute)
#include <Tone.h>
#define OCTAVE_OFFSET 1
#define OUTSIDE_RING 0
#define INSIDE_RING 1
#define CENTER_COL 2
#define countdownSeconds 10
#define countdownPin 4
#define partyPin 5
#define setPin 3
int notes[] = { 0,
NOTE_C4, NOTE_CS4, NOTE_D4, NOTE_DS4, NOTE_E4, NOTE_F4, NOTE_FS4, NOTE_G4, NOTE_GS4, NOTE_A4, NOTE_AS4, NOTE_B4,
NOTE_C5, NOTE_CS5, NOTE_D5, NOTE_DS5, NOTE_E5, NOTE_F5, NOTE_FS5, NOTE_G5, NOTE_GS5, NOTE_A5, NOTE_AS5, NOTE_B5,
NOTE_C6, NOTE_CS6, NOTE_D6, NOTE_DS6, NOTE_E6, NOTE_F6, NOTE_FS6, NOTE_G6, NOTE_GS6, NOTE_A6, NOTE_AS6, NOTE_B6,
NOTE_C7, NOTE_CS7, NOTE_D7, NOTE_DS7, NOTE_E7, NOTE_F7, NOTE_FS7, NOTE_G7, NOTE_GS7, NOTE_A7, NOTE_AS7, NOTE_B7
};
char *song = "AuldLangSyne:d=4,o=6,b=120:g5,c.,8b5,c,e,d.,8c#,d,8e,8d,c.,8c,e,g,2a.,a,g.,8e,e,c,d.,8c#,d,8e,8d,c.,8a5,a5,g5,2c.";//,a,g.,8e,e,c,d.,8c#,d,a,g.,8e,e,g,2a.,a,g.,8e,e,c,d.,8c#,d,8e,8d,c.,8a5,a5,g5,2c.";
Tone tone1;
void setup() {
// initialize the digital pin as an output:
for(int k=2; k<14; k++)
{
pinMode(k, OUTPUT);
}
tone1.begin(2);
// Serial.begin(9600);
clearLeds();
spinLeds();
clearLeds();
}
// the loop() method runs over and over again,
// as long as the Arduino has power
int hour=0,minute=0,second=0;
boolean startCountdown=false;
int countdown=-1;
boolean partyMode=false;
void loop()
{
static unsigned long lastTick = 0;
unsigned long currTime = millis();
if (currTime - lastTick >= 1000 ) {
lastTick = currTime - currTime%1000;
if ( startCountdown ) {
countdown = countdown < 0 ? countdownSeconds : -1;
startCountdown = false;
}
if ( countdown >= 0 ) countdown --;
++second %= 60;
if ( second == 0 ) {
++minute %= 60;
if ( minute == 0 ) {
++hour %= 12;
}
}
}
if ( countdown >= 0 ) {
showCountdown(currTime);
}
else if ( partyMode ) {
showPartyMode(currTime);
}
else {
showHours();
showMinutes();
}
checkButtons();
}
void showHours() {
ledBlink(OUTSIDE_RING, hour);
}
void showMinutes() {
ledBlink(INSIDE_RING, minute/5);
binaryBlink(CENTER_COL, minute%5);
}
void showPartyMode(unsigned long currTime) {
static unsigned long nextTime = 0;
static int count = 0;
if ( nextTime < currTime ) {
++count %= 12*12;
nextTime = currTime + 100;
}
patternBlink(count%12,count/12);
}
void checkButtons() {
static boolean countdownPressed=false,partyPressed=false,setPressed=false;
if (!analogRead (countdownPin) && countdownPressed == false) { // if a normally closed switch is pressed
countdownPressed = true; // note the pressed state
if ( setPressed ) {
++hour %= 12;
}
else {
startCountdown = true;
}
}
if (analogRead (countdownPin)) countdownPressed = false; // reset the state when the button is released
if (!analogRead (partyPin) && partyPressed == false) { // if a normally closed switch is pressed
partyPressed = true; // note the pressed state
if ( setPressed ) {
++minute %= 60;
}
else {
partyMode = !partyMode;
}
}
if (analogRead (partyPin)) partyPressed = false; // reset the state when the button is released
if (!analogRead (setPin) && setPressed == false) { // if a normally closed switch is pressed
setPressed = true; // note the pressed state
}
if (analogRead (setPin)) setPressed = false; // reset the state when the button is released
}
void showCountdown(unsigned long currTime) {
countdownTone(currTime);
if ( countdown > 0 ) {
altLedBlink(OUTSIDE_RING, countdown%2);
altLedBlink(INSIDE_RING, (countdown+1)%2);
binaryBlink(CENTER_COL, countdown);
}
else {
clearLeds();
fireworks();
play_rtttl(song);
clearLeds();
}
}
void countdownTone(unsigned long currTime) {
static boolean tonePlaying = false;
static unsigned long toneStart = 0;
if ( !tonePlaying && toneStart + 1000 < currTime ) {
tonePlaying = true;
toneStart = currTime;
}
if ( tonePlaying && toneStart + 25 < currTime ) {
tonePlaying=false;
tone1.stop();
}
}
void fireworks() {
for (int y=0; y < 2; y++) {
for (int x=0; x < 12; x++) {
clearLeds();
altLed(x%2, x%y, true);
delay(100);
}
}
}
void ledBlink(int rgy, int pos) {
ledOn(rgy, pos);
ledOff(rgy, pos);
}
void binaryBlink(int rgy, int n) {
binaryToggle(rgy, n, true);
binaryToggle(rgy, n, false);
}
void patternBlink(int x, int y) {
altLed(x%2, x%y, true);
altLed(x%2, x%y, false);
}
void spinLeds() {
for (int x=0; x < 12; x++) {
ledOn(x%2, x);
ledOn((x+1)%2, (x+6)%12);
ledOn(x%2, (x+3)%12);
ledOn((x+1)%2, (x+9)%12);
delay(100);
ledOff(x%2, x);
ledOff((x+1)%2, (x+6)%12);
ledOff(x%2, (x+3)%12);
ledOff((x+1)%2, (x+9)%12);
}
}
void binaryToggle(int rgy, int n, boolean on) {
for (int x=0; x < 4; x++) {
if (n & 0x1) {
if ( on ) ledOn(rgy, x);
else ledOff(rgy, x);
}
n = n >> 1;
}
}
void clearLeds() {
for(int i = 3; i < 8; i++) {
digitalWrite(i, HIGH);
}
for(int j = 8; j < 14; j++) {
digitalWrite(j, LOW);
}
}
void altLedBlink(int rgy, int start) {
altLed(rgy, start, true);
altLed(rgy, start, false);
}
void altLed(int rgy, int start, boolean on) {
for (int x=start; x < start+12; x+=2) {
if ( on ) ledOn(rgy, x%12);
else ledOff(rgy, x%12);
}
}
void ledOn(int rgy, int pos) {
digitalWrite(getRow(rgy, pos), LOW);
digitalWrite(getCol(rgy, pos), HIGH);
}
void ledOff(int rgy, int pos) {
digitalWrite(getRow(rgy, pos), HIGH);
digitalWrite(getCol(rgy, pos), LOW);
}
int getRow(int rgy, int pos) {
return rgy*2 + pos/6 + 3;
}
int getCol(int rgy, int pos) {
return pos%6 + 8;
}
#define isdigit(n) (n >= '0' && n <= '9')
void play_rtttl(char *p)
{
// Absolutely no error checking in here
byte default_dur = 4;
byte default_oct = 6;
int bpm = 63;
int num;
long wholenote;
long duration;
byte note;
byte scale;
// format: d=N,o=N,b=NNN:
// find the start (skip name, etc)
while(*p != ':') p++; // ignore name
p++; // skip ':'
// get default duration
if(*p == 'd')
{
p++; p++; // skip "d="
num = 0;
while(isdigit(*p))
{
num = (num * 10) + (*p++ - '0');
}
if(num > 0) default_dur = num;
p++; // skip comma
}
Serial.print("ddur: "); Serial.println(default_dur, 10);
// get default octave
if(*p == 'o')
{
p++; p++; // skip "o="
num = *p++ - '0';
if(num >= 3 && num <=7) default_oct = num;
p++; // skip comma
}
Serial.print("doct: "); Serial.println(default_oct, 10);
// get BPM
if(*p == 'b')
{
p++; p++; // skip "b="
num = 0;
while(isdigit(*p))
{
num = (num * 10) + (*p++ - '0');
}
bpm = num;
p++; // skip colon
}
Serial.print("bpm: "); Serial.println(bpm, 10);
// BPM usually expresses the number of quarter notes per minute
wholenote = (60 * 1000L / bpm) * 4; // this is the time for whole note (in milliseconds)
Serial.print("wn: "); Serial.println(wholenote, 10);
// now begin note loop
while(*p)
{
// first, get note duration, if available
num = 0;
while(isdigit(*p))
{
num = (num * 10) + (*p++ - '0');
}
if(num) duration = wholenote / num;
else duration = wholenote / default_dur; // we will need to check if we are a dotted note after
// now get the note
note = 0;
switch(*p)
{
case 'c':
note = 1;
break;
case 'd':
note = 3;
break;
case 'e':
note = 5;
break;
case 'f':
note = 6;
break;
case 'g':
note = 8;
break;
case 'a':
note = 10;
break;
case 'b':
note = 12;
break;
case 'p':
default:
note = 0;
}
p++;
// now, get optional '#' sharp
if(*p == '#')
{
note++;
p++;
}
// now, get optional '.' dotted note
if(*p == '.')
{
duration += duration/2;
p++;
}
// now, get scale
if(isdigit(*p))
{
scale = *p - '0';
p++;
}
else
{
scale = default_oct;
}
scale += OCTAVE_OFFSET;
if(*p == ',')
p++; // skip comma for next note (or we may be at the end)
// now play the note
if(note)
{
Serial.print("Playing: ");
Serial.print(scale, 10); Serial.print(' ');
Serial.print(note, 10); Serial.print(" (");
Serial.print(notes[(scale - 4) * 12 + note], 10);
Serial.print(") ");
Serial.println(duration, 10);
delay(duration);
tone1.stop();
}
else
{
Serial.print("Pausing: ");
Serial.println(duration, 10);
delay(duration);
}
}
}