Pages: [1]   Go Down
Author Topic: Using interrupts to adjust time on the DS1302  (Read 2062 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 13
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello everyone,

I ordered this Real Time Clock-module from DX a while ago, and I hooked it up yesterday.
I used the example code on the arduino's "Interfacing with hardware" page (the one with the three wire interface), and it worked.

But I can't figure out how to use buttons to adjust the time in the module. I tried to use this:

Code:
pinMode(2, INPUT);
attachInterrupt(0, addHour, FALLING);

...


void addHour(){
    ds1302_struct rtc;
    rtc.h24.Hour++;

    DS1302_clock_burst_write( (uint8_t *) &rtc);

}



but it didn't work.
Does anyone know how this is done?

Thnx in advance smiley-wink

With kind regards,

Azzi
Logged

Switzerland
Offline Offline
Faraday Member
**
Karma: 108
Posts: 5144
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The only module I found (http://dx.com/p/ds1302-real-time-clock-module-with-battery-cr2032-126453) doesn't have buttons. So I guess you have to describe what wiring you have. And post the complete code not excerpts, excerpts doesn't help in most cases.
Logged

Offline Offline
Edison Member
*
Karma: 9
Posts: 1018
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You can add link in your post, just copy the url.
Are you using my code from the Playground section : http://playground.arduino.cc/Main/DS1302 ?
That is very basic code. You have to write you own code to fill the structure or you own code to change only the hours.

For example the hour is split into two parts. Let's say the hour is 10. This is split into '1' and '0' and written to the DS1302.
To use a single variable for the hour, some extra programming is needed.

That sketch is only the basic interface to the DS1302 according to the datasheet. It doesn't contain a normal way to write and read the date and time. Sorry, but I have not added that yet.

Did you take a look at the other code ?
http://playground.arduino.cc//Main/InterfacingWithHardware#time

For the Arduino, the DS1307 is used mostly.


Logged

UK
Offline Offline
Shannon Member
****
Karma: 223
Posts: 12631
-
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm not familiar with that RTC or the example code relating to it, but from general principles I would have thought it was more sensible to do debouncing, edge detection and clock updates in the main code rather than within an interrupt; that avoids any issues relating to reentrancy, conflicting access to the hardware, and use of code that blocks or involves interrupts from within an interrupt handler. There are plenty of examples showing how to detect and handle switch inputs.
Logged

I only provide help via the forum - please do not contact me for private consultancy.

Offline Offline
Newbie
*
Karma: 0
Posts: 13
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You can add link in your post, just copy the url.
Are you using my code from the Playground section : http://playground.arduino.cc/Main/DS1302 ?
That is very basic code. You have to write you own code to fill the structure or you own code to change only the hours.

For example the hour is split into two parts. Let's say the hour is 10. This is split into '1' and '0' and written to the DS1302.
To use a single variable for the hour, some extra programming is needed.

That sketch is only the basic interface to the DS1302 according to the datasheet. It doesn't contain a normal way to write and read the date and time. Sorry, but I have not added that yet.

Did you take a look at the other code ?
http://playground.arduino.cc//Main/InterfacingWithHardware#time

For the Arduino, the DS1307 is used mostly.




Hey,

Yes, I allready found your libraries but couldn't figure out how to use them (I'm a noob programmer you see :p)

Do you have any project where you use it in? (Because I don't think you used it in your i2cLCD project, right?)

Anyways, nice work on both the library and the example code!

@ Pylon: I tried to hookup one a seperate connector to it.
And I used this code: http://playground.arduino.cc//Main/DS1302
Logged

Switzerland
Offline Offline
Faraday Member
**
Karma: 108
Posts: 5144
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote

Where in that code do you find an attachInterrupt() statement? You're not using that code, you're using a modified version. Post your code if you wanna get help.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 13
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

That's why I copy pasted those pieces of code in the original post.

I thought it would be better to post only the relevant parts.

Anyways, here's the full code:
http://pastebin.com/usgC3MqH
Logged

Switzerland
Offline Offline
Faraday Member
**
Karma: 108
Posts: 5144
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Why do you always set the time to 00:00:00 in your setup? Have your read the comments in your code?

Your hour setter should probably look like this:

Code:
// global variables
volatile byte increaseHour = 0;
uint32_t lastMillis = 0;

void uurErbij() {
  // do only the absolutely necessary things in the interrupt handler
  increaseHour = 1;
}

// replace your loop with this
void loop()
{
  ds1302_struct rtc;
  char buffer[80];     // the code uses 70 characters.
 
  if (millis() - lastMillis > 5000) {
    lastMillis = millis();
    // Read all clock data at once (burst mode).
    DS1302_clock_burst_read( (uint8_t *) &rtc);
 
    sprintf(buffer, "Time = %02d:%02d:%02d, ", \
      (rtc.h24.Hour10 * 10) + rtc.h24.Hour, \
      (rtc.Minutes10 * 10) + rtc.Minutes, \
      (rtc.Seconds10 * 10) + rtc.Seconds);
    Serial.print(buffer);
 
    sprintf(buffer, "Date(day of month) = %d, Month = %d, " \
      "Day(day of week) = %d, Year = %d", \
      (rtc.Date10 * 10) + rtc.Date, \
      (rtc.Month10 * 10) + rtc.Month, \
      rtc.Day, \
      2000 + (rtc.Year10 * 10) + rtc.Year);
    Serial.println(buffer);
  }
  if (increaseHour) {
    DS1302_clock_burst_read( (uint8_t *) &rtc);
    rtc.Hour++;
    DS1302_clock_burst_write( (uint8_t *) &rtc);
    increaseHour = 0;
  }
}

This assumes that the debouncing of your button is done in hardware.

I wouldn't use an interrupt to monitor a simple button. With the new loop() version you may find out yourself how you can implement a button monitoring without using interrupts.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 13
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I read all the comments, but I didn't understand what they all meant exactly since I am a newb programmer.

Also, I tried rtc.Hour++ before, but this doesn't work. It gives the error "struct ds1302_struct has no member named rtc.Hour"
Logged

Switzerland
Offline Offline
Faraday Member
**
Karma: 108
Posts: 5144
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Sorry, overlooked that, the line should read:

Code:
    rtc.h24.Hour++;
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 13
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks! I got it to work after a lot of trial and error!

But it acts pretty strange, it cycles to 15 hours, and after that, it goes back to 0 hours? =/
(It should be set to 24h mode)

http://pastebin.com/bMQ9sC5r

any ideas?
Logged

Switzerland
Offline Offline
Faraday Member
**
Karma: 108
Posts: 5144
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Yes, that's because of the pseudo-decimal format the RTC uses.

Use this instead of the hour increase:

Code:
rtc.h24.Hour++;
if (rtc.h24.Hour > 9) {
  rtc.h24.Hour10++;
  rtc.h24.Hour = 0;
}
if (rtc.h24.Hour10 * 10 + rtc.h24.Hour >= 24) {
  rtc.h24.Hour10 = 0;
  rtc.h24.Hour = 0;
}
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 13
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Mhmmm, makes sense, but now it goes to 19 and then goes back to 00.00?
Logged

Pages: [1]   Go Up
Jump to: