Go Down

Topic: Cuckoo Clock Project (Read 17 times) previous topic - next topic

hankster

My Cuckoo Clock Project uses an Arduino Uno, DS1307 RTC, 16x2 LCD and a couple of RC servo's.  Everything has been breadboarded and all the parts are working individually.  The LCD is functioning with Date and Time being displayed properly, the 2 servos that I'm using for the bird motion and operation of the twin bellows are performing as they should.  But now I'm stuck trying to understand the most important part and that is how to program for an hourly event ( the Cuckoo and Sound ).  I thought this part would be easy, and all I would need to do is read the current minute and second and when they were both zero start the servo routine using the hour value.  But I'm having a problem finding a suitable example of this type of event to learn from.  Any suggestions where I might look?  For a 79 year old this project has been a lot of fun so far, and only wish I would have started learning C about 30 years ago.

Nick Gammon

I would start with the RTC library, look at how it gets the time (from some examples). Once you have the time, the rest surely follows.
http://www.gammon.com.au/electronics

lloyddean

Hopefully this gives you an idea!

Code: [Select]

const unsigned long ONE_SECOND  = 16UL;
const unsigned long ONE_MINUTE  = 60 * ONE_SECOND;
const unsigned long ONE_HOUR    = 60 * ONE_MINUTE;

unsigned long msTarget;

unsigned long hms2millisecs(uint8_t const hours, uint8_t const minutes, uint8_t const seconds)
{
    return ((hours * ONE_HOUR) + (minutes * ONE_MINUTE) + (seconds * ONE_SECOND));
}

void millisecs2hms(unsigned long milliseconds, uint8_t* hours, uint8_t* minutes, uint8_t* seconds)
{
    uint8_t h = milliseconds / ONE_HOUR;        milliseconds -= h * ONE_HOUR;       *hours      = h;
    uint8_t m = milliseconds / ONE_MINUTE;      milliseconds -= m * ONE_MINUTE;     *minutes    = m;
    uint8_t s = milliseconds / ONE_SECOND;      milliseconds -= s * ONE_SECOND;     *seconds    = s;
}

void loop()
{
    uint8_t     hours;
    uint8_t     minutes;
    uint8_t     seconds;
    long        remaining = msTarget - millis();
    millisecs2hms(remaining, &hours, &minutes, &seconds);

    Serial.print((short)hours);
    Serial.print(":");
    Serial.print((short)minutes);
    Serial.print(":");
    Serial.println((short)seconds);

    if ( remaining <= 0 )
    {
        // we've reached zero time
        while (true)
        {    }
    }
}

void setup()
{
    Serial.begin(9600);
   
    msTarget = millis() + hms2millisecs(1, 50, 54); // hours, minutes, seconds
}


Nick Gammon

http://www.gammon.com.au/electronics

lloyddean

"DS1307 RTC" yes I see but just because he has doesn't mean it needs to be used.

Nick Gammon

If I had the chip to hand, and I wanted the cuckoo to come out on the hour, personally I would be using it. :P
http://www.gammon.com.au/electronics

lloyddean

School projects every dollar counts and not every student has that extra dollar, of course if the accuracy is an absolute must I'd probably agree with you.

Nick Gammon

Absolutely. But read this:


For a 79 year old this project has been a lot of fun so far, and only wish I would have started learning C about 30 years ago.
http://www.gammon.com.au/electronics

Quick5pnt0

Off the top of my head couldn't you just compare the current hour to the last hour and if it has changed then move the bird? Something like this:

Code: [Select]

if(hour > lastHour){
//move bird
lastHour = hour
}

UKHeliBob

The TimeAlarms library makes using repeating events very simple
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

dannable

I don't think I understand the question. If the OP can read the RTC and display the time on the LCD then he already has hours, minutes and seconds?
Beginners guide to using the Seeedstudio SIM900 GPRS/GSM Shield

hankster

I found an example for what I was looking for in a sketch written for a Radio Shack LED Grandfather Clock project that I found referenced while browsing through the Arduino Forum.

https://github.com/vinmarshall/Radio-Shack-LED-Grandfather-Clock

They were using the same DS1307RTC.h library as I was so I tried this -   if (minute(time) == 0) { Serial.println("On the hour"); }    I ran my sketch and watched the serial monitor as it came to the hour and the message was seen each time.  So I'm half way there.  Now I'm trying to understand the process I need to write a routine that using the hour value will move my servo "x" number of repititions.  In MS Basic I learned to use subroutines, what do you use in "C" ?  I was really good at writing spaghetti code which I'm trying to avoid here.

wildbill

In C a subroutine is called a function. Loop and setup are functions. Lloyddean's example above has a number of examples, e.g. millisecs2hms.

Nick Gammon

Code: [Select]

if (minute (time) == 0)
  {
  Serial.println ("On the hour");
  }


Yes but that will print "on the hour" all that first minute.

Better would be:

Code: [Select]

if (hour (time) != previousHour)
  {
  Serial.println ("On the hour");
  previousHour = hour (time);
  }


That only does it once.
http://www.gammon.com.au/electronics

dannable

And then incorporate a for loop:

for i=1 to hour
  move servo one way
  move servo back again
next i
Beginners guide to using the Seeedstudio SIM900 GPRS/GSM Shield

Go Up