I2C RTC- and LCD-modules do not work together

Helo to all you programmers.

I'm blocked with my DUE: a simple system, RTC module and LCD(20,4)-module using I2C, as libraries use RTC_DUE from JeeLabs and LiquidCrystal_I2C from www.DFRobot.com. My sketch is as follows

// Date and time functions using a DS1307 RTC connected via I2C
#include "RTCdue.h"
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
//#include <OneWire.h>

LiquidCrystal_I2C lcd(0x3f,20,4);

RTC_DS1307 rtc(20,21);

void setup () {
    Serial.begin(115200);
//    lcd.init();
    lcd.backlight();
    lcd.print("I2C-LCD does work!");

  }

void loop () {
    DateTime now = rtc.now();
    
    Serial.print(now.day(), DEC);
    Serial.print('.');
    Serial.print(now.month(), DEC);
    Serial.print('.');
    Serial.print(now.year(), DEC);
    Serial.print(' ');
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.println();
    
   delay(3000);
}

If I compile the shown sketch - with lcd.init() - as comment, the already running RTC module sends correct data to the serial output, evidently the lcd-display shows no reaction.

If I include lcd.init(), the lcd-display shows the message but the RTC is corrupt and shows for all values 85. It seems, that the I2C-bus gets confused. What is best strategy to look for the failure?

Thanks for your help.
Axel

How are you reading the RTC data? If it's based on the DS1307 chip, the data are in BCD format, which won't look right with just a plain serial print. The byte value of 85 has a BCD value of 55. Does that provide any clues (May 5th)? The chip also has an internal register pointer that automatically increments itself after each read. If you are not reading anything, there's no reason to expect the values to change. Since you can call the read() method with a pin number, you'll see most reads start by passing in a 0, which resets the internal pointer to the first data register in the chip.

I don't have a or use a DUE but a couple of things come to mind.

Not for sure which RTCdue library you are using but
two of the ones I've just looked a but "interesting"/"odd".
They didn't use the Wire library and take over the bus to do the i2c protocol themselves.
i.e. they implmented the i2c bus in s/w on any pins you like.
My guess is that it doesn't play nice with others like the real Wire library
when trying to use the same pins as the i2c h/w.

I would find some other library that uses the Wire library if you want
to use multiple i2c devices on the same i2c bus.
There are other 1307 library out there:
Here is one to try instead: DS1307RTC Library, For Accessing Real Time Clock (RTC) Chips
as it uses the wire library.


If that doesn't help, here are some other thoughts:

When using multiple i2c devices the initalization of the wire library can
be done more than once.
(i.e. Wire.begin() gets called more than once)
This seems to work ok on AVR, but it didn't work on pic32.
Perhaps it is also an issue on DUE?
The way to see if this is an issue is to simply
add a couple of Wire.begin() statements to your setup() routine
and see if things still work.

Also, I have seen some i2c lcd libraries go in an muck with the i2c clock to speed it
up. While it works on some i2c chips it won't work on others.
Check to see if the i2c library is mucking with the i2c clock.

Another thing to check is your i2c bus to make sure that there are pullups
somewhere.
Not sure what is on DUE but for AVR, the internal pullups are often enough
for a single i2c slave device to work, but can have issues when using multiples.

--- bill

Hi econjack,
hi Bill,

sorry for the late answer: thanks for your information.

In the meantime besides my regular work I tested a lot of libraries, learned C++ and tried to understand the use of the I2C-bus. So far as I understand the DUE situation there is a lack of tested libraries to work together. I shall give feedback when I succeeded.

In this case, it appears that it isn't so much as a lack of testing of libraries that work together,
but rather two different libraries both being told to directly control the same pins.
It appears that both the RTCdue & Wire library are both wanting to directly control the
same i2c pins.
If, that is the case, that won't work. It is the same issue that happens if you
try to use the same pin for two different things or assign it to two different libraries.
Toss out that RTCdue library and go get a RTC library that uses the Wire library.
That way there is only 1 entity (the Wire library) that is directly controlling
the i2c pins & bus.

--- bill

Helo Bill,

thank you very much for your helpful explanation.
I thought if one slave-device has finished its work end sends the stop signals the bus would have no signals until either the master or by direct control of the pins again a start signal is given with may be a different device address.

Just to say I tried some RTC-libs, but up to now they did not compile on the DUE, so I have to dive more into the bits and pieces - which I did not intend to do. That's the way you do learn.

Axel

argy:
Helo Bill,

thank you very much for your helpful explanation.
I thought if one slave-device has finished its work end sends the stop signals the bus would have no signals until either the master or by direct control of the pins again a start signal is given with may be a different device address.

While that is true, in this case each library is programming the pins differently
and for a different use.
So when they finish the pins are not in the appropriate state to be re-used.
The built in Wire library uses the i2c module h/w. the Wire h/w controls the pins.
I'm not sure how it works on DUE but in most micro-controllers, if a special h/w
function is controlling the pins, then s/w can't go in at control the pins by reading/writing
to the port.
And if s/w has set up the port to use the pins for input/output, then the special function h/w can't
control the pins.