![]() |
Forum Index : Microcontroller and PC projects : That Old Analog Clock...revisited
Author | Message | ||||
crackerjack![]() Senior Member ![]() Joined: 11/07/2011 Location: AustraliaPosts: 164 |
Hi All, I really should get my teeth into some neat hardware oriented projects, but in the meanwhile I've been having yet more Maximite (BASIC software) fun. The evergreen Analog Clock gets some treatment here... but really just as an example of what can be done using converted bitmaps as a background. See this post and this code for details on this. Back to the clock... Photo of the VGA screen: ![]() Screenshot using the SAVEBMP command: ![]() The Maximite is never going to be an Apple-killing graphics work station, but some nice little effects can be obtained - and hey, it's so much fun... I guess gauges and backgrounds of all sorts could be preloaded and then actual measured data displayed within the "blank" zones. jman's neat In-Car Console Display from a month or two back springs to mind as a perfect place to use this type of approach. Code for the clock is zipped and available here including a "blank" bitmap of the Roman Numeral clock face. Checkout the Converted Bitmaps link above on how to convert bitmaps to a snappy format the Maximite likes. Also, the minute- and hour-hand rendering code is far from perfect and leaves the pointers looking a touch "skinny" at certain times of the day. Easily fixed, but those hardware projects beckon... Cheers. |
||||
Greg Fordyce Senior Member ![]() Joined: 16/09/2011 Location: United KingdomPosts: 153 |
Thanks, I can use that. ![]() Greg |
||||
Greg Fordyce Senior Member ![]() Joined: 16/09/2011 Location: United KingdomPosts: 153 |
From the README [quote]I have not tested the program on a Composite display, but it should work with limits according to the dimensions of that display.[/quote] Just tested the BMP2MPF.BAS and MPFVIEW.BAS on a composite display and they both work perfectly. ![]() |
||||
crackerjack![]() Senior Member ![]() Joined: 11/07/2011 Location: AustraliaPosts: 164 |
Thanks for the feedback Greg. Hope the code is useful to you. Cheers. |
||||
crackerjack![]() Senior Member ![]() Joined: 11/07/2011 Location: AustraliaPosts: 164 |
For anybody interested, there is a small update to the code to make the clock behave more like a true analog clock: - the hour and minute hands are now rendered in a uniform way regardless of their position on the face; - the second hand extends beyond the clock center in both directions; - the hour hand indexes according to the number of minutes passed in the hour - e.g. it would be halfway between 10 and 11 at 10:30 AM (not left pointing at 10 with a sudden "snap" to 11 as the hour passes). Also there is an annoying tick-tock sound (which may be switched on/off at program start). The math/trig is probably a bit cryptic in the code as it is not commented - but digging through it you will see a way of rendering rotary gauge-like pointers (or needles) of arbitrary "weight" or "thickness" as is done with the hour and minute hands. The Maximite is quite a marvellous little beast - it only takes about 7 milliseconds to run the entire Time Display routine leaving about another 993 milliseconds of not doing much at all while we wait for time to pass... |
||||
Bill.b![]() Senior Member ![]() Joined: 25/06/2011 Location: AustraliaPosts: 235 |
Hi Lance I have added code to reas the DS1307 RTC so the colock is set to the corrct time when the program is run. 10 ' TICKTOCK V3.0 - Analog Clock with Roman Numeral Bitmap Face & Sound
15 'Added read RTC routine to update Time$. WB (I2C COMS TO DS1307) 20 ' crackerjack 10/2011 30 ' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 40 CLS:INPUT "AUDIBLE TICK (Y/N)? ",TICK$:CLS 50 TICK=INSTR(UCASE$(TICK$),"Y") 55 DIM RTCbuff(255) 60 ' ------ LOAD FACE FROM MPF FILE 70 OPEN "TICKTOCK.MPF" FOR INPUT AS #1 80 LINE INPUT #1,ID$:IF ID$<>"MPF1" THEN GOTO 270 90 LINE INPUT #1,WIDTH$ 100 LINE INPUT #1,HEIGHT$ 110 Y=VAL(HEIGHT$) 120 WIDTH=VAL(WIDTH$)-1 130 X1=0 140 X2=ASC(INPUT$(1,#1))-1 150 PXL=VAL(INPUT$(1,#1)) 160 LINE(X1,Y)-(X2,Y),PXL 170 DO 180 IF X2>=WIDTH THEN 190 X1=0:Y=Y-1 200 ELSE 210 X1=X2+1 220 ENDIF 230 X2=X1+ASC(INPUT$(1,#1))-1 240 PXL=VAL(INPUT$(1,#1)) 250 LINE(X1,Y)-(X2,Y),PXL 260 LOOP UNTIL EOF(#1) 270 CLOSE #1 280 ' ------ SETUP FOR CLOCK 290 PI=3.14159265 300 Z=210:SEC_LEN=150:MIN_LEN=145:HR_LEN=115 310 SPAN=2 320 SETTICK 1000,360 330 CIRCLE(Z,Z),205:CIRCLE(Z,Z),155 340 DO:LOOP 345 gosub 900 350 ' ------ TIME DISPLAY 360 SEC=VAL(MID$(TIME$,7,2))/60*2*PI-PI/2 370 MIN=VAL(MID$(TIME$,4,2))/60*2*PI-PI/2 380 HR=(VAL(MID$(TIME$,1,2))+(VAL(MID$(TIME$,4,2))/60))/12*2*PI- PI/2 390 ' ------ SECONDS 400 LINE(Z,Z)-(Z+SEC_LEN*(COS(OLD_SEC)),Z+SEC_LEN*(SIN(OLD_SEC)) ),0 410 LINE(Z,Z)-(Z+15*(COS(OLD_SEC+PI)),Z+15*(SIN(OLD_SEC+PI))),0 420 CIRCLE(Z+(SEC_LEN-10)*(COS(OLD_SEC)),Z+(SEC_LEN-10)*(SIN(OLD _SEC))),2,0,F 430 LINE(Z,Z)-(Z+SEC_LEN*(COS(SEC)),Z+SEC_LEN*(SIN(SEC))),1 440 LINE(Z,Z)-(Z+15*(COS(SEC+PI)),Z+15*(SIN(SEC+PI))),1 450 CIRCLE(Z+(SEC_LEN-10)*(COS(SEC)),Z+(SEC_LEN-10)*(SIN(SEC))), 2,1,F 460 OLD_SEC=SEC 470 ' ------ MINUTES 480 IF MIN<>OLD_MIN THEN 490 X_OLD_MIN=MIN_LEN*COS(OLD_MIN) 500 Y_OLD_MIN=MIN_LEN*SIN(OLD_MIN) 510 FOR M=-SPAN TO SPAN 520 X1=M*COS(OLD_MIN+(PI/2)) 530 Y1=M*SIN(OLD_MIN+(PI/2)) 540 LINE(Z+X_OLD_MIN,Z+Y_OLD_MIN)-(Z+X1,Z+Y1),0 550 NEXT M 560 ENDIF 570 XMIN=MIN_LEN*COS(MIN) 580 YMIN=MIN_LEN*SIN(MIN) 590 FOR M=-SPAN TO SPAN 600 X1=M*COS(MIN+(PI/2)) 610 Y1=M*SIN(MIN+(PI/2)) 620 LINE(Z+XMIN,Z+YMIN)-(Z+X1,Z+Y1),1 630 NEXT M 640 OLD_MIN=MIN 650 ' ------ HOURS 660 IF HR<>OLD_HR THEN 670 X_OLD_HR=HR_LEN*COS(OLD_HR) 680 Y_OLD_HR=HR_LEN*SIN(OLD_HR) 690 FOR M=-SPAN TO SPAN 700 X1=M*COS(OLD_HR+(PI/2)) 710 Y1=M*SIN(OLD_HR+(PI/2)) 720 LINE(Z+X_OLD_HR,Z+Y_OLD_HR)-(Z+X1,Z+Y1),0 730 NEXT M 740 ENDIF 750 XHR=HR_LEN*COS(HR) 760 YHR=HR_LEN*SIN(HR) 770 FOR M=-SPAN TO SPAN 780 X1=M*COS(HR+(PI/2)) 790 Y1=M*SIN(HR+(PI/2)) 800 LINE(Z+XHR,Z+YHR)-(Z+X1,Z+Y1),1 810 NEXT M 820 OLD_HR=HR 830 CIRCLE(Z,Z),SPAN*2,1 840 SOUND 400,3*TICK 850 'LOCATE 410,405:? TIME$ 860 IRETURN 900 '--------- READ RTC ---------------- 910 i2caddr = &h68 ' DS1307 I2C address 950 I2CEN 100,100 ' Enable I2C 960 I2CRCV i2caddr, 0, 8, RTCbuff(0), 1, 0 965 I2CDIS 970 BCDTEMP = RTCBuff(0) 980 GOSUB 11000 990 sec$ = STR$(decimal) 995 BCDTEMP = RTCBuff(1) 1000 GOSUB 11000 1005 min$ = STR$(decimal) 1010 BCDTEMP = RTCBuff(2) 1011 GOSUB 11000 1012 Hour_12 = decimal 1013 if decimal >12 then 1014 Hour_12 = decimal - 12 1015 endif 1022 if decimal =0 then 1023 Hour_12 = 12 1024 endif 1030 hours$ = STR$(Hour_12) 1040 t$ = hours$+":"+min$+":"+sec$ 1045 TIME$ = T$ 1050 return 11000 ' --- Convert to Decimal ----- 11010 Decimal = FIX(BCDTemp / 16) * 10 11020 Decimal = Decimal + (BCDTEMP AND &hF) 11030 RETURN In the interests of the environment, this post has been constructed entirely from recycled electrons. |
||||
lew247![]() Guru ![]() Joined: 23/12/2015 Location: United KingdomPosts: 1702 |
Can this ONLY be run on a Maximite or is it possible to run (or get it working) on a Micromite+ 64 pin? |
||||
matherp Guru ![]() Joined: 11/12/2012 Location: United KingdomPosts: 10180 |
This is easy enough. Display the bitmap as a background. Write the hands where required. Note that they do not cross over the numerals. To move the hands write the old position in black and then re-write the new position. This is much simpler and very different from writing on top of a multicolour background where the colour background has to be replaced as the hands move. |
||||
redrok![]() Senior Member ![]() Joined: 15/09/2014 Location: United StatesPosts: 209 |
Hi crackerjack; While I haven't tried a Bitmap image in the background I can't see any problems. I have an example uMITE clock program that may be useful. This is a "Indoor/Outdoor Clock Thermometer". My code simulates the small analog movements of the hands just like the real analog clocks. My code allows one to easily adjust the display parameters of the clock such as: 1. Size 2. Position 3. Shape i.e circular or oval face I have several examples of the various clock faces. Just rem out the various setup subroutine. Note! word wrapping occurred in the code below. I will also attach this code. 2016-04-20_171828_TimeTempLcdP1.zip redrok 'TimeTempLcdP1.bas 'Indoor/Outdoor Time & Temperature Clock '28 pin uMITE Ver 5.0 'DS18B20 Temperature Sensors 'PFC8563 Real Time Clock 'ILI9341 320x240 LCD Panel without Touch Screan 'Written by Duane C. Johnson AD0TJ 'Red Rock Energy 'redrok.com 'http://www.redrok.com Initialize: 'ILI9341 Pins 1-9 > VCC,gnd, CS,RST,D/C,SDI,SCK,LED,SDO 'ILI9341 Pins 1-9 > 1, 2, 3, 4, 5, 6, 7, 8, 9 'uMITE Pins > +5,gnd, 4, 5, 6, 3, 25, , 14 'ILI9341 names > orient,D/C,RST,CS pins 'OPTION LCDPANEL ILI9341,RL, 6 , 5 , 4 'OPTION LCDPANEL DISABLE 'OPTION TOUCH DISABLE 'Option AUTORUN ON 'Option DISPLAY 43,120 'Option COLOURCODE OFF 'CPU 40 'Option BAUDRATE 115200 Cls Print Chr$(27);"[2J";Chr$(27);"[1;34m";'Erace Display and Set to BOLD BLUE Dim Stars$(3):Stars$(0)="-":Stars$(1)="\":Stars$(2)="|":Stars$(3)="/" COLOR RGB(0,50,0),RGB(32,0,32)'Set Basic LED Display Colors BOX 0,0,318,239,7,RGB(0,0,255),RGB(32,0,32)'Add A Border ' Choose A Clock Face You like or Make Your Own 'Large Oval Clock Face Parameters Gosub LargeOval 'Small Oval Clock Face Parameters 'Gosub SmallOval 'Large Vertical Oval Clock Face Parameters 'Gosub LargeVerticalOval 'Tiny Circular Clock Face Parameters 'Gosub TinyCircular Circle CenterX,CenterY,FaceRadius-0*FaceThick,FaceThick,AspRatio,RGB(255,0,0),RGB(0,0,0) Circle CenterX,CenterY,FaceRadius-1*FaceThick,FaceThick,AspRatio,RGB(0,255,0),RGB(0,0,0) Circle CenterX,CenterY,FaceRadius-2*FaceThick,FaceThick,AspRatio,RGB(0,0,255),RGB(0,0,0) Circle CenterX,CenterY,FaceRadius-3*FaceThick,FaceThick,AspRatio,RGB(0, 0, 0),RGB(0,0,0) 'Blank Out the Seconds Marks For T=0 To 59 For T1= -30 to 30 MinX=CenterX+Cos((T1/200-15+T)/30*PI)*(FaceRadius)*AspRatio MinY=CenterY+Sin((T1/200-15+T)/30*PI)*(FaceRadius) Line CenterX,CenterY,MinX,MinY,,RGB(0,0,0) Next T1 Next T 'Add Hour Tick Marks For T=0 To 11 FaceX=CenterX+Cos((T-3)/6*PI)*(FaceRadius-.5*FaceThick)*AspRatio FaceY=CenterY+Sin((T-3)/6*PI)*(FaceRadius-.5*FaceThick) For T1 = 0 To TicRadius Circle FaceX,FaceY,T1,T1,1,RGB(0,255,0) Next T1 Next T 'RTC SETTIME year,month,day,hour,minute,second 'RTC SETTIME 16,4,18,11,18,0 'RTC PFC8563 weekdays register = 3 ie 0 to 6 = Sun to Sat DIM DOW$(6)=(" Sunday "," Monday "," Tuesday ","Wednesday","Thursday "," Friday ","Saturday ") 'RTC SETREG 6, 3'Day value 0 to 6 'RTC SETREG 13,128+3'0=32768Hz 1=4096Hz 2=32Hz 3=1Hz 'RTC SETREG 14, 0+3'Timer Off RTC gettime 'Calibration for My DS18B20 Temperature Sensors InTmpPin = 9 'Indoor DS18B20 uMITE Pin OutTmpPin = 7 'Outdoor DS18B20 uMITE Pin InTempCalF =-0.58'Indoor Degrees F Calibration OutTempCalF=-0.76'Outdoor Degrees F Calibration TmpAve=30 'Moving Average of Last "TmpAve" Values, 30 Makes the Time Constant About a Minute TEMPR START InTmpPin ,3:InTmp =TEMPR(9)*1.8+32+InTempCalF TEMPR START OutTmpPin,3:OutTmp=TEMPR(7)*1.8+32+OutTempCalF Again: Star%=Star%+1 'Rotatinging Stars on the Terminal RTC gettime:RTC GetReg 6,Day:Day=Day AND 7'Get Time and Day Of the Week DatTim$= Date$+" "+Time$'Date & Time String from the RTC 'Remember Old Clock Values and Get the New Ones SecsOld=Secs:Secs=Val(Mid$(DatTim$,18,2)) MinsOld=Mins:Mins=Val(Mid$(DatTim$,15,2)) HorsOld=Hors:Hors=Val(Mid$(DatTim$,12,2)) 'Rearange the RTC Time String Tim$=Mid$(DatTim$,7,4)+"/"+Mid$(DatTim$,4,2)+"/"+Left$(DatTim$,2)+" "+Mid$(DatTim$,12,8) 'Assemble Day of the Week String for the Terminal WDay$=" "+Chr$(27)+"[1;31m"+Stars$(Star% Mod 4)+Chr$(27)+"[1;34m"+" "+DOW$(Day) WDay$=WDay$+" "+Chr$(27)+"[1;31m"+Stars$(((Star%+3)Xor 3)Mod 4)+Chr$(27)+"[1;34m" 'Assemble Temperature String for Display on the Terminal InF$ =" Indoor :"+Str$( InTmp,3,2)+"F " OutF$=" Outdoor:"+Str$(OutTmp,3,2)+"F " 'Send to the Terminal Print Chr$(27);"[H";'GoTo HOME 'Print DatTim$ Print Tim$:Print WDay$:Print InF$:Print OutF$; 'Remember Old Clock Hands Parameters OldSecX=secX:OldSecY=SecY:OldMinX=MinX:OldMinY=MinY:OldHorX=HorX:OldHorY=HorY 'Calculate the Hands Orientation Including the Small Analog Movements HorX=CenterX+Cos((Hors+Mins/60+Secs/3600 -3)/ 6*PI)*(FaceRadius-5*FaceThick)*AspRatio HorY=CenterY+Sin((Hors+Mins/60+Secs/3600 -3)/ 6*PI)*(FaceRadius-5*FaceThick) MinX=CenterX+Cos((Mins+Secs/60 -15)/30*PI)*(FaceRadius-3*FaceThick)*AspRatio MinY=CenterY+Sin((Mins+Secs/60 -15)/30*PI)*(FaceRadius-3*FaceThick) SecX=CenterX+Cos((Secs -15)/30*PI)*(FaceRadius-1*FaceThick)*AspRatio SecY=CenterY+Sin((Secs -15)/30*PI)*(FaceRadius-1*FaceThick) 'Erace Old Clock Hands, if changed, from the LCD Panel If SecsOld<>Secs then LINE CenterX,CenterY,OldHorX,OldHorY,1,RGB(0,0,0) If SecsOld<>Secs then LINE CenterX,CenterY,OldMinX,OldMinY,1,RGB(0,0,0) If SecsOld<>Secs then LINE CenterX,CenterY,OldSecX,OldSecY,1,RGB(0,0,0) 'Display New Clock Hands on the LCD Panel 'Note, Paint in this Order so Seconds Overlap Minutes, then Minutes Overlap Hours LINE CenterX,CenterY,HorX,HorY,,RGB(255,128,255) LINE CenterX,CenterY,MinX,MinY,,RGB(128,255,255) LINE CenterX,CenterY,SecX,SecY,,RGB(255,255,128) 'Display Text on the LCD Panel 'TEXT X, Y,STRING,JUSTIFI,FONT,SCALE,C,BC TEXT 160, 1,Tim$ ,CT,1,2,RGB(128,255,128) TEXT 160,25,InF$ ,CT,1,2,RGB(128,255,128) TEXT 160,49,OutF$,CT,1,2,RGB(128,255,128) If(SecsOld<>Secs)And((Secs and 1)=0)Then TEMPR START InTmpPin, 3:InTmp =(TmpAve-1)/TmpAve* InTmp+1/TmpAve*(TEMPR(9)*1.8+32+InTempCalF ) If(SecsOld<>Secs)And((Secs and 1)=1)Then TEMPR START OutTmpPin,3:OutTmp=(TmpAve-1)/TmpAve*OutTmp+1/TmpAve*(TEMPR(7)*1.8+32+OutTempCalF) GoTo Again LargeOval: CenterX=159:CenterY=157'Center Position of the Clock Face FaceRadius=80'Distance from Center to Upper Edge of the Clock Face AspRatio=1.99'Ratio of Face Width to Height FaceThick=7 'Basic Width of Outer Ring of Face TicRadius=0.8*FaceThick'Radius of Hour Clock Tic Marks End Sub SmallOval: CenterX=159:CenterY=157'Center Position of the Clock Face FaceRadius=40'Distance from Center to Upper Edge of the Clock Face AspRatio=2.99'Ratio of Face Width to Height FaceThick=3 'Basic Width of Outer Ring of Face TicRadius=0.8*FaceThick'Radius of Hour Clock Tic Marks End Sub LargeVerticalOval: CenterX=159:CenterY=157'Center Position of the Clock Face FaceRadius=80'Distance from Center to Upper Edge of the Clock Face AspRatio=0.50'Ratio of Face Width to Height FaceThick=3 'Basic Width of Outer Ring of Face TicRadius=0.8*FaceThick'Radius of Hour Clock Tic Marks End Sub TinyCircular: CenterX=60:CenterY=100'Center Position of the Clock Face FaceRadius=25'Distance from Center to Upper Edge of the Clock Face AspRatio=1.00'Ratio of Face Width to Height FaceThick=2 'Basic Width of Outer Ring of Face TicRadius=0.8*FaceThick'Radius of Hour Clock Tic Marks End Sub |
||||
isochronic Guru ![]() Joined: 21/01/2012 Location: AustraliaPosts: 689 |
redrok - anyone there ? No response .. |
||||
redrok![]() Senior Member ![]() Joined: 15/09/2014 Location: United StatesPosts: 209 |
Hi cronic;Where am I supposed to be? Didn't my clock code work for you? It runs on a very minimalist 28 pin uMITE. Of course it needs an Lcd Panel. Doesn't really need a RTC, nor Temp Sensor to work. redrok |
||||
![]() |
![]() |
The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |