1306 OLED doesn't display when USB connected - It's mad or I am

I have an AdaFruit 1306 126x64 OLED white display and the available AdaFruit libraries. I have the sample program called ssd1306_128x64_i2c.ino. It is connected to a Nano.

When I upload the demo program and it runs it displays fine on screen. If I press the reset button on the Nano it reruns and displays fine. If I unplug the Nano and power it from a separate source it displays fine.

If I plug the USB back in it doesn't display anything and neither does hitting the reset button. It will only display with the USB plugged in if I do an upload.

I have tried two Nanos and a ProMini. They are all the same behaviour.

Any assistance please.

More info...

I have also tried this with the library and examples from SSD1306Ascii (which is an unbuffered) library.

The problem persists with this one as well. [Perhaps it uses the same initialisation logic?] Perhaps it is the display or perhaps this happens with all of them... or something else?

I also think the display is not an AdaFruit one but a clone purchased here in the UK on eBay. It as four pins, GND, VCC, SDA and SCL - see attachment.

$_1.JPG

WHAT!

Pulling the power from the circuit switched everything off as you'd imagine.

I'm a little (no a LOT) surprised to find the OLED display remembers what it was showing when the power comes back on before it starts running the sketch again.

If its remembering stuff how can you be certain that it has been reinitialised when it starts up? Is this anything to do with the original problem posted?

This (remembering the screen) ONLY happens if the power that comes on comes from another Nano on the same circuit (unpowered until plugging in its own USB). Repower the circuit from an external power supply and it doesn't remember...

Update:-

My UNO and MEGA2560 behave properly... so it's just the Nano and ProMini both using a CH340G controller... hmmm

Tried a proper Adafruit QUADALPHANUM display using the Adafruit libraries and hey presto... plugging the USB into the Nano freezes the display.

Sufficient evidence that the Nano and perhaps the CH340G controller on it are to blame?

If so, what is it that happens during the upload of a sketch that allows the display or I2C to reset itself? Is it possible to recreate that sequence in the setup() of the sketch?

I put a Salea logic analyser on the SDS and SCL lines and when the USB is plugged into a powered Nano the the i2C signal stops... dead... nothing... zilch

and when I upload the sketch the I2C signal starts again and the display is one happy bunny.... unlike me :frowning:

I need to be able to plug my USB in to connect the PC to the Nano and not have the OLED screen die... seems reasonable to me

Hi,

This appears to be a I2C lockup problem that is often encountered with the stock I2C library, the sketch halts inside the library with interrupts dispabled so nothing printed to the serial port gets out. Try a library with a time-out feature. I suspect your are getting supply/reset glitches when you connect your additional USB feed.

You should be able to test this by switching on an LED before the I2C read and switching it off afterwards. If the LED sticks on then your code is stuck (hung) in the I2C library.

bodmer:
Hi,

This appears to be a I2C lockup problem that is often encountered with the stock I2C library, the sketch halts inside the library with interrupts dispabled so nothing printed to the serial port gets out. Try a library with a time-out feature. I suspect your are getting supply/reset glitches when you connect your additional USB feed.

You should be able to test this by switching on an LED before the I2C read and switching it off afterwards. If the LED sticks on then your code is stuck (hung) in the I2C library.

The code isn't stuck. Serial output still happening and loop() is still looping.

OK! I have had lockup problems with I2C talking to a USB host shield and moved my code over to use the IC2Dev library and that fixed the random lockups completely. The odd thing was that serial debug output stopped but I never figured out why.

Unfortunately it would not be easy to substitute the Wire library in this case.

I can only assume that the I2C communication is failing. I guess you realise that the cheap displays do not have the 5V logic tolerance (that the Adafruit display has built in), so it could be that the display is getting internally upset and is failing to acknowledge I2C transactions.

My preference is to use SPI with these displays, so perhaps that is something you could consider. Sorry I can't help more without having a similar setup.

Its not the display. Its the I2C that stops.

The test loop takes about 3 seconds to run. A LED has been put ion the loop to toggle on/off each time.

When the USB is plugged in the LED flashes about every 1/8th of a second and that is when the I2C signals stop.

If I 'open' the serial port either with the IDE monitor or with another serial reader the program runs at normal speed (and incidently dumps debug info to the serial output).

Closing the serial port and keeping the USB plugged in stops the I2C again and the loop whizzes round again. open the port :slight_smile: close the port :frowning:

This test has been moved to the Adafruit QUAD display and different library code to the OLED. It is almost certainly the CH340G doing something naughty.

The CH340G may be generating a reset at an inconvenient time. This post suggests a bootup test and solution for I2C lockup (SD stuck low). I note that your display does not have a reset line hence the display is only hard reset at power up so could be forcing the line low. It appears the Wire library does indeed have a timeout then that would introduce a delay that would slow things down

This app note describes the I2C lockup problem and solutions nicely. This fault scenario appears to fit with the symptoms you observe.

Due to residual power stored in capacitors a oled can retain an old image for 30s or more after power off.

That's an interesting document.

I'm not sure if it is that problem as it describes the situation where data from the slave is interrupted but in this case the slave isn't providing data as fas as I can tell.

I will be back at the workbench tomorrow and will try some mote tests.

I've snaffled a moment or two to have another think about this...

I'm not sure I'd be in a position to know when a USB has been plugged into a running Nano in order to execute some sort of recovery code.

If the Nano is powered down and the device is also powered down how could there be any traffic coming from a slave when the system is powered up (by plugging in a USB - which also causes the I2C to be dead)?

It seems to need uploading or opening the serial port to let the I2C to run again.

... hmmm my brain hurts

OK. What is the simplest setup that does not work?

I ask because I am getting confused with all the setups your are trying. I interpreted the scenario as you get the failure when your plug in the USB connection into a running (powred) Nano that is operating normally... but it seems that is not the case and that:

  1. You have a completely unpowered system
  2. You plug in just the USB, and then the sketch runs around the loop OK but the I2C does not operate
  3. You then open the serial terminal and I2C now starts working

Or:

  1. You have a powered setup using external power that is running normally
  2. You plug in the USB, the sketch continues to loop slowly but the I2C comms stops and the OLED display freezes

At the moment I am wondering if plugging in the USB is generating a bad (too short) reset pulse or some rubbish is coupling into the I2C lines.

I've been thinking in the background on this problem.

I'm pretty sure you are getting some noise spikes coupling to the I2C lines when you plug in the USB lead and this is locking up the display. The "noise" is coming from the CH340G. Pressing reset does not work then because the I2C start sequence does not work as the SDA line is likely to be stuck low. Uploading a sketch injects more noise on the I2C lines and this accidentally clocks out the bus lockup.

So one option is to reduce the pullup resistance values on the I2C bus, hence hopefully make it harder to inject noise on the lines since the line impedance is lower. The display may be using quite a high value of 10K, so try 4K7 on SDA and SCK pulled up to 3.3V.

Another option is for your sketch to send out 8 SCK low clock pulses at <100kHz periodically to clear out the lockup. This is quite easy turn on the SCK output low, then make it an input so the line is pulled back up, repeat 8 times with say 10uS delays between state changes.

This has turned out not to be a OLED problem but a CH340G controller on the Nano board problem and the topic can be found here

http://forum.arduino.cc/index.php?topic=397326

Probably better to continue any postings there from now on

Alan

I've ordered one of those CH340G Nano's off eBay, just out of curiosity! :slight_smile:

bodmer:
I've ordered one of those CH340G Nano's off eBay, just out of curiosity! :slight_smile:

Let us know how it goes.