0

I programmed an ESP32 as an I2C slave. I was using arduino IDE to program the ESP32 and the version installed in the boards manager is 2.0.17. When I tested it with a master, the data order was incorrect on the received data. To test it at a very basic level, I wrote a piece of code where whatever the master wrote to the slave, the slave would return the double of it on the next data request.

The master code:

#include <Wire.h>

const int slaveAddress = 0x08; // I2C address of the slave

void setup() {
  Wire.begin(); // join I2C bus as master
  Serial.begin(115200);
}

void loop() {
  // Send numbers 1, 2, 3, 4, 5 in series
  for (int valueToSend = 1; valueToSend <= 5; valueToSend++) {
    sendAndReceive(valueToSend); // Send and receive for each number
    delay(1000);                 // 1-second delay between transmissions
  }
}

void sendAndReceive(int valueToSend) {
  // Send the value to the slave
  Wire.beginTransmission(slaveAddress);
  Wire.write(valueToSend); // Send the number to be doubled
  Wire.endTransmission();

  delay(5000); // Small delay to ensure the slave processes the request
  
  // Request 1 byte back from the slave
  Wire.requestFrom(slaveAddress, 1);
  
  if (Wire.available()) {
    int receivedValue = Wire.read(); // Read the response from the slave
    Serial.print("Sent: ");
    Serial.print(valueToSend);
    Serial.print(", Received: ");
    Serial.println(receivedValue); // Expecting the doubled value
  } else {
    Serial.println("No response from slave");
  }
}

The slave code:

#include <Wire.h>

int receivedValue = 0;
int responseValue = 0;

void setup() {
  Wire.begin(0x08); // join I2C bus with address 0x08
  Wire.onReceive(receiveEvent); // register event for receiving data from master
  Wire.onRequest(requestEvent); // register event for responding to master requests
  
  Serial.begin(115200);
}

void loop() {
  }

// This function is triggered when data is received from the master
void receiveEvent(int howMany) {
  if (Wire.available()) {
    receivedValue = Wire.read(); // Receive the number sent by the master
    responseValue = receivedValue * 2; // Double the value
    Serial.print("Received from master: ");
    Serial.print(receivedValue);
    Serial.print(", Prepared to send: ");
    Serial.println(responseValue);
  }
}

// This function is triggered when the master requests data
void requestEvent() {
  Wire.write(responseValue); // Send the doubled value back to the master
}

Response on Master (The return value is shifted to the next read)

Sent: 1, Received: 10
Sent: 2, Received: 2
Sent: 3, Received: 4
Sent: 4, Received: 6
Sent: 5, Received: 8

Response on Slave (Slave is processing correctly)

Received from master: 1, Prepared to send: 2
Received from master: 2, Prepared to send: 4
Received from master: 3, Prepared to send: 6
Received from master: 4, Prepared to send: 8
Received from master: 5, Prepared to send: 10
3
  • It seems like slave is answering the first request with an packet from the previous test. Commented Sep 27, 2024 at 8:05
  • @Tarmo I uploaded the same slave code to an Arduino Mega and used it as a slave. It worked exactly as expected. I do not know why the same code works on Arduino but not on ESP32. Commented Sep 27, 2024 at 9:20
  • One thing different between ESP32 and Arduino Mega board, among other things, is that Arduino Mega board has on-board pull-up resistors on SCL/SDA, while ESP32 doesn't. Do you connect the pull-up resistors on ESP32? BTW, the delay(5000) isn't necessary as Wire.requestFrom(slaveAddress, 1) is blocking in nature and in fact it returns the number of bytes received. Commented Sep 28, 2024 at 1:25

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.