Go Down

Topic: DS3231 Function Library (Read 11 times) previous topic - next topic

ccfreak2k

Jan 26, 2011, 04:29 am Last Edit: Jan 27, 2011, 08:57 am by ccfreak2k Reason: 1
Since my ChronoDot has arrived, I have been able to test the DS3231's extra functions. Until I can get all of them working, I'll be offering them "loose" for those that also want to help test or just want the working ones. They can be dropped into the DS1307 library as public members.

EDIT: All functions are working! A patch for the DS1307 library will come soon; alternatively, I can offer these as part of their own library. The functions below are merely for reference.

NOTE: During testing, with the 32K and SQW pins connected to digital pins 2 and 3 respectively, I've found that the SQW pin will interfere with the 32K one, causing pin 3 to read the SQW signals. After testing as many software combinations as I could think of, and even after attaching a stronger pull-up resistor to the 32K line, my thinking is that it has to do with EMI between the two pins. If you want a clear signal from either pin, your best bet is to disable one and enable the other in software.

Temperature readout, working. Returns a float representing the temperature measured since the last temperature conversion, in degrees celsius (temperatures below zero will be reported incorrectly because of a known bug):
Code: [Select]
float getTemperature(void)
{
Wire.beginTransmission(DS1307_CTRL_ID);
Wire.send(0x11);
Wire.endTransmission();

// Just the two this time (temperature int, frac)
Wire.requestFrom(DS1307_CTRL_ID, 2);

int8_t  fint  = Wire.receive();
uint8_t ffrac = ((Wire.receive() >> 6));

return (float)fint + ((float)ffrac * 0.25);
}


Force temperature conversion, also working. Argument determines whether or not the function should block until the conversion is complete. I tested it briefly; on my chip, it blocks for approximately 150ms.
Code: [Select]
void tempConv(uint8_t block)
{
Wire.beginTransmission(DS1307_CTRL_ID);
Wire.send(0x0E);
Wire.endTransmission();

// control register
Wire.requestFrom(DS1307_CTRL_ID, 1);

uint8_t creg = Wire.receive();

creg |= 0b00100000; // Write CONV bit

Wire.beginTransmission(DS1307_CTRL_ID);
Wire.send(0x0E);
Wire.send(creg);
Wire.endTransmission();

do
{
// Block until CONV is 0
Wire.beginTransmission(DS1307_CTRL_ID);
Wire.send(0x0E);
Wire.endTransmission();
Wire.requestFrom(DS1307_CTRL_ID, 1);
} while ((block && (Wire.receive() & 0b00100000) != 0));
}


Battery-backed square-wave enableworking. When enabled, this disables the alarm function.
Code: [Select]
void SQWEnable(uint8_t enable)
{
Wire.beginTransmission(DS1307_CTRL_ID);
Wire.send(0x0E);
Wire.endTransmission();

// control register
Wire.requestFrom(DS1307_CTRL_ID, 1);

uint8_t creg = Wire.receive();

creg &= ~0b01000000; // Set to 0
if (enable == true) {
creg |=  0b01000000; // Enable if required.
creg &= ~0b00000100; // Clear INTCN bit
}

Wire.beginTransmission(DS1307_CTRL_ID);
Wire.send(0x0E);
Wire.send(creg);
Wire.endTransmission();
}


Battery-backed square-wave frequency setting, working. Make sure the pin it's connected to is pulled up (this can be accomplished on an input pin by writing HIGH to it). Argument MUST be one of the four #defined below.
Code: [Select]
#define DS3231_SQW_FREQ_1    0b00000000 // 1Hz
#define DS3231_SQW_FREQ_1024 0b00001000 // 1024Hz
#define DS3231_SQW_FREQ_4096 0b00010000 // 4096Hz
#define DS3231_SQW_FREQ_8192 0b00011000 // 8192Hz

void SQWFrequency(uint8_t freq)
{
Wire.beginTransmission(DS1307_CTRL_ID);
Wire.send(0x0E);
Wire.endTransmission();

// control register
Wire.requestFrom(DS1307_CTRL_ID, 1);

uint8_t creg = Wire.receive();

creg &= ~0b00011000; // Set to 0
creg |= freq; // Set freq bits

Wire.beginTransmission(DS1307_CTRL_ID);
Wire.send(0x0E);
Wire.send(creg);
Wire.endTransmission();
}


Enable 32KHz pin, partially working. Needs to be pulled up if connected like the SQW pin.
Code: [Select]
void enable32Khz(uint8_t enable)
{
Wire.beginTransmission(DS1307_CTRL_ID);
Wire.send(0x0F);
Wire.endTransmission();

// status register
Wire.requestFrom(DS1307_CTRL_ID, 1);

uint8_t sreg = Wire.receive();

sreg &= ~0b00001000; // Set to 0
if (enable == true)
sreg |=  0b00001000; // Enable if required.

Wire.beginTransmission(DS1307_CTRL_ID);
Wire.send(0x0F);
Wire.send(sreg);
Wire.endTransmission();
}


Enable internal oscillator, UNKNOWN if working. NOTE that this function differs from the actual bit value given in the datasheet, as the name it uses for this bit is misleading. Calling this with "true" will ENABLE the oscillator as the name implies.
Code: [Select]
void enableOSC(uint8_t enable)
{
Wire.beginTransmission(DS1307_CTRL_ID);
Wire.send(0x0E);
Wire.endTransmission();

// status register
Wire.requestFrom(DS1307_CTRL_ID, 1);

uint8_t sreg = Wire.receive();

sreg |= 0b10000000; // Set to 1 (disabled)
if (enable == true)
sreg &= ~0b10000000; // Enable if required.

Wire.beginTransmission(DS1307_CTRL_ID);
Wire.send(0x0E);
Wire.send(sreg);
Wire.endTransmission();
}


The battery-backed square wave feature is present in the DS1307, but it uses a different address to enable/configure it. If anyone could make the necessary changes and see if they can debug it on the DS1307, I would be grateful, as having an accurate external timer would be handy!

mowcius

This will probably help. I can confirm that the sqw function in this library does work.
http://code.google.com/p/gfb/source/browse/arduino/DS3231/DS3231.pde?r=77&safe=vss

Mowcius

Federico

I was not aware of the existence of this DS3231 but now I want to test it :-) Looks the cool version of the DS1307...
Federico - Sideralis
Arduino &C: http://www.sideralis.org
Foto: http://blackman.amicofigo.com

ccfreak2k

#3
Jan 27, 2011, 07:29 am Last Edit: Jan 27, 2011, 07:51 am by ccfreak2k Reason: 1

This will probably help. I can confirm that the sqw function in this library does work.
http://code.google.com/p/gfb/source/browse/arduino/DS3231/DS3231.pde?r=77&safe=vss

Mowcius
I couldn't find anything wave-related in the code behind that link, but the 32K line is magically working now (perhaps I wired it wrong the first time). Configurable square-wave still isn't functioning, however.

EDIT: I fixed the square wave code, so now everything is working(to my knowledge).

mowcius



This will probably help. I can confirm that the sqw function in this library does work.
http://code.google.com/p/gfb/source/browse/arduino/DS3231/DS3231.pde?r=77&safe=vss

Mowcius
I couldn't find anything wave-related in the code behind that link, but the 32K line is magically working now (perhaps I wired it wrong the first time). Configurable square-wave still isn't functioning, however.

EDIT: I fixed the square wave code, so now everything is working(to my knowledge).

Oh sorry - wrong page. I meant this:
Quote

  Wire.beginTransmission(104);
  Wire.send(0x0e);  //select control register
  //set sqw at specified Hz of  0=1Hz
  Wire.send(0);
  Wire.endTransmission();

Glad you got it working though.

Go Up