Richard-Gemmell / teensy4_i2c

An I2C library for the Teensy 4. Provides slave and master mode.
MIT License
92 stars 19 forks source link

no stable communication with slave mode #5

Closed hbitter closed 4 years ago

hbitter commented 4 years ago

Hi Richard, for a while now I am trying to use your teensy4_i2c lib for slave mode communication between a NodeMCU (master) and a Teensy4.0 (slave). The purpose of our project is maesuring the ambient noise level (SPL A-weighted over time). More info about the project via this link http://github.com/hbitter/dnms. The I²C coomunication between NodeMCU and Teensy4.0 is unstable (in contrast to the version for Teensy3.6, that version is running stable). I described the problem in the PJRC Forum Thread: I2C Slave on Teensy 4 Post #26. To make it a bit easier to locate the problem (espacially without having to use a NodeMCU) I tried the I²C communication between two Teensy4.0. Small test programs for the master side and the slave side are attached.

Used Versions: Arduino: 1.8.12 Teensyduino: 1.51 and also 1.52-beta1. -beta2 and -beta3 teensy4_i2c: v0.9.3

Testprogram: On the master side you can first input the number of bytes to transmit to the slave. The slave will then retransmit the received bytes to the master. The last byte in one transmission is a variable runnning from 0 to 255 and then it starts again with 0. Some serial outputs are done on master and slave side, showing the transmitted and received numbers. Between two transmissions from the master there is a delay of 100ms. The transmission repeats until an errors occurs (wrong number of bytes received by master or received variable difers from variable transmitted). Testprogram for master: i2c_test_T4_master_i2c_driver_wire.zip Testprogram for slave with wire: i2c_slave_receive_transmit_t4.0_i2c_driver_wire.zip

I also tried imx_rt1060_i2c_driver.h on the slave side but for me there is no difference in the behaviour. Testprogram for slave with imx_rt1060_i2c_driver: i2c_slave_receive_transmit_t4.0_imx_rt1060_i2c_driver.zip

Here are some examples of the serial outputs as well as LA pictures:

  1. with wire tests_T4_i2c_driver_wire_to_T4_i2c_driver_wire.zip

  2. with imx_rt1060_i2c_driver tests_T4_i2c_driver_wire_to_T4_imx_rt1060_i2c_driver.zip

Any help is appretiated, don' t know maybe I overlooked something really simple. Regards, Helmut Bitter helmut.bitter@t-online.de

Richard-Gemmell commented 4 years ago

Hi Helmut, I've replied to your post in the Teensy forum with some suggestions. With a bit of luck it's just a wiring problem.

The bad news is that I've never been able to eliminate all errors from my own project. (A Teensy 4 talking to a Raspberry Pi.) I get error rates of about 1 message in 5000. I can't remember the size of the messages but they're probably about 12 bytes. In the end I gave up trying to fix it and added a checksum to every message and handshaking to ensure that the messages are received Ok.

The following helped to reduce the error rate in my case:

cheers, Richard

Richard-Gemmell commented 4 years ago

Hi Helmut,

I've spent the last few days playing around with the pin configuration. I found NXPs [URL="https://www.nxp.com/docs/en/application-note/AN5078.pdf"]documentation[/URL] which wasn't in the datasheet and I also looked at changes made to the official Teensy Wire implementation.

The practical upshot of this, is that I've changed the driver to use the config you suggested except that I omitted IOMUXC_PAD_SRE. I've also added API methods so that users can override the default config if necessary without having to modify the driver files. See I2CDriverWire::setPadControlConfiguration(). I've updated the README to explain this as well.

The long story is that I tested various configurations on my project. This has 2 I2C connections. One to an INA260 current sensor and one to a Raspberry Pi. The Teensy is the master for the first connection and a slave for the second. I've never been able to make the connection to the Pi reliable. I was pretty sure that the problem was down to noise and I finally got the error rate down to about 1 failure in 10,000 messages. To achieve this, I had to add external pullups and rearranged the board to keep noisy lines away from the I2C wires.

I've looked at each part of the pad config to see what effect it has. I removed the external pullups before testing as I knew that increased the error rate significantly. The only settings that made any noticeable difference were:-

So I believe I've confirmed your finding that enabling IOMUXC_PAD_HYS seems to eliminate errors caused by noise. I decided to copy the other settings from the official Teensy Wire implementation as they work fine with my project and fix other problems. The only exception is that I didn't removed SRE as NXP's documentation says you shouldn't use it unless necessary as it can cause EMC problems.

Thanks very much for your tip. It's helped enormously. Richard

(This post was copied from the Teensy forums to help anyone who's reading this bug report.)