This is a simple Arduino Binary Clock. It comes with a program that generates the script and uploads it to the arduino board. Part of the code isn’t mine only the part that allows you to get the time from the computer and configure the script to use it.
You can download the script maker program from here. You can get this same circuit diagram by opening the program with the /C parameter. There are a lot of command-line options to choose from to configure your Binary Clock. R1 through R13 must have a value that will limit the current enough that it will not break the Arduino or any of its pins. Its probably best to use a 1kilo ohm resistor.
program binclock_uno; {$APPTYPE CONSOLE} {$RESOURCE binclock_uno32.RES} {This program will need binclock.ino added to the resource as ID 1 and type "ARDUINO" You can use Resource Hacker to build binclock_uno32.RES file. The schematic is id 1 and type is "JPEG"} uses SysUtils, graphics, jpeg, windows,shellapi, Classes; const INSERT_POINT='//INSERT_POINT'; //To make the program use less memory and file size, we will use format type string constants STRING_VAR='String %s = "%s";'; ARDUINO_PINVALUES:ARRAY[0..1]OF STRING=('LOW','HIGH'); DEFINE_INTEGER='#define %s %d'; DEFINE_STRING='#define %s %s'; BYTE_VAR='byte %s=%u;'; INO_PATH='%s\%s.ino'; var args,inofile:tstringlist; res:tresourcestream; i:integer; st:systemtime; exename:string; herr:hinst; rs1:longint; arduino_exename,inocommand,inoname:array[0..max_path]of char; tid:dword; function GetConsoleWindow:hwnd;stdcall;external kernel32; function ConsolePicture(id:integer):dword;stdcall; //This thread draws the schematic onto the console window var jpg:tjpegimage; ConsoleCanvas:tcanvas; res:tresourcestream; r:Trect; label loop; begin jpg:=tjpegimage.Create; res:=tresourcestream.CreateFromID(hinstance,id,'JPEG'); jpg.LoadFromStream(res);res.Free; consolecanvas:=TCanvas.Create; consolecanvas.Handle:=getdc(getconsolewindow); loop: getclientrect(getconsolewindow,r); r.Left:=0;r.Top:=0; consolecanvas.StretchDraw(r,jpg); sleep(5000); goto loop; end; begin args:=tstringlist.Create; for i:=1 to paramcount do args.Add(Paramstr(i)); exename:=extractfilename(paramstr(0)); if paramcount=0then begin writeln('Usage:',exename,' /BIAS=OFFSET /MIDNIGHT /C /F=FILENAME /UP /UTC /24 /12 /LED=number /HBTN=ANALOG_PIN /MBTN=ANALOG_PIN /NBTN'); writeln('/UTC Use UTC Time instead of localtime.'); writeln('/BIAS Uses a custom timezone bias'); writeln('/12 Use 12-hour format'); writeln('/24 Use 24-hour format'); writeln('/LED Sets the LED on position logic, 0 for cathode 1 for anode'); writeln('/MBTN Analog pin for Minute button'); writeln('/HBTN Analog pin for Hour button'); Writeln('/NBTN Disable the use of buttons'); writeln('/UP Automatically upload file to Arduino'); writeln('/F The output script name(without .ino extension),if omitted it will be stored as binclock\binclock.ino'); writeln('/C Brings up the circuit diagram for the clock'); writeln('/MIDNIGHT Use midnight as the starting time instead of computer clock'); writeln; writeln('Example: Use a LOW value on all digital LED pins and UTC Time and 24-hour format'); writeln(exename,' /UTC /24 /LED=0 /F=MyBinClock /UP'); write('Press enter to quit...'); readln; args.Free; exitprocess(0); end; if args.IndexOf('/C')>-1Then begin createthread(nil,0,@consolepicture,pointer(1),0,tid); readln; exitprocess(0); end; getsystemtime(st); if args.IndexOfName('/BIAS')=-1then args.Values['/BIAS']:='00:00'; datetimetosystemtime(systemtimetodatetime(st)-strtotime(args.Values['/BIAS']), st); gettimezoneinformation(tz); if args.indexofname('/F')=-1 then args.Values['/F']:='binclock'; createdirectory(strpcopy(inoname,args.values['/F']),nil); res:=tresourcestream.CreateFromID(hinstance,1,'ARDUINO'); inofile:=tstringlist.Create; inofile.LoadFromStream(res); res.Free; if(strtointdef(args.values['/LED'],1)<0)or(strtointdef(args.values['/LED'],1)>1) then begin writeln('Invalid /LED value');args.free;inofile.free; exitprocess(error_invalid_parameter);end; inofile.Insert(inofile.indexof(insert_point),format(define_string,['LED_ON', ARDUINO_PINVALUES[strtointdef(args.values['/LED'],1)]])); inofile.Insert(inofile.indexof(insert_point),FORMAT(DEFINE_STRING,['LED_OFF', ARDUINO_PINVALUES[Strtointdef(args.values['/LED'],1)xor 1]])); if args.IndexOf('/UTC')=-1Then getlocaltime(st); if(args.IndexOf('/12')>-1)and(args.IndexOf('/24')>-1)then begin writeln('Cannot use both /24 and /12 parameters at the same time'); args.Free;inofile.Free; exitprocess(error_invalid_parameter); end; if args.IndexOf('/MIDNIGHT')>-1then begin if args.IndexOf('/12')>-1then st.wHour:=12 else st.wHour:=0;st.wMinute:=0;st.wSecond:=0;end; if(args.indexof('/24')=-1)and(args.IndexOf('/12')=-1)then begin writeln('Must have a hour format parameter');inofile.Free;args.Free; exitprocess(error_invalid_parameter); end; if args.indexof('/12')>-1then begin inofile.Insert(inofile.indexof(insert_point),FORMAT(DEFINE_INTEGER,['HOUR_FORMAT', 12])); if st.wHour=0then st.wHour:=12; if st.wHour>12then st.wHour:=st.wHour-12; end else inofile.Insert(inofile.indexof(insert_point),FORMAT(DEFINE_INTEGER,['HOUR_FORMAT', 24])); inofile.Insert(inofile.indexof(insert_point),FORMAT(DEFINE_INTEGER,['ANALOG_HSET', STRTOINTDEF(ARGS.VALUES['/HBTN'],5)])); inofile.Insert(inofile.indexof(insert_point),FORMAT(DEFINE_INTEGER,['ANALOG_MSET', STRTOINTDEF(ARGS.VALUES['/MBTN'],0)])); if args.IndexOf('/NBTN')=-1then inofile.Insert(inofile.indexof(insert_point), FORMAT(DEFINE_STRING,['BUTTONS_ENABLED','true']))else inofile.Insert( inofile.indexof(insert_point),FORMAT(DEFINE_STRING,['BUTTONS_ENABLED','false'])); inofile.Insert(inofile.indexof(insert_point),FORMAT(BYTE_VAR,['hour',ST.WHOUR])); inofile.Insert(inofile.indexof(insert_point),FORMAT(BYTE_VAR,['minute',st.wminute])); inofile.Insert(inofile.indexof(insert_point),FORMAT(BYTE_VAR,['second',st.wSecond])); inofile.SaveToFile(format(ino_path,[inoname,inoname])); writeln('Script saved to ',format(ino_path,[inoname,inoname])); if args.IndexOf('/UP')>-1then begin rs1:=sizeof(arduino_exename);regqueryvalue( hkey_classes_root,'Arduino File\shell\open\command',arduino_exename,rs1);herr:= shellexecute(0,nil,strpcopy(arduino_exename,stringreplace(arduino_exename,' "%1"', '',[])),strfmt(inocommand,'--upload "%s\%s.ino"',[inoname,inoname]),nil,sw_showdefault); if herr<33then begin if herr=0then writeln('Out of resources')else writeln(syserrormessage(herr)); args.Free;inofile.Free; exitprocess(herr); end;end; args.Free; inofile.Free; exitprocess(0); end.
/* Filename binclock.ino An open-source binary clock for Arduino. Based on the code from by Rob Faludi (http://www.faludi.com) Code under (cc) by Daniel Spillere Andrade, www.danielandrade.net http://creativecommons.org/license/cc-gpl I modified the code a little bit so it can have 12-hour format and pin configuration. By Justin Roeder /* IMPORTANT NOTICE BEFORE ADDING THIS SCRIPT TO THE RESOURCE OF THE GENERATOR EXECUTABLE YOU MUST REMOVE ALL OF THE LINES UNTIL YOU GET TO //INSERT_POINT LEAVE //INSERT_POINT IN SCRIPT. THAT TELLS THE GENERATOR WHERE TO PUT THE VARIABLES. IF YOU ARE JUST GOING TO UPLOAD THHIS SCRIPT TO THE BOARD, YOU CAN LEAVE THE CODE ALONE. */ #define LED_ON HIGH //LED Bit on logic #define LED_OFF LOW //LED Bit off logic #define HOUR_FORMAT 24 //Change to 12 for 12 hour time #define ANALOG_HSET 5 //defines hour set button pin #define ANALOG_MSET 0 //defines minure set buttonpin #define BUTTONS_ENABLED true //set to false to disable buttons byte hour=0; byte minute=0; byte second=0; //Start at midnight 00:00:00 //INSERT_POINT int munit,hunit,valm=0,valh=0,ledstats,i; void setup() { //set outputs for(int k=1;k<=13;k++) { pinMode(k, OUTPUT); } //set inputs pinMode(0, INPUT); } void loop() { static unsigned long lastTick = 0; // set up a local variable to hold the last time we moved forward one second // (static variables are initialized once and keep their values between function calls) // move forward one second every 1000 milliseconds if (millis() - lastTick >= 1000) { lastTick = millis(); second++; } // move forward one minute every 60 seconds if (second >= 60) { minute++; second = 0; // reset seconds to zero } // move forward one hour every 60 minutes if (minute >=60) { hour++; minute = 0; // reset minutes to zero } if (hour >=24) { hour = 0; minute = 0; // reset minutes to zero } if(HOUR_FORMAT==12){ if(hour>12){hour=hour-12;} if(hour==0){hour=12;} } munit = minute%10; //sets the variable munit and hunit for the unit digits hunit = hour%10; ledstats = digitalRead(0); // read input value, for setting leds off, but keeping count if (ledstats == LOW) { for(i=1;i<=13;i++){ digitalWrite(i, LED_OFF);} } else { //minutes units if(munit == 1 || munit == 3 || munit == 5 || munit == 7 || munit == 9) { digitalWrite(1, LED_ON);} else { digitalWrite(1,LED_OFF);} if(munit == 2 || munit == 3 || munit == 6 || munit == 7) {digitalWrite(2, LED_ON);} else {digitalWrite(2,LED_OFF);} if(munit == 4 || munit == 5 || munit == 6 || munit == 7) {digitalWrite(3, LED_ON);} else {digitalWrite(3,LED_OFF);} if(munit == 8 || munit == 9) {digitalWrite(4, LED_ON);} else {digitalWrite(4,LED_OFF);} //minutes if((minute >= 10 && minute < 20) || (minute >= 30 && minute < 40) || (minute >= 50 && minute < 60)) {digitalWrite(5, LED_ON);} else {digitalWrite(5,LED_OFF);} if(minute >= 20 && minute < 40) {digitalWrite(6, LED_ON);} else {digitalWrite(6,LED_OFF);} if(minute >= 40 && minute < 60) {digitalWrite(7, LED_ON);} else {digitalWrite(7,LED_OFF);} //hour units if(hunit == 1 || hunit == 3 || hunit == 5 || hunit == 7 || hunit == 9) {digitalWrite(8, LED_ON);} else {digitalWrite(8,LED_OFF);} if(hunit == 2 || hunit == 3 || hunit == 6 || hunit == 7) {digitalWrite(9, LED_ON);} else {digitalWrite(9,LED_OFF);} if(hunit == 4 || hunit == 5 || hunit == 6 || hunit == 7) {digitalWrite(10, LED_ON);} else {digitalWrite(10,LED_OFF);} if(hunit == 8 || hunit == 9) {digitalWrite(11, LED_ON);} else {digitalWrite(11,LED_OFF);} //hour if(hour >= 10 && hour < 20) {digitalWrite(12, LED_ON);} else {digitalWrite(12,LED_OFF);} if(hour >= 20 && hour < 24) {digitalWrite(13, LED_ON);} else {digitalWrite(13,LED_OFF);} } if(BUTTONS_ENABLED){ valm = analogRead(ANALOG_MSET); // add one minute when pressed if(valm<800) { minute++; second = 0; delay(250); } valh = analogRead(ANALOG_HSET); // add one hour when pressed if(valh<800) { hour++; second = 0; delay(250); }} }
How to read the display?
Each column represents a digit. As seen in the circuit di
I am going to leave the buttons out of the one I’m building. If you are doing this then use the /NBTN parameter. I will keep you updated