Communication between Ardunio Uno and ESP32 other than I2C

Hello there,
Currently I am doing a school project about water quality.
I have connected many sensors such as DF Robot's 5v pH sensor, 5v Turbidity sensor and a TDS sensor to a Ardunio Uno. I've also connected a I2C Lcd to the Arduino UNO to display what the sensors are showing. All of that works.

The ESP32 microcontroller is compatible with Arduino IOT cloud dashboard and has WiFi and Bluetooth built in.

My idea is to connect the ESP32 to the Arduino Uno via a Logic Converter (Converts the Uno's 5v to 3.3v) so the UNO can transfer the data outputted by the sensors to the ESP32 so it can upload it to the Arduino Dashboard. Any ideas on the communication between the two?

p.s I cant directly hook up the sensors to the ESP because it consumes 5v and the ESP outputs mainly 3.3v
The Arduino UNO is not compatible with the IOT dashboard.

can be done - what communications are you planning to use? serial, I2C, ???
if serial you can use a potential divider on the UNO Tx to ESP32 Rx pin
e.g. see arduino-mega-2560-serial-communication-to-esp8266
if I2C you require a full level converter

Can you use multiple devices on I2C? Because I already have a LCD on it

I need to receive the data and assign it as a variable

also there's multiple data strands, im looking for a communication standard that can do that

yes - it is probably simpler to use serial

you can transmit serial data as binary or text parsing it and assigning results to variables
e.g. you could transmit comma seperated values
12,456,-78,2.3,567.7,-78.9
have a look at serial-input-basics-updated

give an example of what your data transfer would look like

ppm:
1208.00
temp:
47.00
dirt:
73.62
flow:
8

Don't worry about the words

assuming you receive the numeric data over serial communication in the form "1208.00 47.00 73.62 8" you could use

// read float data from Serial seperated by spaces
void setup() {
  while(!Serial);
  Serial.begin(115200);
  // test with "1208.00 47.00 73.62 8"; 
  float ppm=89.0,temp,dirt,flow=78;
  while(!Serial.available());
  ppm=Serial.parseFloat();
  temp=Serial.parseFloat();
  dirt=Serial.parseFloat();
  flow=Serial.parseFloat();
  Serial.println(ppm);
  Serial.println(temp);
  Serial.println(dirt);
  Serial.println(flow);
}
void loop() {}

when run with "1208.00 47.00 73.62 8" entered on the serial monitor the output is

07:44:27.820 -> 1208.00
07:44:27.820 -> 47.00
07:44:27.820 -> 73.62
07:44:27.820 -> 8.00

if using an ESP32 you could use hardware Serial1 port to receive the data

It might be simpler and more chance of success if you remove the Uno and connect the sensors and LCD directly to the ESP32.

You will need to adapt the 5V LCD and sensors to work with the 3.3V ESP, but that should be simpler than getting 2 Arduino to communicate with each other, which is always much more difficult than beginners realise.

You can use a logic level adaptor between the LCD and the ESP.

Post details of your sensors and we can suggest ways to adapt those to work with the ESP.

How is the esp powered?

You can connect ESP32 and UNO as per Fig-1 using I2C Bus and Level Shifter.


Figure-1:

1 Like

Its powered via usb, however I have 5 5v sensors and the project guidelines require a UNO as a main board.

When I run a i2c scanner on the UNO it shows that the ESP32 has 32 addresses, however if I choose one address and use the uno to send a msg, on the esp it does not show up.

Modify the project guidelines and omit the UNO. For your 5V Sensors you can use the level shifter you would also need in the case when you connect the ESP32 and UNO.

Post the sketches that you have uploaded into I2C-MasterUNO and I2C-SlaveESP32.

Alright, give me a min

The code below are just examples

Code for UNO

// Wire Master Writer
// by Nicholas Zambetti <http://www.zambetti.com>

// Demonstrates use of the Wire library
// Writes data to an I2C/TWI Peripheral device
// Refer to the "Wire Peripheral Receiver" example for use with this

// Created 29 March 2006

// This example code is in the public domain.


#include <Wire.h>

void setup()
{
  Wire.begin(); // join i2c bus (address optional for master)
}

byte x = 0;

void loop()
{
  Wire.beginTransmission(1); // transmit to device #4
  Wire.write("hi");        // sends five bytes
  Wire.write(x);              // sends one byte  
  Wire.endTransmission();    // stop transmitting

  x++;
  delay(500);
}

Code for ESP32

// Wire Peripheral Receiver
// by Nicholas Zambetti <http://www.zambetti.com>

// Demonstrates use of the Wire library
// Receives data as an I2C/TWI Peripheral device
// Refer to the "Wire Master Writer" example for use with this

// Created 29 March 2006

// This example code is in the public domain.


#include <Wire.h>

void setup()
{
  Wire.begin(1);                // join i2c bus with address #4
  Wire.onReceive(receiveEvent); // register event
  Serial.begin(115200);           // start serial for output
}

void loop()
{
  delay(100);
}

// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany)
{
  while(1 < Wire.available()) // loop through all but the last
  {
    char c = Wire.read(); // receive byte as a character
    Serial.print(c);         // print the character
  }
  int x = Wire.read();    // receive byte as an integer
  Serial.println(x);         // print the integer
}

here are also the I2C ports read by the ESP32 using a scanner:

Found address: 9 (0x9)

Found address: 11 (0xB)

Found address: 14 (0xE)

Found address: 15 (0xF)

Found address: 16 (0x10)

Found address: 22 (0x16)

Found address: 23 (0x17)

Found address: 24 (0x18)

Found address: 27 (0x1B)

Found address: 28 (0x1C)

Found address: 34 (0x22)

Found address: 35 (0x23)

Found address: 37 (0x25)

Found address: 38 (0x26)

Found address: 46 (0x2E)

Found address: 47 (0x2F)

Found address: 48 (0x30)

Found address: 51 (0x33)

Found address: 53 (0x35)

Found address: 54 (0x36)

Found address: 55 (0x37)

Found address: 67 (0x43)

Found address: 70 (0x46)

Found address: 71 (0x47)

Found address: 76 (0x4C)

Found address: 78 (0x4E)

Found address: 79 (0x4F)

Found address: 81 (0x51)

Found address: 88 (0x58)

Found address: 92 (0x5C)

Found address: 96 (0x60)

Found address: 101 (0x65)

Found address: 102 (0x66)

Found address: 105 (0x69)

Found address: 110 (0x6E)

Found address: 113 (0x71)

Found address: 117 (0x75)

Found address: 118 (0x76)

I have problem to configure ESP32 as I2C-Slave. So, I have configured ESP32 as I2C-Master and UNO as I2C-Slave. The working sketches are given below ; where, ESP32 recognizes UNO as I2-Slave at slaveAddress 0x23. Connect your all 5V sensors with UNO and collect data from UNO by the ESP32 using I2C protocol.

ESP32-I2CMaster Sketch:

#include<Wire.h>

void setup()
{
  Serial.begin(9600);
  Wire.begin(21, 22); //SDA, SCL
  //--------------

}

void loop()
{
  Wire.beginTransmission(0x23);
  byte busStatus = Wire.endTransmission();
  if (busStatus != 0)
  {
    Serial.print("UNO is not found!");
    while (1); //wait for ever
  }
  Serial.println("UNO is found.");
  delay(1000);
}

UNO-I2cSlave Sketch:

#include<Wire.h>

void setup()
{
  Serial.begin(9600);
  Wire.begin(0x23);
}

void loop()
{

}

Output on ESP32's SM:

UNO is found.
UNO is found.
UNO is found.

yes, that works!
Thank you so much!

1 Like

Well, when in the future it comes your turn to write some project guidelines, I hope you will remember back to this project and take care not to write stupid guidelines! Project guidelines should describe what is to be done, not how it is to be done or which components must or must not be used.

I didnt write those guidelines, the teacher did.