zanduino / mcp7940 Goto Github PK
View Code? Open in Web Editor NEWArduino Library to access the MCP7940M, MCP7940N and MCP7940x Real-Time chips
License: GNU General Public License v3.0
Arduino Library to access the MCP7940M, MCP7940N and MCP7940x Real-Time chips
License: GNU General Public License v3.0
Hello !
First of all, thank you for this librairy !
In the documentation, it is said that the RTC memorize power outage time/ date and when the power comes back on, how do we obtain these times/dates ?
Hello,
Can anybody help me te set an alarm at a day of the week(1-7). I want to create an interrupt(MFP) on a day-of-the-week, other than just a day in the month. is that possible?
the line i am using is:
/*
MCP7940.setAlarm(0,3,DateTime(0,0,3,0,0,0));
kind regards,
Wim
Describe what the feature request is and if it solves an issue or adds functionality
Create a more robust and optimized library
Describe the solution you'd like
Apply some new c++ knowledge, particularly around making the library more rounded and robust and attempt to minimize the memory footprint
Describe alternatives you've considered
n/a
Additional context
n/a
The constants and the function arguments for setting the I2C clock speed are uint_16t, but the actual values are out of range (100000, 400000), hence they are truncated (compiler throws a warning).
Fix:
in MCP7940.h line 72 & 73
#ifndef I2C_MODES // I2C related constants //
#define I2C_MODES // Guard code to prevent multiple //
const uint16_t I2C_STANDARD_MODE = 100000; // Default normal I2C 100KHz speed //
const uint16_t I2C_FAST_MODE = 400000; // Fast mode //
#endif
line 185:
bool begin(const uint16_t i2cSpeed = I2C_STANDARD_MODE);
in MCP7940.cpp line 231
bool MCP7940_Class::begin(const uint16_t i2cSpeed) {
...
change the uint16_t to uint32_t
Arduino Wire library expects an uint32_t passed to the setClock method.
Hello , i want to create OTP token using Arduino TOTP Library. I dont know how to get number of seconds since Epoch using your library. Can you help please ?
MCP7940-master/MCP7940.h:176:19: error: extra qualification 'MCP7940_Class::' on member 'readRAM' [-fpermissive]
uint8_t& MCP7940_Class::readRAM(const uint8_t addr,T &value) { // //
^
MCP7940-master/MCP7940.h:190:12: error: extra qualification 'MCP7940_Class::' on member 'writeRAM' [-fpermissive]
bool MCP7940_Class::writeRAM(const uint8_t addr, const T &value) { // the MCP7940 SRAM //
^
exit status 1
Error compiling for board Generic ESP8266 Module.
Hi
for particular project i need to cancel a setAlarm setting. For example i set a alarm, but in a specific condition is possible to cancel the alarm settings so that this is not generated?
Thanks
Describe what the feature request is and if it solves an issue or adds functionality
At present there is no sketch for regression testing of new code and such a sketch should be added and documented
Describe the solution you'd like
Write a "RegressionTests.ino" sketch that calls up all functions in the library and determines, where possible, if the functions are working as expected.
Describe alternatives you've considered
n/a
Additional context
n/a
The MCP7940 supports up to 400KHz I2C Speeds, allow the user to specify this faster Speed.
Ensure Regression tests and that the new functionality in #16 works as specified. Need to dig out an unused MCP7940 and put together a test bench for this.
A DateTime object initialised to zero should resolve to the unix epoch, i.e. 1/1/1970 00:00:00
I'm trying to initialise the time component to 00:00:00. This seems the easiest way.
The actual output is 6/2/2106 6:28:16
Minimum reproducible code:
#include <MCP7940.h>
void setup() {
Serial.begin(115200);
DateTime dt1 = DateTime(0);
// DateTime dt1(0); // produces same result
Serial.println(dt1.unixtime());
Serial.print(dt1.day());
Serial.print("/");
Serial.print(dt1.month());
Serial.print("/");
Serial.print(dt1.year());
Serial.print(" ");
Serial.print(dt1.hour());
Serial.print(":");
Serial.print(dt1.minute());
Serial.print(":");
Serial.print(dt1.second());
Serial.println();
}
void loop() {
}
Output is:
0
6/2/2106 6:28:16
If I construct the object as
DateTime dt1(1970, 1, 1, 0, 0, 0);
the output is:
2269013504
1/1/2178 0:0:0
calibrate() checks if the local variable int8_t trim
goes out of bound of 130 and -130.
However a 8bit value cannot exceed [128,-127], so checking for an out of bound condition at this point is too late, since it already happened.
Affected lines of code:
https://github.com/SV-Zanshin/MCP7940/blob/0678a66569f9ea81a9d959c8c6cce5247a6916eb/src/MCP7940.cpp#L497 [...]
https://github.com/SV-Zanshin/MCP7940/blob/0678a66569f9ea81a9d959c8c6cce5247a6916eb/src/MCP7940.cpp#L511-L516
Fix:
I think the trim value should be changed to a uint16_t. calibrate(uint8_t) needs to be fixed accordingly too.
I believe this line:
int32_t SecDeviation = dt.unixtime()-now().unixtime();
needs to be this:
int32_t SecDeviation = now().unixtime()-dt.unixtime();
So that the sign of the trim is correct.
thanks
Or no clear example on how to do this properly.
BTW, thanks for making this library... it seems super thorough :-)
I have the TestBatteryBackup example working, and I can disconnect 3V to the MCP7940N and then reconnect and it keeps time fine... but if I pull power to the microcontroller, and re-connect, time is reset.
I though it was due to the
MCP7940.adjust();
Being called in start, but if I change that to look for the powerfail flag and and adjust based on the power restore time and clear the flag, it doesn't work.
Am I missing something here? The entire purpose of a battery backed RTC is to keep time when power to the main device is down, but I can't find any code setup that does this.
Thanks!
Seon
unexpectedmaker.com
Hi, I saw that you created the Square Wave Output function. The mcp7940 has two methods to be calibrated. One is what you have already implemented. the second is to measure the quartz frequency and correct the difference between the measurement and the nominal value.
Could you create a function that allows you to measure the frequency and calibrate the mcp7940?
rif datasheet equation 5-2 (calculating trim value from measured frequency)
Hi Zanshin,
Nice job with the library. But It looks like the library doesn't compile for SAMD21 based boards such as Arduino M0, or adafruit Feather M0. I am not an expert, but I happen to be using these boards, not sure what is wrong...
BR.
Newerbee
Hi
in the file Keyword.txt where is'nt the setAlarmPolarity key. Could you add it?
hello guys,
In my case, i get the code stuck in "waiting for power" once i remove the VCC pin from 3.3V and get it back. I'm also attaching a CR2032 coin cell to VBAT pin.
Originally posted by @manaioussema in #45 (comment)
Hi
i have tested the new version but i have another issue. if i run the code:
#include <MCP7940.h>
MCP7940_Class MCP7940;
DateTime now;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
MCP7940.adjust(DateTime(2018, 04, 29, 23, 59, 45));
MCP7940.setAlarm(1, 7, DateTime(2018, 04, 30, 0, 0, 10));
}
void loop() {
// put your main code here, to run repeatedly:
delay(1000);
now = MCP7940.now();
Serial.print(now.day());
Serial.print("/");
Serial.print(now.month());
Serial.print("/");
Serial.print(now.year());
Serial.print(" ");
Serial.print(now.hour());
Serial.print(":");
Serial.print(now.minute());
Serial.print(":");
Serial.println(now.second());
if (MCP7940.isAlarm(0)) {
Serial.print("Alarm0*");
MCP7940.clearAlarm(0);
}
the alarm is generated at 2018/04//30 0:0:0 but i expected the alarm at 2018/04//30 0:0:10
regards
Marco Lai
Hello,
I'm finding that adjust() is working ok on initialisation in the setup() routine
however I have a menu-driven date and time input system to allow the user to
set their correct time. When I just use setTime() from the Arduino library it works
(at least sets the time locally) however if I use the the MCP7940.adjust(DateTime)
the system freezes. At the end of the menu input I have even hardcoded a value
to see if I can get it to work: MCP7940.adjust(DateTime(2020,9,9,18,19,20));
but that has the same problem.
It is strange that during setup I can adjust the date to any hardcoded value using on the
RTC but this doesn't help me allow the user to set their own date/time.
Any ideas would be appreciated,
thanks,
Stuart
hi
i have found a problem when i use the alarm function.
i use the mach_all_alarm and the mfp output do not generated when the date and the time corresponded at the dow = 0.
In the datasheet the day of the week is beetween 1 and 7 but the function dayOfTheWeek() in your library produce numbert beetween 0 and 6.
this code simulate the problem:
#include <MCP7940.h>
#include "LowPower.h"
MCP7940_Class MCP7940;
DateTime timing;
DateTime allarme;
DateTime prox;
DateTime prova;
byte alarmtype = 0;
enum alarmTypes { matchSeconds, matchMinutes, matchHours, matchDayOfWeek, matchDayOfMonth, Unused1, Unused2, matchAll, Unknown};
void wakeUp()
{
//incrementa la variabile
Serial.println("-------wakeUp-------");
delay(100);
}
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
MCP7940.begin();
delay(500);
MCP7940.setBattery(true);
//set date time
MCP7940.adjust(DateTime(2018, 6, 17, 0, 53, 0));
//retrivie date e time
timing = MCP7940.now();
Serial.print("NOW ");
Serial.print(timing.day());
Serial.print("/");
Serial.print(timing.month());
Serial.print("/");
Serial.print(timing.year());
Serial.print(" ");
Serial.print(timing.hour());
Serial.print(":");
Serial.print(timing.minute());
Serial.print(":");
Serial.println(timing.second());
//set alarm at 10 second from current time
timing = timing + TimeSpan(0, 0, 0, 10);
MCP7940.setAlarm(0, 7, DateTime(timing.year(), timing.month(), timing.day(), timing.hour(), timing.minute(), timing.second()));
//verify if the allarm is set correctly
allarme = MCP7940.getAlarm(0, alarmtype);
Serial.print("ALLARME ");
Serial.print(allarme.day());
Serial.print("/");
Serial.print(allarme.month());
Serial.print("/");
Serial.print(allarme.year());
Serial.print(" ");
Serial.print(allarme.hour());
Serial.print(":");
Serial.print(allarme.minute());
Serial.print(":");
Serial.println(allarme.second());
}
void loop() {
delay(1000);
attachInterrupt(digitalPinToInterrupt(2), wakeUp, LOW);
//Serial.println("----POWER DOWN----");
//Serial.println("");
//Serial.flush();
// Enter power down state with ADC and BOD module disabled.
// Wake up when wake up pin is low.
//LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);
// Disable external pin interrupt on wake up pin.
detachInterrupt(digitalPinToInterrupt(2));
if (MCP7940.isAlarm(0)) {
Serial.println("-------ALLARME-------");
MCP7940.clearAlarm(0);
prox = MCP7940.now();
prox = prox + TimeSpan(1, 0, 0, 0);
MCP7940.adjust(prox);
prox = MCP7940.now();
Serial.print("PROX ");
Serial.print(prox.day());
Serial.print("/");
Serial.print(prox.month());
Serial.print("/");
Serial.print(prox.year());
Serial.print(" ");
Serial.print(prox.hour());
Serial.print(":");
Serial.print(prox.minute());
Serial.print(":");
Serial.print(prox.second());
Serial.print(" WOD ");
Serial.println(prox.dayOfTheWeek());
timing = MCP7940.now();
timing = timing + TimeSpan(0, 0, 0, 5);
Serial.print("ALARM ");
Serial.print(timing.day());
Serial.print("/");
Serial.print(timing.month());
Serial.print("/");
Serial.print(timing.year());
Serial.print(" ");
Serial.print(timing.hour());
Serial.print(":");
Serial.print(timing.minute());
Serial.print(":");
Serial.print(timing.second());
Serial.print(" WOD ");
Serial.println(timing.dayOfTheWeek());
MCP7940.setAlarm(0, 7, DateTime(timing.year(), timing.month(), timing.day(), timing.hour(), timing.minute(), timing.second()));
}
}
i have modified the dayOfTheWeek() function adding 1 at the result and my code run correctly
uint8_t DateTime::dayOfTheWeek() const {
uint16_t day = date2days(yOff, m, d);
return ((day + 6) % 7)+1; //add 1 at the result
} // of method dayOfTheWeek()
you could verify that
regards
Marco Lai
I tested your methods to calibrate by time deviation. As long as trim value is positive, everything is fine.
When I setup a deviation of -1 second and an ExpectedSec of 1 day (86400 secs), the first trim value is -10 what should be correct. I started a new calibration with the same deviation and ExpectedSec then, expecting a new trim value of -20 (Using positive values that is exacty what happened 10, 20, 30, ...).
Unfortunately the method calculated a new trim of 108, which is completely wrong obviously, followed by 98, 88, 78,...
While searching the reason I noticed that you simply write negative trim values to RTC what is invalid regarding to MCP7940 datasheet p. 29. As it is described there, the absolute value of trim must be saved in register bits [0-6]. Setting SIGN bit [7] to 1 will then result in adding this amount of clock cycles. (subtracting for 0 vice versa).
Therefore I suggest changing
int8_t MCP7940_Class::calibrate(const int8_t newTrim) {
int8_t trim = newTrim; // Make a local copy //
if (trim < 0) { // if the trim is less than 0, then //
trim = 0x80 | (trim * -1); // set non-excess 128 negative val //
}
to
int8_t MCP7940_Class::calibrate(const int8_t newTrim) {
uint8_t trim = abs(newTrim); // Get abs //
if (newTrim < 0) // if the trim is less than 0, then //
{
trim = 0x80 | trim; // SET SIGN Bit to add clock cycles //
}
And
int8_t MCP7940_Class::calibrate(const DateTime& dt) {
...
if (trim >> 7) { // use negative value if necessary //
trim = trim * -1;
}
...
to
int8_t MCP7940_Class::calibrate(const DateTime& dt) {
...
if (trim >> 7) // if SIGN Bit is set //
{
trim = (~0x80 & trim) * -1; // Clear SIGN Bit and make negative //
}
...
These changings seem to lead in the expeced behaviour.
Code snippet below is from Line 250 of MCP7940.cpp
. Both #if
and #elif
conditions are the same. Wire.begin()
never gets called. if ESP8266
is not defined.
#if defined(ESP8266)
Wire.begin(sda, scl); // Start I2C as master device using the specified SDA and SCL
#elif defined(ESP8266)
Wire.begin(); // Start I2C as master device
#endif
Changing `#elif defined(ESP8266)` to `#else` solves the issue.
- Library Version: 1.2.0
- Testing on Arduino Due
Hello
I have a problem. after setting the time and date in the mcp7940, if I remove main power to the RTC and after a few minutes, i give power to the RTC, the time and date are reset to 1/1/2001 0:0:0.
(the battery backup is connected and it is charged)
the time data is not retained in memory and is not increased!!
you can verify this
regards
According to function header notes, the return type is a "Pointer to return data structure". This does not make sense as there is no data structure returned. The method behaviour is to populate the variable that is passed in by reference. E.g.:
uint32_t someValue;
rtc.readRam(0, someValue);
Upon execution, someValue
contains the value read from RTC RAM.
Instead of returning a "pointer to return data structure", the function actually returns the number of bytes read by I2C_READ. However, I believe this is also incorrect: The return type of readRAM is defined as uint8_t&
. This is a problem because it is returning a reference to the local variable i
, which immediately goes out of scope, resulting in potentially undefined behaviour (generating appropriate compiler warnnings).
MCP7940 rtc;
rtc.begin();
uint32_t contents, temp;
temp = rtc.ramRead(0, contents);
src/rtc.cpp:38:51: required from here
.pio/libdeps/esp-wrover-kit/MCP7940/src/MCP7940.h:284:13: warning: reference to local variable 'i' returned [-Wreturn-local-addr]
uint8_t i = I2C_read((addr % 64) + MCP7940_RAM_ADDRESS, value);
I believe the correct implementation would be:
template <typename T>
uint8_t readRAM(const uint8_t& addr, T& value) const {
/*!
@brief Template for readRAM()
@details As a template it can support compile-time data type definitions
@param[in] addr Memory address
@param[in] value Data Type "T" to read
@return Pointer to return data structure
*/
return I2C_read((addr % 64) + MCP7940_RAM_ADDRESS, value);
} // of method readRAM()
This simply returns the number of bytes read, rather than a reference to the number of bytes read.
I was looking though the code and saw something that looked odd to me. Lines 469 - 473 seem to be doing nothing. Here are the lines.
int8_t trim = abs(newTrim); // Make a local copy of absolute value
if (newTrim < 0) // if the trim is less than 0
{
trim = 0x80 | trim; // set non-excess 128 negative val
} // of if-then value of trim is less than 0
A new variable trim
is set equal to the absolute value of the passed in newTrim
which makes bit 8 of trim
0. Then, if newTrim
is negative trim
is or'ed with 0x80 which flips bit 8 back to 1. I fail to see the point of this code. It seems to be setting bit 8 to 0 and then if it was originally 1 it sets it back to 1. Why not just use the passed in trim value directly?
As a side-effect of other changes the initialization of the MCP7940's date and time no longer works when setting it from the library compile-time.
Add rule so that years divisible by 100 but not divisible by 400 are not leap years
Adding new begin() method for selectable pins of Wire library
To communicate ESP chips to MCP7940, we need to set up pins, which means we need to pass the number of GPIO to the MCP7940 class
Adding a new begin(SDA_PIN, SCL_PIN) method to the library
To connect the chips, in which i2C pins can be selected, a new method should be added to the library in both .h and .cpp files
Adding begin(SDA_PIN, SCL_PIN) header file
bool begin(int sda, int scl, const uint32_t i2cSpeed = I2C_STANDARD_MODE) const;
I have changed and tested your library with ESP chips and have attached them here.
MCP7940.zip
I've before worked with this RTC with the ATmega328P and it worked great. Now I've build a board around the new ATmega328PB, using the MiniCore, and I'm running into some weird problems.
First I found out the battery backup doesn't work. My multimeter shows voltage at the VBAT pin (about 2.5V - a fresh 3V battery minus a diode drop) , but it doesn't keep the time over power cycles as it should.
Also I had to replace the simple MCP7940.adjust() calls with this:
char d[13];
strcpy_P(d, PSTR(__DATE__));
char t[13];
strcpy_P(t, PSTR(__TIME__));
DateTime dt = DateTime(d, t);
MCP7940.adjust(dt); // Set to library compile Date/Time //
This code works properly setting the time to the compile time Jan 22 2020 at 22:30:04; the adjust() function sets the time to "2075-01-30 32:50:50" (yes, hour 32! No idea how that is even possible). This accounts for both the TestBatteryBackup sketch and the SetAndCalibrate sketch.
As long as the power is up, the time runs just fine. So the chip appears to be in proper working order, and communicates as it should. The ATmega328PB itself runs at 18.432 MHz, Vcc = 5V.
Hi,
I've tried your library on RPI2040. RPI2040 has 2pc of 2wire interfaces, and unfortunately the MCP7940 is connected to the i2c1 (Wire1) interface on my board, so it won't worked as Wire is hard wired in the library.
I've modified the code to be able to use Wire1 also. Now it can be set as an optional parameter to the MCP7940_Class constructor: MCP7940_Class MCP7940(&Wire1); // Create an instance of the MCP7940
Here are my modified files, include them in the next version if you find it useful:
MCP7940.cpp.txt
MCP7940.h.txt
One more problem:
It could be some configuration problem, but for some reason PlatformIO sees only and downloads version 1.2.0 of the library instead of the newest one.
When the date and time is set using the Adjust() function, the weekday in the registry is sometimes not correct afterwards. For me this is mainly a problem because it causes the alarm to not work when using alarmType=0x7.
The problem only occurs in some chips. It seems some batches are more affected then others. This makes reproduction somewhat tricky. For issue 4 what I had to do to reproduce was:
The adjust() function resets the RTCWDAY, PWRFAIL bit and VBATEN bit somehow; this function should only affect the WDAY2-WDAY0 bits?
So if you use a backup battery and multiple adjust() functions in the main loop, the battery will be disabled whenever you call the adjust() function moving forward.
I think this line:
writeByte(MCP7940_RTCSEC,readByte(MCP7940_RTCHOUR)&B10111111);
Should be
writeByte(MCP7940_RTCHOUR,readByte(MCP7940_RTCHOUR)&B10111111);
Thanks for the project.
In file included from C:\Users\Donald\Documents\Arduino\libraries\MCP7940\examples\SquareWave\SquareWave.ino:37:0:
C:\Users\Donald\Documents\Arduino\libraries\MCP7940\src/MCP7940.h: In member function 'uint8_t& MCP7940_Class::readRAM(uint8_t, T&)':
C:\Users\Donald\Documents\Arduino\libraries\MCP7940\src/MCP7940.h:238:17: error: 'BUFFER_LENGTH' was not declared in this scope
if (i%BUFFER_LENGTH==0) { // Read I2C again on buffer boundary//
Add "clang-format" to source files
Add and configure Travis-CI
I need to control a PWR supply for a MCU. For that I need the MFP to output a logic 1.
How do I set the MFP pin to 1 ?
SetMFP() should return false if pin is being used for square wave or alarm output. The statement to test the control register (line 538) is incorrect and never gives a true result (to cause function to return false) because of operator precedence ('&' is below equals/not equals test). It should be if ((registerValue & 0x70) != 0)
hi
in your code the mask bit for the hour register is 7F
from DateTime MCP7940_Class::now()
_hh = bcd2int(Wire.read() & 0x7F);
the correct mask should be 0x3F because the bit6 set the 12/24 format and should be exclude it
the mask bit is present in the follow functions
DateTime MCP7940_Class::now()
DateTime MCP7940_Class::getPowerDown()
DateTime MCP7940_Class::getPowerUp()
regards
Marco
Also integrate the automated production of doxygen output using Travis-CI
In the file "MCP7940.cpp" there are while-loops with a timeout after the Wire.requestFrom. Those while-loops and those timeouts are not needed and can be removed.
When the Wire.requestFrom() returns, the I2C transaction has completely finished and the received data is waiting in a buffer in the Wire library.
To check if the I2C transaction was successful, you may compare the number of requested bytes to the number of bytes that have been received and are waiting in a buffer.
Wire.requestFrom( Wire.requestFrom(MCP7940_ADDRESS, (uint8_t)7);
if( Wire.available() == 7) {
// good
} else {
// fail
}
Hi
setting an alarm for the next day, this is not generated when alarmTypes is set to matchAll. I checked the code and it seems that the problem is in the setAlarm function because the MCP7940_RTCWKDAY is not set for the next day but remains set at the previous day.
thanks
Another thought I was having about calibrate is with regard to the PPM being adjusted to be within the range -130 to 130. I know this is done to keep the trim from overflowing -127/127, but if the PPM is out of range then the time has gotten WAY off. For example ~34 min in 6 months or ~1.5 min a week will give a value of 130 ppm. If the clock is performing that poorly it is at the edge of being able to be corrected and if the value is significantly outside of that there is probably a problem with the chip/crystal/design. What might make more sense in that case would be to assume that the clock was simply wrong when the calibrate method was called. So I'm proposing a method that is calibrateOrAdjust (which I have already implemented) that would either calibrate the chip if the PPM is within range, or adjust the clock to be the correct value (I haven't contemplated if the trim should be zeroed out or not when the clock is adjusted, I'm thinking not, but maybe that is an optional flag passed in to the method).
This came up in my application as I was thinking about daylight savings time. I get the time passed in periodically and I use the passed in value to initially set the time if the oscillator isn't running or to calibrate the chip if the oscillator is running. But twice a year, because I haven't coded to adjust the clock for daylight savings time, the time passed in will be an hour off. This will create a PPM error of approx. 230 or -230 which will cause maximum trim values to be ADDED to or SUBTRACTED from the existing trim value which, as I continue looking at the code, will possibly cause the following line in calibrate to overflow if the previous trim value was not 0. There should probably be a check on the line
trim += ppm * 32768 * 60 / 2000000; // compute the new trim value
to prevent this.
And as I noted in my other post, the time will still be wrong since the time doesn't appear to be adjusted when the timer is calibrated.
Describe what the feature request is and if it solves an issue or adds functionality
the current "SimpleBatteryBackup.ino" program assumes that the Arduino remains powered up while power is removed from the MCP7940N. This is typically not the case in a real implementation, so another example program is needed to demonstrate power-up checking in the sketch.
Describe the solution you'd like
Create new example program
Describe alternatives you've considered
None
I'm looking at the two calibrate methods
int8_t MCP7940_Class::calibrate(const DateTime& dt)
and
int8_t MCP7940_Class::calibrate(const int8_t newTrim)
and am concerned that while the trim value gets set, the actual time is never adjusted. _SetUnixTime is updated to be the current unit time and the comment says "Store time of last change" but all that changed was the trim value. So if the clock was off, it will still be off and the next time calibrate is called the same trim value (assuming the clock was 100% accurate after the current trim) will be calculated and added to the trim throwing the trim off. I'm thinking that the time should be adjusted and _SetUnixTime set as soon as the trim value is calculated. What do you think?
If setAlarmPolarity(1)
is called before setting an alarm through setAlarm()
the polarity will be forced to zero again.
I don't think this is intended, since changing the polarity after setting up the alarm can cause the MFP to have the wrong polarity for the first few us.
Affected line of code:
https://github.com/SV-Zanshin/MCP7940/blob/0678a66569f9ea81a9d959c8c6cce5247a6916eb/src/MCP7940.cpp#L592
Fix: also keep the polarity bit. I also force the dow to be only 3 bit long to prevent an accidental overwrite.
uint8_t wkdayRegister = readByte(MCP7940_ALM0WKDAY + offset); // //
wkdayRegister &= ((1 << MCP7940_ALM0IF) | (1 << MCP7940_ALMPOL)); // Keep pol and alm flag bit //
wkdayRegister |= alarmType << 4; // Set 3 bits from alarmType //
wkdayRegister |= (dt.dayOfTheWeek() & 0x07); // Set 3 bits for dow from date //
Maybe it would also be beneficial to be able to set the polarity right in the setAlarm()
function with an additional optional paramter?
bool setAlarm(const uint8_t alarmNumber, const uint8_t alarmType, const DateTime dt, const bool state = true, const uint8_t polarity = 0);
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.