Weird 2IC Problem - Multiple Devices at once causing errors

Hi all,

I'm at wits end with this one! So I'm just finishing up my first big project, I have a number of sensors and devices hanging off my UNO. I'm having a problem with my LCD displays and Compass running at the same time. I have a total of 4 devices running on 2IC, all with separate addresses (confirmed via 2IC Scanner).

Devices are:
Real Time Clock
Display 1
Display 2
Compass

Each device works fine individually, in fact both displays and the RTC all work fine. As soon as I add the Compass, the displays corrupt and its almost like its out of memory or something as it crashes on the displays a few seconds in and the program stops running (i'm wondering if I have done something wrong with the maths somewhere causing a memory leak or something along those lines).

Now this is the weird thing, the program WAS running fine and has been for a few days now before this started happening. So what changed? I wired up a new protoshield as the previous one was a bit messy due to building as I went. When I plugged the new shield in this started happening. The only difference to this one is that I used 2 x 10k pullup resistors for the 2IC circuits instead of 100k (I read the values wrong when putting it together originally).

I thought to myself, ok I've stuffed up the new shield, no biggy, swapped back to the original and the same issue occurred. I then thought the compass or screens were stuffed, but using example sketches they work fine individually. I thought maybe the Arduino itself was dead, but I can upload other more basic sketches and run them fine so I'm at a loss as to what to look at next.

I have attached my code, it is quite long (and probably messy, but I've commented as much as possible). I'm seeking Arduino guru's to point me in the right direction!!! Please Help!!!

SensorPack_6.ino (16.7 KB)

Everything is working (on its own), so the hardware is good.
You changed the pullup resistor, so the problem could be the I2C-bus itself.

You have to determine which devices need a 5V I2C-bus and which need a 3.3V I2C-bus.
If you connect everything, the voltage level could be too high for the 3.3V devices, or too low for the 5V devices.
You can try to make it work all on the same bus, but you better use a I2C level shifter.

In the ideal world, the I2C-bus has just one pullup resistor of 4k7.
Can you try to see if all your modules have pullup resistors ? and which value ?
Suppose you have five 10k pullup resistors on SDA and also five of 10k on SCL. The resulting pullup would be 2k, which should work. If one of the pullup resistors on a module is 2k2, you are in the danger zone.
My suggestion is to have just one (one for SDA and one for SCL) pullup resistor of 4k7 at the master, and remove all the pullup resistors of the modules.

I use these small cheap I2C level converters:

They have 10k pullup on both sides, so together that is enough, no more pullup is needed.

Hi Peter,

Thanks for the quick reply. All the devices should be 5V.

Devices I'm using are cheap ebay ones though, here:
Clock - DS3231 Precision RTC Module Memory Module for Raspberry Pi for sale online | eBay
Displays - http://www.ebay.com.au/itm/351048340044?ssPageName=STRK:MEWNX:IT&_trksid=p3984.m1439.l2649
Compass - http://www.ebay.com.au/itm/171356681209?ssPageName=STRK:MEWNX:IT&_trksid=p3984.m1439.l2649

I had just been using a single 100k on the SDA and another of the SCL lines (not one for each device), I've replicated that setup but only using 10k.

I had a look at the modules and they all have a few resistors on them, I'm not sure which once I should be looking at?

What's got me confused is why it WAS working on the old protoshield, and now isn't which is why it had me wondering had a stuffed something up in the code

Would you suggest I swap out the 10k pullups with a 4k7?

No, no swapping. You can remove the 10k and see what happens.

I do however notice a problem with the compass module:
RTC: I see two resistors, but I don't know if they are connected to the I2C-bus. The module can be used at 3.3V and 5V.
OLED: I think there are no pullup resistors. The module can be used at 3.3V and 5V.
HMC5883L: The two "472" are pullup resistors of 4k7 to 3.3V. The chip is a 3.3V chip but with the voltage regulator on the module, the compass module is 5V.

So the HMC5883L requires a 3.3V I2C bus. A higher voltage might damage the chip.
Since the other modules can do both, can you try to power the RTC and OLED with 3.3V ?

Since the voltage regulator of the compass module lowers a voltage of 3.3V to 3.2V, the I2C migh no longer work, because the onboard pullup resistors now pull to 3.2V. Power the compass module with the good old 5V and let the voltage regulator on that module make 3.3V for the HMC5883L and pullup resistors.

Don't add any pullup resistors, the compass module has them already.

Now you have a 3.3V I2C-bus for all three devices. Is it working ?

That is just for a test. I don't know if the 3.3V voltage regulator on the Arduino board can power the OLED.
When everything is working, you can go back to 5V, but you need such an I2C level converter for the SDA and SCL of the compass module.

I hope this all makes sense, if you don't understand it, let me know.

Hi Peter,

Thanks for the explanation. So I have removed both the 10k resistors, so there is no pullup resistors in play other than whatever is on the modules, I get exactly the same result though.

So all modules are being powered by 5V, using the onboard resistors.

I'm getting closer though I think, I put a multimeter across both SDA & SCL without the compass in play and I get 4.98V on both terminals.

When I connect up the compass, SCL drops to 3.6V and SDA drops to around 150mV so something isn't happy there electrically.

If I reverse the config (remove the screens and just leave the compass, SCL reads 2.8V and SDA reads 50mv, totally confused now!

Pullup to 3.3V only. I2C is open drain, all devices should work from 3.3V.
Turn off the internal 5V pullups on the arduino too.
After wire.begin, add
pinMode (18, INPUT);
digitalWrite (18, LOW);
pinMode (19, INPUT);
digitalWrite (19, LOW);
that should ensure the pullups are off.
Wire will than use the pins as needed.

Hi CrossRoads,

Thanks for the reply, all the modules have pull up resistors and I'm see 5v on the 2IC lines, how do I drop it to 3.3V?

I'll turn off the internal 5v pullups and give that a go as well.

Cheers,
Matt

I just added the code to remove the built in pullups, still no joy :frowning:

I powered the compass off the 3v line, same result as the first time it seems to pull the 2IC voltage down as well :confused:

Can you read reply #3 once more ?
I tried to explain it all, and I think I didn't make a mistake.

Perhaps the 5V I2C-bus has damaged the HMC5883L, and the HMC5883L is causing trouble on the I2C-bus.
Can you try the compass module without anything else ?

Hi Peter,

I've just gone through it again, i think I understand this time. The Compass module worked fine by itself this morning, but I've just tested it again and I think it and the arduino has had a bit of a meltdown. Circuit got very hot when I plugged it in this time around and it got power, but didn't register on the com port.

I wrote the below assuming it was still working and everything else I had tried today, but based on the above I'm ordering a new board and compass (any suggestions other that that cheap one i bought?) and will test again, this time with the line level already in place. With the line level would you expect 3.3V on the SDA/SCL lines for the compass?

Thanks for all your help so far

As a side note, I ducked down to the local electronics store today and they had a line level converter there, similar to the one you linked.
I've put that in play and it seems 'better' in that its getting through the setup function ok now and wasn't garbling the displays.
It still hangs though once it runs into the main loop routine, lines 216 to 238 are the compass readings, as soon as I un-comment that it locks up.
The 5V 2IC bus shows 5v on both SDA and SCL, compass is only showing 100mv roughly though on SDA and SCL at the compass module inputs.
I'm wondering if the Compass module and the arduino both have been damaged somehow. I was looking at my other sensors and noticed some of them are changing values when not connected. I thought I had a multiplexing issue and it wasn't switching analog pins quickly enough, so I've put in a work around for that, but still no joy.
I then thought ok stuff it, I pulled the proto board out, removed all the sensors and plugged in just the displays into SDA and SCL (and 5v/gnd), with no sensors connected, my Wind Sensor is showing a value of like 54kph on boot which drops off to 0.01 (line 182 - 194 is where it reads it). That sensor comes in on an analog pin, not via 2IC though, but still it shouldn't be reading anything.

SensorPack_6.ino (18.4 KB)

All that code and libraries in a Uno, perhaps you have a memory problem.
Do yo have long I2C wires, or do you use ribbon cable for I2C ?
It should run for years without a single glitch, when everything is okay.
I do not understand what you describe, and what a multiplexing issue is.

yeah I thought about memory issues, it is large compiling out to 29k, but the only time I had issues previously was using arrays and incorrect memory sizes which I resolved (or so I thought). It has been running rock solid for a while now too.

I ran a small memory calculator routine to see how much variable memory I was using and I had about 3k free, so I'm guessing I'm using roughly 5k. Any other ways to look to see if I am having memory issues?

I'm going to look into running 2 x Arduinos to share the load and run a display each and half of the sensors.

The multiplex issues I was referring too is when you are reading more than 1 analog sensor in the loop, with high impedance sensors this can causing erratic data because the multiplexer that switches between pins may need a split second longer to get a stable reading.

The fix is to make two calls to the analog pin, the first is a dummy one to get the pin to switch, with a delay(10) then actually take the reading.

I read about it here when looking at erratic analog data. Problem reading two sensors with analogRead() - adafruit industries

Two Arduinos ? You could also buy an Arduino Mega2560. You might have to check the pins, since some pins are on other locations, like the I2C pins.

There is a memory test for RAM: Arduino Playground - HomePage

Throwing away the first sample after the internal mux is changed with a delay is good.
You could use the average of 5 or 20 samples (after throwing away the first one).

With high impedance (and slow changing) analog inputs, you can add a capacitor from that analog input to GND of about 1nF to 10nF.

yeah I thought about the Mega. My main reasoning for two arduinos is the use of two displays, I've modified the library to make it work, but I don't think its the most efficient way of processing the displays. Two arduinos would allow me to use the single library, one for each.

I also have further expansion plans for sensors so sharing the processing requirements across two wouldn't be the worst idea.

I'll compare that with using a single, larger LCD which might also simplify things.

Thanks for the link, the one I used is at the very bottom of that page.