/* * RTC DS3231 via I2C * IO 13 for power supply */ #include #define RTC_I2C_ADR 0x68 // 7 bit mode! #define MODE_AM 0 #define MODE_PM 1 #define MODE_24H 2 uint8_t rtc_buffer[19]; const char dow[7][10] = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}; void writeRegister(uint8_t address, uint8_t data) { Wire.beginTransmission(RTC_I2C_ADR); Wire.write(address); Wire.write(data); Wire.endTransmission(true); } uint8_t readRegister(uint8_t address) { uint8_t tmp; Wire.beginTransmission(RTC_I2C_ADR); Wire.write(address); Wire.endTransmission(true); Wire.requestFrom(RTC_I2C_ADR, 1, true); tmp = Wire.read(); return tmp; } void measureTemperature(void) { uint8_t statusReg, controlReg; do { statusReg = readRegister(0xF); delay(10); } while (statusReg & (1<<2)); // check busy bit controlReg = readRegister(0xE); writeRegister(0xE, controlReg | (1<<5)); // trigger temperature conversion } // set time // mode: 0: AM; 1: PM; 2: 24h void setTime(uint8_t hh, uint8_t mm, uint8_t ss, uint8_t mode) { uint8_t tmp[3]; uint8_t h, l; h = ss / 10; l = ss % 10; tmp[0] = (h<<4) + l; h = mm / 10; l = mm % 10; tmp[1] = (h<<4) + l; h = hh / 10; l = hh % 10; tmp[2] = (h<<4) + l; switch(mode) { case 0: tmp[2] |= (1<<6); break; // AM case 1: tmp[2] |= (1<<6) | (1<<5); break; // PM case 2: break; // 24h } Wire.beginTransmission(RTC_I2C_ADR); Wire.write(0); // register address for(int i=0; i<3; i++) { Wire.write(tmp[i]); } Wire.endTransmission(true); } void setDate(uint8_t dayofweek, uint8_t day, uint8_t month, uint16_t year) { uint8_t tmp[4]; uint8_t h, l; if (dayofweek < 1) dayofweek = 1; if (dayofweek > 7) dayofweek = 7; if (day < 1) day = 1; if (day > 31) day = 31; if (month < 1) month = 1; if (month > 12) month = 12; if (year < 2000) year = 2000; if (year > 2199) year = 2199; tmp[0] = dayofweek; h = day / 10; l = day % 10; tmp[1] = (h<<4) + l; h = month / 10; l = month % 10; tmp[2] = (h<<4) + l; if (year > 2099) tmp[2] |= (1<<7); year = year % 100; h = year / 10; l = year % 10; tmp[3] = (h<<4) + l; Wire.beginTransmission(RTC_I2C_ADR); Wire.write(3); // register address for(int i=0; i<4; i++) { Wire.write(tmp[i]); } Wire.endTransmission(true); } void decode_regs(const uint8_t data[19]) { int tmp; // hour if (data[2] & (1<<6)) { // AM/PM mode if (data[2] & (1<<5)) { Serial.print(F("PM ")); } else { Serial.print(F("AM ")); } Serial.print((data[2]>>4) & 1); Serial.print(data[2] & 0xF); } else { // 24h mode Serial.print(F(" ")); Serial.print((data[2]>>4) & 3); Serial.print(data[2] & 0xF); } Serial.print(':'); //minute Serial.print((data[1]>>4) & 7); Serial.print(data[1] & 0xF); Serial.print(':'); // seconds Serial.print((data[0]>>4) & 7); Serial.print(data[0] & 0xF); Serial.print(F(" ")); // day of week Serial.print(dow[data[3]-1]); Serial.print(' '); // date Serial.print((data[4]>>4) & 3); Serial.print(data[4] & 0xF); Serial.print('.'); // month Serial.print((data[5]>>4) & 1); Serial.print(data[5] & 0xF); Serial.print('.'); // year tmp = 20; if (data[5] & (1<<7)) tmp++; // century Serial.print(tmp); Serial.print((data[6]>>4)); Serial.print(data[6] & 0xF); Serial.print(F(" ")); // Temperature tmp = (data[17]<<2) | data[18]>>6; if (tmp & (1<<9)) tmp |= 0xFC00; // Vorzeichenerweiterung tmp *= 25 ; // temp mit 0,01°C Auflösung Serial.print(F("Temp: ")); Serial.print(tmp/100); Serial.print('.'); Serial.print(tmp%100); // Aging Offset tmp = data[16]; if (data[16] & (1<<7)) tmp |= 0xFF00; // Vorzeichenerweiterung Serial.print(F(" Age Offset: ")); Serial.print(tmp); Serial.println(); } void read_regs(uint8_t data[19]) { Wire.beginTransmission(RTC_I2C_ADR); Wire.write(0); // register address Wire.endTransmission(true); Wire.requestFrom(RTC_I2C_ADR, 19, true); for(int i=0; i<19; i++) { data[i] = Wire.read(); } } void dump_regs(const uint8_t data[19]) { int tmp; for(int i=0; i<19; i++) { tmp = data[i]; Serial.print(i); Serial.print(" 0x"); if (tmp<16) Serial.print('0'); Serial.println(tmp, HEX); } } void setup() { pinMode(13, OUTPUT); digitalWrite(13, HIGH); Serial.begin(9600); Serial.println(F("RTC test for DS3231 via I2C")); Wire.begin(RTC_I2C_ADR); //setTime(8,20,00, MODE_24H); //setTime(10,30,00, MODE_PM); //setDate(5, 18, 8, 2023); } void loop() { //Serial.print(F("\r\n\r\nDS3231 registers\r\n")); measureTemperature(); delay(250); read_regs(rtc_buffer); //dump_regs(rtc_buffer); decode_regs(rtc_buffer); delay(750); }