Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 04:40 02 Jul 2025 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : That Old Analog Clock...revisited

Author Message
crackerjack

Senior Member

Joined: 11/07/2011
Location: Australia
Posts: 164
Posted: 12:42pm 21 Oct 2011
Copy link to clipboard 
Print this post

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 Kingdom
Posts: 153
Posted: 08:13pm 21 Oct 2011
Copy link to clipboard 
Print this post

Thanks, I can use that.

Greg
 
Greg Fordyce
Senior Member

Joined: 16/09/2011
Location: United Kingdom
Posts: 153
Posted: 12:07pm 22 Oct 2011
Copy link to clipboard 
Print this post

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: Australia
Posts: 164
Posted: 12:24pm 22 Oct 2011
Copy link to clipboard 
Print this post

Thanks for the feedback Greg. Hope the code is useful to you.

Cheers.
 
crackerjack

Senior Member

Joined: 11/07/2011
Location: Australia
Posts: 164
Posted: 12:37pm 30 Oct 2011
Copy link to clipboard 
Print this post

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: Australia
Posts: 235
Posted: 02:18am 04 Nov 2011
Copy link to clipboard 
Print this post

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 Kingdom
Posts: 1702
Posted: 09:38am 07 Apr 2016
Copy link to clipboard 
Print this post

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 Kingdom
Posts: 10180
Posted: 11:49am 07 Apr 2016
Copy link to clipboard 
Print this post

  Quote  is it possible to run (or get it working) on a Micromite+ 64 pin?


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 States
Posts: 209
Posted: 07:20am 20 Apr 2016
Copy link to clipboard 
Print this post

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: Australia
Posts: 689
Posted: 10:26am 20 Apr 2016
Copy link to clipboard 
Print this post

redrok - anyone there ? No response ..
 
redrok

Senior Member

Joined: 15/09/2014
Location: United States
Posts: 209
Posted: 01:14pm 20 Apr 2016
Copy link to clipboard 
Print this post

Hi cronic;
  chronic said   redrok - anyone there ? No response ..
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
 
Print this page


To reply to this topic, you need to log in.

The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2025