Multiple i2c communication with 4 device

I am working on a project. Where I am using two Arduino(UNO, Pro Mini), one ds1307 rtc, one 24LC512 eeprom, one Nokia5110 LCD, Some 4digit 7 segment.

In this project I do some calculation, read/write/send and receive data among two arduino , external eeprom using i2c communication.

For better understanding please see the picture :

In Arduino UNO:
I read time from ds1307 and some data(which i previously stored) from 24LC512 eeprom using same Analog pin A4,A5 using i2c communication with Wire.h library.

And also send the time to another Arduino pro mini via I2C which is connected to the Uno using A4 and A5.
Edit time using push button and show them nokia5110.

In Arduino Pro Mini:
Here i received data from master UNO and read some data from 24LC512 eeprom and the do some calculation.

Finally display the calculated value in 4 digit 7 segment.

All is working fine but when i added some new feature the code size is getting big.

And when i upload the code the two device working smoothly for some moment.
And then suddenly the master Hang.

Code of Master UNO:

#include <RTClib.h>
#include "Wire.h"
#define EEPROM_I2C_ADDRESS 0x50

RTC_DS1307 rtc;

int hour, minute, second, day, month, year;
static const char daysOfTheWeek[7][4] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};

void setup() {
  Wire.begin();
  rtc.begin();
  if (! rtc.isrunning()) {
    //Serial.println("RTC is NOT running!");
    // Set the date and time at compile time
    rtc.adjust(DateTime(__DATE__, __TIME__));
  }

  delay(1000);
  //startMillis = millis();
}

void loop() {
  DateTime now = rtc.now();
  hour = now.hour();
  minute = now.minute();
  second = now.second();
  day = now.day();
  month = now.month();
  year = now.year();
  
  Wire.beginTransmission(9);//9 here is the address of the slave board
  Wire.write(hour);//Transfers the value of potentiometer to the slave board
  Wire.write(minute);
  Wire.write(second);
  Wire.write(day);
  Wire.write(month);
  Wire.write(lowByte(year));
  Wire.write(highByte(year));
  Wire.endTransmission();
  homePage();
  //delay(100);
  //isButtonDown(btnEnt) == false;
  if (isButtonDown(btnEnt) == true) {
    menuHome();
  }
  delay(1000);
}
int readIndex(int index) {
 int newStrLen =  readAddress(index);
 return newStrLen;
}

String read_String(int index) {
 int len = readAddress(index);
 char data[len + 1];
 for (int i = 0; i < len; i++) {
   data[i] = (char)readAddress(i + index + 1);
 }
 data[len] = '\0';
 return String(data);
}

int writeString(int index, String data) {
 int strLen = data.length() + 1;
 char string[strLen];
 data.toCharArray(string, strLen);
 writeAddress(index, strLen);
 int i = 0;
 for (i = 0; i < strLen; i++) {
   writeAddress(i + index + 1, string[i]);
 }
 writeAddress(index + i + 1, strLen);
 return index + strLen + 1;
}

void writeAddress(int address, byte val) {
 Wire.beginTransmission(EEPROM_I2C_ADDRESS);
 Wire.write((int)(address >> 8));   // MSB
 Wire.write((int)(address & 0xFF)); // LSB
 Wire.write(val);
 Wire.endTransmission();
 delay(5);
}

byte readAddress(int address) {
 byte rData = 0xFF;
 Wire.beginTransmission(EEPROM_I2C_ADDRESS);
 Wire.write((int)(address >> 8));   // MSB
 Wire.write((int)(address & 0xFF)); // LSB
 Wire.endTransmission();
 Wire.requestFrom(EEPROM_I2C_ADDRESS, 1);
 rData =  Wire.read();
 delay(10);
 return rData;
}

Sketch uses

Code of slave Pro mini:

#include"Wire.h"
#define EEPROM_I2C_ADDRESS 0x50

void setup() {
 Wire.begin(9);
 //Wire.begin();
 //Serial.begin(9600);
 Wire.onReceive(receiveEvent);

 delay(1000);             // wait 1000 ms
};

void receiveEvent(int bytes) {
 while (0 < Wire.available()) {
   hour = Wire.read();
   minute = Wire.read();
   second = Wire.read();
   day = Wire.read();
   month = Wire.read();
   year = Wire.read()  |  (Wire.read() << 8);
 }
}

void loop() {

 String data = read_String(1806);
 int dataLen = data.length();
 int dashIndex = data.lastIndexOf('-');
 int comma = 1 + data.lastIndexOf(',');
 String latitudeStr, longitudeStr, latiLongiStr;

 latiLongiStr = data.substring(dashIndex + 1, dataLen);
 latitudeStr = data.substring(dashIndex + 1, comma - 1);
 longitudeStr = data.substring(comma, dataLen);

 latitude = latitudeStr.toDouble();
 longitude = longitudeStr.toDouble();
 

 delay(1000);
};

int readIndex(int index) {
 int newStrLen =  readAddress(index);
 return newStrLen;
}

String read_String(int index) {
 int len = readAddress(index);
 char data[len + 1];
 for (int i = 0; i < len; i++) {
   data[i] = (char)readAddress(i + index + 1);
 }
 data[len] = '\0';
 return String(data);
}

int writeString(int index, String data) {
 int strLen = data.length() + 1;
 char string[strLen];
 data.toCharArray(string, strLen);
 writeAddress(index, strLen);
 int i = 0;
 for (i = 0; i < strLen; i++) {
   writeAddress(i + index + 1, string[i]);
 }
 writeAddress(index + i + 1, strLen);
 return index + strLen + 1;
}

void writeAddress(int address, byte val) {
 Wire.beginTransmission(EEPROM_I2C_ADDRESS);
 Wire.write((int)(address >> 8));   // MSB
 Wire.write((int)(address & 0xFF)); // LSB
 Wire.write(val);
 Wire.endTransmission();
 delay(5);
}

byte readAddress(int address) {
 byte rData = 0xFF;
 Wire.beginTransmission(EEPROM_I2C_ADDRESS);
 Wire.write((int)(address >> 8));   // MSB
 Wire.write((int)(address & 0xFF)); // LSB
 Wire.endTransmission();
 Wire.requestFrom(EEPROM_I2C_ADDRESS, 1);
 rData =  Wire.read();
 delay(10);
 return rData;
}

Sketch uses

My question is:

  1. Why the master hang or stop responding?
  2. Is it for multiple I2C communication at a time using same pin(All of them use only A4 And A5 ) ?
  3. Is the code size is too big and at tha same time transmit data that's why hang or stop?

New problem: The UNO receive unknown value from ds1307.

What makes you say that the code is too big to post here ?

Post is updated with code.

Thank you

If your I2C bus is really bad, then it can halt the sketch.
Please show us a photo, that shows the wiring of the I2C bus.
You can use a single 4k7 pullup resistor at the Master. But a few 10k here and there is no problem.
To solve noise problems on the I2C bus, a timeout was added. The Wire.setWireTimeout() should be called after Wire.begin().
https://github.com/arduino/ArduinoCore-avr/blob/master/libraries/Wire/src/Wire.cpp#L90

I thought that the Nokia 5110 LCD display was a 3.3V display and that resistors are used between a 5V Arduino and the 3.3V 5110 display. My 5110 was very faint and worn out. Are you sure that you want to use it, instead of a new modern display ?

Master sketch: At first glance I see no major issues. Some code seems to be redundant. Check what the RTC library can do, I think you can use some of those functions instead of your own code. We prefer a sketch that is responsive has no delay and does not wait in do-while loops. There are libraries that debounce buttons, that will also make your sketch smaller.

Slave sketch: No major issues here at first glance. A Arduino Uno / Mega / Nano / Pro Mini uses 32-bit 'float' instead of 'double'. Is that good enough for your project ? I doubt it, with so many calculations. The String class is used a lot, I don't know if that causes problems in the heap. The global variables that are used in receiveEvent() should be 'volatile'.

How is the UNO powered?

both UNO and pro mini powered from my laptop through usb.

Fine. Then power problems can be ruled out.
You use some while statements that look like road blocks. Any chance they can be the reason?

Try by changing String data types to cstring in both UNO and Pro.

1 Like

Is the code size is too big for UNO and its RAM and At the same time transmit data that's why hang or stop?

New problem: The UNO receive unknown value from ds1307.

Ok i will try it.

Can you write down in plain text using serial numbers what do you want to achive from your this hardware setup: UNO-Pro-EEPROM-RTC-LCD-7SDU.

Note: You are missing common ground connection in your diagram of Post-1! Check that you have also missed it in the actual wiring!

2 Likes

Several of the places you use String can simply be replaced by directly printing the leading '0'.

Your PROGMEM arrays of char* do not store the actual text in PROGMEM, only the pointers. The text strings are being stored in ram.

Is there a reason you cannot use a mega or some other board with more memory?

No in actual wiring i also put the common GND. But in this picture i missed to point out it.

In Uno I have 3 buttons for set time and setting and nokia5110 lcd for showing what changes are done.
Here i also save the changed setting in eeprom 24lc512 using master UNO.

Also read time from rtc and send the time to the slave pro mini using i2c.
Because slave Arduino pro mini need the time to calculate the Muslim prayer time.

In pro mini I received time from UNO and read some data(settings value that i saved previously from UNO) from eeprom 24lc512 and then calculate Muslim Prayer Time
Finally show the prayer time in 4 digit 7 segment .

That's it......

You have said that your system works for a while!
1. 7-segment Display Unit is connected with Pro; then why have you included SevenSegmentExtended.h librray with Master?

2. In Master code, you have the object display. But, in the code there is another uncreated object named display1. Why?

3. In master code, you have an unefined routine named: menuHome().

Please, recompile your Master sketch and remove the redundant codes.

I have also connect a 7segment with Master to show current time.

display object is used for nokia 5110 display. And display1 object is used for 7segment with Master to show current time.

homePage() function is to show this

and menuHome() is used for menu below

Have you created it? Check your sketch. I have encountered compilation ertor.

yes i created.

But i can successfully compile and run it.

Did you mean to use CString ?
So do i need to add #include<string.h> library ?
But what is the benefit of using CString instead of String ?

I think the problem that I faces is caused for I2C communication. But I am not sure about that.
I just guessed it. Because:

  1. All of the I2C devices are connected to the Master with same two pin A4 and A5.
  2. Master read data from two I2C devices(ds1307 rtc and 24lc512 eeprom) and transmit it to slave at the same time using same I2C pin A4 and A5.
  3. Slave also receive data from Master and read data from same eeprom using I2C communication at the same time.

Is this multiple I2C communication with same pin are conflicted and which causes hang ?
Or is it because the code is biggerand RAM is not enough to run the code?

Any suggestions or advice?