Go Down

Topic: Understanding bits translations (Read 438 times) previous topic - next topic

KirAsh4

Jan 14, 2013, 10:19 am Last Edit: Jan 14, 2013, 10:27 am by KirAsh4 Reason: 1
This is specific to a DS3231 RTC.  I'm using a library that sets the alarm in the following syntax:
Code: [Select]
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));
// 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 | ((AlarmBits & 0b00000100)<<5);
// A1 hour is figured out, send it
Wire.write(temp_buffer);
// Figure out A1 day/date and A1M4
temp_buffer = ((AlarmBits & 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();
}


Where I'm stuck is how to set the proper AlarmBits.  The examples that come with the library always passes '0x0' to that, which translates to "Alarm when date, hours, minutes, and seconds match" if A1Dy is FALSE, or "Alarm when day, hours, minutes, and seconds match" if A1Dy is TRUE, according to the datasheet.

I need to change that to "Alarm when hours, minutes, and seconds match".  Reading the datasheet, there's this specific table for those bits:


Here's my problem, well two of them:
First, it shows DY/DT as either X, 0, or 1.  That's A1Dy in the library code.  How do I not set either TRUE nor FALSE to that so I can use one of the other options for alarms.
Second, how do I translate what the table is giving me into what I need to pass to the AlarmBits variable?  Specifically, the one I need has bits set at 1,0,0,0 (or 1,0,0 for the second alarm.)

AWOL

X means "don't care", meaning the value of that particular bit in the shown combination is irrelevant.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

KirAsh4

Got it, so it doesn't matter what it's set at as soon as I can figure out how to set the AlarmBits to something other than 0x0 ... based on the table.  Thanks AWOL.

Also, reached 1,000 posts with this one. :)

KirAsh4

Bump ... still trying to figure out how to pass the proper bits to the AlarmBits variable based on the table provided.  Right now, the library simply passes 0x0 to it.  I need to pass the equivalent of bits 1,0,0,0 for Alarm 1, and 1,0,0 for Alarm 2.

GoForSmoke

Google on C bit fields, you can define the RAM to give specific bits and bit-groups names.

Nick Gammon on multitasking Arduinos:
1) http://gammon.com.au/blink
2) http://gammon.com.au/serial
3) http://gammon.com.au/interrupts

KirAsh4

Hrm yes.  I somewhat understand that.  But I still don't know what I should be passing to AlarmBits ...  I see it getting passed within the library code and what not ...

KirAsh4

Figured it out!  Thanks for the hint!

The solution is to pass those bits in as hex values, so
Code: [Select]
once a second                  1111  = 0x0f
when secs match                1110  = 0x0e
when mins + secs match         1100  = 0x0c
when hrs + mins + secs match   1000  = 0x08

AWOL

Quote
The solution is to pass those bits in as hex values, so

Or as binary values,
0b1111  etc
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

KirAsh4

I suppose that would work too AWOL.  I just stuck to the same format that the library was using.  Though looking at it in binary format makes more sense since it actually matches exactly what the table shows and one doesn't have to convert it to HEX values.

AWOL

Or, if you've got a lot of these operations, give the individual bits names, and use OR operations to combine them.
Easier to read and therefore to maintain.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Go Up