I2C devices freezing program

Hi everybody,
I'm faced with a problem, perhaps several, which is causing behavior that seems relatively random and therefore rather difficult for me to debug. I've simplified my project to try to find the issue, and failing that, to make the explanation here simpler ^^.

I'm looking to control several I2C devices (Adafruit AW9523 and MPR121 in this simplified test) from a Adafruit Grand Central which also command a Neopixel Ring connected to a 5V power source. The I2C devices are connected in chain with qwiic cables.

But I've a lot of board freezing and non responding components that I can't figure out :frowning:

#include <Wire.h>
#include "Adafruit_MPR121.h"

//==== Capacitive touch
#ifndef _BV
#define _BV(bit) (1 << (bit)) 
#endif

Adafruit_MPR121 cap = Adafruit_MPR121();
uint16_t lasttouched = 0;
uint16_t currtouched = 0;

//==== Neopixel Strip

#include <Adafruit_NeoPixel.h>
#define LED_PIN   4
#define LED_COUNT  24
#define BRIGHTNESS 100
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRBW + NEO_KHZ800);

//==== AW9523 / LED
#include <Adafruit_AW9523.h>
Adafruit_AW9523 aw;
uint8_t led_pin[8] = {14,12,6,15,13,7,5,4};

// counter for testing purpose
uint8_t x = 0;

void setup(void)
{
  Serial.begin(115200);

  while (!Serial) delay(10);  // wait for serial port to open!
  Serial.println("Test starts");

  //==== Cap 
  if (!cap.begin(0x5A)) {
    Serial.println("MPR121 not found, check wiring?");
    //while (1);
  }
  Serial.println("MPR121 found!");
  
  //==== AW

  if (! aw.begin(0x58)) {
    Serial.println("AW9523 not found? Check wiring!");
    //while (1) delay(10);  // halt forever
  }

  Serial.println("AW9523 found!");

  for(int i=0; i<sizeof(led_pin); i++){
    aw.pinMode(led_pin[i], AW9523_LED_MODE);
  }

  aw.analogWrite(led_pin[6], 255);
  aw.analogWrite(led_pin[7], 255);
  
  Serial.println("LED ready");

  //==== Strip
  strip.begin();           // INITIALIZE NeoPixel strip object (REQUIRED)
  strip.show();            // Turn OFF all pixels ASAP
  strip.setBrightness(BRIGHTNESS); // Set BRIGHTNESS to about 1/5 (max = 255)

  Serial.println("Strip ready");
}

void loop(void)
{
  //==== Strip
  strip.fill(strip.Color(0, 0, 0, x));
  strip.show();

  Serial.print("\tX: ");
  Serial.print(x);

  //==== Cap
  // Get the currently touched pads
 
  currtouched = cap.touched();
  Serial.print(" test cap" );
  
  for (uint8_t i=0; i<12; i++) {
    // it if *is* touched and *wasnt* touched before, alert!
    if ((currtouched & _BV(i)) && !(lasttouched & _BV(i)) ) {
      Serial.print(i); Serial.println(" touched");
    }
    // if it *was* touched and now *isnt*, alert!
    if (!(currtouched & _BV(i)) && (lasttouched & _BV(i)) ) {
      Serial.print(i); Serial.println(" released");
    }
  }

  // reset our state
  lasttouched = currtouched;

  Serial.println("");
  x++;
  delay(100);
}

The following erratic behaviors occur:

  • Sometimes the program freezes during I2C devices initialization (not always the same)
  • Sometimes the program stops working during one of the loop (I think when communicating with an I2C devices)
  • Sometimes the programme continue to loop but the I2C devices are not responding (e.g. no capacitive detection)

So quickly my program is stuck / useless and I need to reset the board.

I tested a lot of things with more random behaviors from my amateur point of view^^:

  • When I removed the 5V power supply, the issues seem to occurs way less (but still sometimes, especially with more I2C devices), even if they only shared a ground... If I connect the 5V power supply after the start, it freezes after few seconds
  • When I'm adding more I2C devices or doing more calls to them, the issues seem to occur more (this one could make sense, maybe a busy bus or a power issue?)
  • I tried to add a dedicated power supply for the I2Cs, with a shared ground (as I thought that my board could not supply enough power and causing it to freeze) but the issues occur more!
  • I tried to change the components, the board, test all the connexions without success

Have you any idea of what I'm doing wrong and what else can I test?
Thanks a lot in advance :slight_smile:

3,3V output of any arduino board is pretty weak. you better not use it at all.

Thanks for your answer :slight_smile:
Yes, that's what I had in mind! In the first version of this project, I used an external 3V power supply, but surprisingly, the problems were even worse... It was when I switched to the card's output that I had fewer freezes! Maybe it was my power supply that wasn't of good quality, maybe I should try a higher voltage with a regulator :thinking:

I've tested with an external power supply and a regulator to 3.3v and 5v (as they are 3-5v devices) and the devices do not even init! I've my grounds connected, power LED is turn on, my voltmeter show the right voltage. But the program get stuck at "cap.begin(0x5A)" :frowning:

And what's really strange for me is that if I disconnect the 5V power supply for the ring, after a few seconds (the time it takes for the capacitor to empty?), the devices are recognized and the program works (even if it may stop from time to time). I really don't understand that. They are only connected from the common ground. Maybe a EMI issue? The 5V power unit and the LEDs are rather far from the other devices...

So I've done the following tests:

  • Not calling the stripe.show() = no difference (starts 0/5)
  • Removing the capacitor = almost the same (starts 1/5)
  • Unplug the stripe data pin = slightly better? (starts 2/5)
  • Unplug the common ground with 5V power supply = way better (starts 4/5) [but the neopixels become erratic]

I really don't understand the link with my I2C devices ^^'

Hi,
Have you tried 4K7 pullups on the I2C lines?

Tom.. :smiley: :+1: :coffee: :australia:

I Tom, thanks for your suggestion :slight_smile:
I've just done the test and I sadly don't see a difference.
I think my I2C devices have their own pull-up resistors!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.