Arduino Zero Compilation errors with MCP79410 Library (SOLVED)

Hi, my Zero project uses the RTCC (Real Time Clock & Calendar) Microchip MCP79410, a much better IC in terms of features and accuracy than the standar DS1307 used in most of the Arduino projects.

Please note, that I can not use the internal Atmel M0+ RTC because it does not admit a backup battery.

The communication between the Microcontroller and the MCP79410 is via I2C Bus. I have compiled the following I2C scanner program, that I modified slightly to send the information through the USB port. I can detect two devices (RTCC and EPROOM) in the datasheet addresses 0xD7 and 0xEF. It seems there is no Hardware problem.

// I2C Scanner
// Written by Nick Gammon
// Date: 20th April 2011

#include <Wire.h>
#define Serial SerialUSB

void setup() {
  Serial.begin (115200);
  while (!Serial) {}      // wait for serial port to connect. Needed for native USB port only

  Serial.println ("I2C scanner. Scanning ...");
  byte count = 0;
  
  Wire.begin();
  for (byte i = 8; i < 255; i++)   {
    
    Wire.beginTransmission (i);
    Serial.print(i);
    Serial.print("\t-->  ");
    if (Wire.endTransmission () == 0)  {
       Serial.print ("\t Found address!!!: ");
       Serial.print (i, DEC);
       Serial.print (" (0x");
       Serial.print (i, HEX);
       Serial.println (")");
       count++;
       delay (1);  // maybe unneeded?
    } // end of good response
    else  {
       Serial.println("No respuesta");  
    } // end of no answer
    
  } // end of for loop
  
  Serial.println ("Done.");
  Serial.print ("Found ");
  Serial.print (count, DEC);
  Serial.println (" device(s).");
}  // end of setup

void loop() {}

I have many choices in Github in relation to Arduino libraries that can work with the MCP79410, actually I took a look before deciding to go with this IC.

JChristensen/MCP79412RTC
crako1t/MCP7940-library-for-logger
ichilton/mcp7941x_arduino
nathanchantrell/MCP79410RTC
anarduino/mcp7940
rjfedor/arduino-mcp79410
JohnSL/MCP7940
phishman/MCP7940x
lucidtronix/MCP79410Arduino

But I am facing a problem: most of them don´t compile in the Atmel SAMD21 mainly giving errors in the Core and Time libraries.

The Lucidtronix/MCP79410Arduino compiles correctly but when I upload it, I can not see the native USB port, I assume something went really wrong with the code.

These are the errors I am getting in the most starred libraries:

JChristensen/MCP79412RTC
This library seems to be well polished and documented, 12 stars, it uses the Time.h library, which seems to be not ready for the Zero Architecture. When compiling the TimeRTC example I get the following:

In file included from C:\Users\quino\Documents\Arduino\libraries\MCP79412RTC-master\examples\TimeRTC\TimeRTC.pde:10:0:

C:\Users\quino\Documents\Arduino\libraries\MCP79412RTC-master/MCP79412RTC.h:96:29: error: 'tmElements_t' has not been declared

         static boolean read(tmElements_t &tm);

                             ^

C:\Users\quino\Documents\Arduino\libraries\MCP79412RTC-master/MCP79412RTC.h:97:27: error: 'tmElements_t' has not been declared

         static void write(tmElements_t &tm);

                           ^

In file included from C:\Users\quino\AppData\Local\Arduino15\packages\arduino\tools\CMSIS\4.0.0-atmel/Device/ATMEL/samd21/include/samd21.h:55:0,

                 from C:\Users\quino\AppData\Local\Arduino15\packages\arduino\tools\CMSIS\4.0.0-atmel/Device/ATMEL/samd.h:91,

                 from C:\Users\quino\AppData\Local\Arduino15\packages\arduino\tools\CMSIS\4.0.0-atmel/Device/ATMEL/sam.h:581,

                 from C:\Users\quino\AppData\Local\Arduino15\packages\arduino\hardware\samd\1.6.2\cores\arduino/Arduino.h:47,

                 from C:\Users\quino\AppData\Local\Temp\build96ff943aee33474230649d867284b0c7.tmp\sketch\TimeRTC.pde.cpp:1:

C:\Users\quino\AppData\Local\Arduino15\packages\arduino\tools\CMSIS\4.0.0-atmel/Device/ATMEL/samd21/include/samd21g18a.h:486:38: error: expected ')' before '*' token

 #define RTC               ((Rtc      *)0x40001400U) /**< \brief (RTC) APB Base Address */

                                      ^

C:\Users\quino\Documents\Arduino\libraries\MCP79412RTC-master/MCP79412RTC.h:130:20: note: in expansion of macro 'RTC'

 extern MCP79412RTC RTC;

                    ^

C:\Users\quino\AppData\Local\Arduino15\packages\arduino\tools\CMSIS\4.0.0-atmel/Device/ATMEL/samd21/include/samd21g18a.h:486:38: error: expected ')' before '*' token

 #define RTC               ((Rtc      *)0x40001400U) /**< \brief (RTC) APB Base Address */

                                      ^

C:\Users\quino\Documents\Arduino\libraries\MCP79412RTC-master/MCP79412RTC.h:130:20: note: in expansion of macro 'RTC'

 extern MCP79412RTC RTC;

                    ^

C:\Users\quino\Documents\Arduino\libraries\MCP79412RTC-master\examples\TimeRTC\TimeRTC.pde: In function 'void setup()':

TimeRTC:14: error: request for member 'get' in '1073746944u', which is of pointer type 'Rtc*' (maybe you meant to use '->' ?)

   setSyncProvider(RTC.get);   // the function to get the time from the RTC

                       ^

TimeRTC:14: error: 'setSyncProvider' was not declared in this scope

   setSyncProvider(RTC.get);   // the function to get the time from the RTC

                          ^

TimeRTC:15: error: 'timeStatus' was not declared in this scope

   if(timeStatus()!= timeSet) 

                 ^

TimeRTC:15: error: 'timeSet' was not declared in this scope

   if(timeStatus()!= timeSet) 

                     ^

C:\Users\quino\Documents\Arduino\libraries\MCP79412RTC-master\examples\TimeRTC\TimeRTC.pde: In function 'void digitalClockDisplay()':

TimeRTC:29: error: 'hour' was not declared in this scope

   Serial.print(hour());

                     ^

TimeRTC:30: error: 'minute' was not declared in this scope

   printDigits(minute());

                      ^

TimeRTC:31: error: 'second' was not declared in this scope

   printDigits(second());

                      ^

TimeRTC:33: error: 'day' was not declared in this scope

   Serial.print(day());

                    ^

TimeRTC:35: error: 'month' was not declared in this scope

   Serial.print(month());

                      ^

TimeRTC:37: error: 'year' was not declared in this scope

   Serial.print(year()); 

                     ^

Using library Wire at version 1.0 in folder: C:\Users\quino\AppData\Local\Arduino15\packages\arduino\hardware\samd\1.6.2\libraries\Wire 
Using library MCP79412RTC-master in folder: C:\Users\quino\Documents\Arduino\libraries\MCP79412RTC-master (legacy)
exit status 1
request for member 'get' in '1073746944u', which is of pointer type 'Rtc*' (maybe you meant to use '->' ?)

Seems to be a no go, because it is using Time.h

crako1t/MCP7940-library-for-logger Seems to be simpler, not using so many dependencies. Four stars, fork from Jeelabs, but no documentation and examples, in addition that is for a slightly different IC -> No go

ichilton/mcp7941x_arduino Well documented, 2 stars, clean examples, and no Time.h dependency. But I get the following compilation error:

C:\Users\quino\Documents\Arduino\libraries\mcp7941x_arduino-master\MCP7941x.cpp: In member function 'void MCP7941x::setDateTime(byte, byte, byte, byte, byte, byte, byte)':

C:\Users\quino\Documents\Arduino\libraries\mcp7941x_arduino-master\MCP7941x.cpp:13:35: error: call of overloaded 'write(int)' is ambiguous

   #define WireSend(x) Wire.write(x)

                                   ^

C:\Users\quino\Documents\Arduino\libraries\mcp7941x_arduino-master\MCP7941x.cpp:107:3: note: in expansion of macro 'WireSend'

   WireSend(RTC_LOCATION);

   ^

C:\Users\quino\Documents\Arduino\libraries\mcp7941x_arduino-master\MCP7941x.cpp:13:35: note: candidates are:

   #define WireSend(x) Wire.write(x)

                                   ^

C:\Users\quino\Documents\Arduino\libraries\mcp7941x_arduino-master\MCP7941x.cpp:107:3: note: in expansion of macro 'WireSend'

   WireSend(RTC_LOCATION);

   ^

In file included from C:\Users\quino\Documents\Arduino\libraries\mcp7941x_arduino-master\MCP7941x.cpp:21:0:

C:\Users\quino\AppData\Local\Arduino15\packages\arduino\hardware\samd\1.6.2\libraries\Wire/Wire.h:50:12: note: virtual size_t TwoWire::write(uint8_t)

     size_t write(uint8_t data);

            ^

In file included from C:\Users\quino\AppData\Local\Arduino15\packages\arduino\hardware\samd\1.6.2\cores\arduino/Stream.h:26:0,

                 from C:\Users\quino\AppData\Local\Arduino15\packages\arduino\hardware\samd\1.6.2\cores\arduino/HardwareSerial.h:24,

                 from C:\Users\quino\AppData\Local\Arduino15\packages\arduino\hardware\samd\1.6.2\cores\arduino/Arduino.h:73,

                 from C:\Users\quino\Documents\Arduino\libraries\mcp7941x_arduino-master\MCP7941x.cpp:12:

C:\Users\quino\AppData\Local\Arduino15\packages\arduino\hardware\samd\1.6.2\cores\arduino/Print.h:48:12: note: size_t Print::write(const char*)

     size_t write(const char *str) {

            ^

C:\Users\quino\Documents\Arduino\libraries\mcp7941x_arduino-master\MCP7941x.cpp:13:35: error: call of overloaded 'write(int)' is ambiguous


(etc...)


Using library Wire at version 1.0 in folder: C:\Users\quino\AppData\Local\Arduino15\packages\arduino\hardware\samd\1.6.2\libraries\Wire 
Using library mcp7941x_arduino-master in folder: C:\Users\quino\Documents\Arduino\libraries\mcp7941x_arduino-master (legacy)
exit status 1
Error compiling.

Can someone guide me in relation to this issue?, choosing a library?, provide any advice?

tmElements_t type is defined in the Time library. try including it at the beginning of your code :

#include <Time.h>

Yes, I included it in my code. But I discovered it seems there are “old versions” and not compatible with our Arduino Zero.

I got the information about the time Library in the Arduino web page:
http://playground.arduino.cc/code/time

Following the instructions, I went to the PJRC Web site:
http://www.pjrc.com/teensy/td_libs_Time.html

Which redirects to the PaulStroffegen Github repo :

I downloaded the last version, updated 3 months ago, and I get the listed errors

I am trying to document here my changes adapting an AVR library to SAMD Architecture. I have finally chosen the RTC MCP79412RTC Library (GitHub - JChristensen/MCP79412RTC: Arduino library for the Microchip MCP79411/12 Real-Time Clock/Calendar), to access the RTC IC in my project, mainly because this library is very well documented and adopt all the IC functionality like calibration, access to EEPROM, etc…

The first error message I get is related to the keyword “RTC”:

C:\Users\quino\AppData\Local\Arduino15\packages\arduino\tools\CMSIS\4.0.0-atmel/Device/ATMEL/samd21/include/samd21g18a.h:486:38: error: expected ')' before '*' token

 #define RTC               ((Rtc      *)0x40001400U) /**< \brief (RTC) APB Base Address */

                                      ^

C:\Users\quino\Documents\Arduino\libraries\MCP79412RTC-master/MCP79412RTC.h:130:20: note: in expansion of macro 'RTC'

 extern MCP79412RTC RTC;

                    ^

Could It be that the object named “RTC” is defined twice in the Core SAMD libraries and this external MCP79412 library?. It makes sense because the ATMEL SAMD has also another (useless) internal RTC circuit.

So I renamed the RTC object in the MCPRTC79412 library from “RTC” to “RTCMCP79412”, and the first errors vanished.

I am now getting a different bunch of errors:

C:\Users\quino\Documents\Arduino\libraries\MCP79412RTC-master\MCP79412RTC.cpp:100:48: error: '_BV' was not declared in this scope

         tm.Second = bcd2dec(i2cRead() & ~_BV(ST));

The _BV macro is normally defined by Atmel in its library, and it is very dependent of AVR Architecture. Fortunately it seems that many people has faced this, for example:

If I introduce the following definition in the MCP79412.h file:

#define _BV(bit) (1 << (bit))

Then the compilation is succesfull !!, Which means that this is the last hurdle to overcome.

However replacing this is bitwise manipulation Macro that only works in AVR architecture is not so easy. I need to find alternatives for the following instructions involving the _BV Macro in the library code:

tm.Second = bcd2dec(i2cRead() & ~_BV(ST)); 
...
tm.Hour = bcd2dec(i2cRead() & ~_BV(HR1224));    //assumes 24hr clock
...
tm.Wday = i2cRead() & ~(_BV(OSCON) | _BV(VBAT) | _BV(VBATEN));    //mask off OSCON, VBAT, VBATEN bits
...
tm.Month = bcd2dec(i2cRead() & ~_BV(LP));       //mask off the leap year bit
...
i2cWrite(tm.Wday | _BV(VBATEN));             //enable battery backup operation
...
i2cWrite(dec2bcd(tm.Second) | _BV(ST));    //set the seconds and start the oscillator (Bit 7, ST == 1)
...
if ( day & _BV(VBAT) ) {
...
dn.Hour = bcd2dec(i2cRead() & ~_BV(HR1224));    //assumes 24hr clock
...
ctrlReg &= ~_BV(SQWE);
...
ctrlReg = (ctrlReg & 0xF8) | _BV(SQWE) | freq;
...
ctrl |= _BV(ALM0 + alarmNumber);        //enable the alarm
...
ctrlReg |= _BV(OUT);
...
alm0Day |= _BV(OUT);
...
return i2cRead() & _BV(ST);

And here, to replace the _BV Macro I really need help…

OK I found a working solution, or better a library that works flawlessly with our Arduino Zero:

You need to make two small changes to the Example sketch:

  1. First, you need to use another name for the RTC object. “RTC” is already in use by the internal RTC of the SAMD21 microcontroller. I changed line 5th
RTC_MCP7940X RTCMCP;

and of course in all the lines of the sketch where the object RTCMCP is called. Lines 12th, 37th

  1. As usual to be able to use the USB port:
#define Serial SerialUSB

So, It is possible to use our Arduino Zero with the MCP79410, 11 y 12 Real Time Clock and Calendar

Thanks for figuring this out, I found it very useful!

kinematik: Which redirects to the PaulStroffegen Github repo : https://github.com/PaulStoffregen/Time

I downloaded the last version, updated 3 months ago, and I get the listed errors

Sounds like all the errors turned out to be other stuff with the RTC defs?

If the Time library has any unresolved problems on Arduino Zero, please create an issue on github with the complete code to reproduce the problem. I maintain this library, but I depend on you to create reproducible bug reports on github.