


Maker Faire Bay Area 2012 Countdown TimerGreat news! The Call for Makers has been launched for Maker Faire Bay Area 2012. We're excited and apprehensive at the same time...the days seem to melt away in the months before Maker Faire. The Maker Faire site has a nice countdown timer, and we wanted to duplicate that so we could always keep an eye on the dwindling time. So we did it...in style! Check out the video below: A big Betabrite LED sign (scored from Silicon Valley Electronics Flea Market) receives serial data from an Arduino. The Arduino is keeping track of the difference in time between now and 10:00 AM on May 19th, 2012. Since the Arduino by itself would quickly drift into the meaningless voids of time, we have a ChronoDot installed to keep everything precise. The very handy Time Library by Michael Margolis works as-is with the ChronoDot, and also provides some handy data structures to help do the necessary math. Here are a few technical details: The ChronoDot is wired to the Arduino on the following pins:
The Time Library works great with the ChronoDot since the DS3231 on the ChronoDot works the same as many other Maxim RTCs, like the DS1307 and DS1337. It's just way more accurate, especially in changing temperature. Between now and Maker Faire, we won't be more than 20 or 30 seconds off the real time. Simply download the Time library, and put the "Time" and "DS1307" folders in your Libraries folder within your Arduino sketch folder. Restart Arduino and it'll pick up the new libraries. Go to Sketch > Import Library... and choose the Time, DS1307, and Wire libraries. Don't forget to look under File > Examples > Time for some good hints on how to proceed. The Betabrite sign was old and slightly damaged, but a great deal at the flea market for $20. The protocol is pretty complex, and doing something wrong can corrupt the internal memory and require a reset. However, a decent amount of information is available. Most of the protocol info in this document applies to the Betabrite signs: http://www.ams-e.com/Download_files/97088061E_lite.pdf We don't need to worry about baud rate much, since the Betabrite will detect it. However, it does want a 7E1 serial protocol, instead of the normal 8N1 you get from the Arduino serial port. So we need to tweak some registers to get the correct protocol. Also, the LED sign expects standard RS232 voltage levels instead of TTL RS232, so we need a level converter. We simply threw a MAX232 and capacitors on a piece of proto board. The idea behind the Arduino sketch is simply to get the Time Library running, synchronize to the ChronoDot, calculate the difference between the current time and a hardcoded time for the start of Maker Faire, and output that time to the Betabrite sign. Controlling the sign was a little less direct than it could be; the sign will shut off the display when you write a new text file, so instead we needed to allocate memory, define a string that can be called within the text file, and then update the string only. That allows the time to be updated as the message begins to scroll across the display. Here is the Arduino sketch: // Betabrite Countdown // Counts down the time until Maker Faire Bay Area 2012 // Uses Betabrite 1040 display, Arduino, and ChronoDot #include <Time.h> // Time Library #include <Wire.h> // Wire for RTC #include <DS1307RTC.h> // DS3231/ChronoDot works like DS1307 time_t MFBA; // Start time of Maker Faire time_t difftime; // difference between current and target time int diff_seconds; int diff_minutes; int diff_hours; int diff_days; // Initialize RTC and Betabrite sign void setup() { Serial.begin(9600); // set baud to 9600 UCSR0C = (2<<UPM00)|(0<<USBS0)|(2<<UCSZ00)|(0<<UCPOL0); // configure for 7E1 not 8N1 setSyncProvider(RTC.get); // set sync to use the ChronoDot setSyncInterval(10); // sync every 10 seconds if possible // check whether sync worked if(timeStatus()!= timeSet) Serial.println("Unable to sync with the RTC"); else Serial.println("RTC has set the system time"); tmElements_t MFBA_elements; // elements array to construct Maker Faire start time // 10:00 AM on May 19th, 2012 MFBA_elements.Second = 0; MFBA_elements.Minute = 0; MFBA_elements.Hour = 10; MFBA_elements.Wday = 7; MFBA_elements.Day = 19; MFBA_elements.Month = 5; MFBA_elements.Year = 2012 - 1970; MFBA = makeTime(MFBA_elements); // Unix timestamp of Maker Faire start time // Initialize Betabrite memory locations for(int i = 0; i < 5; i++) Serial.write((byte)0x00); // auto detect baud Serial.write((byte)0x01); // SOH Serial.print("Z00"); // All displays Serial.write((byte)0x02); // STX Serial.print("E$AAU0100FF001BL00C00000"); // Set mem locations for text and string Serial.write((byte)0x04); // ETX delay(1000); // Initialize text file // String "1" will be called whenever scrolling animation restarts for(int i = 0; i < 5; i++) Serial.write((byte)0x00); // auto detect baud Serial.write((byte)0x01); // SOH Serial.print("Z00"); // All displays Serial.write((byte)0x02); // STX Serial.print("AA"); // Text string Serial.write((byte)0x1B); // ESC Serial.write((byte)0x20); // Line number Serial.print("a"); // Scroll right to left Serial.write((byte)0x10); Serial.print("1 until Maker Faire"); // Call string 1 plus text Serial.write((byte)0x04); // ETX } time_t systime; // holds current time for diff calculation void loop() { if (systime != now()) { // wait for new second to do anything systime = now(); difftime = MFBA - systime; // subtract current time from Maker Faire time diff_seconds = difftime % 60; // get seconds difftime /= 60; // convert to minutes diff_minutes = difftime % 60; // get minutes difftime /= 60; // convert to hours diff_hours = difftime % 24; // get hours difftime /= 24; // convert to days diff_days = difftime; // get days // Update string on Betabrite with updated countdown for(int i = 0; i < 5; i++) Serial.write((byte)0x00); // auto baud rate Serial.write((byte)0x01); // SOH Serial.print("Z00"); // All displays Serial.write((byte)0x02); // STX Serial.print("G1"); // Write to string 1 digitalClockDisplay(); // Send countdown string Serial.write((byte)0x04); // ETX } } // modified routine from Time Library example void digitalClockDisplay(){ Serial.print(diff_days); Serial.print(" Days "); printDigits(diff_hours); Serial.print(" Hours "); printDigits(diff_minutes); Serial.print(" Minutes "); printDigits(diff_seconds); Serial.print(" Seconds"); } // routine from Time Library example void printDigits(int digits){ // utility function for digital clock display: prints preceding colon and leading 0 //Serial.print(":"); if(digits < 10) Serial.print('0'); Serial.print(digits); } Suggestions for improvement: detect when Maker Faire arrives and display an exciting message! However, we'll be there and will never see it, so it didn't seem worthwhile. I'd also like to attach PIR sensor so the display can be turned off when no one is around...alternately, it could shut down the display during timeframes where no one is likely to be nearby. Feel free to suggest your own improvements in the comments, show off your own LED signs, or ask for help building something similar!
Submitted by Garrett on Fri, 02/10/2012 - 02:56. |
Recent Comments
|
Happy Birthday! :)
Happy Birthday! :)
Seriously happy birthday!!!
Seriously happy birthday!!! It's an big achievement!
// BetaBrite Basic Output -
// BetaBrite Basic Output - provides basic output to scrolling led panel BetaBrite 1026 and similar
// based on work found at http://macetech.com/blog/node/115 accessed 27 April 2013 by topls64
// jmg
// Initialize Betabrite sign
void setup() {
Serial.begin(2400);
UCSR0C = (2<
// Initialize Betabrite memory locations
for(int i = 0; i < 5; i++) Serial.write((byte)0x00); // auto detect baud
Serial.write((byte)0x01); // SOH
Serial.print("Z00"); // All displays
Serial.write((byte)0x02); // STX
Serial.print("E$AAU0100FF001BL00C00000"); // Set mem locations for text and string
Serial.write((byte)0x04); // ETX
delay(1000);
// Initialize text file
// String "1" will be called whenever scrolling animation restarts
for(int i = 0; i < 5; i++) Serial.write((byte)0x00); // auto detect baud
Serial.write((byte)0x01); // SOH
Serial.print("Z00"); // All displays
Serial.write((byte)0x02); // STX
Serial.print("AA"); // Text string
Serial.write((byte)0x1B); // ESC
Serial.write((byte)0x20); // Line number
Serial.print("a"); // Scroll right to left
Serial.write((byte)0x10);
Serial.print("1 Employees are to return to work NOW !!!"); // Call string 1 plus text
Serial.write((byte)0x04); // ETX
}
void loop() {
sendText();
}
// this can be modified on the fly for dynamic output, it would think.
void sendText(){
for(int i = 0; i < 5; i++) Serial.write((byte)0x00); // auto baud rate
Serial.write((byte)0x01); // SOH
Serial.print("Z00"); // All displays
Serial.write((byte)0x02); // STX
Serial.print("G1"); // Write to string 1
Serial.print("Lunch has been canceled. Management will issue Red Bull and Power Aid at 12:45."); // this can be modified on the fly for dynamic output, it would think.
Serial.write((byte)0x04); // ETX
}