I2C issues in slave mode, sometime stay in I2C_SLAVE_RX state

Status
Not open for further replies.
Hello all,

I'm need your help.
I use to write softwares on an MEGA2560 which talk with an I2C bus to other devices base on PCF8574 (write and read) but this is my first time I connect an Teensy.
So, I added on a such network an Teensy 3.2 with an TXS0102 (for 3.3V to 5V level translator).
MEGA2560 / I2C 5V (MASTER)
  • TXS0102/ I2C 3.3V + pull-up 4.7k --> Teensy3.2 (SLAVE)
  • PCF8574
  • PCF8574 + pull-up 10k

After many tests / checks / (flying Teensy :rolleyes: ) , I don't understund why Teensy keep sometime the I2C bus in I2C_SLAVE_RX state?
The master send to the Teensy an message of 2 byte (+ address) each 200ms. Often (one per 5 minutes), Teensy "miss" one message. At this time the I2C state keep "I2C_SLAVE_RX" in the main loop. And some other times (less frenquently) the SCL line stay low, until I reboot the Teensy. Of course, the 2 behaviors introduce heavy disturbtions in the network.

I realized in writing the post that my issue is not necessary clear. It probablycould be something simple, but I miss it. Many thanks in advanced for your help or support

Other informations : I used short cables (less than 20cm). Rate : low speed 100kHz
PS : also many thank for the forum that I used dally.

Code:
// -------------------------------------------------------------------------------------------
// Base on "Basic Slave" i2c_t3
// -------------------------------------------------------------------------------------------


#include <i2c_t3.h>

// Function prototypes
void receiveEvent(size_t count);
void requestEvent(void);

// Memory
#define MEM_LEN 256
char databuf[MEM_LEN];
volatile uint8_t received;

IntervalTimer TimerPrincipal;
boolean b_FlagTimerCompteur;
int i_Index;


void Tache_Timer()
{
	b_FlagTimerCompteur = true;
}


// Setup
void setup()
{
    pinMode(LED_BUILTIN,OUTPUT); // LED

    // Setup for Slave mode, address 0x10, pins 18/19, external pullups, 100kHz
    Wire.begin(I2C_SLAVE, 0x10, I2C_PINS_18_19, I2C_PULLUP_EXT, 100000);
	Wire.setDefaultTimeout ( 1000 );

    // Data init
    received = 0;
    memset(databuf, 0, sizeof(databuf));

    // register events
    Wire.onReceive(receiveEvent);
    Wire.onRequest(requestEvent);

    Serial.begin(115200);
	// Start Timer
	TimerPrincipal.begin(Tache_Timer, 200000);
	TimerPrincipal.priority(1);					// todo : check value to set
}


void loop()
{
	if (b_FlagTimerCompteur == true)
	{
		if(received)							// print received data - this is done in main loop to keep time spent in I2C ISR to minimum
		{	digitalWrite(LED_BUILTIN,HIGH);
			/*if (i_Index > 0)
			{	i_Index = i_Index - 1; }*/
			Serial.printf("Slave received: '%s' ; char[0] : '%2X' ; char[1] : '%2X' , received : %X, index : %X\n", databuf, databuf[0], databuf[1], received, i_Index);
			received = 0;
			digitalWrite(LED_BUILTIN,LOW); }
		else
		{	i_Index = i_Index + 1;
			Serial.printf("No I2C message, statut : '%X' , index : %X\n",Wire.status(),i_Index); }
    	b_FlagTimerCompteur = false;
	}
}

//
// handle Rx Event (incoming I2C data)
//
void receiveEvent(size_t count)
{
    Wire.read(databuf, count);  // copy Rx data to databuf
    received = count;           // set received flag to count, this triggers print in main loop
}

//
// handle Tx Event (outgoing I2C data)
//
void requestEvent(void)
{
    Wire.write(databuf, MEM_LEN); // fill Tx buffer (send full mem)
}

Serial Output
Code:
Slave received: 'Q' ; char[0] : '51' ; char[1] : ' 3' , received : 2, index : 5F
Slave received: 'Q' ; char[0] : '51' ; char[1] : ' 3' , received : 2, index : 5F
Slave received: 'Q' ; char[0] : '51' ; char[1] : ' 3' , received : 2, index : 5F
No I2C message, statut : 'C' , index : 60
Slave received: 'Q' ; char[0] : '51' ; char[1] : ' 3' , received : 2, index : 60
Slave received: 'Q' ; char[0] : '51' ; char[1] : ' 3' , received : 2, index : 60
Slave received: 'Q' ; char[0] : '51' ; char[1] : ' 3' , received : 2, index : 60
 
@Theremingenieur thanks for time and idea.

I made the change, there are know 2.2k pull-up resistors beetwen level shifter and the Teensy.

It's the same issue.... it's seem to be worth, issue happens more often.
Furthermore, Teensy sometime catch only one byte, instead of two.
 
Code:
Slave received: '' ; char[0] : ' 1' ; char[1] : ' 0' , received : 2, index : 75
No I2C message, statut : 'C' , index : 76
Slave received: '' ; char[0] : ' 1' ; char[1] : ' 0' , received : 2, index : 76
Slave received: '' ; char[0] : ' 1' ; char[1] : ' 0' , received : 2, index : 76
Slave received: '' ; char[0] : ' 1' ; char[1] : ' 0' , received : 2, index : 76
Slave received: '' ; char[0] : ' 1' ; char[1] : ' 0' , received : 2, index : 76
Slave received: '' ; char[0] : ' 1' ; char[1] : ' 0' , received : 2, index : 76
Slave received: '' ; char[0] : ' 1' ; char[1] : ' 0' , received : 2, index : 76
No I2C message, statut : 'C' , index : 77
Slave received: '' ; char[0] : ' 1' ; char[1] : ' 0' , received : 2, index : 77
Slave received: '' ; char[0] : ' 1' ; char[1] : ' 0' , received : 2, index : 77
Slave received: '' ; char[0] : ' 1' ; char[1] : ' 0' , received : 1, index : 77
Slave received: '' ; char[0] : ' 1' ; char[1] : ' 0' , received : 2, index : 77
 
Status
Not open for further replies.
Back
Top