Introduction: ANOLOUGE DIGITAL -B-I-N-A-R-Y- CLOCK ALL IN ONE!?!?
That is right! Have you ever wanted an all-in-one Binary, Digital, Analouge Clock? Well this is what you get when you let a 13 year old program! I have this clock down and the programming works! This clock is something that you will want, the reason being is that no need to go and have 3 2 clocks next to each-other to see time in three two different ways! Or if you can't read lets say binary or analouge clocks then you can read the digital one! Like I said it is all-in-one! I have it so that you can have the simplest clock possible to build! no need for gear ratios and all that! It actually is very cool how I did it and it incorporates modern technology of a touch screen and a COLOR LCD. Due to time constraint I was unable to complete my Binary Clock added to the other clocks. I so happened to make the binary version, but It seemed that i could not configure the devise correctly to get it to work. Stay tuned for updates!
Step 1: Presenting!
THE ALL NEW TOUCH SCREEN CLOCK!
Step 2: TOOLS & SUPPLIES & SOFTWARE
SUPPLIES
First you will need uLCD 32-PT (GFX)
which you can find here ( uLCD 32-PT (GFX) )
Next you will need a programmer, µUSB-CE5
which you can find here ( µUSB-CE5 )
Lastly you will need some external memory for storing the pictures, a 2 Gb µSD card
which you can find here ( 2 Gb µSD card ) (reason why you need this one is because it needs the correct format on the card to function)
TOOLS
computer
SOFTWARE
4D Workshop3 IDE
which you can find here ( 4D Workshop 3 IDE )
First you will need uLCD 32-PT (GFX)
which you can find here ( uLCD 32-PT (GFX) )
Next you will need a programmer, µUSB-CE5
which you can find here ( µUSB-CE5 )
Lastly you will need some external memory for storing the pictures, a 2 Gb µSD card
which you can find here ( 2 Gb µSD card ) (reason why you need this one is because it needs the correct format on the card to function)
TOOLS
computer
SOFTWARE
4D Workshop3 IDE
which you can find here ( 4D Workshop 3 IDE )
Step 3: Getting Drivers to Work
Most of the time your computer fails to find a driver for the programmer, so this is where you have to go and download a driver from so that it will function. click here Now to download the driver go to the left of the screen and find "Latest Firmware" now click the computer you have. For other computers that windows you will need to select the "Drivers for other Platforms" button so that you can select you computer type! Install the drivers for the programmer and soon it will be a COM port. After it is a COM port open up 4D Workshop 3. Here comes the best part!
Step 4: Programming
Due to time constraint I was unable to complete my Binary Clock added to the other clocks. I will finish the project and post the Binary clock on here later.
Here is the program
#platform "uLCD-32PT_GFX2"
#inherit "4DGL_16bitColours.fnc"
#inherit "FONT4.fnt"
#constant FALSE, TRUE // FALSE=0, TRUE=1
#STACK 100
// image labels for what we use in GFX2DEMO.GCI (image control indexes)
#constant SEG7 0
#constant KEYPAD 1
#constant EXITBTN 4
#constant ADDBTN 8
#constant CHECKBTN 15
#constant CLOCKBTN 27
// clock registers
#constant SECONDS 0
#constant MINUTES 1
#constant HOURS 2
#constant DS1307 0xD0
#constant WR 1
var seconds, minutes, hours;
#constant SEG7_BG_COLOUR 0x0841 // 7 seg display background colour
var iHndl; // image control handle
var mx, my; // mouse/touch position
var edstate; // clock edit state, 1=HH, 2=MM, 3=SS
var hFile;
#constant FACECOLOUR RED
#constant SECONDSCOLOUR WHITE
#constant MINUTESCOLOUR YELLOW
#constant HOURSCOLOUR BLUE
// global variables
var seconds2, minutes2, hours2;
var targetX, targetY;
var screenwidth, screenheight;
var xc, yc, r;
var n, x, y, k, colr, t, kj:=1;
var kkl := 1;
var exit2 := 0;
var firstx, firsty, x2, y2, state2;
var set_timeButtonX, set_timeButtonY;
// map of key values for keypad
#DATA
byte keys 7,8,9,4,5,6,1,2,3,0,0,0
#END
// max time register value for edit check
#DATA
byte maxval 0x59,0x59,0x23
#END
// translate edit pos to required register
#DATA
word xlat HOURS,MINUTES,SECONDS
#END
func DrawHand(var length, var angle, var colour)
gfx_MoveTo(xc, yc); // MUST RE_ESTABLISH THE CENTRE POINT!!!
gfx_Set(OBJECT_COLOUR, colour);
gfx_Orbit(angle -90, length);
// gfx_LineRel(targetX, targetY); // WRONG! Picaso legacy had a broken gfx_LineRel which worked ok here,
gfx_LineTo(targetX, targetY); // but it should be gfx_LineTo, this is now correct
endfunc
func Keypad(var state)
var private charpos;
var temp,r,n,x,y,k,x1,y1,xoffs,yoffs,oldshadow;
var private keyval;
//if(!Clock.edit)
if(!edstate)
charpos := 2;
oldshadow := gfx_Set(BEVEL_SHADOW,1);
img_Darken(iHndl, KEYPAD);
img_SetAttributes(iHndl, KEYPAD, I_TOUCH_DISABLE); // disable keypad touch
img_SetWord(iHndl, KEYPAD, IMAGE_INDEX, 10); // set 10th frame, button up (non pressed) state
gfx_Set(BEVEL_SHADOW,oldshadow);
else
img_ClearAttributes(iHndl, KEYPAD, I_TOUCH_DISABLE); // enable keypad touch
keyval := 10; // initially, assume no key pressed, select last frame
if(state == TOUCH_PRESSED)
// calc which button is pressed
//x1 := 4+img_GetWord(iHndl, KEYPAD, IMAGE_XPOS);
//y1 := 4+img_GetWord(iHndl, KEYPAD, IMAGE_YPOS);
//xoffs := (img_GetWord(iHndl, KEYPAD, IMAGE_WIDTH)-8)/3;
//yoffs := (img_GetWord(iHndl, KEYPAD, IMAGE_HEIGHT)-8)/4;
x1 := 44;
y1 := 89;
xoffs := 16; // we know where the keypad is, just use fixed values to save codespace
yoffs := 16;
for(y := y1; y < y1 + yoffs * 4;y += yoffs) // now find touch co-ord
for(x := x1; x < x1 + xoffs * 3; x += xoffs)
n++;
if(mx > x && mx < x + xoffs && my > y && my < y + yoffs) k := n;
next
if(k) break;
next
if(k) // if we got a valid key
keyval := keys[k - 1]; // get the key val
r := xlat[edstate - 1]; // point to correct register
temp := Clock.time[r]; // shift and add new digit
temp := ((temp << 4) & 0xF0) + keyval;
Clock.time[r] := temp;
Clock.edit &= ~(charpos << ((edstate-1) << 1)); // modify the underscore
charpos := 1;
Clock(); // update 7seg display
endif
endif
img_SetWord(iHndl, KEYPAD, IMAGE_INDEX, keyval); // set required frame, if 10th frame, its the button up (non pressed) state
endif
img_Show(iHndl, KEYPAD);
endfunc
// show time normally if edit==0, else show required underscore.
// each bit in var edit coresponds to an underline displayed, bit5 is
// digit 1 downto bit 0 = digit 6
func Clock()
//pause(1000);
var private edit; // editing mode, bits 5:0 selects uderscores for digits 6:1
var private time[3]; // time in BCD format, coresponds to clock registers SECONDS,MINUTES,HOURS
var k, n, xpos, regptr;
#constant X 22 // x position for time
#constant Y 32 // y position for time
#constant W 22 // digit width
img_Enable(iHndl, SEG7); // enable the 7seg display while we display it
xpos := X; // set starting x
regptr := HOURS; // start at hours
while(n < 6)
img_SetPosition(iHndl, SEG7, xpos, Y); // set position for digit
if((edit>>n)&1) // if editing digit,
k := 11; // select underscore character
else
k := time[regptr]; // else get required time register
if(!(n & 1)) k := k >> 4; // get HI nibble if HI digit
endif
img_SetWord(iHndl, SEG7, IMAGE_INDEX, k&15); // select required digit
img_Show(iHndl, SEG7); // show the image
xpos += W;
n++;
if(n == 2 || n == 4) // when required,
regptr--; // decrement register pointer
xpos += 4;
gfx_RectangleFilled(xpos, Y + 10,xpos + 4, Y + 14,ORANGE); // place colon
gfx_RectangleFilled(xpos, Y + 20,xpos + 4, Y + 24,ORANGE);
xpos += 10;
endif
wend
img_Disable(iHndl, SEG7); // we're done displaying, disable the 7seg display
endfunc
// check that the calue that was just edited is ok
// prompt with a short error message if out of range,
// setting the edit field back to same pos for another try.
// returns zero if failed
func checkRegisters()
var reg, retval:=TRUE;
if(edstate)
reg := xlat[edstate-1];
if(Clock.time[reg] > maxval[reg]) // check for sensible value
gfx_MoveTo(90,3);
txt_FGcolour(RED); // if not, throw the message
putstr("ERROR\r");
pause(500);
putstr(" ");
edstate--; // and backup so we stay in current edit field
retval := FALSE;
endif
endif
return retval;
endfunc
func main()
var n, c, colr:=GRAY;
var state;
var exit;
var retry := 10;
while(retry-- && !file_Mount()); // mount the drive
if (!retry)
putstr("Mount Failed!");
pause(2000);
return; // exit if can't mount
endif
iHndl := file_LoadImageControl("GFX2DEMO.DAT", "GFX2DEMO.GCI", 1); // build the image control using required mode, returning a pointer to the structure allocation
if (!iHndl)
pause(2000);
return; // exit if can't load image control
endif
// I2C_Open(I2C_SLOW); // 100khz
//I2C_Open(I2C_MED); // 400khz
//I2C_Open(I2C_FAST); // 1mhz NB DS1307 may not run at 1mhz!!!
pause(10);
// n:=readbyte(SECONDS) & 0x7F; // ensure CH bit is clear else clock wont run
// writebyte(SECONDS, n);
pause(1000);
gfx_Cls();
img_Disable(iHndl, ALL); // first up, disable all the images
// now enable what we need
img_Enable(iHndl, KEYPAD); // we want the keypad
img_Enable(iHndl, ADDBTN);
img_Enable(iHndl, EXITBTN); // we want the exit button
img_Enable(iHndl, CLOCKBTN); // we want the time button
//gfx_Origin(30,15);
gfx_Panel(PANEL_RAISED,0, 0, 200, 17, DARKBLUE); // title bar
gfx_Panel(PANEL_RAISED,0, 18, 200, 150,GRAY); // main window panel
img_SetPosition(iHndl, EXITBTN, 184, 2); // place the exit button
gfx_MoveTo(8,3);
txt_Opacity(OPAQUE);
txt_BGcolour(DARKBLUE);
txt_FGcolour(CYAN);
putstr("Set Time"); // place the title
// 7 seg display panel
gfx_Panel(PANEL_SUNKEN,15, 24, 170, 50, GRAY);
gfx_Panel(PANEL_RAISED,19, 28, 162, 42, SEG7_BG_COLOUR);
img_SetPosition(iHndl, KEYPAD, 40, 85); // place the keypad
img_SetPosition(iHndl, CLOCKBTN, 140, 90); // place the time button
img_SetPosition(iHndl, CHECKBTN, 138, 130); // place the exit button (hidden until editing)
img_SetPosition(iHndl, ADDBTN, 3, 100);
// gfx_Button(BUTTON_UP, 3, 100, SILVER, RED, FONT1, 1, 1, "Set" );
img_Show(iHndl, ALL); // update images
// gfx_Rectangle(140, 90, 163, 111, RED); // place RED rectangle around clock button (locked state)
Keypad(0);
touch_Set(TOUCH_ENABLE); // enable the touch screen
// Clock();
while(!exit) // stay in loop til quit button hit
if(Clock.edit == 0 && edstate == 0) // if we're not edition
c:=seconds; // if seconds has rolled over
if(c!=Clock.time[SECONDS])
Clock.time[SECONDS] := seconds; // read the clock chip
Clock.time[MINUTES] := minutes;
Clock.time[HOURS] := hours;
Clock();
endif
endif
state := touch_Get(TOUCH_STATUS); // we'll look for any touch activity
mx := touch_Get(TOUCH_GETX); // we'll also grab the x
my := touch_Get(TOUCH_GETY); // and the y coordinates of the touch
if(state == TOUCH_PRESSED) // if there's a press
n := img_Touched(iHndl, ALL); // see if any images were touched
if (n != -1)
if(n == KEYPAD) // if keypad was touched,
Keypad(state); // update keypad
else
img_Lighten(iHndl, n); // else just lighten when we touch
img_Show(iHndl, n);
endif
endif
gfx_Rectangle(140, 90, 163, 111, colr); // place rectangle round clock btn
endif
//if(state == TOUCH_MOVING) // if there's movement
//endif
if(state == TOUCH_RELEASED) // if there's a release;
if (n != -1)
if(n==EXITBTN) exit := 1; // exit if exit button hit
if(n==CHECKBTN) // if check button hit
if(checkRegisters()) // if last edit was ok
seconds := Clock.time[SECONDS]; // write seconds+hold
minutes := Clock.time[MINUTES]; // write minutes
hours := Clock.time[HOURS]; // write hours
seconds2 := Clock.time[SECONDS]; // write seconds+hold
minutes2 := Clock.time[MINUTES]; // write minutes
hours2 := Clock.time[HOURS]; // write hours
// n:=readbyte(SECONDS) & 0x7F; // release HOLD
// writebyte(SECONDS, n);
pause(100);
Clock.edit := 0; // not editing now, run mode
edstate := 0;
colr := RED;
img_Disable(iHndl, CHECKBTN); // disable check button
gfx_RectangleFilled(138, 130, 138+28, 130+28, GRAY); // erase the check button
Clock();
Keypad(0);
else
n := CLOCKBTN; // else error, redo current edit phase
endif
endif
if(n==ADDBTN)
if (kkl == 0)
main();
kkl := 1;
endif
if (kkl == 1)
kkl := 2;
endif
if (kkl == 2)
gfx_Cls();
iHndl := file_LoadImageControl("GFX2DEMO.DAT", "GFX2DEMO.GCI", 1);
if (!iHndl)
pause(2000);
return;
endif
img_Disable(iHndl, ALL);
// pause(10);
img_Enable(iHndl, ADDBTN);
img_SetPosition(iHndl, ADDBTN, 30, 10);
img_Show(iHndl, ADDBTN);
exit2 := 1;
seconds2 := Clock.time[SECONDS]; // write seconds+hold
minutes2 := Clock.time[MINUTES]; // write minutes
hours2 := Clock.time[HOURS]; // write hours
kj := 1;
endif
endif
if(n == CLOCKBTN)
img_Darken(iHndl, CLOCKBTN);
img_Show(iHndl, CLOCKBTN);
checkRegisters(); // check for legal values
if(++edstate == 4) edstate := 1; // cycle through the edit fields
Clock.edit := 3 << ((edstate-1) << 1); // set required bits high in edit register
Keypad.charpos := 2; // start edit at least significant digit
Clock.time[xlat[edstate-1]] := 0; // zero the holding register ready
img_Enable(iHndl, CHECKBTN); // enable check button
img_Show(iHndl, CHECKBTN); // display it
gfx_Rectangle(138, 130, 138+27, 130+27, GRAY); // rectangle to get rid of those annoying alignment dots
colr := LIME;
Clock();
Keypad(state);
endif
if(n == KEYPAD) // if keypad release
Keypad(state); // update state
endif
endif
gfx_Rectangle(140, 90, 163, 111, colr); // place rectangle round clock btn
n := -1;
endif
setup();
wend
//setupclock();
endfunc
func setup()
if (exit2 == 1 && kj == 1)
kj := 0;
txt_Set(TEXT_OPACITY, OPAQUE);
screenwidth := gfx_Get( X_MAX );
screenheight := gfx_Get( Y_MAX );
xc := screenwidth >> 1;
yc := screenheight >> 1;
r := MIN(screenwidth, screenheight) >> 1;
gfx_Set(PEN_SIZE, SOLID);
gfx_Circle( xc, yc, r-16, FACECOLOUR );
gfx_Set(PEN_SIZE, OUTLINE);
n := -8;
while (n++ < 8)
colr := GREEN;
gfx_Circle( xc, yc, r+n-8, colr );
wend
// set up the centre point
gfx_MoveTo(xc, yc);
// a target variable for the orbit command
gfx_OrbitInit(&targetX, &targetY);
// mark the hours round the clockface
gfx_Set(PEN_SIZE, SOLID);
gfx_MoveTo(xc, yc);
n := -90; // 12 o'clock position
while (n<270)
gfx_Orbit(n, r-6);
k := 3;
if (!(n % 90)) k := 5;
gfx_Circle(targetX, targetY, k, BLUE);
n := n + 30; // each 30 degreees
wend
// kkl := 0;
setupclock();
// touch();
else
setupclock();
endif
endfunc
func setupclock()
//seconds := 80;
//minutes := 89;
//hours := 18;
repeat
if (Clock.edit == 0 && edstate == 0)
pause(1000);
if (kkl == 1)
//print ("The Time is ", [DEC1Z] hours, ":", [DEC2Z] minutes, ":", [DEC2Z] seconds);
//seconds
if (seconds == 9)
seconds := seconds + 6;
endif // 25, 40, 55
if (seconds == 25)
seconds := seconds + 6;
endif
if (seconds == 41)
seconds := seconds + 6;
endif
if (seconds == 57)
seconds := seconds + 6;
endif
if (seconds == 73)
seconds := seconds + 6;
endif
// minutes
if (minutes == 9)
minutes := minutes + 7;
endif // 25, 40, 55
if (minutes == 25)
minutes := minutes + 7;
endif
if (minutes == 41)
minutes := minutes + 7;
endif
if (minutes == 57)
minutes := minutes + 7;
endif
if (minutes == 73)
minutes := minutes + 7;
endif
//hours
if (hours == 9)
hours := hours + 7;
endif
if (!(seconds := (++seconds % 90)))
if (!(minutes := (++minutes % 90)))
if (hours == 18)
hours := 0;
endif
hours := (++hours % 19);
endif
endif
// endif
Clock.time[SECONDS] := seconds; // read the clock chip
Clock.time[MINUTES] := minutes;
Clock.time[HOURS] := hours;
Clock();// update the time
return;
endif
if (kkl == 2 && exit2 == 1)
DrawHand(r-20, seconds2*6, FACECOLOUR); // undraw the second hand
DrawHand(r-35, minutes2*6+seconds2/10, FACECOLOUR); // undraw the minute hand
DrawHand(r-50, hours2*30+minutes2>>1, FACECOLOUR); // undraw the hour hand
gfx_Circle( xc, yc, 5, FACECOLOUR );
// calculate the new time
// Note that this was buggy,
if (!(seconds2 := (++seconds2 % 60)))
if (!(minutes2 := (++minutes2 % 60)))
hours2 := (++hours2 % 12);
endif
endif
//display_Vsync();
DrawHand(r-20, seconds2*6, SECONDSCOLOUR); // redraw the second hand
DrawHand(r-35, minutes2*6+seconds2/10, MINUTESCOLOUR); // redraw the minute hand
DrawHand(r-50, hours2*30+minutes2>>1, HOURSCOLOUR); // redraw the hour hand
gfx_Circle( xc, yc, 5, ORANGE );
return;
touch();
// return;
endif
else
return;
while(!Clock.edit == 0 && !edstate == 0)
pause(100);
wend
endif
forever
endfunc
func touch()
touch_Set(TOUCH_ENABLE); // enable the touch screen
// Clock();
repeat
var n, colr:=RED;
var state;
state := touch_Get(TOUCH_STATUS); // we'll look for any touch activity
mx := touch_Get(TOUCH_GETX); // we'll also grab the x
my := touch_Get(TOUCH_GETY); // and the y coordinates of the touch
if(state == TOUCH_PRESSED) // if there's a press
n := img_Touched(iHndl, ALL); // see if any images were touched
if(state == TOUCH_RELEASED) // if there's a release;
if (n != -1)
if(n==ADDBTN)
main();
kkl := 0;
exit2 := 0;
endif
endif
endif
endif
return;
forever
endfunc
Here is the program
#platform "uLCD-32PT_GFX2"
#inherit "4DGL_16bitColours.fnc"
#inherit "FONT4.fnt"
#constant FALSE, TRUE // FALSE=0, TRUE=1
#STACK 100
// image labels for what we use in GFX2DEMO.GCI (image control indexes)
#constant SEG7 0
#constant KEYPAD 1
#constant EXITBTN 4
#constant ADDBTN 8
#constant CHECKBTN 15
#constant CLOCKBTN 27
// clock registers
#constant SECONDS 0
#constant MINUTES 1
#constant HOURS 2
#constant DS1307 0xD0
#constant WR 1
var seconds, minutes, hours;
#constant SEG7_BG_COLOUR 0x0841 // 7 seg display background colour
var iHndl; // image control handle
var mx, my; // mouse/touch position
var edstate; // clock edit state, 1=HH, 2=MM, 3=SS
var hFile;
#constant FACECOLOUR RED
#constant SECONDSCOLOUR WHITE
#constant MINUTESCOLOUR YELLOW
#constant HOURSCOLOUR BLUE
// global variables
var seconds2, minutes2, hours2;
var targetX, targetY;
var screenwidth, screenheight;
var xc, yc, r;
var n, x, y, k, colr, t, kj:=1;
var kkl := 1;
var exit2 := 0;
var firstx, firsty, x2, y2, state2;
var set_timeButtonX, set_timeButtonY;
// map of key values for keypad
#DATA
byte keys 7,8,9,4,5,6,1,2,3,0,0,0
#END
// max time register value for edit check
#DATA
byte maxval 0x59,0x59,0x23
#END
// translate edit pos to required register
#DATA
word xlat HOURS,MINUTES,SECONDS
#END
func DrawHand(var length, var angle, var colour)
gfx_MoveTo(xc, yc); // MUST RE_ESTABLISH THE CENTRE POINT!!!
gfx_Set(OBJECT_COLOUR, colour);
gfx_Orbit(angle -90, length);
// gfx_LineRel(targetX, targetY); // WRONG! Picaso legacy had a broken gfx_LineRel which worked ok here,
gfx_LineTo(targetX, targetY); // but it should be gfx_LineTo, this is now correct
endfunc
func Keypad(var state)
var private charpos;
var temp,r,n,x,y,k,x1,y1,xoffs,yoffs,oldshadow;
var private keyval;
//if(!Clock.edit)
if(!edstate)
charpos := 2;
oldshadow := gfx_Set(BEVEL_SHADOW,1);
img_Darken(iHndl, KEYPAD);
img_SetAttributes(iHndl, KEYPAD, I_TOUCH_DISABLE); // disable keypad touch
img_SetWord(iHndl, KEYPAD, IMAGE_INDEX, 10); // set 10th frame, button up (non pressed) state
gfx_Set(BEVEL_SHADOW,oldshadow);
else
img_ClearAttributes(iHndl, KEYPAD, I_TOUCH_DISABLE); // enable keypad touch
keyval := 10; // initially, assume no key pressed, select last frame
if(state == TOUCH_PRESSED)
// calc which button is pressed
//x1 := 4+img_GetWord(iHndl, KEYPAD, IMAGE_XPOS);
//y1 := 4+img_GetWord(iHndl, KEYPAD, IMAGE_YPOS);
//xoffs := (img_GetWord(iHndl, KEYPAD, IMAGE_WIDTH)-8)/3;
//yoffs := (img_GetWord(iHndl, KEYPAD, IMAGE_HEIGHT)-8)/4;
x1 := 44;
y1 := 89;
xoffs := 16; // we know where the keypad is, just use fixed values to save codespace
yoffs := 16;
for(y := y1; y < y1 + yoffs * 4;y += yoffs) // now find touch co-ord
for(x := x1; x < x1 + xoffs * 3; x += xoffs)
n++;
if(mx > x && mx < x + xoffs && my > y && my < y + yoffs) k := n;
next
if(k) break;
next
if(k) // if we got a valid key
keyval := keys[k - 1]; // get the key val
r := xlat[edstate - 1]; // point to correct register
temp := Clock.time[r]; // shift and add new digit
temp := ((temp << 4) & 0xF0) + keyval;
Clock.time[r] := temp;
Clock.edit &= ~(charpos << ((edstate-1) << 1)); // modify the underscore
charpos := 1;
Clock(); // update 7seg display
endif
endif
img_SetWord(iHndl, KEYPAD, IMAGE_INDEX, keyval); // set required frame, if 10th frame, its the button up (non pressed) state
endif
img_Show(iHndl, KEYPAD);
endfunc
// show time normally if edit==0, else show required underscore.
// each bit in var edit coresponds to an underline displayed, bit5 is
// digit 1 downto bit 0 = digit 6
func Clock()
//pause(1000);
var private edit; // editing mode, bits 5:0 selects uderscores for digits 6:1
var private time[3]; // time in BCD format, coresponds to clock registers SECONDS,MINUTES,HOURS
var k, n, xpos, regptr;
#constant X 22 // x position for time
#constant Y 32 // y position for time
#constant W 22 // digit width
img_Enable(iHndl, SEG7); // enable the 7seg display while we display it
xpos := X; // set starting x
regptr := HOURS; // start at hours
while(n < 6)
img_SetPosition(iHndl, SEG7, xpos, Y); // set position for digit
if((edit>>n)&1) // if editing digit,
k := 11; // select underscore character
else
k := time[regptr]; // else get required time register
if(!(n & 1)) k := k >> 4; // get HI nibble if HI digit
endif
img_SetWord(iHndl, SEG7, IMAGE_INDEX, k&15); // select required digit
img_Show(iHndl, SEG7); // show the image
xpos += W;
n++;
if(n == 2 || n == 4) // when required,
regptr--; // decrement register pointer
xpos += 4;
gfx_RectangleFilled(xpos, Y + 10,xpos + 4, Y + 14,ORANGE); // place colon
gfx_RectangleFilled(xpos, Y + 20,xpos + 4, Y + 24,ORANGE);
xpos += 10;
endif
wend
img_Disable(iHndl, SEG7); // we're done displaying, disable the 7seg display
endfunc
// check that the calue that was just edited is ok
// prompt with a short error message if out of range,
// setting the edit field back to same pos for another try.
// returns zero if failed
func checkRegisters()
var reg, retval:=TRUE;
if(edstate)
reg := xlat[edstate-1];
if(Clock.time[reg] > maxval[reg]) // check for sensible value
gfx_MoveTo(90,3);
txt_FGcolour(RED); // if not, throw the message
putstr("ERROR\r");
pause(500);
putstr(" ");
edstate--; // and backup so we stay in current edit field
retval := FALSE;
endif
endif
return retval;
endfunc
func main()
var n, c, colr:=GRAY;
var state;
var exit;
var retry := 10;
while(retry-- && !file_Mount()); // mount the drive
if (!retry)
putstr("Mount Failed!");
pause(2000);
return; // exit if can't mount
endif
iHndl := file_LoadImageControl("GFX2DEMO.DAT", "GFX2DEMO.GCI", 1); // build the image control using required mode, returning a pointer to the structure allocation
if (!iHndl)
pause(2000);
return; // exit if can't load image control
endif
// I2C_Open(I2C_SLOW); // 100khz
//I2C_Open(I2C_MED); // 400khz
//I2C_Open(I2C_FAST); // 1mhz NB DS1307 may not run at 1mhz!!!
pause(10);
// n:=readbyte(SECONDS) & 0x7F; // ensure CH bit is clear else clock wont run
// writebyte(SECONDS, n);
pause(1000);
gfx_Cls();
img_Disable(iHndl, ALL); // first up, disable all the images
// now enable what we need
img_Enable(iHndl, KEYPAD); // we want the keypad
img_Enable(iHndl, ADDBTN);
img_Enable(iHndl, EXITBTN); // we want the exit button
img_Enable(iHndl, CLOCKBTN); // we want the time button
//gfx_Origin(30,15);
gfx_Panel(PANEL_RAISED,0, 0, 200, 17, DARKBLUE); // title bar
gfx_Panel(PANEL_RAISED,0, 18, 200, 150,GRAY); // main window panel
img_SetPosition(iHndl, EXITBTN, 184, 2); // place the exit button
gfx_MoveTo(8,3);
txt_Opacity(OPAQUE);
txt_BGcolour(DARKBLUE);
txt_FGcolour(CYAN);
putstr("Set Time"); // place the title
// 7 seg display panel
gfx_Panel(PANEL_SUNKEN,15, 24, 170, 50, GRAY);
gfx_Panel(PANEL_RAISED,19, 28, 162, 42, SEG7_BG_COLOUR);
img_SetPosition(iHndl, KEYPAD, 40, 85); // place the keypad
img_SetPosition(iHndl, CLOCKBTN, 140, 90); // place the time button
img_SetPosition(iHndl, CHECKBTN, 138, 130); // place the exit button (hidden until editing)
img_SetPosition(iHndl, ADDBTN, 3, 100);
// gfx_Button(BUTTON_UP, 3, 100, SILVER, RED, FONT1, 1, 1, "Set" );
img_Show(iHndl, ALL); // update images
// gfx_Rectangle(140, 90, 163, 111, RED); // place RED rectangle around clock button (locked state)
Keypad(0);
touch_Set(TOUCH_ENABLE); // enable the touch screen
// Clock();
while(!exit) // stay in loop til quit button hit
if(Clock.edit == 0 && edstate == 0) // if we're not edition
c:=seconds; // if seconds has rolled over
if(c!=Clock.time[SECONDS])
Clock.time[SECONDS] := seconds; // read the clock chip
Clock.time[MINUTES] := minutes;
Clock.time[HOURS] := hours;
Clock();
endif
endif
state := touch_Get(TOUCH_STATUS); // we'll look for any touch activity
mx := touch_Get(TOUCH_GETX); // we'll also grab the x
my := touch_Get(TOUCH_GETY); // and the y coordinates of the touch
if(state == TOUCH_PRESSED) // if there's a press
n := img_Touched(iHndl, ALL); // see if any images were touched
if (n != -1)
if(n == KEYPAD) // if keypad was touched,
Keypad(state); // update keypad
else
img_Lighten(iHndl, n); // else just lighten when we touch
img_Show(iHndl, n);
endif
endif
gfx_Rectangle(140, 90, 163, 111, colr); // place rectangle round clock btn
endif
//if(state == TOUCH_MOVING) // if there's movement
//endif
if(state == TOUCH_RELEASED) // if there's a release;
if (n != -1)
if(n==EXITBTN) exit := 1; // exit if exit button hit
if(n==CHECKBTN) // if check button hit
if(checkRegisters()) // if last edit was ok
seconds := Clock.time[SECONDS]; // write seconds+hold
minutes := Clock.time[MINUTES]; // write minutes
hours := Clock.time[HOURS]; // write hours
seconds2 := Clock.time[SECONDS]; // write seconds+hold
minutes2 := Clock.time[MINUTES]; // write minutes
hours2 := Clock.time[HOURS]; // write hours
// n:=readbyte(SECONDS) & 0x7F; // release HOLD
// writebyte(SECONDS, n);
pause(100);
Clock.edit := 0; // not editing now, run mode
edstate := 0;
colr := RED;
img_Disable(iHndl, CHECKBTN); // disable check button
gfx_RectangleFilled(138, 130, 138+28, 130+28, GRAY); // erase the check button
Clock();
Keypad(0);
else
n := CLOCKBTN; // else error, redo current edit phase
endif
endif
if(n==ADDBTN)
if (kkl == 0)
main();
kkl := 1;
endif
if (kkl == 1)
kkl := 2;
endif
if (kkl == 2)
gfx_Cls();
iHndl := file_LoadImageControl("GFX2DEMO.DAT", "GFX2DEMO.GCI", 1);
if (!iHndl)
pause(2000);
return;
endif
img_Disable(iHndl, ALL);
// pause(10);
img_Enable(iHndl, ADDBTN);
img_SetPosition(iHndl, ADDBTN, 30, 10);
img_Show(iHndl, ADDBTN);
exit2 := 1;
seconds2 := Clock.time[SECONDS]; // write seconds+hold
minutes2 := Clock.time[MINUTES]; // write minutes
hours2 := Clock.time[HOURS]; // write hours
kj := 1;
endif
endif
if(n == CLOCKBTN)
img_Darken(iHndl, CLOCKBTN);
img_Show(iHndl, CLOCKBTN);
checkRegisters(); // check for legal values
if(++edstate == 4) edstate := 1; // cycle through the edit fields
Clock.edit := 3 << ((edstate-1) << 1); // set required bits high in edit register
Keypad.charpos := 2; // start edit at least significant digit
Clock.time[xlat[edstate-1]] := 0; // zero the holding register ready
img_Enable(iHndl, CHECKBTN); // enable check button
img_Show(iHndl, CHECKBTN); // display it
gfx_Rectangle(138, 130, 138+27, 130+27, GRAY); // rectangle to get rid of those annoying alignment dots
colr := LIME;
Clock();
Keypad(state);
endif
if(n == KEYPAD) // if keypad release
Keypad(state); // update state
endif
endif
gfx_Rectangle(140, 90, 163, 111, colr); // place rectangle round clock btn
n := -1;
endif
setup();
wend
//setupclock();
endfunc
func setup()
if (exit2 == 1 && kj == 1)
kj := 0;
txt_Set(TEXT_OPACITY, OPAQUE);
screenwidth := gfx_Get( X_MAX );
screenheight := gfx_Get( Y_MAX );
xc := screenwidth >> 1;
yc := screenheight >> 1;
r := MIN(screenwidth, screenheight) >> 1;
gfx_Set(PEN_SIZE, SOLID);
gfx_Circle( xc, yc, r-16, FACECOLOUR );
gfx_Set(PEN_SIZE, OUTLINE);
n := -8;
while (n++ < 8)
colr := GREEN;
gfx_Circle( xc, yc, r+n-8, colr );
wend
// set up the centre point
gfx_MoveTo(xc, yc);
// a target variable for the orbit command
gfx_OrbitInit(&targetX, &targetY);
// mark the hours round the clockface
gfx_Set(PEN_SIZE, SOLID);
gfx_MoveTo(xc, yc);
n := -90; // 12 o'clock position
while (n<270)
gfx_Orbit(n, r-6);
k := 3;
if (!(n % 90)) k := 5;
gfx_Circle(targetX, targetY, k, BLUE);
n := n + 30; // each 30 degreees
wend
// kkl := 0;
setupclock();
// touch();
else
setupclock();
endif
endfunc
func setupclock()
//seconds := 80;
//minutes := 89;
//hours := 18;
repeat
if (Clock.edit == 0 && edstate == 0)
pause(1000);
if (kkl == 1)
//print ("The Time is ", [DEC1Z] hours, ":", [DEC2Z] minutes, ":", [DEC2Z] seconds);
//seconds
if (seconds == 9)
seconds := seconds + 6;
endif // 25, 40, 55
if (seconds == 25)
seconds := seconds + 6;
endif
if (seconds == 41)
seconds := seconds + 6;
endif
if (seconds == 57)
seconds := seconds + 6;
endif
if (seconds == 73)
seconds := seconds + 6;
endif
// minutes
if (minutes == 9)
minutes := minutes + 7;
endif // 25, 40, 55
if (minutes == 25)
minutes := minutes + 7;
endif
if (minutes == 41)
minutes := minutes + 7;
endif
if (minutes == 57)
minutes := minutes + 7;
endif
if (minutes == 73)
minutes := minutes + 7;
endif
//hours
if (hours == 9)
hours := hours + 7;
endif
if (!(seconds := (++seconds % 90)))
if (!(minutes := (++minutes % 90)))
if (hours == 18)
hours := 0;
endif
hours := (++hours % 19);
endif
endif
// endif
Clock.time[SECONDS] := seconds; // read the clock chip
Clock.time[MINUTES] := minutes;
Clock.time[HOURS] := hours;
Clock();// update the time
return;
endif
if (kkl == 2 && exit2 == 1)
DrawHand(r-20, seconds2*6, FACECOLOUR); // undraw the second hand
DrawHand(r-35, minutes2*6+seconds2/10, FACECOLOUR); // undraw the minute hand
DrawHand(r-50, hours2*30+minutes2>>1, FACECOLOUR); // undraw the hour hand
gfx_Circle( xc, yc, 5, FACECOLOUR );
// calculate the new time
// Note that this was buggy,
if (!(seconds2 := (++seconds2 % 60)))
if (!(minutes2 := (++minutes2 % 60)))
hours2 := (++hours2 % 12);
endif
endif
//display_Vsync();
DrawHand(r-20, seconds2*6, SECONDSCOLOUR); // redraw the second hand
DrawHand(r-35, minutes2*6+seconds2/10, MINUTESCOLOUR); // redraw the minute hand
DrawHand(r-50, hours2*30+minutes2>>1, HOURSCOLOUR); // redraw the hour hand
gfx_Circle( xc, yc, 5, ORANGE );
return;
touch();
// return;
endif
else
return;
while(!Clock.edit == 0 && !edstate == 0)
pause(100);
wend
endif
forever
endfunc
func touch()
touch_Set(TOUCH_ENABLE); // enable the touch screen
// Clock();
repeat
var n, colr:=RED;
var state;
state := touch_Get(TOUCH_STATUS); // we'll look for any touch activity
mx := touch_Get(TOUCH_GETX); // we'll also grab the x
my := touch_Get(TOUCH_GETY); // and the y coordinates of the touch
if(state == TOUCH_PRESSED) // if there's a press
n := img_Touched(iHndl, ALL); // see if any images were touched
if(state == TOUCH_RELEASED) // if there's a release;
if (n != -1)
if(n==ADDBTN)
main();
kkl := 0;
exit2 := 0;
endif
endif
endif
endif
return;
forever
endfunc
Step 5: USD Card
Now you will need to upload ALL of the given sample files from your computer, to the uSD Card so that your touch screen can read the files needed.
Step 6: DONE!
YAY! NOW YOU HAVE A NEW TYPE OF CLOCK YOU MADE!