Introduction: ANOLOUGE DIGITAL -B-I-N-A-R-Y- CLOCK ALL IN ONE!?!?

About: Hey YOU! Yeah, I'm talking to you who is reading this. Send me ideas for instructables, like things that you are wondering how to make or build, or really anything electronically related, and I'll get back to …

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 )

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

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!

Clocks Challenge

Participated in the
Clocks Challenge

4th Epilog Challenge

Participated in the
4th Epilog Challenge