NerdKits - electronics education for a digital generation

You are not logged in. [log in]

NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.

Project Help and Ideas » Alarm Clock

August 11, 2010
by mikey
mikey's Avatar

I want to make a alarm clock 3 function with snooze,alarm,time. but i dont know where to start with the programming and ect.

August 11, 2010
by Rick_S
Rick_S's Avatar

Mikey,

No disrespect intended, but this is a learn as you build type of environment. I'll point you at some locations here that would directly relate to whay you are wanting to do. Then, you need to try to build and program. Once you've gotten there, you'll have much more specific questions and code to post to ask direct questions to.

There are dozens of ways to build a clock... for instance one could use the LCD to display time, one could add 7 segment LED displays for displaying the time, one could make a binary clock... the possibilities are all there.

The NK guys have 21 different tutorials on the tutorial page, several with code and circuit descriptions.

The 1st step if you haven't already done it would be to READ the entire NK guide and do all the projects in it. While they may seem like they don't mean much, they help teach the basics of programming a micro-controller in 'C' and how to connect various components to the micro-controller.

2nd, I'd look at the tutorial page for anything that might have anything to do with the project you want to do.

For instance:

  1. An obvious 1st place would be the Crystal Real Time Clock to get an Idea of how to tell time with the micro.
  2. Then I would look for a tutorial that makes sound like maybe Making Music with a Microcontroller.
  3. Then, your clock will need buttons for setting and alarm fuctions, maybe look at the way the push button is used in Making Music or how the postition of the DIP switches are detected in Digital Arithmetic with DIP Switches

Then, I'd search the forum --- there is a wealth of information here and believe me, clocks are common projects. Then, I'd search the web, for instance, Sparkfun Electronics sells a Digital Clock Kit that performs all the functions you want based around the same micro-controller in your nerdkit.

I hope this gives you some ideas of how to research, and find what you are looking for in projects you want to build. Just remember, there are a bunch of helpful people here that can answer most any question you may have. However, we don't want to do your project for you. Develop your project, and as you have questions along the way, ask with specificity. We'll do our best to help.

Hope I didn't scare you away, :D

Rick

August 11, 2010
by mikey
mikey's Avatar

Thanks :D

-mikey

August 25, 2010
by Solorbob
Solorbob's Avatar

mikey, I'm working on a POV binary watch project. It currently keeps track of time, has 2 POV modes (both set to just a default message), and allows the user to set the hours and minutes. I could send over my code if you would like to take a look at it. I started out by finding some or someone sending me over some code for their binary clock. I've added in the additional modes and POV settings and code.

I'm toying with the idea of trying to add in the temp sensor too for just that little bit more of nerdyness that would push it over the top.

let me know if you would be interested in seeing my code.

August 30, 2010
by mikey
mikey's Avatar

ya i would be intested

August 31, 2010
by Solorbob
Solorbob's Avatar

I didn't have your email addr, so I posted the code below. Maybe someone else would like it too.

// BinaryClock.c
// Shawn Jones 
// dagroundzero "@" gmail dot com
// 06/10/2010
//
// for use with NerdKits with ATmega168
// base time method - mrobbins@mit.edu
//
// based on the  Binary Clock code by mcai8sh4 on.17/05/2009
// Changes made include adding multiple modes, mode led
// 
//
// When the program starts the time is set to 1:00.
//
#define F_CPU 14745600
// *Includes
#include <stdio.h>
#include <stdlib.h>

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <inttypes.h>

#include "../libnerdkits/delay.h"
#include "../libnerdkits/lcd.h"
#include "../libnerdkits/uart.h"

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// *PIN DEFINITIONS
// std base setup
//
// hours displayed via PB1..PB4
// hour 1 place  PB1 - pin 15
// hour 2 place  PB2 - pin 16
// hour 4 place  PB3 - pin 17
// hour 8 place  PB4 - pin 18
//
// Mode LED      PB5 - Pin 19
//
// minutes displayed via PC0..PC5
// minute 1 place PC0 - pin 23
// minute 2 place PC1 - pin 24
// minute 4 place PC2 - pin 25
// minute 8 place PC3 - pin 26
// minute 16 place PC4 - pin 27
// minute 32 place PC5 - pin 28
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Led annode (+ve longer leg) to pin, cathode 
// (-ve shorter leg with cut away in plastic) to GND
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Push buttons: PD0 and PD1.
// Switch A (ENTER) s1 PD0 -> GND - pin 2
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// switch B (MODE) s2 PD1 -> GND - pin 3
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// END of PIN DEFINITIONS
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

void realtimeclock_setup()
{
   // setup Timer0:
    // CTC (Clear Timer on Compare Match mode)
    // TOP set by OCR0A register
    TCCR0A |= (1<<WGM01);
    // clocked from CLK/1024
    // which is 14745600/1024, or 14400 increments per second
    TCCR0B |= (1<<CS02) | (1<<CS00);
    // set TOP to 143
    // because it counts 0, 1, 2, ... 142, 143, 0, 1, 2 ...
    // so 0 through 143 equals 144 events
    OCR0A = 143;
    // enable interrupt on compare event
    // (14400 / 144 = 100 per second)
    TIMSK0 |= (1<<OCIE0A);
}

// *Explanation comments
// the_time will store the elapsed time
// in hundredths of a second.
// (100 = 1 second)
// 
// note that this will overflow in approximately 248 days!
//
// This variable is marked "volatile" because it is modified
// by an interrupt handler.  Without the "volatile" marking,
// the compiler might just assume that it doesn't change in 
// the flow of any given function (if the compiler doesn't
// see any code in that function modifying it -- sounds 
// reasonable, normally!).
//
// But with "volatile", it will always read it from memory 
// instead of making that assumption.

volatile int32_t the_time;

typedef struct
{
    // structure for keeping time data
    int seconds;
    int minutes;
    int hours;
}time;

// set variable to store the time (t) and switch status (s1) (s2)
time t, display_t;
uint8_t s1, s2, modeCounter, modeFlashLED,i,show_binary_time;

SIGNAL(SIG_OUTPUT_COMPARE0A)
{
    // Update the_time
    // when Timer0 gets to its Output Compare value,
    // one one-hundredth of a second has elapsed (0.01 seconds).
    the_time++;
}

void set_pins()
{
    //initialise output and switch pins
    // set PC0..5 to output for minutes
    DDRC |= 0x3F;
    // set PB1..4 to output for hours plus PB5 for Mode
    //DDRB |= 0x1E;  <-- Orgnial code for PB1..4.
    DDRB |= 0x3E;

    // set PD0 to input for button A
    DDRD &= ~(1<<PD0);
    // turn on internal pull-up resistor for PD0
    PORTD |= (1<<PD0);

    // set PD1 to input for button B (mode button)
    DDRD &= ~(1<<PD1);
    // turn on internal pull-up resistor for PD1
    PORTD |= (1<<PD1);

}

//This will flash the MODE LED to indicate the current mode.
void display_Mode(inModeCounter)
{

for (i = 0; i < inModeCounter; i++) 
   {
      // turn on LED
      PORTB |= (1<<PB5);

      //delay for XX milliseconds to let the light stay on
      delay_ms(200);

      // turn off LED
      PORTB &= ~(1<<PB5);

      //delay for XX milliseconds to let the light stay off
      delay_ms(200);

   }
}

//This function will diplay the time via POV
void display_pov_time()
{
   //Test message is "12:00"

  //Setup up 2 delay times.  Delay 1 will be used between columns of letters
  //while delay 2 will be the space between words.

  int delay1 = 12;
  int delay2 = 20;

  //turn off all the leds;
  PORTC = 0;
  PORTB = 0;
  int x;

    for (x=0;x<=50;x++)
    {
     //1
     PORTC = 0;
     delay_ms(delay1);
     PORTC = 31;
     delay_ms(delay1);
     PORTC = 0;
     delay_ms(delay1);

     PORTC = 0;
     delay_ms(delay2);

     //2
     PORTC = 23;
     delay_ms(delay1);
     PORTC = 21;
     delay_ms(delay1);
     PORTC = 29;
     delay_ms(delay1);

     PORTC = 0;
     delay_ms(delay2);

     //:
     PORTC = 0;
     delay_ms(delay1);
     PORTC = 10;
     delay_ms(delay1);
     PORTC = 0;
     delay_ms(delay1);

     PORTC = 0;
     delay_ms(delay2);

     //0
     PORTC = 31;
     delay_ms(delay1);
     PORTC = 17;
     delay_ms(delay1);
     PORTC = 31;
     delay_ms(delay1);

     PORTC = 0;
     delay_ms(delay2);

     //0
     PORTC = 31;
     delay_ms(delay1);
     PORTC = 17;
     delay_ms(delay1);
     PORTC = 31;
     delay_ms(delay1);

     PORTC = 0;
     delay_ms(delay2);  
     delay_ms(delay2);  
    }
}

//This function will diplay a msg via POV.
void display_pov_msg()
{
   //Test message is "Shawn"

  //Setup up 2 delay times.  Delay 1 will be used between columns of letters
  //while delay 2 will be the space between words.

  int delay1 = 12;
  int delay2 = 20;

  //turn off all the leds;
  PORTC = 0;
  PORTB = 0;
  int x;

    for (x=0;x<=50;x++)
    {
     //S
     //PORTC = 29;
     PORTC = 29;
     delay_ms(delay1);
     PORTC = 21;
     delay_ms(delay1);
     PORTC = 21;
     delay_ms(delay1);
     PORTC = 23;
     delay_ms(delay1);

     //PORTC = 0;
     PORTC = 0;
     delay_ms(delay2);
     //h
     //PORTC = 31;
     PORTC = 31;
     delay_ms(delay1);
     PORTC = 4;
     delay_ms(delay1);
     PORTC = 4;
     delay_ms(delay1);
     PORTC = 7;
     delay_ms(delay1);

     //PORTC = 0;
     PORTC = 0;
     delay_ms(delay2);

     //a
     //PORTC = 7;
     PORTC = 7;
     delay_ms(delay1);
     PORTC = 5;
     delay_ms(delay1);
     PORTC = 5;
     delay_ms(delay1);
     PORTC = 15;
     delay_ms(delay1);

     PORTC = 0;
     delay_ms(delay2);

     //w
     PORTC = 15;
     delay_ms(delay1);
     PORTC = 1;
     delay_ms(delay1);
     PORTC = 6;
     delay_ms(delay1);
     PORTC = 1;
     delay_ms(delay1);
     PORTC = 15;
     delay_ms(delay1);

     PORTC = 0;
     delay_ms(delay2);

     //n
     PORTC = 15;
     delay_ms(delay1);
     PORTC = 4;
     delay_ms(delay1);
     PORTC = 4;
     delay_ms(delay1);
     PORTC = 7;
     delay_ms(delay1);

     PORTC = 0;
     delay_ms(delay2);  
     delay_ms(delay2);
    }
}

/*********************************************/
//The Set delay min function will take the 
//current hour, min, and seconds and copy it
//to the display hour, display min, and display
//seconds vars.  You can add to which time
//section you want to create a delay time
//based on the current system time.
/*********************************************/
void set_delay_min()
{
   //Capture the time to turn off the display
   //Get current hour and set it to the display hour
   display_t.hours = t.hours;
   //Get current minute plus 1
  // display_t.minutes = (t.minutes + 1); //adds in 
   display_t.minutes = (t.minutes);

   //check to make sure we didn't go past 59 minutes, if so, set it to 0 minutes and add 1 
   //to the display hours.
   if (display_t.minutes > 59 )
   {
     display_t.hours++;
     display_t.minutes = 0;
   }

    //Get current seconds.
    display_t.seconds = t.seconds + 15;

}
/*********************************************/
/*********************************************/

void track_time()
{
    //keep track of seconds, minutes and hours
    //if (t.seconds > 1)  //<-- used for testing.  1 minute every 1 seconds.
    //if (t.seconds > 5)  //<-- used for testing.  1 minute every 5 seconds
    if (t.seconds > 59) //<-- Real value, but commented out for testing.
    {
       t.minutes++;
       // reset the_time to prevent overflowing and keep the minutes idea simple
       the_time = 0; 
       t.seconds = 0;
       if (t.minutes > 59)
        {
           t.hours++;
           t.minutes = 0;
           // since we're only playing on a 12hr clock, we can ignore 0
           if (t.hours > 12) t.hours = 1;
        }
    }
}

int main()
{
   // MAIN FUNCTION
   // init everything
   realtimeclock_setup();
   set_pins();
   sei(); // turn on interript handler
   t.seconds = 0; // initalise the time vars
   t.minutes = 0;
   t.hours = 1;

   //init the display_t struct.
   display_t.seconds = 0; 
   display_t.minutes = 0;
   display_t.hours = 0;

   //Set the mode counter variable to 1.
   modeCounter = 1;

   //Init the modeFlashLED variable to False.
   modeFlashLED =0;

   //Init the show_binary_time variable
   show_binary_time = 0;

   while(1) 
      {
         // *main loop - runs forever
         //
         // use the switch to alter the state of pin PD0 and use 
         // this state (on or off) in the switch variable s1
         s1 = (PIND & (1<<PD0)) >> PD0; //switch sets this var to 1 or 0

         // use the switch to alter the state of pin PD1 and use 
         // this state (on or off) in the switch variable s2
         s2 = (PIND & (1<<PD1)) >> PD1; //switch sets this var to 1 or 0

         // simplify the seconds and store to 't'
         t.seconds = the_time / 100;

         // if the switch has been pressed and we are in mode 5 - set seconds to 60
         // to add to the minutes.

         //Check to see if button B (action button) has been pressed.
         if (s1 == 0) 
         {
           // Action button has been pressed.  Find out which mode we are in and do something.

           //Debounce button press
           delay_ms(10);

           switch(modeCounter)
           {
              //This will display the binary time for 1 minute.
              case 1:
                //Set the binaryTimeDisplay to true
                show_binary_time = 1;

                //Set the delay time.
                set_delay_min();

                /*
                //Capture the time to turn off the
                //Get current hour
                display_t.hours = t.hours;
                //Get current minute plus 1
                display_t.minutes = (t.minutes + 1);

                //check to make sure we didn't go past 59 minutes, if so, set it to 0 minutes and add 1 
                //to the display hours.
                if (display_t.minutes > 59 )
                {
                   display_t.hours++;
                   display_t.minutes = 0;
                }

                //Get current seconds.
                display_t.seconds = t.seconds;
                */
              break;

              case 2:
              //We don't want to show the binary time, so turn it off.
              show_binary_time = 0;

              //Do show the POV time
              display_pov_time ();
              break;

              //display POV message
              case 3:
              //We don't want to show the binary time, so turn it off.
              show_binary_time = 0;

              //Do show the POV message
              display_pov_msg();
              break;

              //Case 4 - Update hours
              case 4:

              t.seconds = 60;            
              t.minutes = 60;

              //Set the binaryTimeDisplay to true
              show_binary_time = 1;

              //Set the delay time.
              set_delay_min();        
              break;

              //Case 5 - Update minutes
              case 5:         
              //Add a minute.
              t.seconds = 60;

              //Set the binaryTimeDisplay to true
              show_binary_time = 1;

              //Set the delay time.
              set_delay_min();

              break;

            }

           //Delay to finish function
           delay_ms(160);
         }

         // Code to set the hours.
         if (s2 == 8)
         {
             // switch state
        // Addin in a 10 ms delay to debounce the button before doing anything else.
           delay_ms(10);
           t.seconds = 60;           
           t.minutes = 60;
           delay_ms(160);
         }

        //Check to see if the mode button was pressed.  If so, then add 1 to the mode counter.
        if (s2 == 0)
        {
          delay_ms(10);
          modeCounter++;

           if (modeCounter > 5)
           {    
               //Reset back to 1
               modeCounter = 1;

           }
           //Set the mode flash LED to true
           modeFlashLED = 1;
           delay_ms(160);
        }

        //if (s2 == 0)
        // {
        //    modeCounter++;
        // }

        //Check to see if we need to flash the modeLED
        if (modeFlashLED == 1)
        {
            display_Mode(modeCounter);
            modeFlashLED = 0;
        }

         // correct all other parts of the time structure to keep everything in order
         track_time();

        //check to see if we need to display the binary time.
        if (show_binary_time == 1)
        {
           //Show time.
           PORTC = t.minutes;
           PORTB = t.hours * 2; // *2 to bitshift to avoid PB0

           // **********************************************************************************
           //Code to turn off the leds to save the bat. in watch mode.  Comment out this
           //code for a desktop clock.

           unsigned long a = (t.hours * 3600) + (t.minutes * 60) + t.seconds;
           unsigned long b = (display_t.hours * 3600) + (display_t.minutes * 60) + display_t.seconds;

           // Check to see if the current time, a, is greater than the display time, b.  If so, turn off the leds
           // and reset the show binary time indicator.

           if (a > b)
           {

              // turn off the leds.
              PORTC = 0;
              PORTB = 0;

              //re-init the display_t struct.
              display_t.seconds = 0; 
              display_t.minutes = 0;
              display_t.hours = 0;

              //Reset the show time indicator
              show_binary_time = 0;

              //set the mode back to 1 just to make sure we are in the display mode if we just
              //finished setting the hours or minutes.
              modeCounter =1;
           }

           //End turn off of led for watch.. 
           // **********************************************************************************

        }   
     } // end of while(1)

     return 0;
}

Shawn

September 01, 2010
by Ralphxyz
Ralphxyz's Avatar

Is there a schematic for this alarm clock?

I would like to see just how it is wired up, Probable I can figure it out from the pin usage.

Shawn, thank you for posting your code.

It really is so much nicer when people post their working code instead of just saying they were working on some project and then never finalizing the thought.

Ralph

September 01, 2010
by Solorbob
Solorbob's Avatar

Ralph - I agree it does help having running code to aid in the learning process.

The time works great on my watch as well as setting the hours and minutes.The POV modes show up via digital photos, but I still need to adjust the timing so it can be seen by the naked eye, then change it from the default time. I'm going to wait until I have a watch prototype built to do this. It is just too much of a pain in the butt to swing around my proto board to get it to show up.

Mikey - I started out by trying to identify what and how I wanted this watch to operate. I did just what Ralph said on looking at other projects to see which parts I could learn from and add to my code. I found that really knowing what you are trying to achieve will help the development process move along.

Post a Reply

Please log in to post a reply.

Did you know that SPDT stands for "Single Pole, Double Throw"? Learn more...