I2C: ISO1541 I2C isolator not working with 2 Arduinos - Page 1
Forum section: electronics / projects

author: jmibk
author_rank: Regular Contributor
timestamp: June 06, 2022, 12:48:57 pm
content: Hi,I'm trying to connect several slave I2C Arduinos to a I2C master Arduino though an ISO1541 I2C isolator chip from TI. See datasheet here:https://www.ti.com/lit/ds/symlink/iso1541-q1.pdfThe Arduinos are on different voltage potentials - thats why I use the ISO1541.Now I set up the 2 Arduinos with a simple example sketch for I2C communication:The master device:Code:// Include Arduino Wire library for I2C#include <Wire.h>// Define Slave I2C Address#define SLAVE_ADDR 9// Define Slave answer size#define ANSWERSIZE 5void setup() {// Initialize I2C communications as MasterWire.begin();// Setup serial monitorSerial.begin(115200);Serial.println("I2C Master Demonstration");}void loop() {delay(50);//write some byte data to the slaveSerial.println("Write data to slave");Wire.beginTransmission(SLAVE_ADDR);Wire.write(199);Wire.endTransmission();Serial.println("Receive data");// Read response from Slave// Read back 5 charactersWire.requestFrom(SLAVE_ADDR,ANSWERSIZE);// Add characters to stringString response = "";while (Wire.available()) {char b = Wire.read();response += b;}// Print to Serial MonitorSerial.println(response);}The slave device:Code:// Include Arduino Wire library for I2C#include <Wire.h>// Define Slave I2C Address#define SLAVE_ADDR 9// Define Slave answer size#define ANSWERSIZE 5// Define string with response to MasterString answer = "Hello";void setup() {pinMode(LED_BUILTIN, OUTPUT);// Initialize I2C communications as SlaveWire.begin(SLAVE_ADDR);// Function to run when data requested from masterWire.onRequest(requestEvent);// Function to run when data received from masterWire.onReceive(receiveEvent);// Setup Serial MonitorSerial.begin(115200);Serial.println("I2C Slave Demonstration");}void receiveEvent() {// Read while data receivedbyte x;while (0 < Wire.available()) {x = Wire.read();}//set the led according to the dataif (x%2 == 1)digitalWrite(LED_BUILTIN, HIGH);elsedigitalWrite(LED_BUILTIN, LOW);// Print to Serial MonitorSerial.println("Receive event");}void requestEvent() {// Setup byte variable in the correct sizebyte response;// Format answer as arrayfor (byte i=0;i<ANSWERSIZE;i++) {response = (byte)answer.charAt(i);}// Send response back to MasterWire.write(response,sizeof(response));// Print to Serial MonitorSerial.println("Request event");}void loop() {// Time delay in loopdelay(50);}Here you can see the 2 Arduinos chatting via I2C. Left one is slave, right one is master.The serial output (master) looks good. "Hello" is coming from the slave. If a I2C lins is disconnected, the "Hello" is missing.Now I connect the ISO in between and the master seems to block or receives bullshit data.Pins 1-4 is connected to the master, SDA and SCL have 1k pullups,Pins 5-8 is connected to the slave, SDA and SCL have 1k pullups.Now I tested the ISO with a function gen and an scope to see, if it directs all signalsSetup is not beautiful but it does its job.In this document you can see the results in both directions - all seems to be ok.https://audiowerk.at/downloads/temp/eev/i2c_arduino_iso_failure/ISO1541-Transmission.pdfNow I got into more detail. The master sketch consists of two parts. One is for sending a value to the slave and the seconds reads a value from the slave.The first part where the sketch is writing a single value to the slave works with the ISO driver without any problems. I checked by sending incrementing data to the slave and blinked the LED according the number is even or odd. Heres the master sketch (slave is the same as above)Code:// Include Arduino Wire library for I2C#include <Wire.h>// Define Slave I2C Address#define SLAVE_ADDR 9void setup() {// Initialize I2C communications as MasterWire.begin();// Setup serial monitorSerial.begin(115200);Serial.println("I2C Master Demonstration");}void loop() {delay(250);//write some byte data to the slaveSerial.println("Write data to slave");Wire.beginTransmission(SLAVE_ADDR);Wire.write(millis()/250);Wire.endTransmission();}Here the scope views of the signals - without ISO, direct connection:and with ISO:Both working!The second part where the master requests a string is latching up or someting else.Heres the code that is on the master (slave is the same as above):Code:// Include Arduino Wire library for I2C#include <Wire.h>// Define Slave I2C Address#define SLAVE_ADDR 9// Define Slave answer size#define ANSWERSIZE 5void setup() {// Initialize I2C communications as MasterWire.begin();// Setup serial monitorSerial.begin(115200);Serial.println("I2C Master Demonstration");}void loop() {delay(50);Serial.println("Receive data");// Read response from Slave// Read back 5 charactersWire.beginTransmission(SLAVE_ADDR);Wire.requestFrom(SLAVE_ADDR,ANSWERSIZE);Wire.endTransmission();// Add characters to stringString response = "";while (Wire.available()) {char b = Wire.read();response += b;}// Print to Serial MonitorSerial.println(response);}Scoping the I2C lines at the master, following shows up - with direct connection without the iso driver:With the ISO driver in between i get two signals, seems like on is glitched:The serial monitor shows:In a short form - here is what I tried and what is working and whats not:Has someone an idea, what is going on here?

author: ledtester
author_rank: Super Contributor
timestamp: June 06, 2022, 03:01:23 pm
content: In this diagram:what pins of the ISO1541 are the SCL lines connected to?One thing I noticed is that on the ISO1541 is that the SDA1/SDA2 pair is bi-directional but the SCL1/SCL2 pair is not. Both are bi-directional on the 1540. The configurations which work seem to be where the SDA and SCL lines can communicate bi-directionally -- either by a direct connection or through the SDA1/SDA2 pair of the ISO1541.

author: free_electron
author_rank: Super Contributor
timestamp: June 06, 2022, 03:23:29 pm
content: did you notice that the SDA has a third level ? there are moments where the signal does not go to ground. it hovers at like 0.2 or 0.3 volts. That is the moment the iso chip does the "turnaround".The side with VCC1 needs to be attached to the master. the side with VCC2 goes to the slaves.also , put a decoupling cap close to that little board you have and provide proper pullups. your edges are crappy. at 5 volts : 1K to 2k2 will do nicely.

author: jmibk
author_rank: Regular Contributor
timestamp: June 06, 2022, 04:07:14 pm
content: QuoteMaster:SDA => Pin 2SCL => Pin 3VCC (1) and GND (4) connected to the supply voltage of the master (5V)Slave:SDA => Pin 7SCL => Pin 6VCC (and GND (5) connected to the supply voltage of the slave (5V)4x 1k pullups and 2 caps are there, see detailed image. Its not pretty, but they are there.The edges are horrible - yes I agree. But they are only on the direct connection without the isolator chip. 1:10 probing doesn't change much - maybe it is a thing of unpropper grounding of the scope leads.The horrible edges work, the beautiful ones of the ISO chip notI think it is OK that the ISO1541 has a unidirectional clock line. I have only one master, so the slaves don't have to clock something - or I am missing something?I bought some ISO1540 with bidirectional clock and will try them on my boards - they should be pin compatible.

author: jmibk
author_rank: Regular Contributor
timestamp: June 13, 2022, 03:27:34 pm
content: Yesterday I was at a mates house and we talked about the issue with the I2C and I showed him the scope printouts (you can see them above in a previous thread).He saw that at the isolated version the master is clocking after the first byte without any break. It can't be unseen until you saw it.There the slave pulls the SDA line low but the master clocks for the bytes coming from the slave.So the thing must be that the master can't read the slave information of the SDA line (that is pulled low).That new thing doesn't match up with the experiments with the ISO driver and bridging some signals around the ISO driver.There was an experiment to direct connect the SCL and the SDA goes through the ISO chip - and it worked.

author: Nominal Animal
author_rank: Super Contributor
timestamp: June 13, 2022, 04:38:23 pm
content: Quote from: jmibk on June 06, 2022, 12:48:57 pmI disagree. The master SCL (SCL1) stays high regardless of slave state, even though the master SDA follows the slave state. The slave should be able to pull SDA down.Edited: Ah, okay; this is as expected for ISO1541, since it has an unidirectional clock. Ouch. Me.The idea of the I2C protocol is that the pull-up resistors pull the SCL and SDA lines high by default. Any party, at any time, can pull either signal down. No party, at any time, can (reliably) pull a signal high if others are pulling it down. (In EE-speak, I guess this is usually stated as "I2C bus is an open-drain/open-collector design".)Edited: Thus, with an unidirectional clock, the slave cannot doclock stretching. I don't know whether this matters in this case, though; one would need to examine how the SCL line behaves at and after an ACK on both sides of the isolator, and see if there is a difference. Ithinktheunbenannt.jpgattached to jmibk's message above is a case of clock stretching – the slave not being ready to receive yet, and keeps SCL down – based on the slight voltage level change that AIUI indicates a direction change on the SCL signal, but I've already been wrong once in this message...

author: Nominal Animal
author_rank: Super Contributor
timestamp: June 13, 2022, 05:01:44 pm
content: To summarize – and apologies to everyone (especially rstofer) if I'm restating the obvious!ISO1541 has an unidirectional SCL.Free_electron pointed out that the0.3V to 0.4V instead of 0.0V indicates the ISO chip doing a turnaround.jmibkposted an attachmentshowing the SDA behaviour at the moment of the problem:Combining these observations, it looks like this particular slave is doing clock stretching, i.e. keeping SCL down, because it is not immediately ready to receive more data; based on how the SDA line changes direction in the erroneous change, showing a 0.3V instead of 0.0V. As clock stretching is the only sensible reason for the slave to try to assert the SDA/SCL lines at this point, it makes sense. But, since ISO1541 has an unidirectional SCL, it does not support clock stretching at all.To verify, compare SCL lines across the ISO1541. At the moment of clock stretching (the start of the section you circled in red), you should see master SCL going high, but slave SCL staying low.Thus, the solution seems to be to switch to an ISO1540, which fortunately is pin-compatible.