Go Down

Topic: I2C Slave and Serial (Read 82 times) previous topic - next topic

eried

Hi, I am reading a Chess clock (DGT3000) via I2C with a Leonardo, and my receive function looks like:

Code: [Select]
void receiveEvent(int howMany)
{
  // loop through all but the last
  for (int i = 0; i < howMany; i++)
  {
    // read byte as a character
    char c = Wire.read();
    Serial.print(i);
  }
}


And this is working perfectly, however if I add something extra:

Code: [Select]
void receiveEvent(int howMany)
{
  // loop through all but the last
  for (int i = 0; i < howMany; i++)
  {
    // read byte as a character
    char c = Wire.read();
    Serial.print(i);
    Serial.print(":");
    Serial.print(c, HEX); // print the character
    Serial.print(" ");
  }
  Serial.println();
}


The master (chess clock) just send 2 messages and stop sending. I am guessing this is because I am taking too much time inside the routine and conflicts between the interruption and Serial, but I actually need to output what I get via serial :/

What can I do?

The messages arrive twice a second, so I think there is time. Can I just tell the master to wait for me while I do Serial stuff?
My website: http://ried.cl

ron_sutherland

#1
Sep 15, 2018, 12:02 am Last Edit: Sep 15, 2018, 12:05 am by ron_sutherland
Perhaps it would be better to not do the Serial in the I2C receive event. Make a copy (buffer) in the I2C event and set a flag (got_i2c) so the main loop can see it and copy the buffer to the Serial.  

My guess is the serial buffer fills up (e.g. more than 32 bytes) and then starts blocking while the I2C receive event is running. The TWI code that is used for Wire starts clock stretching before running the receive callback, so I would guess that having a blocking serial during a receive event would be a disaster.

eried

Thanks Ron, it works perfect with your suggestion.
My website: http://ried.cl

Go Up