Skip to content

Instantly share code, notes, and snippets.

@bigjosh
Created February 16, 2017 03:44
Show Gist options
  • Save bigjosh/002dffefb082828348e07397289f8587 to your computer and use it in GitHub Desktop.
Save bigjosh/002dffefb082828348e07397289f8587 to your computer and use it in GitHub Desktop.
Arduino sketch that will put a DS3231 time keeping chip into a low power mode where it outputs a 1Hz square wave (pull up needed)
#include "Wire.h"
#define DS3231_I2C_ADDRESS 0x68
#define DS_REG_CR (0x0e) // Control Reg
#define DS_REG_SR (0x0f) // Status Reg
// Pins connected to the DS2321
// We want to know these so we can put them HI_Z when not talking to the board to get a real power measurement.
#define D_SCLK A5
#define D_SDAT A4
#define D_VIN A3
#define D_GND A2
// Base code stolen from
// http://tronixstuff.com/2014/12/01/tutorial-using-ds1307-and-ds3231-real-time-clock-modules-with-arduino/
// Convert normal decimal numbers to binary coded decimal
byte decToBcd(byte val)
{
return( (val/10*16) + (val%10) );
}
// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val)
{
return( (val/16*10) + (val%16) );
}
void setDS3231time(byte second, byte minute, byte hour, byte dayOfWeek, byte
dayOfMonth, byte month, byte year)
{
// sets time and date data to DS3231
Wire.beginTransmission(DS3231_I2C_ADDRESS);
Wire.write(0); // set next input to start at the seconds register
Wire.write(decToBcd(second)); // set seconds
Wire.write(decToBcd(minute)); // set minutes
Wire.write(decToBcd(hour)); // set hours
Wire.write(decToBcd(dayOfWeek)); // set day of week (1=Sunday, 7=Saturday)
Wire.write(decToBcd(dayOfMonth)); // set date (1 to 31)
Wire.write(decToBcd(month)); // set month
Wire.write(decToBcd(year)); // set year (0 to 99)
Wire.endTransmission();
}
// Set reg r to v
void setReg( uint8_t r, uint8_t v ){
Wire.beginTransmission(DS3231_I2C_ADDRESS);
Wire.write(r);
Wire.write( v);
Wire.endTransmission();
}
void setCR()
{
// Set Alarm
setReg(0x07 , 0b10001111); // Enable (A1M1), Set alarm 1 match to every second
// sets Control Register on DS3231
// setReg(0x0e , 0b01000101); // SQ enabled on VBAT, Alarm output on SQW pin (INITCN), Enable Alarm 1 (A1IE)
setReg(0x0e , 0b01000000); // SQ enabled on VBAT, Square wave enabled with 1hrz
//Wire.write( 0b00000100); // Assign SQ to INT pin, but without alarm enable, no output on SQW
// now address is 0x0f (status reg)
// setReg( 0x0f , 0b00000000); // Disable the 32khz output to save power
setReg( 0x0f , 0b00001000); // Enaable the 32khz output
}
void readDS3231time(byte *second,
byte *minute,
byte *hour,
byte *dayOfWeek,
byte *dayOfMonth,
byte *month,
byte *year)
{
Wire.beginTransmission(DS3231_I2C_ADDRESS);
Wire.write(0); // set DS3231 register pointer to 00h
Wire.endTransmission();
Wire.requestFrom(DS3231_I2C_ADDRESS, 7);
// request seven bytes of data from DS3231 starting from register 00h
*second = bcdToDec(Wire.read() & 0x7f);
*minute = bcdToDec(Wire.read());
*hour = bcdToDec(Wire.read() & 0x3f);
*dayOfWeek = bcdToDec(Wire.read());
*dayOfMonth = bcdToDec(Wire.read());
*month = bcdToDec(Wire.read());
*year = bcdToDec(Wire.read());
}
uint8_t readR(uint8_t r) {
Wire.beginTransmission(DS3231_I2C_ADDRESS);
Wire.write(r); // set DS3231 register pointer to 00h
Wire.endTransmission();
Wire.requestFrom(DS3231_I2C_ADDRESS, 1);
// request seven bytes of data from DS3231 starting from register 00h
return(Wire.read() & 0x7f);
}
void displayTime()
{
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
// retrieve data from DS3231
readDS3231time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month,
&year);
// send it to the serial monitor
Serial.print(hour, DEC);
// convert the byte variable to a decimal number when displayed
Serial.print(":");
if (minute<10)
{
Serial.print("0");
}
Serial.print(minute, DEC);
Serial.print(":");
if (second<10)
{
Serial.print("0");
}
Serial.print(second, DEC);
Serial.print(" ");
Serial.print(dayOfMonth, DEC);
Serial.print("/");
Serial.print(month, DEC);
Serial.print("/");
Serial.print(year, DEC);
Serial.print(" Day of week: ");
switch(dayOfWeek){
case 1:
Serial.println("Sunday");
break;
case 2:
Serial.println("Monday");
break;
case 3:
Serial.println("Tuesday");
break;
case 4:
Serial.println("Wednesday");
break;
case 5:
Serial.println("Thursday");
break;
case 6:
Serial.println("Friday");
break;
case 7:
Serial.println("Saturday");
break;
}
}
void displayRegs(void) {
Serial.print("CR:");
Serial.print( readR(DS_REG_CR) , BIN );
Serial.print(" SR:");
Serial.println( readR(DS_REG_SR) , BIN );
}
void powerUpDS(void) {
digitalWrite( D_GND, 0 );
pinMode( D_GND, OUTPUT);
pinMode( D_VIN, OUTPUT); // This pin is connected to Vin
digitalWrite( D_VIN , 1 ); // Power the board so we can talk to it.
delay(100); // Give a moment for the board to stabilize
//pinMode( D_SCLK, OUTPUT); // This pin is connected to Vin
//pinMode( D_DAT, OUTPUT); // This pin is connected to Vin
}
void powerDownDS(void) {
//pinMode( A0, INPUT); // This pin is connected to Vin
// pinMode( D_SCLK, INPUT); // This pin is connected to SCLK
// pinMode( D_SDAT, INPUT); // This pin is connected to SDAT
pinMode( D_GND, INPUT); // This pin is connected to SDAT
digitalWrite( D_VIN , 0 ); // ...otherwise we wll see pullup?
pinMode( D_VIN, INPUT); // This pin is connected to SCLK
}
void setup()
{
powerUpDS();
Wire.begin();
Serial.begin(9600);
// set the initial time here:
// DS3231 seconds, minutes, hours, day, date, month, year
//setDS3231time(00,0,0,0,1,1,17);
setCR();
powerDownDS();
}
void loop()
{
powerUpDS();
displayTime(); // display the real-time clock data on the Serial Monitor,
displayRegs();
powerDownDS();
delay(10000); // every 10 second
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment