/* Cwik Clock v1.0 - Prototyping the Display Author: Dennis Cwik Date: July 23, 2012 This program is the controller for a binary clock, with LEDs attached to digital pins 0 through 10, 12, and 13. This example code is in the public domain. */ // This can be modified for debug purposes to make a minute go by quicker. int ONE_SECOND = 1000; // measured in milliseconds int DELAY_BETWEEN_LOOP_CALLS = 200; // measured in milliseconds // I didn't come up with this, it's from the arduino documentation unsigned long MAX_UNSIGNED_LONG = 4294967295; // = (2 ^ 32) - 1 // 1st column of LEDs int PIN_MIN1 = 1; int PIN_MIN2 = 2; int PIN_MIN4 = 3; int PIN_MIN8 = 4; // 2nd column of LEDs int PIN_MIN10 = 5; int PIN_MIN20 = 6; int PIN_MIN40 = 7; // 3rd column of LEDs int PIN_HOUR1 = 8; int PIN_HOUR2 = 9; int PIN_HOUR4 = 10; int PIN_HOUR8 = 11; // 4th column of LEDs int PIN_HOUR10 = 12; int PIN_HOUR20 = 13; // the last time the seconds in the time were incremented unsigned long m_lastTick; // used to tell us if we're setting the time or not boolean m_inTimeSetMode = false; // the time byte m_second; byte m_minute; byte m_hour; // the setup routine runs once when you press reset void setup() { // initialize the pins used for outputting time as OUTPUT pinMode(PIN_MIN1, OUTPUT); pinMode(PIN_MIN2, OUTPUT); pinMode(PIN_MIN4, OUTPUT); pinMode(PIN_MIN8, OUTPUT); pinMode(PIN_MIN10, OUTPUT); pinMode(PIN_MIN20, OUTPUT); pinMode(PIN_MIN40, OUTPUT); pinMode(PIN_HOUR1, OUTPUT); pinMode(PIN_HOUR2, OUTPUT); pinMode(PIN_HOUR4, OUTPUT); pinMode(PIN_HOUR8, OUTPUT); pinMode(PIN_HOUR10, OUTPUT); pinMode(PIN_HOUR20, OUTPUT); // initialize clock variables m_lastTick = 0; setTime(10, 31, 0); } // the loop routine runs over and over again forever void loop() { // see if we're setting the time, or letting time flow normally if (m_inTimeSetMode) { getTimeFromPots(); } else { tick(); } // now that the time has been updated, show the time displaySeconds(); displayMinutes(); displayHours(); // arbitrary delay so that we're not processing away 100% of the time, // an act of power saving delay(DELAY_BETWEEN_LOOP_CALLS); } /** * A helper method to set m_second, m_minute, and m_hour. */ void setTime(byte newHour, byte newMinute, byte newSecond) { m_second = newSecond; m_minute = newMinute; m_hour = newHour; } /** * This method keeps track of the logical flow of time. If enough time has * passed since the last time it was called, m_second, m_minute, and m_hour * will be updated appropriate. This takes into account that millis() rolls * over roughly every 50 days. */ void tick() { unsigned long now = millis(); unsigned long msElapsed; // first we need to find out how much time has passed since the last time we // called tick() if (now < m_lastTick) { // gasp, either we've succeeded in travelling back in time, or millis() wrapped around! msElapsed = (MAX_UNSIGNED_LONG - m_lastTick) + now; } else { msElapsed = now - m_lastTick; } // for each second that has passed (hopefully just 1, unless our code is really laggy), // add 1 second to the time, and increase the minutes & hours if necessary. for (int i = 0; i < msElapsed / ONE_SECOND; ++i) { m_lastTick = m_lastTick + ONE_SECOND; ++m_second; if (m_second == 60) { m_second = 0; ++m_minute; if (m_minute == 60) { m_minute = 0; ++m_hour; if (m_hour == 24) { m_hour = 0; } } } } } void displaySeconds() { // TODO control the analog display } /** * This method reads the variable m_minute, converts it to binary, and displays * it on the appropriate LEDs (those being PIN_MIN*). */ void displayMinutes() { byte ones = m_minute % 10; digitalWrite(PIN_MIN1, ones & B1); digitalWrite(PIN_MIN2, ones & B10); digitalWrite(PIN_MIN4, ones & B100); digitalWrite(PIN_MIN8, ones & B1000); // division is kind of expensive, but we'll assume the compile optimizes this for us :) byte tens = m_minute / 10; digitalWrite(PIN_MIN10, tens & B1); digitalWrite(PIN_MIN20, tens & B10); digitalWrite(PIN_MIN40, tens & B100); } /** * This method reads the variable m_hour, converts it to binary, and displays * it on the appropriate LEDs (those being PIN_HOUR*). */ void displayHours() { byte ones = m_hour % 10; digitalWrite(PIN_HOUR1, ones & B1); digitalWrite(PIN_HOUR2, ones & B10); digitalWrite(PIN_HOUR4, ones & B100); digitalWrite(PIN_HOUR8, ones & B1000); byte tens = m_hour / 10; digitalWrite(PIN_HOUR10, tens & B1); digitalWrite(PIN_HOUR20, tens & B10); } /** * This method reads the values from the 2 potentiometers, converts them to * mimnutes and hours, and sets m_minute and m_hour to the associated values. */ void getTimeFromPots() { // TODO read the potentiometers, set the hour and minutes }