Colorado
Offline
Edison Member
Karma: 45
Posts: 1386
Reviving dead brain cells with Arduinos.
|
 |
« on: January 15, 2013, 03:15:39 am » |
I'm wondering if anyone is using this library that Eric Ayars released quite some time ago. I modified it so it would compile under v1.0.x of the IDE. Everything I've tried to do with this library so far worked without a problem, from setting the clock, setting simple alarms, reading the clock, etc., etc. Till now. I've run into what seems to be a bug but I can't verify that it is a bug or not, or if the example file provided with the library has a problem. Basically, when setting the alarms, the syntax for Alarm 1 is: Clock.setA1Time(DoW, Hour, Minute+1, Second, 0x0, true, false, false); ... and the syntax for Alarm 2 is similar except it doesn't have a "Second" variable to pass. Alarm 2 doesn't support that. The issue here is that whatever I put in for the AlarmBits part (in the above example it's the 0x0) for Alarm 2, it seems to get overwritten by whatever the bits are for Alarm 1. In the _set example file, I changed the setA1Time() syntax to have 0b1000 as AlarmBits and setA2Time syntax to have 0b111. However when I read it back, both of them had 0b1000 in them. I thought it was a fluke so I changed the bits only on Alarm 2 but nothing changed when I read the data back. Then I changed the bits on Alarm 1 and sure enough, reading the data back and both alarms have the same information, namely what I just changed Alarm 1 to. So at this point I don't know where the problem sits. For one, the AlarmBits for Alarm 2 should only be 0b000 to 0b111, so why do I see 0b0000 (four digits), I don't know. And second I don't understand why it's copying whatever the bits are for Alarm 1 into Alarm 2. I've attached the library here in the hopes that someone can look over it and figure out what may be the problem. The author doesn't seem to be responding or supporting it anymore. At least, his last posting was early last year and I haven't gotten a response from him from the messages I've sent.
|
|
|
|
|
Logged
|
|
|
|
|
Seattle, WA USA
Offline
Brattain Member
Karma: 334
Posts: 36433
Seattle, WA USA
|
 |
« Reply #1 on: January 15, 2013, 04:58:22 am » |
There is a problem with adding attachments to posts this week. Can you post a link to where you got the library?
|
|
|
|
|
Logged
|
|
|
|
|
Colorado
Offline
Edison Member
Karma: 45
Posts: 1386
Reviving dead brain cells with Arduinos.
|
 |
« Reply #2 on: January 15, 2013, 11:03:05 am » |
Of course. The original download came from Eric Ayars' website, located here http://hacks.ayars.org/2011/04/ds3231-real-time-clock.htmlKeep in mind that it was written pre 1.0x, so you have to make the necessary changes to the example files.
|
|
|
|
|
Logged
|
|
|
|
|
Seattle, WA USA
Offline
Brattain Member
Karma: 334
Posts: 36433
Seattle, WA USA
|
 |
« Reply #3 on: January 15, 2013, 11:34:08 am » |
The AlarmBits variable defines the bits for BOTH alarms. You need to use bitRead() and bitWrite() to diddle with the bits for each alarm individually. /* Retrieves everything you could want to know about alarm * one. * A1Dy true makes the alarm go on A1Day = Day of Week, * A1Dy false makes the alarm go on A1Day = Date of month. * * byte AlarmBits sets the behavior of the alarms: * Dy A1M4 A1M3 A1M2 A1M1 Rate * X 1 1 1 1 Once per second * X 1 1 1 0 Alarm when seconds match * X 1 1 0 0 Alarm when min, sec match * X 1 0 0 0 Alarm when hour, min, sec match * 0 0 0 0 0 Alarm when date, h, m, s match * 1 0 0 0 0 Alarm when DoW, h, m, s match * * Dy A2M4 A2M3 A2M2 Rate * X 1 1 1 Once per minute (at seconds = 00) * X 1 1 0 Alarm when minutes match * X 1 0 0 Alarm when hours and minutes match * 0 0 0 0 Alarm when date, hour, min match * 1 0 0 0 Alarm when DoW, hour, min match */
|
|
|
|
|
Logged
|
|
|
|
|
Colorado
Offline
Edison Member
Karma: 45
Posts: 1386
Reviving dead brain cells with Arduinos.
|
 |
« Reply #4 on: January 15, 2013, 11:55:55 am » |
It shouldn't be. At least, if I understand the code correctly, it's not. If I read the top of A1's setA1Time function, I see this: void DS3231::setA1Time(byte A1Day, byte A1Hour, byte A1Minute, byte A1Second, byte AlarmBits, bool A1Dy, bool A1h12, bool A1PM) { // Sets the alarm-1 date and time on the DS3231, using A1* information byte temp_buffer; Wire.beginTransmission(CLOCK_ADDRESS); Wire.write(0x07); // A1 starts at 07h // Send A1 second and A1M1 Wire.write(decToBcd(A1Second) | ((AlarmBits & 0b00000001) << 7)); // Send A1 Minute and A1M2 Wire.write(decToBcd(A1Minute) | ((AlarmBits & 0b00000010) << 6)); ... } And for A2: void DS3231::setA2Time(byte A2Day, byte A2Hour, byte A2Minute, byte AlarmBits, bool A2Dy, bool A2h12, bool A2PM) { // Sets the alarm-2 date and time on the DS3231, using A2* information byte temp_buffer; Wire.beginTransmission(CLOCK_ADDRESS); Wire.write(0x0b); // A1 starts at 0bh <-- this should read A2 starts at 0bh // Send A2 Minute and A2M2 Wire.write(decToBcd(A2Minute) | ((AlarmBits & 0b00010000) << 3)); ... } So it appears that they each use the AlarmBits passed to their respective function as opposed to copying from A1. So what am I missing? Where does it set both Alarmbits to the same thing? And even if, let's say A1 is already set to some previous value, and I only set A2, it completely ignores whatever I put in for AlarmBits. The time gets set properly, but AlarmBits does not. <note_to_self>Dude, it's time to learn C/C++ ... get a book.</note_to_self>
|
|
|
|
« Last Edit: January 15, 2013, 12:00:36 pm by KirAsh4 »
|
Logged
|
|
|
|
|
Seattle, WA USA
Offline
Brattain Member
Karma: 334
Posts: 36433
Seattle, WA USA
|
 |
« Reply #5 on: January 15, 2013, 12:26:35 pm » |
It seems easy enough to test. Create a variable. Set the bits for alarm 1. Set the bits for alarm 2. Call the setA1Time() method. Call the setA2Time() method. Call the getA1Time() method. Check the flags for both alarms. Call the getA2Time() method. Check the flags for both alarms.
|
|
|
|
|
Logged
|
|
|
|
|
Colorado
Offline
Edison Member
Karma: 45
Posts: 1386
Reviving dead brain cells with Arduinos.
|
 |
« Reply #6 on: January 15, 2013, 12:52:58 pm » |
That's exactly how I figured out that there's a problem. I created two different variables in my sketch, ARLM1 and ALRM2, with different bits in each (one had 0b1111 and the other 0b100) and passed those variables to setA1Time and setA2Time. Setting A2 never takes the AlarmBits into account. When I read things back, A2 reported its bits as 0b1111 (or whatever A1 is set as.)
|
|
|
|
|
Logged
|
|
|
|
|
Colorado
Offline
Edison Member
Karma: 45
Posts: 1386
Reviving dead brain cells with Arduinos.
|
 |
« Reply #7 on: January 15, 2013, 01:08:18 pm » |
The only other thing I can think of attempting is modifying the .cpp file to use two different variables, for example A1AlarmBits and A2Alarmbits as opposed to one single one. But I still can't figure out why it's not working right now, as written.
|
|
|
|
|
Logged
|
|
|
|
|
Colorado
Offline
Edison Member
Karma: 45
Posts: 1386
Reviving dead brain cells with Arduinos.
|
 |
« Reply #8 on: January 15, 2013, 04:18:06 pm » |
Anyone else feel like taking a stab at this before I start my attempt at hacking the library, hoping I know what I'm actually doing and figure out what's going on?
|
|
|
|
|
Logged
|
|
|
|
|
Colorado
Offline
Edison Member
Karma: 45
Posts: 1386
Reviving dead brain cells with Arduinos.
|
 |
« Reply #9 on: January 26, 2013, 11:35:40 pm » |
Ok, having changed the variables in the different routines to specifically say Alarm1Bits and Alarm2Bits did not make a difference. Now what I'm seeing is, when I try to read the data back, the bits for Alarm1 get set, but Alarm 2 remains at 0. Nothing's set. So, I'm still stuck. The relevant lines in my sketch that sets the alarms is: Clock.setA1Time(Clock.getDoW(), Clock.getHour(h12, PM), Clock.getMinute(), 30, ALRM1_SET, true, false, false); Clock.setA2Time(Clock.getDate(), Clock.getHour(h12, PM), Clock.getMinute(), ALRM2_SET, false, false, false); // Turn alarms on Clock.turnOnAlarm(1); Clock.turnOnAlarm(2); The variables ALRM1_SET and ALRM2_SET are 0b1000 and 0b111 respectively. Alarm1 is set properly. Alarm2 returns 0 when I read the bits back. The relevant part in the .cpp is: void DS3231::setA1Time(byte A1Day, byte A1Hour, byte A1Minute, byte A1Second, byte Alarm1Bits, bool A1Dy, bool A1h12, bool A1PM) { // Sets the alarm-1 date and time on the DS3231, using A1* information byte temp_buffer; Wire.beginTransmission(CLOCK_ADDRESS); Wire.write(0x07); // A1 starts at 07h // Send A1 second and A1M1 Wire.write(decToBcd(A1Second) | ((Alarm1Bits & 0b00000001) << 7)); // Send A1 Minute and A1M2 Wire.write(decToBcd(A1Minute) | ((Alarm1Bits & 0b00000010) << 6)); // Figure out A1 hour if (A1h12) { // Start by converting existing time to h12 if it was given in 24h. if (A1Hour > 12) { // well, then, this obviously isn't a h12 time, is it? A1Hour = A1Hour - 12; A1PM = true; } if (A1PM) { // Afternoon // Convert the hour to BCD and add appropriate flags. temp_buffer = decToBcd(A1Hour) | 0b01100000; } else { // Morning // Convert the hour to BCD and add appropriate flags. temp_buffer = decToBcd(A1Hour) | 0b01000000; } } else { // Now for 24h temp_buffer = decToBcd(A1Hour); } temp_buffer = temp_buffer | ((Alarm1Bits & 0b00000100)<<5); // A1 hour is figured out, send it Wire.write(temp_buffer); // Figure out A1 day/date and A1M4 temp_buffer = ((Alarm1Bits & 0b00001000)<<4) | decToBcd(A1Day); if (A1Dy) { // Set A1 Day/Date flag (Otherwise it's zero) temp_buffer = temp_buffer | 0b01000000; } Wire.write(temp_buffer); // All done! Wire.endTransmission(); }
void DS3231::setA2Time(byte A2Day, byte A2Hour, byte A2Minute, byte Alarm2Bits, bool A2Dy, bool A2h12, bool A2PM) { // Sets the alarm-2 date and time on the DS3231, using A2* information byte temp_buffer; Wire.beginTransmission(CLOCK_ADDRESS); Wire.write(0x0b); // A1 starts at 0bh // Send A2 Minute and A2M2 Wire.write(decToBcd(A2Minute) | ((Alarm2Bits & 0b00010000) << 3)); // Figure out A2 hour if (A2h12) { // Start by converting existing time to h12 if it was given in 24h. if (A2Hour > 12) { // well, then, this obviously isn't a h12 time, is it? A2Hour = A2Hour - 12; A2PM = true; } if (A2PM) { // Afternoon // Convert the hour to BCD and add appropriate flags. temp_buffer = decToBcd(A2Hour) | 0b01100000; } else { // Morning // Convert the hour to BCD and add appropriate flags. temp_buffer = decToBcd(A2Hour) | 0b01000000; } } else { // Now for 24h temp_buffer = decToBcd(A2Hour); } // add in A2M3 bit temp_buffer = temp_buffer | ((Alarm2Bits & 0b00100000)<<2); // A2 hour is figured out, send it Wire.write(temp_buffer); // Figure out A2 day/date and A2M4 temp_buffer = ((Alarm2Bits & 0b01000000)<<1) | decToBcd(A2Day); if (A2Dy) { // Set A2 Day/Date flag (Otherwise it's zero) temp_buffer = temp_buffer | 0b01000000; } Wire.write(temp_buffer); // All done! Wire.endTransmission(); } Ideas anyone? I really need to get this second alarm working for my project.
|
|
|
|
|
Logged
|
|
|
|
|
Temple, Texas
Offline
Sr. Member
Karma: 14
Posts: 354
|
 |
« Reply #10 on: January 27, 2013, 09:20:20 am » |
What happens if you try to use only the alarm2? something like setA2Time(...) getA2Time(...)
Do the AlarmBits still come back as 0?
Also are the other values coming back ok? (day, hour, min, ...)
John
|
|
|
|
« Last Edit: January 27, 2013, 09:31:54 am by johncc »
|
Logged
|
|
|
|
|
Colorado
Offline
Edison Member
Karma: 45
Posts: 1386
Reviving dead brain cells with Arduinos.
|
 |
« Reply #11 on: January 27, 2013, 06:03:35 pm » |
What happens if you try to use only the alarm2? something like setA2Time(...) getA2Time(...)
Do the AlarmBits still come back as 0? Yep. Also are the other values coming back ok? (day, hour, min, ...)
Those are fine. It correctly sets the time of the alarm. It just doesn't seem to set the alarm bits which determines when that alarm goes off.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
God Member
Karma: 15
Posts: 962
|
 |
« Reply #12 on: January 27, 2013, 06:37:18 pm » |
In the library, the Alarmbits hold the values for BOTH alarms and are ordered like this: 0 A2.2 A2.1 A2.0 A1.3 A1.2 A1.1 A1.0
So if you want to set alarm 1 to zero and alarm 2 to 111 you would set Alarmbits to 0B01110000
Pete
|
|
|
|
|
Logged
|
|
|
|
|
Colorado
Offline
Edison Member
Karma: 45
Posts: 1386
Reviving dead brain cells with Arduinos.
|
 |
« Reply #13 on: January 27, 2013, 06:39:41 pm » |
Ok, now we're getting somewhere. I was under the impression I only needed to pass the bits relevant to each alarm, as opposed to everything together. So this appears to be working now. I need to rewrite my sketch now to account for that.
Thanks!
|
|
|
|
« Last Edit: January 27, 2013, 06:47:53 pm by KirAsh4 »
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 1
|
 |
« Reply #14 on: April 06, 2013, 08:13:20 am » |
The AlarmBits are sent to the DS3231 correctly, but there is a bug in reading back. The problem is that AlarmBits in getA1Time and getA2Time were not initialized to 0x00. AlarmBits is ORd with the correct bit each time, but any random bits will remain. Fix as follows: Change DS3231.cpp line 275 (first time AlarmBits is used in getA1Time) from AlarmBits = AlarmBits | (temp_buffer & 0b10000000)>>7; to AlarmBits = (temp_buffer & 0b10000000)>>7;
Similarly, also fix the bug in getA2Time, line 318 AlarmBits = AlarmBits | (temp_buffer & 0b10000000)>>3; to AlarmBits = (temp_buffer & 0b10000000)>>3;
Then it works 100%. pvz
|
|
|
|
|
Logged
|
|
|
|
|
|