I2C - Requesting specific data

I need to request specific data from the slave. I have a MEGA2560 (slave) gathering data and sending it to an ESP32(Master) when the ESP requests. The data is approaching the 32byte buffer limit. I can break up the data into two sets but how do I tell the MEGA which set to send?

Thanks.

Google is your friend.

Take a peek at

for example.

You have to make a little story about all your data, and send the story in pieces.

a7

What kind of data is it ?
Can you show the sketch of both ?
The ESP32 is not 5V tolerant, do you use a I2C level shifter ?

Google and i don't get along. Anyway, He says that code does not work. How is he requesting struct1 or struct2? It looks like he is basing it on the size of the two structures. Is there a way for the master to say "send me struct1"?

SMH. How do you get anywhere at all ever?

a7

It is sensor data consisting of 16 bit integers. Right now I am sending one uint16_t and 15 int16_t . I need to send another uint16_t and around 15 more int16_t. If I am counting correct this will exceed the 32 byte limit on the MEGA side. I am uploading the script for the slave.

Would like to make the existing structure Struc1 and the rest of the data Struct2. and have the master make a request for Struct1k get the data then request Struct2

Yes I am using an I2C level shifter.

GH_mega2560_F1.ino (10.9 KB)

Send a 1 or 2 to the slave, then request and expect to receive struct 1 or 2.

DrDiettrich has the right solution.

volatile byte select = 1;      // default 1

void onReceive( int howMany)
{
  if( howMany == 1)        // extra check, only 1 byte expected
  {
    byte s = Wire.read();
    if( s == 1 or s == 2)
      select = s;
  }
}

void onRequest()
{
  if( select == 1)
    Wire.write( ... struct1 ...
  if( select == 2)
    Wire.write( ... struct2 ...
}

Since it is all 16-bit values, you could create a single large array of 16-bit integers, and send the index before requesting data. Then the Slave will emulate a sensor with 16-bit registers.

Note: Since the Slave does not know how many bytes the Master has requested, the Slave may fill the complete (internal) buffer up to 32 bytes, even if the Master was only requesting 2 bytes. That is okay.

You could buy a other board. The newer boards have sometimes a buffer of 256 bytes. There is however a problem with the Slave mode with newer boards (ESP8266, Arduino MKR Zero and all the other SAMD boards, Arduino Due, ESP32, Raspberry Pi Pico). According to the problems on this forum only the Arduino Uno and Mega and similar boards from the AVR family work in Slave mode.

The I2C bus is not really a communication bus. It was not meant for communication between processors.

1 Like

In case you weren't aware, the Mega has 4 additional hardware UART (serial) ports and the ESP32 has 2 additional hardware UART ports. That means you can communicate between 2 boards, while also having the primary UART port's available for uploading and debugging.

Using UART ports is a lot easier than using I2C for communication. In particular, 2 nodes can send to each other simultaneously, without collision, so there's no need for a master and slave protocol, in which the master polls the slave for data continuously. Level shifting is also required if you're using both the 3.3v ESP32 and 5v mega.

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.