Created
February 16, 2017 03:44
-
-
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)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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