Arduino DUE and RTClib

Dear All,

ON an genuine Arduino DUE,

If I use I2C on wire1 (SDA1,SCL1,), I have no problem to use RTClib
on a DS3231 breakout board.

But If I use wire (SDA,SCL) on pins 20,21. I cannot do anything. It seems that communication is not
working. Probably its a soft problem, but I cannot find it.

I have removed the 1k pull up resistors, but it does not change anything.

Can someone help ? as I need to use the (20,21) pins for I2C.

Thanks

as I need to use the (20,21) pins for I2C.

The I2C bus pins? You know that a bus has multiple seats, right? You can attach multiple devices to the I2C bus.

Can have up to 128 I2C devices connected. The only thing that prevents really large numbers is increasing capacitance build up leading to signal degradation.

Maybe I was not clear enough, or you do not assume the same level of knowledge.

My problem right now is to make work a single DS3231 on a single Arduino DUE.
As I had problems in a much more complex setting, I have isolated
just this part.

If I cannot make this part work, I have no chance in the full circuit.
I must say that although I have some experience on the Atmega328 based Arduinos,
I am new to the DUE.

If you think it's a software problem, why don't you post your code?

You said you removed the pullups from the Due board. Does the RTC board have its own pullups?

You said you removed the pullups from the Due board. Does the RTC board have its own pullups?

Yes 4.7 kohm

If you think it's a software problem, why don't you post your code?

This is it :

Harware setting : Arduino DUE (genuine) with nothing plugin except the RTC

RTC : ebay 3231 breakout board with 4.7 k ohms pull up resistors

DUE RTC
3.3V <--> Vcc
GND <--> GND
SDA <--> SDA1
SCL <--> SCL1

code : example ds1307 from the RTClib

#include <Wire.h>
#include "RTClib.h"

RTC_DS1307 rtc;

void setup () {
Serial.begin(57600);
Wire1.begin();
rtc.begin();

if (! rtc.isrunning()) {
Serial.println("RTC is NOT running!");
// following line sets the RTC to the date & time this sketch was compiled
rtc.adjust(DateTime(F(DATE), F(TIME)));
// This line sets the RTC with an explicit date & time, for example to set
// January 21, 2014 at 3am you would call:
// rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
}
}

void loop () {
DateTime now = rtc.now();

Serial.print(now.year(), DEC);
Serial.print('/');
Serial.print(now.month(), DEC);
Serial.print('/');
Serial.print(now.day(), DEC);
Serial.print(' ');
Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);
Serial.print(':');
Serial.print(now.second(), DEC);
Serial.println();

Serial.print(" since midnight 1/1/1970 = ");
Serial.print(now.unixtime());
Serial.print("s = ");
Serial.print(now.unixtime() / 86400L);
Serial.println("d");

// calculate a date which is 7 days and 30 seconds into the future
DateTime future (now.unixtime() + 7 * 86400L + 30);

Serial.print(" now + 7d + 30s: ");
Serial.print(future.year(), DEC);
Serial.print('/');
Serial.print(future.month(), DEC);
Serial.print('/');
Serial.print(future.day(), DEC);
Serial.print(' ');
Serial.print(future.hour(), DEC);
Serial.print(':');
Serial.print(future.minute(), DEC);
Serial.print(':');
Serial.print(future.second(), DEC);
Serial.println();

Serial.println();
delay(3000);
}

This is working well, as expected

2015/7/21 22:11:45
since midnight 1/1/1970 = 1437516705s = 16637d
now + 7d + 30s: 2015/7/28 22:12:15

Now the same thing with (SDA and SCL ) (pins 20 and 21) using "wire.begin" instead of "wire1.begin"

#include <Wire.h>
#include "RTClib.h"

RTC_DS1307 rtc;

void setup () {
Serial.begin(57600);
Wire.begin();
rtc.begin();

if (! rtc.isrunning()) {
Serial.println("RTC is NOT running!");
// following line sets the RTC to the date & time this sketch was compiled
rtc.adjust(DateTime(F(DATE), F(TIME)));
// This line sets the RTC with an explicit date & time, for example to set
// January 21, 2014 at 3am you would call:
// rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
}
}

This does not work ! Most probably the code from the RTClib does not allow to use (SCL and SDA) ???

This is what I want to know, and how to make it work.

2000/0/0 0:0:0
since midnight 1/1/1970 = 2313941504s = 26781d
now + 7d + 30s: 2043/5/6 17:32:14

Most probably the code from the RTClib does not allow to use (SCL and SDA)

Why not look at the source code, and know, instead of guessing. Which RTC library are you using?

Two problems

  1. On Due one of the I2C /SDA / SCL has internal pull-ups and the other DOES NOT. Check the manual, I don't remember "details" like this. You definitely need pull-up on the bus and if RTC has them already TOO many parallel pull-ups is not always better. Again, best to consult Due manual.

  2. begin() is Arduino.inc time honored but STUPID WAY to hide the class constructor , hence pins used. You need to check wire / wire1 or spi libraries to find out WHICH port is in use , especially on Due - sometime the libraries forget to add "SAM hardware" too. Or find out if there is a real constructor with pins passed to it you can use.
    Good luck

Vaclav:
Two problems

  1. On Due one of the I2C /SDA / SCL has internal pull-ups and the other DOES NOT. Check the manual, I don't remember "details" like this. You definitely need pull-up on the bus and if RTC has them already TOO many parallel pull-ups is not always better. Again, best to consult Due manual.

The SDA1/SCL1 has no pull up ; This is the one that is working. As I said there are pull up on the
RTC3231 board I am using (4.7 k)

The SDA/SCL has pull up, but these are 1k pull up. I have removed these resistors.
So the configuration is the same as for SDA1/SCL1

  1. begin() is Arduino.inc time honored but STUPID WAY to hide the class constructor , hence pins used. You need to check wire / wire1 or spi libraries to find out WHICH port is in use , especially on Due - sometime the libraries forget to add "SAM hardware" too. Or find out if there is a real constructor with pins passed to it you can use.
    Good luck

Why not look at the source code, and know, instead of guessing. Which RTC library are you using?

This is the reason why I ask on the Forum. As I am not expert in Arduinos, I am searching if someone has already had the same problem and has found the solution. I believe that this should be the purpose of such forums: sharing expertise.

JacquesBBB:
Probably its a soft problem, but I cannot find it.

So you are using a library? The library code is the problem? And you cannot find the code in the library?

Strange.

I can easily find this piece of source code in file RTClib.cpp:

#ifdef __AVR__
 #include <avr/pgmspace.h>
 #define WIRE Wire
#else
 #define PROGMEM
 #define pgm_read_byte(addr) (*(const unsigned char *)(addr))
 #define WIRE Wire1
#endif

So the DUE uses Wire1, because that's what is written in the source code of the library.

I don't know why the author of the library decided for Wire1 with the DUE and if you need to do different code changes than defining Wire instead of Wire1.

jurs:
So you are using a library? The library code is the problem? And you cannot find the code in the library?

Strange.

I can easily find this piece of source code in file RTClib.cpp:

#ifdef __AVR__

#include <avr/pgmspace.h>
#define WIRE Wire
#else
#define PROGMEM
#define pgm_read_byte(addr) (*(const unsigned char *)(addr))
#define WIRE Wire1
#endif




So the DUE uses Wire1, because that's what is written in the source code of the library.

I don't know why the author of the library decided for Wire1 with the DUE and if you need to do different code changes than defining Wire instead of Wire1.

All this I have found before asking on the Forum.

But the change is not as simple, as it is also coded somewhere else, and it then become difficult to be able to search the way to change the setting, without even knowing if there is a good reason (hardware) for this setting. Before messing with the library, which is usually not a good thing to do as it will be obsolete at the next upgrade, I naively thought that I could get some help from this forum.

Finally, I found a solution that solved my problem with the alternate library

Which has the advantage of not using wire, so there are much less imbricated dependencies.
In this library, the setting is made by default with the (SDA/SCL) port, which fits my needs.
Moreover, the code is more understandable, and it appears more easily
where to put some modification to access to the RTC by the other port (SCL1/SDA1).

Hopefully this will be useful for someone.

With this library, the use of the two ports is easy, although one has to be careful to the used names for the pins.

the two way to initiate the clock are

// Date and time functions using a DS1307 RTC connected via I2C
#include "RTCdue.h"

RTC_DS1307 rtc(PIN_WIRE_SDA,PIN_WIRE_SCL);

and

// Date and time functions using a DS1307 RTC connected via I2C
#include "RTCdue.h"

RTC_DS1307 rtc(PIN_WIRE1_SDA,PIN_WIRE1_SCL);

I had to search somewhat to find the above one, after some trials and errors with
RTC_DS1307 rtc(PIN_WIRE_SDA1,PIN_WIRE_SCL1);
That send back an error message.

So I had adopted this library.

jurs:
So you are using a library? The library code is the problem? And you cannot find the code in the library?

Strange.

I can easily find this piece of source code in file RTClib.cpp:

#ifdef __AVR__

#include <avr/pgmspace.h>
#define WIRE Wire
#else
#define PROGMEM
#define pgm_read_byte(addr) (*(const unsigned char *)(addr))
#define WIRE Wire1
#endif




So the DUE uses Wire1, because that's what is written in the source code of the library.

I don't know why the author of the library decided for Wire1 with the DUE and if you need to do different code changes than defining Wire instead of Wire1.

Not my way to justify this piece of code - BY DEFAULT?
Assuming you actually using this code - safer way would be to
#undef AVR in your x.ino file.

Bottom line - this "library" does not know much about ARM / Due.

Back to Due INTERNAL pullups - how did you "remove" them?
1kOhms does not sound correct.

JacquesBBB:
With this library, the use of the two ports is easy, although one has to be careful to the used names for the pins.

the two way to initiate the clock are

// Date and time functions using a DS1307 RTC connected via I2C
#include "RTCdue.h"

RTC_DS1307 rtc(PIN_WIRE_SDA,PIN_WIRE_SCL);

and

// Date and time functions using a DS1307 RTC connected via I2C
#include "RTCdue.h"

RTC_DS1307 rtc(PIN_WIRE1_SDA,PIN_WIRE1_SCL);

I had to search somewhat to find the above one, after some trials and errors with
RTC_DS1307 rtc(PIN_WIRE_SDA1,PIN_WIRE_SCL1);
That send back an error message.

So I had adopted this library.

NO COMMENTS!

Vaclav:
Back to Due INTERNAL pullups - how did you "remove" them?
1kOhms does not sound correct.

I just took two soldering irons and gently squeezed this resistor array on both sides.
it did not resisted for long, and was gently put aside.

They are actually 1k resistors. They may be some reason for high frequency signals, but as
I am more concerned on saving power, I preferred to suppress them, knowing also that there are additional
pull up in the breakout board I could use.

I have checked on the Mega 2560 which has the same setting. In this case they are 10k resistors.
Much better for my point of view, as it is always possible to add some pull up in parallel to decrease the
pullup value if needed.

I thought I solved my problem,
but this is not hte case

the library

is bugged.
In particular, the unixtime is completely wrong.

If anybody has a suggestion for a rtc library compatible with the SDA SCL pins of the DUE and
proper time conversion, this will be helpful.

Up to now, I do not see any.

For using pins SCL(21) and SDA(20) with the Due Board :

  1. Desolder the 1K resistors for I2C pull-up on the DUE board
  2. Comment the following in the RTCLib.cpp file
    C:\Users<USER>\Documents\Arduino\libraries\RTClib\RTCLib.cpp
    #elif defined(ARDUINO_SAM_DUE)
    #define PROGMEM
    #define pgm_read_byte(addr) (*(const unsigned char *)(addr))
    // #define Wire Wire1 //comment this line and connect to pins 20,21
    #endif
    with these two changes I could use the DS3231 RTC break-out board with Arduino DUE

I could also use ADC ADS1115 simultaneously on the same port / pins.

Connections :
DUE RTC
3.3V <--> Vcc
GND <--> GND
SDA <--> SDA (20)
SCL <--> SCL (21)

Code :

#include <Wire.h>
#include "RTClib.h"

void setup() {
    ...
    Serial.begin(19200);
    Wire.setClock(100000);
    Wire.begin();
    if (! rtc.begin()) {
      Serial.println("Couldn't find RTC");
      while (1);
    }
   ...
}

void loop() {
       ...
       now = rtc.now();
       char chartime[8];        // long enough to hold complete integer string
       int chartimelen;
       chartimelen = sprintf(chartime, "%02d:%02d:%02d",now.hour(),now.minute(),now.second()); 
       Serial.println(chartime);
       ...
}

That suggests that there are already Pull-ups on DS3231 RTC break-out board, therefore it should work without desoldering anything on the DUE board, write #define Wire Wire1 just after the RTC Library include and use SDA1/SCL1.

The library DS3232RTC works with the Due on pins D20, D21 out of the box.

But instead of using the object instantiated in the library files you have to instantiate a new object in the sketch.