first commit

This commit is contained in:
2021-12-01 22:41:59 -06:00
commit ad68ba1cac
208 changed files with 42683 additions and 0 deletions

View File

@ -0,0 +1,27 @@
#include "FM24I2C.h"
FM24I2C::FM24I2C(int id_addr) {
id=id_addr;
}
FM24I2C::~FM24I2C() {}
void FM24I2C::pack(int addr, void* data, int len) {
Wire.beginTransmission(id);
Wire.write((byte*)&addr,2);
Wire.write((byte*)data,len);
Wire.endTransmission(true);
}
int FM24I2C::unpack(int addr, void* data, int len) {
int rc;
byte *p;
Wire.beginTransmission(id);
Wire.write((byte*)&addr,2);
Wire.endTransmission(false);
Wire.requestFrom(id,len);
for (rc=0, p=(byte*)data; Wire.available() && rc < len; rc++, p++) {
*p=Wire.read();
}
return(rc);
}

View File

@ -0,0 +1,29 @@
#include "Wire.h"
#if ARDUINO >= 100
#include <Arduino.h>
#else
#include <WProgram.h>
#endif
#ifndef _FM24I2C_H_
#define _FM24I2C_H_
class FM24I2C {
private:
int id;
public:
FM24I2C(int id_addr);
~FM24I2C();
void pack(int addr, void* data, int len); // Pack data into FRAM
int unpack(int addr, void* data, int len); // Unpack data from FRAM. Returns number of bytes read.
void inline writeUnsignedLong(int addr, unsigned long data) {
pack(addr, (void*)&data, sizeof(unsigned long));
}
unsigned long inline readUnsignedLong(int addr) {
unsigned long data;
return unpack(addr, (void*)&data, sizeof(unsigned long)) == sizeof(unsigned long) ? data : 0UL;
}
};
#endif

View File

@ -0,0 +1,506 @@
// Code by JeeLabs http://news.jeelabs.org/code/
// Released to the public domain! Enjoy!
#include <Wire.h>
#include "RTClib.h"
#ifdef __AVR__
#include <avr/pgmspace.h>
#elif defined(ESP8266)
#include <pgmspace.h>
#elif defined(ARDUINO_ARCH_SAMD)
// nothing special needed
#elif defined(ARDUINO_SAM_DUE)
#define PROGMEM
#define pgm_read_byte(addr) (*(const unsigned char *)(addr))
#define Wire Wire1
#endif
#if (ARDUINO >= 100)
#include <Arduino.h> // capital A so it is error prone on case-sensitive filesystems
// Macro to deal with the difference in I2C write functions from old and new Arduino versions.
#define _I2C_WRITE write
#define _I2C_READ read
#else
#include <WProgram.h>
#define _I2C_WRITE send
#define _I2C_READ receive
#endif
static uint8_t read_i2c_register(uint8_t addr, uint8_t reg) {
Wire.beginTransmission(addr);
Wire._I2C_WRITE((byte)reg);
Wire.endTransmission();
Wire.requestFrom(addr, (byte)1);
return Wire._I2C_READ();
}
static void write_i2c_register(uint8_t addr, uint8_t reg, uint8_t val) {
Wire.beginTransmission(addr);
Wire._I2C_WRITE((byte)reg);
Wire._I2C_WRITE((byte)val);
Wire.endTransmission();
}
////////////////////////////////////////////////////////////////////////////////
// utility code, some of this could be exposed in the DateTime API if needed
const uint8_t daysInMonth [] PROGMEM = { 31,28,31,30,31,30,31,31,30,31,30,31 };
// number of days since 2000/01/01, valid for 2001..2099
static uint16_t date2days(uint16_t y, uint8_t m, uint8_t d) {
if (y >= 2000)
y -= 2000;
uint16_t days = d;
for (uint8_t i = 1; i < m; ++i)
days += pgm_read_byte(daysInMonth + i - 1);
if (m > 2 && y % 4 == 0)
++days;
return days + 365 * y + (y + 3) / 4 - 1;
}
static long time2long(uint16_t days, uint8_t h, uint8_t m, uint8_t s) {
return ((days * 24L + h) * 60 + m) * 60 + s;
}
////////////////////////////////////////////////////////////////////////////////
// DateTime implementation - ignores time zones and DST changes
// NOTE: also ignores leap seconds, see http://en.wikipedia.org/wiki/Leap_second
DateTime::DateTime (uint32_t t) {
t -= SECONDS_FROM_1970_TO_2000; // bring to 2000 timestamp from 1970
ss = t % 60;
t /= 60;
mm = t % 60;
t /= 60;
hh = t % 24;
uint16_t days = t / 24;
uint8_t leap;
for (yOff = 0; ; ++yOff) {
leap = yOff % 4 == 0;
if (days < 365 + leap)
break;
days -= 365 + leap;
}
for (m = 1; ; ++m) {
uint8_t daysPerMonth = pgm_read_byte(daysInMonth + m - 1);
if (leap && m == 2)
++daysPerMonth;
if (days < daysPerMonth)
break;
days -= daysPerMonth;
}
d = days + 1;
}
DateTime::DateTime (uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t min, uint8_t sec) {
if (year >= 2000)
year -= 2000;
yOff = year;
m = month;
d = day;
hh = hour;
mm = min;
ss = sec;
}
DateTime::DateTime (const DateTime& copy):
yOff(copy.yOff),
m(copy.m),
d(copy.d),
hh(copy.hh),
mm(copy.mm),
ss(copy.ss)
{}
static uint8_t conv2d(const char* p) {
uint8_t v = 0;
if ('0' <= *p && *p <= '9')
v = *p - '0';
return 10 * v + *++p - '0';
}
// A convenient constructor for using "the compiler's time":
// DateTime now (__DATE__, __TIME__);
// NOTE: using F() would further reduce the RAM footprint, see below.
DateTime::DateTime (const char* date, const char* time) {
// sample input: date = "Dec 26 2009", time = "12:34:56"
yOff = conv2d(date + 9);
// Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
switch (date[0]) {
case 'J': m = (date[1] == 'a') ? 1 : ((date[2] == 'n') ? 6 : 7); break;
case 'F': m = 2; break;
case 'A': m = date[2] == 'r' ? 4 : 8; break;
case 'M': m = date[2] == 'r' ? 3 : 5; break;
case 'S': m = 9; break;
case 'O': m = 10; break;
case 'N': m = 11; break;
case 'D': m = 12; break;
}
d = conv2d(date + 4);
hh = conv2d(time);
mm = conv2d(time + 3);
ss = conv2d(time + 6);
}
// A convenient constructor for using "the compiler's time":
// This version will save RAM by using PROGMEM to store it by using the F macro.
// DateTime now (F(__DATE__), F(__TIME__));
DateTime::DateTime (const __FlashStringHelper* date, const __FlashStringHelper* time) {
// sample input: date = "Dec 26 2009", time = "12:34:56"
char buff[11];
memcpy_P(buff, date, 11);
yOff = conv2d(buff + 9);
// Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
switch (buff[0]) {
case 'J': m = (buff[1] == 'a') ? 1 : ((buff[2] == 'n') ? 6 : 7); break;
case 'F': m = 2; break;
case 'A': m = buff[2] == 'r' ? 4 : 8; break;
case 'M': m = buff[2] == 'r' ? 3 : 5; break;
case 'S': m = 9; break;
case 'O': m = 10; break;
case 'N': m = 11; break;
case 'D': m = 12; break;
}
d = conv2d(buff + 4);
memcpy_P(buff, time, 8);
hh = conv2d(buff);
mm = conv2d(buff + 3);
ss = conv2d(buff + 6);
}
uint8_t DateTime::dayOfTheWeek() const {
uint16_t day = date2days(yOff, m, d);
return (day + 6) % 7; // Jan 1, 2000 is a Saturday, i.e. returns 6
}
uint32_t DateTime::unixtime(void) const {
uint32_t t;
uint16_t days = date2days(yOff, m, d);
t = time2long(days, hh, mm, ss);
t += SECONDS_FROM_1970_TO_2000; // seconds from 1970 to 2000
return t;
}
long DateTime::secondstime(void) const {
long t;
uint16_t days = date2days(yOff, m, d);
t = time2long(days, hh, mm, ss);
return t;
}
DateTime DateTime::operator+(const TimeSpan& span) {
return DateTime(unixtime()+span.totalseconds());
}
DateTime DateTime::operator-(const TimeSpan& span) {
return DateTime(unixtime()-span.totalseconds());
}
TimeSpan DateTime::operator-(const DateTime& right) {
return TimeSpan(unixtime()-right.unixtime());
}
////////////////////////////////////////////////////////////////////////////////
// TimeSpan implementation
TimeSpan::TimeSpan (int32_t seconds):
_seconds(seconds)
{}
TimeSpan::TimeSpan (int16_t days, int8_t hours, int8_t minutes, int8_t seconds):
_seconds((int32_t)days*86400L + (int32_t)hours*3600 + (int32_t)minutes*60 + seconds)
{}
TimeSpan::TimeSpan (const TimeSpan& copy):
_seconds(copy._seconds)
{}
TimeSpan TimeSpan::operator+(const TimeSpan& right) {
return TimeSpan(_seconds+right._seconds);
}
TimeSpan TimeSpan::operator-(const TimeSpan& right) {
return TimeSpan(_seconds-right._seconds);
}
////////////////////////////////////////////////////////////////////////////////
// RTC_DS1307 implementation
static uint8_t bcd2bin (uint8_t val) { return val - 6 * (val >> 4); }
static uint8_t bin2bcd (uint8_t val) { return val + 6 * (val / 10); }
boolean RTC_DS1307::begin(void) {
Wire.begin();
return true;
}
uint8_t RTC_DS1307::isrunning(void) {
Wire.beginTransmission(DS1307_ADDRESS);
Wire._I2C_WRITE((byte)0);
Wire.endTransmission();
Wire.requestFrom(DS1307_ADDRESS, 1);
uint8_t ss = Wire._I2C_READ();
return !(ss>>7);
}
void RTC_DS1307::adjust(const DateTime& dt) {
Wire.beginTransmission(DS1307_ADDRESS);
Wire._I2C_WRITE((byte)0); // start at location 0
Wire._I2C_WRITE(bin2bcd(dt.second()));
Wire._I2C_WRITE(bin2bcd(dt.minute()));
Wire._I2C_WRITE(bin2bcd(dt.hour()));
Wire._I2C_WRITE(bin2bcd(0));
Wire._I2C_WRITE(bin2bcd(dt.day()));
Wire._I2C_WRITE(bin2bcd(dt.month()));
Wire._I2C_WRITE(bin2bcd(dt.year() - 2000));
Wire.endTransmission();
}
DateTime RTC_DS1307::now() {
Wire.beginTransmission(DS1307_ADDRESS);
Wire._I2C_WRITE((byte)0);
Wire.endTransmission();
Wire.requestFrom(DS1307_ADDRESS, 7);
uint8_t ss = bcd2bin(Wire._I2C_READ() & 0x7F);
uint8_t mm = bcd2bin(Wire._I2C_READ());
uint8_t hh = bcd2bin(Wire._I2C_READ());
Wire._I2C_READ();
uint8_t d = bcd2bin(Wire._I2C_READ());
uint8_t m = bcd2bin(Wire._I2C_READ());
uint16_t y = bcd2bin(Wire._I2C_READ()) + 2000;
return DateTime (y, m, d, hh, mm, ss);
}
Ds1307SqwPinMode RTC_DS1307::readSqwPinMode() {
int mode;
Wire.beginTransmission(DS1307_ADDRESS);
Wire._I2C_WRITE(DS1307_CONTROL);
Wire.endTransmission();
Wire.requestFrom((uint8_t)DS1307_ADDRESS, (uint8_t)1);
mode = Wire._I2C_READ();
mode &= 0x93;
return static_cast<Ds1307SqwPinMode>(mode);
}
void RTC_DS1307::writeSqwPinMode(Ds1307SqwPinMode mode) {
Wire.beginTransmission(DS1307_ADDRESS);
Wire._I2C_WRITE(DS1307_CONTROL);
Wire._I2C_WRITE(mode);
Wire.endTransmission();
}
void RTC_DS1307::readnvram(uint8_t* buf, uint8_t size, uint8_t address) {
int addrByte = DS1307_NVRAM + address;
Wire.beginTransmission(DS1307_ADDRESS);
Wire._I2C_WRITE(addrByte);
Wire.endTransmission();
Wire.requestFrom((uint8_t) DS1307_ADDRESS, size);
for (uint8_t pos = 0; pos < size; ++pos) {
buf[pos] = Wire._I2C_READ();
}
}
void RTC_DS1307::writenvram(uint8_t address, uint8_t* buf, uint8_t size) {
int addrByte = DS1307_NVRAM + address;
Wire.beginTransmission(DS1307_ADDRESS);
Wire._I2C_WRITE(addrByte);
for (uint8_t pos = 0; pos < size; ++pos) {
Wire._I2C_WRITE(buf[pos]);
}
Wire.endTransmission();
}
uint8_t RTC_DS1307::readnvram(uint8_t address) {
uint8_t data;
readnvram(&data, 1, address);
return data;
}
void RTC_DS1307::writenvram(uint8_t address, uint8_t data) {
writenvram(address, &data, 1);
}
////////////////////////////////////////////////////////////////////////////////
// RTC_Millis implementation
long RTC_Millis::offset = 0;
void RTC_Millis::adjust(const DateTime& dt) {
offset = dt.unixtime() - millis() / 1000;
}
DateTime RTC_Millis::now() {
return (uint32_t)(offset + millis() / 1000);
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// RTC_PCF8563 implementation
boolean RTC_PCF8523::begin(void) {
Wire.begin();
return true;
}
boolean RTC_PCF8523::initialized(void) {
Wire.beginTransmission(PCF8523_ADDRESS);
Wire._I2C_WRITE((byte)PCF8523_CONTROL_3);
Wire.endTransmission();
Wire.requestFrom(PCF8523_ADDRESS, 1);
uint8_t ss = Wire._I2C_READ();
return ((ss & 0xE0) != 0xE0);
}
void RTC_PCF8523::adjust(const DateTime& dt) {
Wire.beginTransmission(PCF8523_ADDRESS);
Wire._I2C_WRITE((byte)3); // start at location 3
Wire._I2C_WRITE(bin2bcd(dt.second()));
Wire._I2C_WRITE(bin2bcd(dt.minute()));
Wire._I2C_WRITE(bin2bcd(dt.hour()));
Wire._I2C_WRITE(bin2bcd(dt.day()));
Wire._I2C_WRITE(bin2bcd(0)); // skip weekdays
Wire._I2C_WRITE(bin2bcd(dt.month()));
Wire._I2C_WRITE(bin2bcd(dt.year() - 2000));
Wire.endTransmission();
// set to battery switchover mode
Wire.beginTransmission(PCF8523_ADDRESS);
Wire._I2C_WRITE((byte)PCF8523_CONTROL_3);
Wire._I2C_WRITE((byte)0x00);
Wire.endTransmission();
}
DateTime RTC_PCF8523::now() {
Wire.beginTransmission(PCF8523_ADDRESS);
Wire._I2C_WRITE((byte)3);
Wire.endTransmission();
Wire.requestFrom(PCF8523_ADDRESS, 7);
uint8_t ss = bcd2bin(Wire._I2C_READ() & 0x7F);
uint8_t mm = bcd2bin(Wire._I2C_READ());
uint8_t hh = bcd2bin(Wire._I2C_READ());
uint8_t d = bcd2bin(Wire._I2C_READ());
Wire._I2C_READ(); // skip 'weekdays'
uint8_t m = bcd2bin(Wire._I2C_READ());
uint16_t y = bcd2bin(Wire._I2C_READ()) + 2000;
return DateTime (y, m, d, hh, mm, ss);
}
Pcf8523SqwPinMode RTC_PCF8523::readSqwPinMode() {
int mode;
Wire.beginTransmission(PCF8523_ADDRESS);
Wire._I2C_WRITE(PCF8523_CLKOUTCONTROL);
Wire.endTransmission();
Wire.requestFrom((uint8_t)PCF8523_ADDRESS, (uint8_t)1);
mode = Wire._I2C_READ();
mode >>= 3;
mode &= 0x7;
return static_cast<Pcf8523SqwPinMode>(mode);
}
void RTC_PCF8523::writeSqwPinMode(Pcf8523SqwPinMode mode) {
Wire.beginTransmission(PCF8523_ADDRESS);
Wire._I2C_WRITE(PCF8523_CLKOUTCONTROL);
Wire._I2C_WRITE(mode << 3);
Wire.endTransmission();
}
////////////////////////////////////////////////////////////////////////////////
// RTC_DS3231 implementation
boolean RTC_DS3231::begin(void) {
Wire.begin();
return true;
}
bool RTC_DS3231::lostPower(void) {
return (read_i2c_register(DS3231_ADDRESS, DS3231_STATUSREG) >> 7);
}
void RTC_DS3231::adjust(const DateTime& dt) {
Wire.beginTransmission(DS3231_ADDRESS);
Wire._I2C_WRITE((byte)0); // start at location 0
Wire._I2C_WRITE(bin2bcd(dt.second()));
Wire._I2C_WRITE(bin2bcd(dt.minute()));
Wire._I2C_WRITE(bin2bcd(dt.hour()));
Wire._I2C_WRITE(bin2bcd(0));
Wire._I2C_WRITE(bin2bcd(dt.day()));
Wire._I2C_WRITE(bin2bcd(dt.month()));
Wire._I2C_WRITE(bin2bcd(dt.year() - 2000));
Wire.endTransmission();
uint8_t statreg = read_i2c_register(DS3231_ADDRESS, DS3231_STATUSREG);
statreg &= ~0x80; // flip OSF bit
write_i2c_register(DS3231_ADDRESS, DS3231_STATUSREG, statreg);
}
DateTime RTC_DS3231::now() {
Wire.beginTransmission(DS3231_ADDRESS);
Wire._I2C_WRITE((byte)0);
Wire.endTransmission();
Wire.requestFrom(DS3231_ADDRESS, 7);
uint8_t ss = bcd2bin(Wire._I2C_READ() & 0x7F);
uint8_t mm = bcd2bin(Wire._I2C_READ());
uint8_t hh = bcd2bin(Wire._I2C_READ());
Wire._I2C_READ();
uint8_t d = bcd2bin(Wire._I2C_READ());
uint8_t m = bcd2bin(Wire._I2C_READ());
uint16_t y = bcd2bin(Wire._I2C_READ()) + 2000;
return DateTime (y, m, d, hh, mm, ss);
}
Ds3231SqwPinMode RTC_DS3231::readSqwPinMode() {
int mode;
Wire.beginTransmission(DS3231_ADDRESS);
Wire._I2C_WRITE(DS3231_CONTROL);
Wire.endTransmission();
Wire.requestFrom((uint8_t)DS3231_ADDRESS, (uint8_t)1);
mode = Wire._I2C_READ();
mode &= 0x93;
return static_cast<Ds3231SqwPinMode>(mode);
}
void RTC_DS3231::writeSqwPinMode(Ds3231SqwPinMode mode) {
uint8_t ctrl;
ctrl = read_i2c_register(DS3231_ADDRESS, DS3231_CONTROL);
ctrl &= ~0x04; // turn off INTCON
ctrl &= ~0x18; // set freq bits to 0
if (mode == DS3231_OFF) {
ctrl |= 0x04; // turn on INTCN
} else {
ctrl |= mode;
}
write_i2c_register(DS3231_ADDRESS, DS3231_CONTROL, ctrl);
//Serial.println( read_i2c_register(DS3231_ADDRESS, DS3231_CONTROL), HEX);
}

View File

@ -0,0 +1,135 @@
// Code by JeeLabs http://news.jeelabs.org/code/
// Released to the public domain! Enjoy!
#ifndef _RTCLIB_H_
#define _RTCLIB_H_
#include <Arduino.h>
class TimeSpan;
#define PCF8523_ADDRESS 0x68
#define PCF8523_CLKOUTCONTROL 0x0F
#define PCF8523_CONTROL_3 0x02
#define DS1307_ADDRESS 0x68
#define DS1307_CONTROL 0x07
#define DS1307_NVRAM 0x08
#define DS3231_ADDRESS 0x68
#define DS3231_CONTROL 0x0E
#define DS3231_STATUSREG 0x0F
#define SECONDS_PER_DAY 86400L
#define SECONDS_FROM_1970_TO_2000 946684800
// Simple general-purpose date/time class (no TZ / DST / leap second handling!)
class DateTime {
public:
DateTime (uint32_t t =0);
DateTime (uint16_t year, uint8_t month, uint8_t day,
uint8_t hour =0, uint8_t min =0, uint8_t sec =0);
DateTime (const DateTime& copy);
DateTime (const char* date, const char* time);
DateTime (const __FlashStringHelper* date, const __FlashStringHelper* time);
uint16_t year() const { return 2000 + yOff; }
uint8_t month() const { return m; }
uint8_t day() const { return d; }
uint8_t hour() const { return hh; }
uint8_t minute() const { return mm; }
uint8_t second() const { return ss; }
uint8_t dayOfTheWeek() const;
// 32-bit times as seconds since 1/1/2000
long secondstime() const;
// 32-bit times as seconds since 1/1/1970
uint32_t unixtime(void) const;
DateTime operator+(const TimeSpan& span);
DateTime operator-(const TimeSpan& span);
TimeSpan operator-(const DateTime& right);
protected:
uint8_t yOff, m, d, hh, mm, ss;
};
// Timespan which can represent changes in time with seconds accuracy.
class TimeSpan {
public:
TimeSpan (int32_t seconds = 0);
TimeSpan (int16_t days, int8_t hours, int8_t minutes, int8_t seconds);
TimeSpan (const TimeSpan& copy);
int16_t days() const { return _seconds / 86400L; }
int8_t hours() const { return _seconds / 3600 % 24; }
int8_t minutes() const { return _seconds / 60 % 60; }
int8_t seconds() const { return _seconds % 60; }
int32_t totalseconds() const { return _seconds; }
TimeSpan operator+(const TimeSpan& right);
TimeSpan operator-(const TimeSpan& right);
protected:
int32_t _seconds;
};
// RTC based on the DS1307 chip connected via I2C and the Wire library
enum Ds1307SqwPinMode { OFF = 0x00, ON = 0x80, SquareWave1HZ = 0x10, SquareWave4kHz = 0x11, SquareWave8kHz = 0x12, SquareWave32kHz = 0x13 };
class RTC_DS1307 {
public:
boolean begin(void);
static void adjust(const DateTime& dt);
uint8_t isrunning(void);
static DateTime now();
static Ds1307SqwPinMode readSqwPinMode();
static void writeSqwPinMode(Ds1307SqwPinMode mode);
uint8_t readnvram(uint8_t address);
void readnvram(uint8_t* buf, uint8_t size, uint8_t address);
void writenvram(uint8_t address, uint8_t data);
void writenvram(uint8_t address, uint8_t* buf, uint8_t size);
};
// RTC based on the DS3231 chip connected via I2C and the Wire library
enum Ds3231SqwPinMode { DS3231_OFF = 0x01, DS3231_SquareWave1Hz = 0x00, DS3231_SquareWave1kHz = 0x08, DS3231_SquareWave4kHz = 0x10, DS3231_SquareWave8kHz = 0x18 };
class RTC_DS3231 {
public:
boolean begin(void);
static void adjust(const DateTime& dt);
bool lostPower(void);
static DateTime now();
static Ds3231SqwPinMode readSqwPinMode();
static void writeSqwPinMode(Ds3231SqwPinMode mode);
};
// RTC based on the PCF8523 chip connected via I2C and the Wire library
enum Pcf8523SqwPinMode { PCF8523_OFF = 7, PCF8523_SquareWave1HZ = 6, PCF8523_SquareWave32HZ = 5, PCF8523_SquareWave1kHz = 4, PCF8523_SquareWave4kHz = 3, PCF8523_SquareWave8kHz = 2, PCF8523_SquareWave16kHz = 1, PCF8523_SquareWave32kHz = 0 };
class RTC_PCF8523 {
public:
boolean begin(void);
void adjust(const DateTime& dt);
boolean initialized(void);
static DateTime now();
Pcf8523SqwPinMode readSqwPinMode();
void writeSqwPinMode(Pcf8523SqwPinMode mode);
};
// RTC using the internal millis() clock, has to be initialized before use
// NOTE: this clock won't be correct once the millis() timer rolls over (>49d?)
class RTC_Millis {
public:
static void begin(const DateTime& dt) { adjust(dt); }
static void adjust(const DateTime& dt);
static DateTime now();
protected:
static long offset;
};
#endif // _RTCLIB_H

View File

@ -0,0 +1,401 @@
#include "Timer_lite.h"
//** CONSTRUCTOR **
Timer_lite::Timer_lite(uint8_t relay_pin)
{
setRelayPin(relay_pin);
_init();
}
Timer_lite::Timer_lite(uint8_t relay_pin, uint8_t initial_eeprom_address)
{
setRelayPin(relay_pin);
_init(initial_eeprom_address);
}
//** DESTRUCTOR **
Timer_lite::~Timer_lite()
{
}
//** MÉTODOS PRIVADOS**
// Para constructor
void Timer_lite::_init(uint8_t initial_eeprom_address = 0)
{
_instancia_num = ++_instancias_num;
_eeprom_address_tiempo_inicio_espera = initial_eeprom_address;
_eeprom_address_tiempo_arranque = initial_eeprom_address +4;
_eeprom_address_tiempo_arranque_espera = initial_eeprom_address +8;
_eeprom_address_tiempo_encendido = initial_eeprom_address +12;
_eeprom_address_tiempo_encendido_espera = initial_eeprom_address +16;
_eeprom_address_timer_detenido = initial_eeprom_address +20;
}
// EEPROM
void Timer_lite::EEPROMWritelong(uint8_t address, uint32_t value)
{
//Decomposition from a long to 4 bytes by using bitshift.
//One = Most significant -> Four = Least significant byte
uint8_t four = (value & 0xFF);
uint8_t three = ((value >> 8) & 0xFF);
uint8_t two = ((value >> 16) & 0xFF);
uint8_t one = ((value >> 24) & 0xFF);
//Write the 4 bytes into the eeprom memory.
EEPROM.write(address, four);
EEPROM.write(address + 1, three);
EEPROM.write(address + 2, two);
EEPROM.write(address + 3, one);
}
uint32_t Timer_lite::EEPROMReadlong(uint8_t address)
{
//Read the 4 bytes from the eeprom memory.
uint32_t four = EEPROM.read(address);
uint32_t three = EEPROM.read(address + 1);
uint32_t two = EEPROM.read(address + 2);
uint32_t one = EEPROM.read(address + 3);
//Return the recomposed long by using bitshift.
return ((four << 0) & 0xFF) + ((three << 8) & 0xFFFF) + ((two << 16) & 0xFFFFFF) + ((one << 24) & 0xFFFFFFFF);
}
// Proximo periodo
/*
void Timer_lite::proximoPeriodo()
{
switch (getPeriodo()){
case TIMER_INICIO_ESPERA:
_periodo = TIMER_ARRANQUE;
_periodo_time = getTiempoArranque();
break;
case TIMER_ARRANQUE:
_periodo = TIMER_ARRANQUE_ESPERA;
_periodo_time = getTiempoArranqueEspera();
break;
case TIMER_ARRANQUE_ESPERA:
_periodo = TIMER_ENCENDIDO;
_periodo_time = getTiempoEncendido();
break;
case TIMER_ENCENDIDO:
_periodo = TIMER_ENCENDIDO_ESPERA;
_periodo_time = getTiempoEncendidoEspera();
break;
case TIMER_ENCENDIDO_ESPERA:
_periodo = TIMER_ENCENDIDO;
_periodo_time = getTiempoEncendido();
break;
}
// Si Retraso o Arranque igual a 0, recalculamos
if((status_temporizador == TIMER_RETARDO || status_temporizador == TIMER_ARRANQUE) && periodo_time == 0)
procesar_proximo_periodo();
}
*/
//** MÉTODOS PUBLICOS **
// Set Fecha y Hora
void Timer_lite::setFechaHoraSistema()
{
_RTC.adjust(DateTime(__DATE__, __TIME__));
}
void Timer_lite::setFecha(uint16_t anho, uint8_t mes, uint8_t dia)
{
_RTC.adjust(DateTime(anho, mes, dia, _now.hour(), _now.minute(), _now.second()));
}
void Timer_lite::setHora(uint8_t hrs, uint8_t min, uint8_t seg)
{
_RTC.adjust(DateTime(_now.year(), _now.month(), _now.day(), hrs, min, seg));
}
void Timer_lite::setFechaHora(uint16_t anho, uint8_t mes, uint8_t dia, uint8_t hrs, uint8_t min, uint8_t seg)
{
_RTC.adjust(DateTime(anho, mes, dia, hrs, min, seg));
}
// Get Fecha y Hora
String Timer_lite::getFecha()
{
String year = (String) _now.year();
String month = (_now.month() < 10? "0": "") + (String) _now.month();
String day = (_now.day() < 10? "0": "") + (String) _now.day();
return day + "/" + month + '/' + year;
}
String Timer_lite::getHora()
{
String hour = (_now.hour() < 10? "0": "") + (String) _now.hour();
String minute = (_now.minute() < 10? "0": "") + (String) _now.minute();
String second = (_now.second() < 10? "0": "") + (String) _now.second();
return hour + ":" + minute + ':' + second;
}
// Configuraciones Hardware
void Timer_lite::setRelayPin(uint8_t relay_pin)
{
_relay_pin = relay_pin;
}
void Timer_lite::setRelaySatus(uint8_t relay_status)
{
_status_relay = relay_status;
digitalWrite(_relay_pin, relay_status);
}
uint8_t Timer_lite::getStatusRelay()
{
return _status_relay;
}
// Set Configuraciones Timer_lite
void Timer_lite::setTiempoInicioEspera(uint32_t segundos)
{
EEPROMWritelong(_eeprom_address_tiempo_inicio_espera, segundos);
}
void Timer_lite::setTiempoInicioEspera(uint8_t minutos, uint8_t segundos)
{
uint32_t _segundos = (minutos * 60) + segundos;
EEPROMWritelong(_eeprom_address_tiempo_inicio_espera, _segundos);
}
void Timer_lite::setTiempoArranque(uint32_t segundos)
{
EEPROMWritelong(_eeprom_address_tiempo_arranque, segundos);
}
void Timer_lite::setTiempoArranque(uint8_t horas, uint8_t minutos, uint8_t segundos)
{
uint32_t _segundos = (horas * 3600) + (minutos * 60) + segundos;
EEPROMWritelong(_eeprom_address_tiempo_arranque, _segundos);
}
void Timer_lite::setTiempoArranqueEspera(uint32_t segundos)
{
EEPROMWritelong(_eeprom_address_tiempo_arranque_espera, segundos);
}
void Timer_lite::setTiempoArranqueEspera(uint8_t horas, uint8_t minutos, uint8_t segundos)
{
uint32_t _segundos = (horas * 3600) + (minutos * 60) + segundos;
EEPROMWritelong(_eeprom_address_tiempo_arranque_espera, _segundos);
}
void Timer_lite::setTiempoEncendido(uint32_t segundos)
{
EEPROMWritelong(_eeprom_address_tiempo_encendido, segundos);
}
void Timer_lite::setTiempoEncendido(uint8_t horas, uint8_t minutos, uint8_t segundos)
{
uint32_t _segundos = (horas * 3600) + (minutos * 60) + segundos;
EEPROMWritelong(_eeprom_address_tiempo_encendido, _segundos);
}
void Timer_lite::setTiempoEncendidoEspera(uint32_t segundos)
{
EEPROMWritelong(_eeprom_address_tiempo_encendido_espera, segundos);
}
void Timer_lite::setTiempoEncendidoEspera(uint8_t horas, uint8_t minutos, uint8_t segundos)
{
uint32_t _segundos = (horas * 3600) + (minutos * 60) + segundos;
EEPROMWritelong(_eeprom_address_tiempo_encendido_espera, _segundos);
}
// Get Timer_lite EEPROM
uint32_t Timer_lite::getTiempoInicioEspera()
{
return EEPROMReadlong(_eeprom_address_tiempo_inicio_espera);
}
uint32_t Timer_lite::getTiempoArranque()
{
return EEPROMReadlong(_eeprom_address_tiempo_arranque);
}
uint32_t Timer_lite::getTiempoArranqueEspera()
{
return EEPROMReadlong(_eeprom_address_tiempo_arranque_espera);
}
uint32_t Timer_lite::getTiempoEncendido()
{
return EEPROMReadlong(_eeprom_address_tiempo_encendido);
}
uint32_t Timer_lite::getTiempoEncendidoEspera()
{
return EEPROMReadlong(_eeprom_address_tiempo_encendido_espera);
}
uint8_t Timer_lite::getTimerDetenido()
{
return EEPROM.read(_eeprom_address_timer_detenido);
}
// Get Status Timer_lite
uint8_t Timer_lite::getInstanciasNum()
{
return _instancias_num;
}
uint8_t Timer_lite::getInstanciaNum()
{
return _instancia_num;
}
uint8_t Timer_lite::getPeriodo()
{
return _periodo;
}
uint32_t Timer_lite::getFinPeriodoSeg()
{
return _fin_de_periodo_seg;
}
uint32_t Timer_lite::getRestantePeriodoSeg()
{
return _fin_de_periodo_seg - _now.unixtime();
}
// PROCESO DEL TEMPORIZADOR
void Timer_lite::initialize()
{
if(_instancia_num == 1){
Wire.begin();
if(!_RTC.begin())
//Serial.println("Couldn't find RTC");
serialPrintln("Couldn't find RTC");
if(_RTC.lostPower()){
//Serial.println("RTC lost power, lets set the time!");
serialPrintln("RTC lost power, lets set the time!");
//_RTC.adjust(DateTime(2021, 1, 1, 0, 0, 0));
}
_now = _RTC.now();
}
pinMode(_relay_pin, OUTPUT);
reiniciar();
}
void Timer_lite::process_loop()
{
if(_instancia_num == 1)
_now = _RTC.now();
if(getTimerDetenido()){
setRelaySatus(RELAY_OFF);
}else{
if(_now.unixtime() >= _fin_de_periodo_seg){
switch(_periodo){
case TIMER_INICIO_ESPERA:
_periodo = TIMER_ARRANQUE;
_fin_de_periodo_seg = _now.unixtime() + getTiempoArranque();
setRelaySatus(RELAY_ON);
break;
case TIMER_ARRANQUE:
_periodo = TIMER_ARRANQUE_ESPERA;
_fin_de_periodo_seg = _now.unixtime() + getTiempoArranqueEspera();
setRelaySatus(RELAY_OFF);
break;
case TIMER_ENCENDIDO:
_periodo = TIMER_ENCENDIDO_ESPERA;
_fin_de_periodo_seg = _now.unixtime() + getTiempoEncendidoEspera();
setRelaySatus(RELAY_OFF);
break;
case TIMER_ARRANQUE_ESPERA:
case TIMER_ENCENDIDO_ESPERA:
_periodo = TIMER_ENCENDIDO;
_fin_de_periodo_seg = _now.unixtime() + getTiempoEncendido();
setRelaySatus(RELAY_ON);
break;
}
}
/*
// Una vez cada segundo por Instancia
if(_now.unixtime() >= _T[2] +1) {
writeMemory(_memory_address_periodo_time, --_periodo_time, 4);
if(_periodo_time <= 0)
proximoPeriodo();
// Estatus del relevador
_status_relay = (_periodo == TIMER_ARRANQUE || _periodo == TIMER_ENCENDIDO) && _periodo_time > 0;
digitalWrite(_relay_pin, _status_relay);
_T[2] = _now.unixtime();
}
*/
}
}
// Reinicio y detener del temporizador
void Timer_lite::detener()
{
EEPROM.write(_eeprom_address_timer_detenido, 1);
_restante_del_periodo_seg = _fin_de_periodo_seg - _now.unixtime();
}
void Timer_lite::reanudar()
{
EEPROM.write(_eeprom_address_timer_detenido, 0);
_fin_de_periodo_seg = _now.unixtime() + _restante_del_periodo_seg;
}
void Timer_lite::reiniciar()
{
setRelaySatus(RELAY_OFF);
_periodo = TIMER_INICIO_ESPERA;
_fin_de_periodo_seg = _now.unixtime() + getTiempoInicioEspera();
}

View File

@ -0,0 +1,153 @@
/*
Timer_lite.h - Librería para temporizador ligero
Copyright (c) 2021 Koneko Microcontroladores. Todos los derechos reservados.
Autor: Arturo Corro arturo@koneko.mx
Versiones: 0.1.0
v0.0.1 - May 2, 2021 - Versión inicial
RTClib
https://github.com/adafruit/RTClib
Direcciones de memoria 0x07-0x0D (0-6)
*/
#ifndef Timer_lite_H
#define Timer_lite_H
#include <Arduino.h>
#include <EEPROM.h>
#include <Wire.h>
#include "RTClib.h"
//#define DEBUG_SERIAL_ENABLE
#define dbSerial Serial
#ifdef DEBUG_SERIAL_ENABLE
#define serialPrint(a) dbSerial.print(a)
#define serialPrintln(a) dbSerial.println(a)
#define serialBegin(a) dbSerial.begin(a)
#define serialBeginWhile(a) while(!dbSerial) delay(1)
#else
#define serialPrint(a) do{}while(0)
#define serialPrintln(a) do{}while(0)
#define serialBegin(a) do{}while(0)
#define serialBeginWhile(a) do{}while(0)
#endif
#define RELAY_OFF HIGH
#define RELAY_ON LOW
#define TIMER_DETENIDO 0
#define TIMER_INICIO_ESPERA 1
#define TIMER_ARRANQUE 2
#define TIMER_ARRANQUE_ESPERA 3
#define TIMER_ENCENDIDO 4
#define TIMER_ENCENDIDO_ESPERA 5
class Timer_lite
{
private:
// Numero de instancias
static uint8_t _instancias_num;
uint8_t _instancia_num;
// Direcciones de Hardware
uint8_t _relay_pin;
// EEPROM ADDRESS
uint8_t _eeprom_address_tiempo_inicio_espera;
uint8_t _eeprom_address_tiempo_arranque;
uint8_t _eeprom_address_tiempo_arranque_espera;
uint8_t _eeprom_address_tiempo_encendido;
uint8_t _eeprom_address_tiempo_encendido_espera;
uint8_t _eeprom_address_timer_detenido;
// Uso del temporizador
uint8_t _periodo;
uint32_t _fin_de_periodo_seg;
uint32_t _restante_del_periodo_seg;
uint8_t _status_relay;
// Contador para ciclo
//uint32_t _T[3];
//** MÉTODOS PRIVADOS**
void _init(uint8_t initial_eeprom_address = 0);
void EEPROMWritelong(uint8_t address, uint32_t value);
uint32_t EEPROMReadlong(uint8_t address);
//void proximoPeriodo();
public:
// Fecha y hora, Reloj de Tiempo Real
static DateTime _now;
static RTC_DS3231 _RTC;
//** CONSTRUCTOR **
Timer_lite(uint8_t relay_pin);
Timer_lite(uint8_t relay_pin, uint8_t initial_eeprom_address);
//** DESTRUCTOR **
~Timer_lite();
// Relay
void setRelayPin(uint8_t relay_pin);
void setRelaySatus(uint8_t relay_status);
// Configuraciones Timer_lite
void setTiempoInicioEspera(uint32_t segundos);
void setTiempoInicioEspera(uint8_t minutos, uint8_t segundos);
void setTiempoArranque(uint32_t segundos);
void setTiempoArranque(uint8_t horas, uint8_t minutos, uint8_t segundos);
void setTiempoArranqueEspera(uint32_t segundos);
void setTiempoArranqueEspera(uint8_t horas, uint8_t minutos, uint8_t segundos);
void setTiempoEncendido(uint32_t segundos);
void setTiempoEncendido(uint8_t horas, uint8_t minutos, uint8_t segundos);
void setTiempoEncendidoEspera(uint32_t segundos);
void setTiempoEncendidoEspera(uint8_t horas, uint8_t minutos, uint8_t segundos);
// Set Fecha y Hora
void setFecha(uint16_t anho, uint8_t mes, uint8_t dia);
void setHora(uint8_t hrs, uint8_t min, uint8_t seg);
void setFechaHora(uint16_t anho, uint8_t mes, uint8_t dia, uint8_t hrs, uint8_t min, uint8_t seg);
void setFechaHoraSistema();
// Get Fecha y Hora
String getFecha();
String getHora();
// Status Timer_lite
uint8_t getInstanciasNum();
uint8_t getInstanciaNum();
uint8_t getPeriodo();
uint32_t getFinPeriodoSeg();
uint32_t getRestantePeriodoSeg();
uint8_t getStatusRelay();
uint32_t getTiempoInicioEspera();
uint32_t getTiempoArranque();
uint32_t getTiempoArranqueEspera();
uint32_t getTiempoEncendido();
uint32_t getTiempoEncendidoEspera();
uint8_t getTimerDetenido();
// Metodos de control
void detener();
void reanudar();
void reiniciar();
// PROCESO DEL TEMPORIZADOR
void initialize();
void process_loop();
};
#endif

View File

@ -0,0 +1,49 @@
#######################################
# Syntax Coloring Map For ExampleLibrary
#######################################
#######################################
# Datatypes (KEYWORD1)
#######################################
Temporizador KEYWORD1
~Temporizador KEYWORD1
#######################################
# Methods and Functions (KEYWORD2)
#######################################
procesar_proximo_periodo KEYWORD2
proceso_temporizador KEYWORD2
reiniciar_temporizador KEYWORD2
instancias_num KEYWORD2
setEepromAddressTiempoInicioEspera KEYWORD2
setEepromAddressTiempoArranque KEYWORD2
setEepromAddressTiempoArranqueEspera KEYWORD2
setEepromAddressTiempoActivo KEYWORD2
setEepromAddressTiempoActivoEspera KEYWORD2
setFmramAddressStatusTemporizador KEYWORD2
setFmramAddressPeriodoTime KEYWORD2
setDS3231Adress KEYWORD2
setFmramAdress KEYWORD2
setRelayPin KEYWORD2
inizializar KEYWORD2
procesarTemporizador KEYWORD2
setAutoinicio KEYWORD2
#######################################
# Instances (KEYWORD2)
#######################################
#######################################
# Constants (LITERAL1)
#######################################
AUTOINICIO_CONFIRMACION LITERAL1
AUTOINICIO_ESPERA LITERAL1
AUTOINICIO_INMEDIATO LITERAL1

View File

@ -0,0 +1,10 @@
name=Temporizador
version=0.0.1
author=FaradayBits <arturocorro@hotmail.com>
maintainer=FaradayBits <arturo@elitesystems.mx>
sentence=Temporizador Diken International
paragraph=Temporizador Diken International
category=Device Control
url=
architectures=avr
includes=EEPROM.h,Wire.h,RTClib.h,FM24I2C.h

View File

@ -0,0 +1,5 @@
Temporizador con Sensor
Arturo Corro Pacheco
arturo@elitesystems.mx