Go Down

Topic: DS3234 Alarms (Read 8 times) previous topic - next topic

MobileWill

#30
Jun 21, 2011, 04:12 am Last Edit: Jun 21, 2011, 04:20 am by MobileWill Reason: 1
So far that is working!!! I would buy you a beer or something if this wasn't online. I can't believe its working.
Current Projects:                    Arduinos:
Security Robot Tank               Uno
Security Robot II 4WD            Mega2560

http://mobilewill.blogspot.com

Jack Christensen

#31
Jun 21, 2011, 04:38 am Last Edit: Jun 21, 2011, 04:43 am by Jack Christensen Reason: 1

So far that is working!!! I would buy you a beer or something if this wasn't online. I can't believe its working.


You should know, I only drink in groups of one or more.

I was also going to suggest changing the rtcAlarm() function.  The SPI library might use interrupts.  If it does, I would avoid calling it from an ISR.  Likewise Serial.println().  Instead, have the ISR just set a flag variable.  Then have the main loop watch the variable, when it's set, it can reset the RTC flag, clear the flag variable, and print the message.

This is probably a good idea regardless, best not to have things like Serial.println() that can take a relatively long time, in an ISR.

Declare the flag variable in the main module as a global variable, similar to:
Code: [Select]
volatile boolean intFlag = false;

volatile tells the compiler not to save the variable in a register, this can cause issues when an interrupt is triggered.

Then the ISR becomes simply:
Code: [Select]
void rtcAlarm(){
 intFlag = true;
}


And somewhere in the loop() function (but note that the delay() in loop() will have to go; since the interrupt is now effectively handled in loop(), we want to process it promptly.  Use millis() instead to achieve the desired delay):
Code: [Select]
if (intFlag) {
 intFlag = false;
 Serial.println("Alarm 2");
 digitalWrite(RTC_CS, LOW);
 SPI.transfer(0x8F);
 SPI.transfer(0x0);
 digitalWrite(RTC_CS, HIGH);
}

MCP79411/12 RTC ... "One Million Ohms" ATtiny kit ... available at http://www.tindie.com/stores/JChristensen/

MobileWill

In my robot version of the code I started the flag thing but kept the clear RTC flag in the ISR. Thanks for advice, going to work on cleaning it up now.
Current Projects:                    Arduinos:
Security Robot Tank               Uno
Security Robot II 4WD            Mega2560

http://mobilewill.blogspot.com

MobileWill

I am also thinking I should have a function to read/write SPI. That would reduce the code.
Current Projects:                    Arduinos:
Security Robot Tank               Uno
Security Robot II 4WD            Mega2560

http://mobilewill.blogspot.com

Jack Christensen

You work on that, I'll work on finding that beer.  I think there's one here somewhere ...  ;)
MCP79411/12 RTC ... "One Million Ohms" ATtiny kit ... available at http://www.tindie.com/stores/JChristensen/

MobileWill

#35
Jun 21, 2011, 04:58 am Last Edit: Jun 21, 2011, 05:08 am by MobileWill Reason: 1
So weird, as soon as I move the RTC reset alarm flag to the main loop, it freezes when it does that. But it works fine in the interrupt loop.

Granted I haven't tried it with the stand alone Arduino. So weird though.


So at least the code in ISR is less, just clears RTC flag and set MCU flag.
Current Projects:                    Arduinos:
Security Robot Tank               Uno
Security Robot II 4WD            Mega2560

http://mobilewill.blogspot.com

MobileWill

OMG I figured out the reading part, my fault.

Code: [Select]

digitalWrite(RTC_CS, LOW);
     SPI.transfer(0x0e);
     in_byte = SPI.transfer(0);
     Serial.println(in_byte,BIN);
digitalWrite(RTC_CS, HIGH);


I didn't realize that it was the same as writing. I was trying to read with only one line.


That was probably messing it up. Well I guess I know all about SPI now!
Current Projects:                    Arduinos:
Security Robot Tank               Uno
Security Robot II 4WD            Mega2560

http://mobilewill.blogspot.com

Jack Christensen


OMG I figured out the reading part, my fault.
I didn't realize that it was the same as writing. I was trying to read with only one line.
That was probably messing it up. Well I guess I know all about SPI now!


Guess I missed that when looking at the code.  Correct, SPI basically just interchanges data between the master and slave.  At the end of the transfer, the byte that was in the master's register is in the slave's, and vice versa.  Good picture here: http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus#Data_transmission
MCP79411/12 RTC ... "One Million Ohms" ATtiny kit ... available at http://www.tindie.com/stores/JChristensen/

fireman_sam6986

Wow comprehensive discussion :-)

I've got the same clock and was trying to enable an alarm every hour. However, would I be right in thinking that for this situation I need to set the time/date registers to a suitable time, then use the flag bits to achieve the ' Alarm when minutes match' setting?

I guess during setup I could read the current time and set the alarm a hour ahead. After this point it will go off every hour.
Am I right in my thinking or would it be possible to configure an alarm to alert every hour regardless of the time like in the ' Alarm once per minute (00 seconds of every minute' option your were discussing?

Ideally I would like an alarm every 30min however its not on the list of support timers. I guess I could achieve this by setting the alarm time 30min in the future each time the Arduino wakes up, but that seems kind of messy.

Any ideas?

Thanks
Sam

Jack Christensen

I think you've got it. The alarm registers have mask bits which are used to indicate which part(s) of the time take part in the compare. See table 2 in the datasheet. So an alarm every second, minute, hour, day or date is easy to set up. What can't be done with the built-in alarm registers is an increment like every 30 minutes, or every 4 days, etc.

But that wouldn't be complicated or messy. If I wanted every 30 minutes, the alarm could be set for every minute, then the sketch could check whether it had been 30 minutes (or alternately if it was the correct minute to raise an alarm), and if not, go back to sleep. 29 times out of 30, nothing would happen. This would happen quickly enough that battery life would be unaffected if sleep mode is being employed.
MCP79411/12 RTC ... "One Million Ohms" ATtiny kit ... available at http://www.tindie.com/stores/JChristensen/

fireman_sam6986

I didn't think of that. Are you thinking the Arduino wakes up and simply counts the number of wakes until it reaches 30? Or reading the RTC?

Also, is the Sq. Wave output the same as pulling the interrupt on the Arduino LOW? I've left the freq at the default 8.12kHZ



Jack Christensen


I didn't think of that. Are you thinking the Arduino wakes up and simply counts the number of wakes until it reaches 30? Or reading the RTC?


Either would work, depending on requirements. If for example, it's important to do something at 12 minutes and 42 minutes after the hour, then I might read the RTC. Else could just count number of wakes.

Quote

Also, is the Sq. Wave output the same as pulling the interrupt on the Arduino LOW? I've left the freq at the default 8.12kHZ


Yes. Definition of a square wave, it goes high for half the period, then low. So an 8192 Hz square wave could be used to interrupt the MCU 8192 times per second. Sounds like a lot, but I've done a little more than that without ill effect. Keep the ISR short and fast. Still, that'd seem like overkill for something that needs doing every 30 minutes! XD
MCP79411/12 RTC ... "One Million Ohms" ATtiny kit ... available at http://www.tindie.com/stores/JChristensen/

fireman_sam6986

#42
Feb 15, 2012, 11:06 am Last Edit: Feb 15, 2012, 11:15 am by fireman_sam6986 Reason: 1
Thanks again, its all working fine. Gotta love that every question is already answered :)
Though I thought the alarms might work while the device is running on battery however the datasheet says that read/write access to the registers is blocked while Vcc is lower than VBat

racheney

Hi Jack, SPI.transfer question.
When reading, Data=SPI.transfer(value)
value usually is 0 or 0×00
but I have seen data=SPI.transfer(-1)
Is this dropping bit(7) of a MSB request?
Can I use -6 to get only bit(1) and bit(0)?
Thanks racheney

Go Up