Binary + Bamboo = BinBoo. This project is my first attempt at making a laser-cut enclosure. Ponoko was used to cut the project which holds itself together. The LEDs are driven by an Arduino-based clock that incorporates a RTC1307, FTDI chip, ATmega328, and TLC5940.
Electronics
BinBoo-v1 PCB
Schematic (PDF): binary_clock_rev1
V1 Of the Electronics (there are many issues with v1!)
Parts list:
(12) – Bright Blue 5mm LEDs
(13) – Jumper Wires
(1) – BinBoo Controller Board with:
(1) – ATmega328
(1) – TLC5940
(1) – FTDI 232
(Various) Decoupling capacitors
USB Mini-B Port
Schematic:
The core design came from the Arduino Duemilanove schematic. There were changes to the FTDI chip in order to make it work correctly.
LED Panel:
BinBoo – LED Panel FrontHow BinBoo’s LED Matrix is Wired
The LED panel is constructed with all Anodes connected to VCC. The cathodes each connect to an output of the TLC5940. Due to a design change (from straight binary to BCD), the BinBoo Controller board does not have enough outputs connected to header pins.
Firmware
The code is based on the TimeRTC example from the Arduino Time Library. In order to set the time, a serial monitor must be used. The syntax is simplistic: “T<seconds since epoch>”. The UNIX time library provides this value rather easily.
Code was added for: startup effect, fading between time changes, determining the BCD of the time, and getting time from the RTC.
The startup effect is useful because it helps to identify wiring mistakes since it fades the LEDs in sequence.
Code as of 5/19/2012:
/*
*
* BinBooV2
* Created by: James C Lewis. [email protected]
* www.baldengineer.com
*
* BinBoo is a Binary clock made out of bamboo materials. The electrical hardware includes
* a ATmega328, DS1307 RTC, and a TLC5940. These chips are connected to 11 LEDs.
*
* from bash: date +%s (for number of seconds)
* CDT offset: -18000
* CST offset: -21600
*/
#include <Time.h>
#include <Wire.h>
#include <DS1307RTC.h>
#include <Tlc5940.h>
#define EPOCH_OFFSET -18000
#define TIME_MSG_LEN 11
#define TIME_HEADER 'T'
#define TIME_REQUEST 7
#define WAIT_INTERVAL 5000
#define DAY_BRITE 512
#define NIGHT_BRITE 128
unsigned long waitMillis;
void setup() {
Serial.begin(9600);
Serial.println(F("BinBoo Release 0.2 - James Lewis ([email protected])"));
Serial.println(F("Use date +%s to get current time in seconds"));
setSyncProvider(RTC.get); // grab time from the RTC
if(timeStatus()!= timeSet)
Serial.println("Unable to sync with the RTC"); // not really sure who is going to see this one.. ;)
else
Serial.println("RTC has set the system time");
Tlc.init();
Tlc.clear();
Tlc.update();
waitMillis = millis() + 1000; // setup first crossing point
startUpSequence();
}
void loop() {
int previousTime=0;
int currentTime=0;
while(1) { // want to avoid making currentTime/previousTime global
if (Serial.available())
processSyncMessage();
if ((long)(millis() - waitMillis) >= 0) { // need to cast to signed math...
printTimeDate();
currentTime = calculateTimeBits();
setTLCtime(previousTime, currentTime);
previousTime = currentTime;
waitMillis += WAIT_INTERVAL; //sit around for another second.
}
}
}
void setTLCtime(int previousTime, int currentTime ) {
if (previousTime == currentTime) // time hasn't changed, so don't do anything
return;
int bright = 0; // what is the max brightness, based on the time.
if ((hour() >= 6) && (hour() <= 18))
bright = DAY_BRITE;
else
bright = NIGHT_BRITE;
for (int i=0; i<=bright; i++) {
int fadeAmount = 0; // each look of the bright for, will be to fade up/down the leds
for (int j=0; j<12; j++) { // this loop determines which direction and intensity of fade
switch (bitRead(previousTime, j) - bitRead(currentTime,j)) {
case 0: // no change, the led alone
if bitRead(currentTime,j)
fadeAmount = bright;
else
fadeAmount = 0;
break;
case -1: // turn the led on
fadeAmount = i;
break;
case 1: // turn the led off
fadeAmount = bright - i;
break;
}
Tlc.set(j, fadeAmount);
}
Tlc.update();
delay(1);
}
}
int calculateTimeBits() {
int hours = hourFormat12();
int minutes = minute();
int timeLEDs=0;
timeLEDs = hours;
timeLEDs = hours << 8;
timeLEDs += (minutes/10)<<4;
timeLEDs += minutes%10;
if (isPM())
bitSet(timeLEDs, 11);
return timeLEDs;
}
void printTimeDate() {
printTime();
Serial.print(" ");
printDate();
Serial.println("");
}
void printTime() {
Serial.print(hourFormat12());
printDigits(minute());
printDigits(second());
Serial.print(" ");
if (isAM())
Serial.print("AM");
else
Serial.print("PM");
}
void printDate() {
Serial.print(month());
Serial.print("/");
Serial.print(day());
Serial.print("/");
Serial.print(year());
}
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);
}
void startUpSequence() {
for (int j=0; j<12; j++) {
Tlc.clear();
for (int i=0; i<(DAY_BRITE+1); i=i+32) {
Tlc.set(j, i);
Tlc.update();
delay(10);
}
for (int i=DAY_BRITE; i > 0; i=i-32) {
Tlc.set(j,i);
Tlc.update();
delay(10);
}
}
}
void processSyncMessage() {
// if time sync available from serial port, update time and return true
if (Serial.available() >= TIME_MSG_LEN ) { // time message consists of a header and ten ascii digits
char c = Serial.read() ;
if( c == TIME_HEADER ) {
Serial.print(c);
time_t pctime = 0;
for(int i=0; i < TIME_MSG_LEN -1; i++){
c = Serial.read();
if( c >= '0' && c <= '9'){
pctime = (10 * pctime) + (c - '0'); // convert digits to a number
}
}
pctime = pctime EPOCH_OFFSET; // the define has a math sign in it
Serial.print(" - ");
Serial.println(pctime);
RTC.set(pctime);
setTime(pctime); // Sync Arduino clock to the time received on the serial port
waitMillis += 100;
}
}
}
Fan of making things beep, blink and fly. Created AddOhms. Writer for Hackster.io News. Freelance electronics content creator for hire! KN6FGY and, of course, bald.
Like other websites, this one uses cookies to remember things. Mostly, I use Google Analytics to know how many people come here. ¯\_(ツ)_/¯
By clicking “Accept”, you consent to the use of ALL the cookies.
This website uses cookies to improve your experience while you navigate through the website. Out of these, the cookies that are categorized as necessary are stored on your browser as they are essential for the working of basic functionalities of the website. We also use third-party cookies that help us analyze and understand how you use this website. These cookies will be stored in your browser only with your consent. You also have the option to opt-out of these cookies. But opting out of some of these cookies may affect your browsing experience.
Necessary cookies are absolutely essential for the website to function properly. These cookies ensure basic functionalities and security features of the website, anonymously.
Cookie
Duration
Description
cookielawinfo-checkbox-advertisement
1 year
Set by the GDPR Cookie Consent plugin, this cookie is used to record the user consent for the cookies in the "Advertisement" category .
cookielawinfo-checkbox-analytics
11 months
This cookie is set by GDPR Cookie Consent plugin. The cookie is used to store the user consent for the cookies in the category "Analytics".
cookielawinfo-checkbox-functional
11 months
The cookie is set by GDPR cookie consent to record the user consent for the cookies in the category "Functional".
cookielawinfo-checkbox-necessary
11 months
This cookie is set by GDPR Cookie Consent plugin. The cookies is used to store the user consent for the cookies in the category "Necessary".
cookielawinfo-checkbox-others
11 months
This cookie is set by GDPR Cookie Consent plugin. The cookie is used to store the user consent for the cookies in the category "Other.
cookielawinfo-checkbox-performance
11 months
This cookie is set by GDPR Cookie Consent plugin. The cookie is used to store the user consent for the cookies in the category "Performance".
CookieLawInfoConsent
1 year
Records the default button state of the corresponding category & the status of CCPA. It works only in coordination with the primary cookie.
viewed_cookie_policy
11 months
The cookie is set by the GDPR Cookie Consent plugin and is used to store whether or not user has consented to the use of cookies. It does not store any personal data.
Functional cookies help to perform certain functionalities like sharing the content of the website on social media platforms, collect feedbacks, and other third-party features.
Cookie
Duration
Description
language
session
This cookie is used to store the language preference of the user.
Performance cookies are used to understand and analyze the key performance indexes of the website which helps in delivering a better user experience for the visitors.
Analytical cookies are used to understand how visitors interact with the website. These cookies help provide information on metrics the number of visitors, bounce rate, traffic source, etc.
Cookie
Duration
Description
_ga
2 years
The _ga cookie, installed by Google Analytics, calculates visitor, session and campaign data and also keeps track of site usage for the site's analytics report. The cookie stores information anonymously and assigns a randomly generated number to recognize unique visitors.
_ga_LHR6J24XSY
2 years
This cookie is installed by Google Analytics.
_gat_gtag_UA_42726312_1
1 minute
Set by Google to distinguish users.
_gid
1 day
Installed by Google Analytics, _gid cookie stores information on how visitors use a website, while also creating an analytics report of the website's performance. Some of the data that are collected include the number of visitors, their source, and the pages they visit anonymously.
browser_id
5 years
This cookie is used for identifying the visitor browser on re-visit to the website.
CONSENT
2 years
YouTube sets this cookie via embedded youtube-videos and registers anonymous statistical data.
Advertisement cookies are used to provide visitors with relevant ads and marketing campaigns. These cookies track visitors across websites and collect information to provide customized ads.
Cookie
Duration
Description
VISITOR_INFO1_LIVE
5 months 27 days
A cookie set by YouTube to measure bandwidth that determines whether the user gets the new or old player interface.
YSC
session
YSC cookie is set by Youtube and is used to track the views of embedded videos on Youtube pages.
yt-remote-connected-devices
never
YouTube sets this cookie to store the video preferences of the user using embedded YouTube video.
yt-remote-device-id
never
YouTube sets this cookie to store the video preferences of the user using embedded YouTube video.
yt.innertube::nextId
never
This cookie, set by YouTube, registers a unique ID to store data on what videos from YouTube the user has seen.
yt.innertube::requests
never
This cookie, set by YouTube, registers a unique ID to store data on what videos from YouTube the user has seen.
2 Comments
Pingback: baldengineer | Binary + Bamboo = BinBoo
Pingback: CMiYC Labs, Inc. | BoxMaker: Create a new box