2 Arduinos not comunicating with SDA and SCL

This question may seem rather crazy but in a project I was connecting an arduino mega with a TFT SPI 2.4 LCD because of all the pins needed to connect and working with other sensors in the mean time on a regular arduino uno so all the team could split acctivities. The problem arises when we are trying to connect one of the sensors to the mega, we discovered yesterday that that particular sensor could never work with the arduino mega so our profesor recommended us to connect 2 arduinos UNOS via I2C (SDA and SCL) so one could be the master and the other one the slave. The problem is that both arduinos work with their sensors, one arduino with the lcs and the other with the sensors for the project, but when we try to connect both arduinos via SDA and SCL and also the ground, it didn't work out, we didn't want to intervene with the power supply so one arduino is alimented with 5 V and the other via the computer, we know that we could connect the pin via de 5V pin. Also we send the arduino with the lcd the interphase for it and the other arduino we send the code for the sensors. We believe that there is a problem with the overlap of information but we don't know yet how to solve it.

As your topic does not relate directly to the installation or operation of the IDE it has been moved to the Programming Questions category of the forum

And neither will anyone else based on that monolithic block of text that never actually asks a question.

Show us your sketch(es).

Show us a schematic. Drawing one by hand is fine as long as all parts are labelled and it's clear how everything is connected.

Show us a clear, well lit, in focus picture (or pictures) of your wiring. Before posting, look at the images with a critical eye. Can you tell where the wires are going, solely based on the pictures? No? Then neither can anyone else.

And finally, tell us what didn't happen that you expected to happen. Be precise. "It didn't work" does not help.

1 Like

Master code (for the arduino with the sensors)

#include <SoftwareSerial.h>
#include <DHT11.h>
#include <Wire.h>

#define RE 8
#define DE 7
const byte nitro[] = {0x01, 0x03, 0x00, 0x1e, 0x00, 0x01, 0xe4, 0x0c};
const byte phos[] = {0x01, 0x03, 0x00, 0x1f, 0x00, 0x01, 0xb5, 0xcc};
const byte pota[] = {0x01, 0x03, 0x00, 0x20, 0x00, 0x01, 0x85, 0xc0};
const byte ec[] = {0x01, 0x03, 0x00, 0x15, 0x00, 0x01, 0x95, 0xCE};
const byte salinity[] = {0x01, 0x03, 0x00, 0x14, 0x00, 0x01, 0xC4, 0x0E};
const byte ph[] = {0x01, 0x03, 0x00, 0x00, 0x00, 0x01, 0x84, 0x0A};

DHT11 dht11(4);
byte values[11];
SoftwareSerial mod(2, 3); // Pines para RS485

const int arraySize = 7;
int dataToSend[arraySize] = {1, 2 ,3 ,4 ,5, 6, 7};


void setup() {
  // put your setup code here, to run once:
  Wire.begin();
  Serial.begin(9600);
  mod.begin(9600); // ComunicaciĆ³n RS485
  delay(100);
  pinMode(RE, OUTPUT);
  pinMode(DE, OUTPUT);
}

void loop() {
    // Leer valores de sensores
  Serial.print("Nitrogeno (mg/kg): ");
  dataToSend[0] = readSensor(nitro);
  delay(250);


  Serial.print("Fosforo (mg/kg): ");
  dataToSend[1] = readSensor(phos);
  delay(250);


  Serial.print("Potasio (mg/kg): ");
  dataToSend[2] = readSensor(pota);
  delay(250);

  Serial.print("Salinidad: ");
  dataToSend[4] = readSensor(salinity);
  delay(250);


  dataToSend[3] =  readSensorPH();
  Serial.print("pH del suelo: ");

  int temperature = 0;
  int humidity = 0;
  int result = dht11.readTemperatureHumidity(temperature, humidity);
  dataToSend[5] = humidity;
  dataToSend[6] = temperature;
  delay(5000);
  // put your main code here, to run repeatedly:
  Wire.beginTransmission(1); //ADDRESS 1
  for(int i = 0; i < arraySize; i++){
    Wire.write(dataToSend[i]); 
  }
  Wire.endTransmission();

  delay(5000);
}
byte readSensor(const byte *command) {
  digitalWrite(DE, HIGH);
  digitalWrite(RE, HIGH);
  delay(10);


  if (mod.write(command, 8) == 8) {
    digitalWrite(DE, LOW);
    digitalWrite(RE, LOW);
    for (byte i = 0; i < 7; i++) {
      values[i] = mod.read();
    }
  }
  return values[4];
}


// FunciĆ³n para leer valores en formato entero (16 bits)



// FunciĆ³n para leer el pH y convertirlo en flotante
float readSensorPH() {
  digitalWrite(DE, HIGH);
  digitalWrite(RE, HIGH);
  delay(10);


  if (mod.write(ph, 8) == 8) {
    digitalWrite(DE, LOW);
    digitalWrite(RE, LOW);
    for (byte i = 0; i < 11; i++) {
      values[i] = mod.read();
    }
  }
  return float(values[4]) / 10.0; // ConversiĆ³n a pH real
}```

Code for the lcd

#include <SPFD5408_Adafruit_GFX.h>    // Core graphics library
#include <SPFD5408_Adafruit_TFTLCD.h> // Hardware-specific library
#include <SPFD5408_TouchScreen.h>
#include <Wire.h>

#define RE 24
#define DE 22

#define LCD_CS A3
#define LCD_CD A2
#define LCD_WR A1
#define LCD_RD A0
#define LCD_RESET A4

const byte nitro[] = {0x01, 0x03, 0x00, 0x1e, 0x00, 0x01, 0xe4, 0x0c};
const byte phos[] = {0x01, 0x03, 0x00, 0x1f, 0x00, 0x01, 0xb5, 0xcc};
const byte pota[] = {0x01, 0x03, 0x00, 0x20, 0x00, 0x01, 0x85, 0xc0};
const byte ec[] = {0x01, 0x03, 0x00, 0x15, 0x00, 0x01, 0x95, 0xCE};
const byte salinity[] = {0x01, 0x03, 0x00, 0x14, 0x00, 0x01, 0xC4, 0x0E};
const byte ph[] = {0x01, 0x03, 0x00, 0x00, 0x00, 0x01, 0x84, 0x0A};

#define BLACK   0x31A7
#define BLUE    0x1B7B
#define RED     0xD8C3
#define GREEN   0x1C03
#define CYAN    0x1ED7
#define MAGENTA 0xA89C
#define YELLOW  0xDEA3
#define WHITE   0xFFFF

Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);

const int arraySize = 7;
int receivedData[arraySize];

byte values[11];

float nivel_ph = 0;
float nivel_temp = 0;
float nivel_humedad = 0;
float nivel_salinidad = 0;
float nivel_n = 0;
float nivel_p = 0;
float nivel_k = 0;

int avg_temp = 0;
int avg_humedad = 0;
float avg_ph = 0;
float avg_salinidad = 0;
float avg_n = 0;
float avg_p = 0;
float avg_k = 0;

bool lenguaje = 1;
float carga_bateria = 100;



void setup(void) {
  Serial.begin(9600);
  progmemPrintln(PSTR("TFT LCD test"));

  Wire.begin(1);
  Wire.onReceive(receiveEvent);
  pinMode(RE, OUTPUT);
  pinMode(DE, OUTPUT);

  tft.reset();
  tft.begin(0x1B7B);
  tft.setRotation(1);

  progmemPrintln(PSTR("Benchmark                Time (microseconds)"));
  progmemPrint(PSTR("PonTierra                  "));
  Serial.println(PonTierra());
  delay(3000);
}

void loop(void) {

}

void receiveEvent(int howMany) {
  progmemPrint(PSTR("Leyendo"));
  Serial.println(Leyendo());
  delay(100);
  int i = 0;
  while (Wire.available() && i < arraySize) {
    receivedData[i] = Wire.read();
    i++;
  }

  nivel_ph = receivedData[3];
  nivel_temp = receivedData[6];
  nivel_humedad = receivedData[5];
  nivel_salinidad = receivedData[4];
  nivel_n = receivedData[0];
  nivel_p = receivedData[1];
  nivel_k = receivedData[2];

  Serial.println("Array received:");
  for (int j = 0; j < arraySize; j++) {
    Serial.print("Element ");
    Serial.print(j);
    Serial.print(": ");
    Serial.println(receivedData[j]);
  }
  progmemPrint(PSTR("Datos"));
  Serial.println(Datos());
  delay(300);
  lenguaje = !lenguaje;
}

unsigned long PonTierra() {
  unsigned long start = micros();
  tft.fillScreen(BLUE);
  tft.setCursor(60, 100);
  tft.setTextColor(WHITE);
  tft.setTextSize(3);
  tft.println("EN TZOTZIL");
  tft.println();
  tft.setCursor(10, 130);
  tft.println("INSERTE EN TIERRA");
  delay(1000); // Add delay to stabilize display
  return micros() - start;
}

unsigned long Leyendo() {
  unsigned long start = micros();
  tft.fillScreen(GREEN);
  tft.setCursor(60, 100);
  tft.setTextColor(WHITE);
  tft.setTextSize(3);
  tft.println("EN TZOTZIL");
  tft.println();
  tft.setCursor(60, 130);
  tft.println("LEYENDO");
  delay(1000); // Add delay to stabilize display
  return micros() - start;
}

unsigned long Datos() {
  tft.fillScreen(WHITE);
  unsigned long start = micros();
  tft.setCursor(0, 0);
  tft.setTextColor(RED);
  tft.setTextSize(3);
  if (lenguaje == 0) {
    tft.print("Espanol");
  } else {
    tft.print("Tzozil");
  }

  tft.print("   ");
  tft.print(carga_bateria);
  tft.print("%");
  tft.println();
  tft.setTextColor(BLUE);
  tft.setTextSize(3);
  if (lenguaje == 0) {
    tft.print(" Temp: ");
  } else {
    tft.print(" K'ok': ");
  }
  tft.print(nivel_temp);
  tft.println(" C");
  if (lenguaje == 0) {
    tft.print(" Humedad: ");
  } else {
    tft.print(" Tl'ushul':");
  }
  tft.print(nivel_humedad);
  tft.println("%");
  tft.println();
  tft.setTextColor(MAGENTA);
  tft.setTextSize(3);
  tft.print(" PH:");
  tft.print(nivel_ph);
  tft.println("");
  if (lenguaje == 0) {
    tft.print(" Salinidad:");
  } else {
    tft.print(" TZOTZIL: ");
  }
  tft.print(nivel_salinidad);
  tft.println("%");

  tft.setTextColor(CYAN);
  tft.setTextSize(3);
  tft.print("  N: ");
  tft.print(nivel_n);
  tft.println(" mg/kg");
  tft.print("  P: ");
  tft.print(nivel_p);
  tft.println(" mg/kg");
  tft.print("  K: ");
  tft.print(nivel_k);
  tft.println(" mg/kg");

  return micros() - start;
}

void progmemPrint(const char *str) {
  char c;
  while ((c = pgm_read_byte(str++))) Serial.print(c);
}

void progmemPrintln(const char *str) {
  progmemPrint(str);
  Serial.println();
}

O my bad, since the question was already long, I was planning to send the codes and the problem below, I didn't expect a rapid answer

There's a good chance that your master code is transferring data too quickly to the slave device and your slave can't react quickly enough. I would insert a delay between each byte you write over the I2C link - start with something like a 10ms delay and see how it goes.

You should also strip out a lot of the code from your receiveEvent function as you need that code to be as small as possible.

Doesn't receiveEvent get called after each byte is received? I don't think you can sit in a loop inside receiveEvent reading in bytes - but I could be wrong.

So the main problem is the communication, the lcd do insert the welcome page but at the time for the "reading the values" and then inserting them where there are suppose to be entered the lcd doesn't print the values of the sensors. The interphase is correct since we tried with a temperature and humidity sensor (dth11) before having the problem with the arduino MEGA with the specific sensor, so it did insert and printed the values on arduino mega before now we are having trouble with the two arduinos uno at the same time

Ooo! thanks let me check that

Why not? Which sensor is it?

If it won't work with a Mega then it probably won't work with an UNO either, unless of course the sensor is on a shield that is only designed for use with an UNO.

The sensor do work with the arduino Uno we make a lot of tries. The sensor is a
Aqur2020 Integrated soil sensor, RS485 5 Pins with PH NPK Temperature and humidity Sensor. The link is the following: Link
We were actually investigating a lot since the problem arised (Last Saturday) and even we post it on here in this forum but with a different account, my friends one, and they where having a fight about this particular sensor. But on the bright side it did work on the arduino uno this sensor

The problem we have is the comunication between both arduinos

Ah, one of those RS485 (Modbus) NPK sensors. Putting aside the fact that those sensors are a scam, there's no reason why it shouldn't work on a Mega.

In fact it should work better on the Mega as you have 4 hardware serial ports so no need for a software serial port.

I would stick with the Mega as splitting the project across 2 UNOs and transferring data over I2C is likely to be a bigger headache.

Do you know like a code or how correctly connect it since we were having problems, or a page were to consult

You can use Serial1 on the Mega to talk to your sensor via the RS485 module. Your RS485 module will either have RE and DE pins to control the direction of the data or be an auto switching one.

Part of the problem you will have is that most of the NPK code found on the various websites is flawed - they copy eachother and the bug(s) in the code get copied too.

I would suggest using the ModbusMaster library rather than those canned Modbus message arrays as the library will take care of all the serial timing etc.

Perhaps start simple and get just the NPK sensor working on Serial1 and then add in functionality as you go.

I guess your friends discussion was this one:

we did tried yesterday that, the serial1 and didn't work

The problem is not the npk sensor, I'm not writing this forum for that, is the problem with the comunication between 2 arduinos via I2C

Have you had a read of: