I decided recently to bypass the DS3231 library and communicate directly with the DS3231 module with I2C and wire.h.
Setting the registers was a pretty easy task but when reading the registers I came up against a problem.
The registers were being read, but not starting at register 0x00.
This is the code I was using.
#include <Wire.h>
int ds3231_address = 0x68; //ds3231 address
// create an array to hold the values of the DS3231 register
char mByte[0x13];
void setup() {
Serial.begin(9600);
Wire.begin();
}
void loop() {
// request 19 bytes from the DS3231 and release the I2C bus
Wire.requestFrom(ds3231_address, 0x13, true);
int idx = 0;
// read the bytes into an array
while(Wire.available()) {
byte input = Wire.read(); // read each byte from the register
mByte[idx] = input; // store each single byte in the array
idx++;
}
for(int i = 0; i < 0x13; i++){
int ab = mByte[i];
Serial.print("Register: ");Serial.print(i, HEX);Serial.print(" ");Serial.println(ab, HEX);
}
delay(1000);
}
And this is the result.
Register: 0 0
Register: 1 59
Register: 2 15
Register: 3 47
Register: 4 60
Register: 5 15
Register: 6 29
Register: 7 10
Register: 8 B
Register: 9 0
Register: A 1B
Register: B FFFFFFC0
Register: C 50
Register: D 10
Register: E 22
Register: F 7
Register: 10 29
Register: 11 6
Register: 12 19
The content of register 0 should be 50h, this is in register C. Apart from that the register content is in the correct order just offset.
If anybody has any ideas about how to remedy this, I would be grateful.
I have no clue if this will work for you, but a while back I was using a PCA9685 servo controller board that also used wire I2C. I too did away with the library and nothing would work. The solution was extremely simple. All I had to do was change int to uint16_t. And that solved everything.
Hopefully this might work in your case as well.
DroneBot Workshop Robotics Engineer
James
Yeah, there is a lot of mixed data types there. I would use just the byte type since that's was the what the I2c read returns. If I remember, that part passes BCD data back and forth as well. None of this still may not be your issue though. If you can a logic analyzer, you may be able to see the raw of what it's sending. I do love the knockoff Saleae Logic ones found on eBay.
Scott
I read somewhere that some I2C slave modules actually hold the SCL low, until all the registers have been fully updated, after receiving the data request interrupt. This module obviously doesn't.
I was wondering whether I could drop the SCL pin to low on the Arduino for a few microseconds in the sketch, before sending the Wire.read() command.
Worth a try. Are you using pull-ups on the I2C bus? I have learned by lots of errors that it's better to than not.
I've got 10k pullup resistors on both SCL and SDA lines.
One thing I have noticed is that when I remove and reinsert the battery, the register contents are returned correctly. Only after I reset the registers to the actual time, this problem returns.
Thanks, Scott
that worked a treat.
Doing something like that was whirling around in the back of my head, but I guess I couldn't see the wood for the trees.
Glad it worked. After you said it worked on startup and not after, I had an oh yeah moment.
I should have seen it myself but worthwhile keeping that sort of trick in my bag of ....
Now for the fun stuff, filling the registers with values without a library, using bit shift and compound or, to fill the four high bits and the four low bits.
I just wonder what these guys were smoking when they came up with the idea to use hexadecimal for these registers.
These are macros I did for bcd translation from a pic controller project I did. They should work.
#define bcd2dec(bcd_in) (bcd_in >> 4) * 10 + (bcd_in & 0x0f)
#define dec2bcd(dec_in) ((dec_in / 10) << 4) + (dec_in % 10)
Thanks, I'll give them a try. I was going to just write a function() to do the conversion.
Oh! Just one more thing.
How do you implement these macros?
Never dealt with them before!
Just place them under you include section then just use them like you would a function.
i.e.
int dec_val = bcd2dec (0x25);