arduino based wordclock
https://www.champonthis.de/projects/wordclock
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
491 lines
8.1 KiB
491 lines
8.1 KiB
#include <Arduino.h>
|
|
|
|
#include <Wire.h>
|
|
|
|
#include <DS3231.h>
|
|
|
|
void DS3231::begin()
|
|
{
|
|
Wire.begin();
|
|
}
|
|
|
|
uint8_t DS3231::getSeconds()
|
|
{
|
|
uint8_t seconds;
|
|
// read seconds
|
|
seconds = getRegister(DS3231_SECONDS);
|
|
return bcdtodec(seconds);
|
|
}
|
|
|
|
void DS3231::setSeconds(uint8_t seconds)
|
|
{
|
|
// write seconds
|
|
setRegister(DS3231_SECONDS, dectobcd(seconds));
|
|
}
|
|
|
|
void DS3231::incrementSeconds()
|
|
{
|
|
uint8_t seconds = getSeconds();
|
|
|
|
if (seconds == 58)
|
|
{
|
|
seconds = 0;
|
|
}
|
|
else
|
|
{
|
|
seconds += 2;
|
|
}
|
|
|
|
setSeconds(seconds);
|
|
}
|
|
|
|
void DS3231::decrementSeconds()
|
|
{
|
|
uint8_t seconds = getSeconds();
|
|
|
|
if (seconds == 1)
|
|
{
|
|
seconds = 59;
|
|
}
|
|
else
|
|
{
|
|
seconds -= 2;
|
|
}
|
|
|
|
setSeconds(seconds);
|
|
}
|
|
|
|
uint8_t DS3231::getMinutes()
|
|
{
|
|
uint8_t minutes;
|
|
// read minutes
|
|
minutes = getRegister(DS3231_MINUTES);
|
|
return bcdtodec(minutes);
|
|
}
|
|
|
|
void DS3231::setMinutes(uint8_t minutes)
|
|
{
|
|
// write minutes
|
|
setRegister(DS3231_MINUTES, dectobcd(minutes));
|
|
}
|
|
|
|
void DS3231::incrementMinutes()
|
|
{
|
|
uint8_t minutes = getMinutes();
|
|
|
|
if (minutes == 59)
|
|
{
|
|
minutes = 0;
|
|
}
|
|
else
|
|
{
|
|
minutes++;
|
|
}
|
|
|
|
setMinutes(minutes);
|
|
}
|
|
|
|
void DS3231::decrementMinutes()
|
|
{
|
|
uint8_t minutes = getMinutes();
|
|
|
|
if (minutes == 0)
|
|
{
|
|
minutes = 59;
|
|
}
|
|
else
|
|
{
|
|
minutes--;
|
|
}
|
|
|
|
setMinutes(minutes);
|
|
}
|
|
|
|
uint8_t DS3231::getHours()
|
|
{
|
|
uint8_t hours;
|
|
// read hours
|
|
hours = getRegister(DS3231_HOURS);
|
|
return bcdtodec(hours);
|
|
}
|
|
|
|
void DS3231::setHours(uint8_t hours)
|
|
{
|
|
// write hours
|
|
setRegister(DS3231_HOURS, dectobcd(hours));
|
|
}
|
|
|
|
void DS3231::incrementHours()
|
|
{
|
|
uint8_t hours = getHours();
|
|
|
|
if (hours == 23)
|
|
{
|
|
hours = 0;
|
|
}
|
|
else
|
|
{
|
|
hours++;
|
|
}
|
|
|
|
setHours(hours);
|
|
}
|
|
|
|
void DS3231::decrementHours()
|
|
{
|
|
uint8_t hours = getHours();
|
|
|
|
if (hours == 0)
|
|
{
|
|
hours = 23;
|
|
}
|
|
else
|
|
{
|
|
hours--;
|
|
}
|
|
|
|
setHours(hours);
|
|
}
|
|
|
|
uint8_t DS3231::getDay()
|
|
{
|
|
uint8_t day;
|
|
// read day
|
|
day = getRegister(DS3231_DAY);
|
|
return bcdtodec(day);
|
|
}
|
|
|
|
void DS3231::setDay(uint8_t day)
|
|
{
|
|
// write day
|
|
setRegister(DS3231_DAY, dectobcd(day));
|
|
}
|
|
|
|
uint8_t DS3231::getDate()
|
|
{
|
|
uint8_t date;
|
|
// read date
|
|
date = getRegister(DS3231_DATE);
|
|
return bcdtodec(date);
|
|
}
|
|
|
|
void DS3231::setDate(uint8_t date)
|
|
{
|
|
// write date
|
|
setRegister(DS3231_DATE, dectobcd(date));
|
|
}
|
|
|
|
void DS3231::incrementDate()
|
|
{
|
|
uint8_t date = getDate();
|
|
date++;
|
|
if (date > 31)
|
|
{
|
|
date = 1;
|
|
}
|
|
setDate(date);
|
|
}
|
|
|
|
void DS3231::decrementDate()
|
|
{
|
|
uint8_t date = getDate();
|
|
date--;
|
|
if (date < 1)
|
|
{
|
|
date = 31;
|
|
}
|
|
setDate(date);
|
|
}
|
|
|
|
uint8_t DS3231::getMonth()
|
|
{
|
|
uint8_t month;
|
|
// read month
|
|
month = getRegister(DS3231_MONTH);
|
|
|
|
// read month, ingore century;
|
|
return bcdtodec(month & 0x1F);
|
|
}
|
|
|
|
void DS3231::setMonth(uint8_t month)
|
|
{
|
|
uint8_t century = getCentury();
|
|
|
|
month = dectobcd(month);
|
|
|
|
if (century == 1)
|
|
{
|
|
month = month + 0x80;
|
|
}
|
|
|
|
// write month
|
|
setRegister(DS3231_MONTH, month);
|
|
}
|
|
|
|
void DS3231::incrementMonth()
|
|
{
|
|
uint8_t month = getMonth();
|
|
month++;
|
|
if (month > 12)
|
|
{
|
|
month = 1;
|
|
}
|
|
setMonth(month);
|
|
}
|
|
|
|
void DS3231::decrementMonth()
|
|
{
|
|
uint8_t month = getMonth();
|
|
month--;
|
|
if (month < 1)
|
|
{
|
|
month = 12;
|
|
}
|
|
setMonth(month);
|
|
}
|
|
|
|
int16_t DS3231::getYear()
|
|
{
|
|
uint8_t century = getCentury();
|
|
|
|
int16_t year;
|
|
|
|
// read year
|
|
year = getRegister(DS3231_YEAR);
|
|
|
|
year = bcdtodec(year);
|
|
|
|
if (century == 1)
|
|
{
|
|
year = 2000 + year;
|
|
}
|
|
else
|
|
{
|
|
year = 1900 + year;
|
|
}
|
|
|
|
return year;
|
|
}
|
|
|
|
void DS3231::setYear(int16_t year)
|
|
{
|
|
if (year > 1999)
|
|
{
|
|
year = year - 2000;
|
|
setCentury(0x80);
|
|
}
|
|
else
|
|
{
|
|
year = year - 1900;
|
|
setCentury(0);
|
|
}
|
|
|
|
setRegister(DS3231_YEAR, dectobcd(year));
|
|
}
|
|
|
|
void DS3231::incrementYear()
|
|
{
|
|
int16_t year = getYear();
|
|
year++;
|
|
if (year > 2099)
|
|
{
|
|
year = 1900;
|
|
}
|
|
setYear(year);
|
|
}
|
|
|
|
void DS3231::decrementYear()
|
|
{
|
|
int16_t year = getYear();
|
|
year--;
|
|
if (year < 1900)
|
|
{
|
|
year = 2099;
|
|
}
|
|
setYear(year);
|
|
}
|
|
|
|
uint8_t DS3231::getAlarm1Seconds()
|
|
{
|
|
return bcdtodec(getRegister(DS3231_ALARM1_SECONDS));
|
|
}
|
|
|
|
void DS3231::setAlarm1Seconds(uint8_t seonds)
|
|
{
|
|
setRegister(DS3231_ALARM1_SECONDS, dectobcd(seconds % 60));
|
|
}
|
|
|
|
uint8_t DS3231::getAlarm1Minutes()
|
|
{
|
|
return bcdtodec(getRegister(DS3231_ALARM1_MINUTES));
|
|
}
|
|
|
|
void DS3231::setAlarm1Minutes(uint8_t minutes)
|
|
{
|
|
setRegister(DS3231_ALARM1_MINUTES, dectobcd(minutes % 60));
|
|
}
|
|
|
|
uint8_t DS3231::getAlarm1Hours()
|
|
{
|
|
return bcdtodec(getRegister(DS3231_ALARM1_HOURS));
|
|
}
|
|
|
|
void DS3231::setAlarm1Hours(uint8_t hours)
|
|
{
|
|
setRegister(DS3231_ALARM1_HOURS, dectobcd(hours % 24));
|
|
}
|
|
|
|
uint8_t DS3231::getAlarm1Date()
|
|
{
|
|
return bcdtodec(getRegister(DS3231_ALARM1_DATE));
|
|
}
|
|
|
|
void DS3231::setAlarm1Date(uint8_t date)
|
|
{
|
|
setRegister(DS3231_ALARM1_DATE, dectobcd(data % 31));
|
|
}
|
|
|
|
void DS3231::setAlarm1Mask(uint8_t mask)
|
|
{
|
|
setRegister(DS3231_ALARM1_SECONDS, dectobcd(getAlarm1Seconds()) | ((mask & 0b00000001) << 7));
|
|
setRegister(DS3231_ALARM1_MINUTES, dectobcd(getAlarm1Minutes()) | ((mask & 0b00000010) << 6));
|
|
setRegister(DS3231_ALARM1_HOURS, dectobcd(getAlarm1Hours()) | ((mask & 0b00000100) << 5));
|
|
setRegister(DS3231_ALARM1_DATE, dectobcd(getAlarm1Date()) | ((mask & 0b00001000) << 4));
|
|
}
|
|
|
|
uint8_t DS3231::getAlarm2Minutes()
|
|
{
|
|
return bcdtodec(getRegister(DS3231_ALARM2_MINUTES));
|
|
}
|
|
|
|
void DS3231::setAlarm2Minutes(uint8_t minutes)
|
|
{
|
|
setRegister(DS3231_ALARM2_MINUTES, dectobcd(minutes % 60));
|
|
}
|
|
|
|
uint8_t DS3231::getAlarm2Hours()
|
|
{
|
|
return bcdtodec(getRegister(DS3231_ALARM2_HOURS));
|
|
}
|
|
|
|
void DS3231::setAlarm2Hours(uint8_t hours)
|
|
{
|
|
setRegister(DS3231_ALARM2_HOURS, dectobcd(hours % 24));
|
|
}
|
|
|
|
uint8_t DS3231::getAlarm2Date()
|
|
{
|
|
return bcdtodec(getRegister(DS3231_ALARM2_DATE));
|
|
}
|
|
|
|
void DS3231::setAlarm2Date(uint8_t date)
|
|
{
|
|
setRegister(DS3231_ALARM2_DATE, dectobcd(date % 31));
|
|
}
|
|
|
|
void DS3231::setAlarm2Mask(uint8_t mask)
|
|
{
|
|
setRegister(DS3231_ALARM2_MINUTES, dectobcd(getAlarm2Minutes()) | ((mask & 0b00000001) << 7));
|
|
setRegister(DS3231_ALARM2_HOURS, dectobcd(getAlarm2Hours()) | ((mask & 0b00000010) << 6));
|
|
setRegister(DS3231_ALARM2_DATE, dectobcd(getAlarm2Date()) | ((mask & 0b00000100) << 5));
|
|
}
|
|
|
|
uint8_t DS3231::getControlRegister()
|
|
{
|
|
return getRegister(DS3231_CONTROL);
|
|
}
|
|
|
|
void DS3231::setControlRegister(uint8_t value)
|
|
{
|
|
setRegister(DS3231_CONTROL, value);
|
|
}
|
|
|
|
uint8_t DS3231::getStatusRegister()
|
|
{
|
|
return getRegister(DS3231_STATUS);
|
|
}
|
|
|
|
void DS3231::setStatusRegister(uint8_t value)
|
|
{
|
|
setRegister(DS3231_STATUS, value);
|
|
}
|
|
|
|
uint8_t DS3231::getTemperature()
|
|
{
|
|
int8_t msb_temp;
|
|
uint8_t msb_value = getRegister(DS3231_MSB_TEMP);
|
|
uint8_t lsb_temp = getRegister(DS3231_LSB_TEMP) >> 6;
|
|
float result;
|
|
|
|
if ((msb_value & 0x80) != 0)
|
|
{
|
|
msb_temp = msb_value | ~((1 << 8) - 1);
|
|
}
|
|
else
|
|
{
|
|
msb_temp = msb_value;
|
|
}
|
|
|
|
result = 0.25 * lsb_temp + msb_temp;
|
|
|
|
return result;
|
|
}
|
|
|
|
uint8_t DS3231::getRegister(uint8_t address)
|
|
{
|
|
uint8_t value;
|
|
|
|
Wire.beginTransmission(DS3231_I2C_ADDRESS);
|
|
Wire.write(address);
|
|
Wire.endTransmission();
|
|
|
|
// request 1 byte
|
|
Wire.requestFrom(DS3231_I2C_ADDRESS, 1);
|
|
|
|
// read value
|
|
value = Wire.read();
|
|
|
|
return value;
|
|
}
|
|
|
|
void DS3231::setRegister(uint8_t address, uint8_t value)
|
|
{
|
|
Wire.beginTransmission(DS3231_I2C_ADDRESS);
|
|
// start at address
|
|
Wire.write(address);
|
|
|
|
// write value
|
|
Wire.write(value);
|
|
|
|
Wire.endTransmission();
|
|
}
|
|
|
|
uint8_t DS3231::dectobcd(uint8_t value)
|
|
{
|
|
return ((value / 10 * 16) + (value % 10));
|
|
}
|
|
|
|
uint8_t DS3231::bcdtodec(uint8_t value)
|
|
{
|
|
return ((value / 16 * 10) + (value % 16));
|
|
}
|
|
|
|
uint8_t DS3231::getCentury()
|
|
{
|
|
uint8_t century = 0;
|
|
|
|
uint8_t month = getRegister(DS3231_MONTH);
|
|
|
|
// read century from month
|
|
century = (month & 0x80) >> 7;
|
|
return century;
|
|
}
|
|
|
|
void DS3231::setCentury(uint8_t century)
|
|
{
|
|
uint8_t month = getMonth();
|
|
|
|
month = month + century;
|
|
|
|
setRegister(DS3231_MONTH, month);
|
|
}
|