Cut which I2C jumpers / keep which pull up resistors on several Qwiic daisy chains

Hi,

Question about which I2C jumpers should be severed when using several devices and daisy chains:

I may have reached the limit of Qwiic-connected devices as I get random errors (freezes, booting wrong) since I added the last device (a LED strip).

I use a Micromod Single Mainboard which comes with 2 Qwiic connectors that are connected to the primary I2C bus.

On Qwiic connector 1 attached are 2 devices (9DOF IMU and LED strip)
On Qwiic connector 2 attached are 3 devices (Button, Haptic and display)

In several hookup guides I read that in case of random errors, one should have “only a single pair of pull up resistors enabled” (like mentioned in the LED hookup guide).

Now my question:

a) Does that mean that on each of the 2 Qwiic chains I will have to severe every I2C jumper except one for each daisy chain (so two I2C jumpers are kept intact, one on each daisy chain)? And in that case, the one I do not severe is which one? The last one (end of the daisy chain, farthest away from mainboard) or the first one?

b) or do I have to cut every I2C jumper on 4 devices except 1 (ignoring that there are 2 Qwiic-daisy chains)? And in that case, keep the I2C jumper on which device (last one, first one, in the middle?)

Thanks,
Michael

Whlle there are 2 QWIIC connectors, it is ONE single Qwiic / I2c bus. On a single bus you should only have one pair of SDA / SCL pull-up resistors. On the Single board there are already pullups.. so NONE of the peripherals need a pull-up.

That said there could be other reasons:
Wire speed. In earlier post you set Wire speed to 400kps. Not all I2C/Qwiic devices support that speed.
Line length: i2C/Qwiic, can handle up to 1Meter/ 100Khz with a good quality cable. the cable capacitance ( pf) has a high impact.
Power consumption: The Qwiic 3v3 voltage generator on a single board can deliver max 500mA, all depending on the 5V quality that is provided.
Connection quality: How are the cables connected with low connection resistors. Also are the cables “thick” enough to pass on the current and voltage.

Hi, thanks for your answer.

Wire speed is set to its default value (100.000).

I tested power consumption by adding devices one after another and checking with amperemeter the consumed power from the LiPo battery.

Result: 300 mA max (mainboard, esp32, imu, button pressed, haptic on, display white, led strip on) and around 150 mA idle.

The Qwiic cables are around 30 cm long all together. I use this Qwiic cables.

Next I will cut all but 1 pullup jumper.

Thanks
There are already pull-up resistors on the single mainboard. So none of the devices need it.

Ok so I did many tests today, with these results:

Cut pullup resistors worked but does solve the issue why I wrote this posting.

I forgot to describe it in the first place: as soon as I add the LED strip to the setup, on random occasions I get either “I2C transaction timeouts” (minor impact: LED strip behaves wrong, like a wrong color somewhere) or worse the board/sketch crashes, flooding the console with “I2C transaction timeouts” (only power cycle helps).

Setup: Single Mainboard + ESP32 + Micromod PoE Ethernet
Qwiic connector 1: Button > Haptic > OLED Display > LED Strip
Qwiic connector 2: 9DOF IMU

What I’ve tried and ruled out / found out today:

  • as long as I do not add the LED strip to the setup, I do not get transaction timeouts at all
  • when I add the LED strip, I have to remove the IMU from the setup to also not get transation timeouts
  • when I use only LED strip and OLED Display and do rapid changes (like every 100ms) I also get a lot of transaction errors
  • these things do not make a difference:
    – the connection order of the Qwicc devices
    – cutting pullup resistors
    – the power supply (problem is the same with USB, LiPo or PoE)
    – (and the things I’ve already described in the posting before: power consumption is around 300 mA max, cable length is altogether around 30cm)

The only thing that impacts system stabililty (and how often I see transaction timeouts) is changing the I2C clock:

  • per default, this is 100.000
  • the higher I set this value, the less I2C transaction errors I get when both IMU and LED Strip are attached (the other Qwiic devices Button, Haptic, OLED Display do not have an impact)
  • when setting the clock lower, like 50.000 I get a lot of errors and the board almost immediately crashes
  • if I set clock to 400.000 (as in the IMU example) I get almost zero timeouts, although it happens from time to time.

Now, unfortunately, when it happens it was also already the case that the whole board gets stuck and needs a manual power cycle.

As the problems seem to start in different configurations as soon as I add the LED strip - Is the LED strip known to cause this kind of issues? I cannot find a clue on whats going on in the LED strip documentation.

which led strip do you use ?

I suspect that it might use clockstretching. This means that the device needs to process the received information, and holds the SDL low while doing so. Try different values on setClockStretchLimit().

This one: SparkFun Qwiic LED Stick - APA102C

Ok I will try that tomorrow (kids waiting at home :wink: )

I’ve tried Wire.setClockStretchLimit but I get:
Class “TwoWire” has no member “setClockStretchLimit”

Update:
on ESP32 it is called Wire.setTimeout(stretch) AHTxx.cpp:101:8: error: 'class TwoWire' has no member named 'setClockStretchLimit' · Issue #2 · enjoyneering/AHTxx · GitHub

The Attiny85 on the LED stick board clock stretching.. Try on ESP32 to extend timeouts milleseconds:

void TwoWire::setTimeOut(uint16_t timeOutMillis) {
_timeOutMillis = timeOutMillis;
}

uint16_t TwoWire::getTimeOut() {
return _timeOutMillis;
}

Hi, I’ve changed timeouts but with no success. (also I read here that there is likely an underlying problem and timeout is only a last-resort workaround if it works).

400.000 clock speed, timeouts from 30ms, 50ms (default), 100, 200, 300, 500
=> crashes after around 20-30 times turning on/off the led strip (it changes a bit depending on the timeout and clock speed, but it always happens sooner or later)

Noticeable is that each time the I2C.master throws an error, the LED strip also shows some wrong behavior, eg. a single pixel flickering or having the wrong color.

As soon as the board crashes, only a power cycle can recover it. Reset button does not help, because on the next boot, I2C throws an error and halts when looking for the LED strip (that is now probably locked up too).

Next thing I will try is to change the order how the devices are Qwiic connected,
instead of Mainboard > Button > Haptic > Oled > LED strip
I will try
Mainboard > LED strip > Oled > Haptic > Button

That is what the serial monitor gives me:
10:38:52.924 → E (98566) i2c.master: i2c_master_receive(1240): I2C transaction failed
10:38:52.924 → E (98573) i2c.master: I2C hardware timeout detected
10:38:52.966 → E (98577) i2c.master: s_i2c_synchronous_transaction(924): I2C transaction failed

Changing the wiring order did not help.

There is a relation between the LED strip and the IMU.

When I only initialize one of the 2 troublemakers via code (either the IMU or the LED strip), everything works fine. When I add both, I get the described errors. The other devices seem to not interfere (Display, Button, Haptic).

As we have discussed this in another thread about the IMU and RX/TX for INT and RST signal, could there be a relation?

Update 1
Ok timeouts still happen, but much less likely. Might have been a coincidence.
I will further play around with the values.

Update 2
OK it seems that the more commands I send to the LED Strip (e.g. LEDOff(), setLEDColor() ) the less stable it gets.

The most stable situation is when I only change brightness to turn LEDs on/off and use 350.000 as clock speed. I had 1 or 2 timeouts during 5 min test session, but no crash.

This is not ideal as I cannot make fancy LED animations then, but for now I think I move on with other tasks. Maybe I have to remove the LED strip in the final product if it then still creates stability problems.

Update 3
OK unfortunately this does also lead to crashes. Weirdly, the board crashes now after a few minutes of inactivity and with another exception:
12:16:57.117 → E (197240) i2c.master: I2C software timeout
12:16:57.117 → E (197240) i2c.master: s_i2c_synchronous_transaction(924): I2C transaction failed
12:16:57.117 → E (197240) i2c.master: i2c_master_receive(1240): I2C transaction failed
(before it said “hardware timeout”, now its “software timeout”).

Seems I have to remove the led strip..


I might have found something.

I now have a working config without timeout issues, but both using LED Strip and IMU with default clock speed and timeouts.

What I’ve changed is what I do with the LED strip.

Before I’ve changed which LEDs are colored (starting 10 red LEDs, going down to 0 red LEDs in around 5 seconds) like this (taken from the example):

void UpdateLED(int pCount)
{
#ifdef LEDSTRIP
  Log("UpdateLED");
  Log(String(pCount));

  LEDStick.LEDOff();
  for (byte i = 0; i < 10; i++)
  {
    redArray[i] = 0; //dont make it too bright, needs a lot of power
    greenArray[i] = 0;
    blueArray[i] = 10;
  }
  LEDStick.setLEDColor(redArray, greenArray, blueArray, pCount);
#endif
}

Now I only change the brightness. LEDs are always white. When button is pressed, brightness is 31, otherwise 0 (LEDs off). No use of LEDStick.LEDOff();

void UpdateLED(int pCount)
{
#ifdef LEDSTRIP
  Log("UpdateLED");
  Log(String(pCount));
  LEDStick.setLEDBrightness(pCount);
#endif
}

I will play around and see if the issue arises again when using LEDOff or setLEDColor.

As I expected before your issue is related to the LED strip and clock stretch. The less commands you send, the less it needs to perform a clock stretch.

In the passed I worked on SCD30, which is using clock stretch as well and I could not get it to work with ESP32. I have then added Softwire(). This is like SoftwareSerial, but then doing bit-banging for I2C.
It may not be fast, maybe not fast enough for you, but if you want to try it is on GitHub - paulvha/scd30: arduino esp8266 ESP8266 SCD30 SCD-30 ESP32 UNOR4 in the “src” folder.

It does require changes in the code on a number of places. Maybe first try with only the LED-strip examples.