Multiple I2C libraries

FiveO
Wed Dec 13, 2017 10:46 am
Hi,

I am having troubles with multiple I2C libraries in one sketch on stm32f103

Separately they work:

Adafruit SSD1306
Adarfuit VL6180
I2C anything

They work together in Arduino Nano or Mega.

Why is that? How can it be done?


RogerClark
Wed Dec 13, 2017 10:51 am
Which core are you using ?

FiveO
Wed Dec 13, 2017 1:12 pm
Latest Arduino_STM32 Core

Oled starts with Adafruit logo and stays there, nothing after that works.

SSD1306 with VL6180 code here:
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306_STM32.h>

#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);

#if (SSD1306_LCDHEIGHT != 64)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif

#include "Adafruit_VL6180X.h"
Adafruit_VL6180X vl = Adafruit_VL6180X();

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

display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.display();
delay(2000);

vl.begin();
Serial.println("Sensor found!");
}

void loop() {
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(0, 0);
display.println(vl.readRange());
display.display();
}


stevestrong
Wed Dec 13, 2017 1:18 pm
Put some serial output lines to detect which is the line where the sketch hangs.

mrburnette
Wed Dec 13, 2017 2:42 pm
[FiveO – Wed Dec 13, 2017 10:46 am] –
Hi, I am having troubles with multiple I2C libraries in one sketch on stm32f103
Separately they work:

Adafruit SSD1306
Adarfuit VL6180
I2C anything

They work together in Arduino Nano or Mega. Why is that? How can it be done?

The STM32duino core IS NOT THE SAME as the official AVR core. As late as last year, the AVR core was still defaulting to I2C software, if my memory serves me correctly. As such, the I2C implementation is “blocking” by implementation.

The LeafLabs’ implementation was also software I2C (blocking) even though there is a dedicated I2C peripheral in the STM32F1xx. I had to use Google to get to the next layer, but it seems that the STM32duino F1 core was changed this past summer and the default is now hardware I2C, that is, non-blocking.
Reference: viewtopic.php?t=2408

  • You can therefore configure the most recent core to use I2C software.
  • Or, you can “regress” the code on github to deliver a download image prior to the change.

Sadly, I cannot promise that doing either of the above will make your code work as it does on the 16-bit AVR uC; testing will be your responsibility. We all will be grateful that you do report back in this thread if you are successful or if you are not successful. This forum is not moderated, but a few members often take your (full) code and attempt to ascertain a fix – strictly on a volunteer basis since to test generally requires exactly the same hardware components.

For future reference, please do NOT assume that the STM32F1xx STM32duino core will work the same as the official Arduino core(s) … some serious effort has gone into migrating the original LeafLabs core to be compatible with the current ArduinoIDE and some serious effort has gone into manipulating the STM32F1xx core to conform to official Arduino compatibility. However, the two cores are very different in the underlying codebase. And, this forum reserves the option to change core functionality to make best usage of the more advance architectural design of the STM32Fxxx devices.

Ray


FiveO
Thu Dec 14, 2017 9:22 am
[stevestrong – Wed Dec 13, 2017 1:18 pm] –
Put some serial output lines to detect which is the line where the sketch hangs.

Ok, I did that. It doesn’t print thing in setup or loop.

And to mrburnette. Thanks for your answer, coding is kind of new for me and I will try to read that thread.


RogerClark
Thu Dec 14, 2017 9:54 am
Sounds like the code may be crashing before setup() is called.

This is commonly caused by the constructors in libraries attempting to use GPIO or I2c or SPI etc before its initialised.


stevestrong
Thu Dec 14, 2017 12:25 pm
You can try adding similar check points:
void setup() {
Serial.begin(115200);
while (!Serial) ; // wait for a serial connection via USB
delay(1000);

Serial.println("SSD1306 begin"); // check point
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.display();
delay(2000);

Serial.println("VL begin"); // check point
vl.begin();
Serial.println("Sensor found!");
}


FiveO
Fri Dec 15, 2017 8:40 am
With that While() it now prints only “SSD1306 begin” and “VL begin”. Doesn’t print “Sensor found!” or any other markers I added to loop.

stevestrong
Fri Dec 15, 2017 10:38 pm
So it seems that it hangs in the VL6180 begin () function.

Where did you get the library? Any link?


FiveO
Sat Dec 16, 2017 9:01 am
Adafruit VL6180 – https://github.com/adafruit/Adafruit_VL6180X
Adafruit SSD1306 stm32 – https://github.com/rogerclarkmelbourne/ … it_SSD1306

and I2C Anything. Same problem. Hangs with SSD1306 or VL6180
http://www.gammon.com.au/forum/?id=10896&reply=8#reply8

Each of these works well alone.


stevestrong
Sat Dec 16, 2017 9:23 am
Have you tried the i2c_scanner example when both are connected?
Are they connected to the same I2C lines?

Have you tested the Adafruit OLED example? https://github.com/adafruit/Adafruit_VL … x_oled.ino
It seems that it is using the same ICs as you.


FiveO
Sat Dec 16, 2017 1:06 pm
Yes. I2C scanner finds 0x29 and 0x3C.

Yes. Same lanes B6 and B7 on stm32f103 “bluebill”

Yes. Not working with original ssd1306 or that stm32 version.


stevestrong
Sat Dec 16, 2017 4:29 pm
Do you have 4k7 pull-up resistors connected to the I2C lines and 3.3V?

The Adafruit example sketch is different from yours, the VL instance is declared before the OLED: https://github.com/adafruit/Adafruit_VL … ed.ino#L16

So please try that example and tell us where it hangs.


FiveO
Sun Dec 17, 2017 10:27 am
Yes I tried. But I tried again, now with pull-up resistors.

The original vl6180x_oled.ino:
Didn’t have 4k7
without – hangs after “Adafruit VL6180x test!”
2k – hangs after “Adafruit VL6180x test!”
4k – hangs after “Adafruit VL6180x test!”
10k – hangs after “Adafruit VL6180x test!”

Modified vl6180x_oled.ino with Adafruit_SSD1306_STM32.h (Adafruit_SSD1306.h don’t work):
With this code:#include <Wire.h>
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306_STM32.h>

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

Adafruit_VL6180X vl = Adafruit_VL6180X();

#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);

#if (SSD1306_LCDHEIGHT != 64)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif

void setup()
{
Serial.begin(115200);
while (!Serial) ; // wait for a serial connection via USB
delay(1000);

Serial.println("SSD1306 begin"); // check point
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 0x3C (for the 128x32)
// init done
display.display();
delay(1000);

Serial.println("Adafruit VL6180x test!");
if (! vl.begin()) {
Serial.println("Failed to find sensor");
while (1);
}
Serial.println("Sensor found!");

// text display big!
display.setTextSize(4);
display.setTextColor(WHITE);
}

void loop()
{
Serial.println("In loop"); // check point

float lux = vl.readLux(VL6180X_ALS_GAIN_5);

Serial.print("Lux: "); Serial.println(lux);

uint8_t range = vl.readRange();
uint8_t status = vl.readRangeStatus();

if (status == VL6180X_ERROR_NONE) {
Serial.print("Range: "); Serial.println(range);
display.clearDisplay();
display.setCursor(0, 0);
display.print(range);
display.print("mm");
display.display();
Serial.println();
} else {
display.display();
display.clearDisplay();
return;
}

// Some error occurred, print it out!

if ((status >= VL6180X_ERROR_SYSERR_1) && (status <= VL6180X_ERROR_SYSERR_5)) {
Serial.println("System error");
}
else if (status == VL6180X_ERROR_ECEFAIL) {
Serial.println("ECE failure");
}
else if (status == VL6180X_ERROR_NOCONVERGE) {
Serial.println("No convergence");
}
else if (status == VL6180X_ERROR_RANGEIGNORE) {
Serial.println("Ignoring range");
}
else if (status == VL6180X_ERROR_SNR) {
Serial.println("Signal/Noise error");
}
else if (status == VL6180X_ERROR_RAWUFLOW) {
Serial.println("Raw reading underflow");
}
else if (status == VL6180X_ERROR_RAWOFLOW) {
Serial.println("Raw reading overflow");
}
else if (status == VL6180X_ERROR_RANGEUFLOW) {
Serial.println("Range reading underflow");
}
else if (status == VL6180X_ERROR_RANGEOFLOW) {
Serial.println("Range reading overflow");
}
delay(10);
}


zmemw16
Sun Dec 17, 2017 1:17 pm
is Wire.h guarded for multiple includes ?

what I2C clock speed is this defaulting too ?

does any of the hardware have regulators, are you feeding them 5v or 3v3 ?

have you got a bus analyzer ?

stephen


FiveO
Mon Dec 18, 2017 11:45 am
to zmemw16

1. Can you be a bit more specific?
2. I haven’t change a thing. In which file I can look it up?
3. Yes, both have 3.3v to 5v. I use 3.3v additional power supply with grounds connected.
4. No I don’t.


zmemw16
Mon Dec 18, 2017 4:16 pm
it’s usual to wrap the contents of an include file in an if-ndef to prevent double inclusion
#ifndef _TWOWIRE_H_
#define _TWOWIRE_H_

#include "utility/WireBase.h"
#include "wirish.h"
#include <libmaple/i2c.h>

class TwoWire : public WireBase {
private:
i2c_dev* sel_hard;
uint8 dev_flags;
protected:
/*
* Processes the incoming I2C message defined by WireBase to the
* hardware. If an error occured, restart the I2C device.
*/
uint8 process(uint8);
uint8 process();
public:
/*
* Check if devsel is within range and enable selected I2C interface with
* passed flags
*/
TwoWire(uint8, uint8 = 0);
// blah blah blah rest of file etc
#endif


FiveO
Tue Dec 19, 2017 10:20 am
The sensor and oled are up to 5v tolerant. I use 3.3v dc power supply on them. The stm32f103 bluebill is using usb voltage and grounds between stm32f103 and 3.3v external power supply.

Yes they work together. I have tested them together with Arduino Nano and Mega, without resistors.
Yes they work also separately on Nano and Mega, without resistors.
Yes they work separately on stm32f103, without resistors.


stevestrong
Tue Dec 19, 2017 11:52 am
I think you would need an oscilloscope or a logic analyzer to find out the root cause.

You should remove
#include <SPI.h>


zmemw16
Wed Dec 20, 2017 4:05 pm
definitely daft ideas mode
just how slow can we clock i2c ? set timeouts in seconds?
replace resistors with led and resistor, really, really slow the clock.
record video and then playback frame by frame ;)
not nearly enough really’s in that line
maybe trying a bit-bang i2c would help in slowing it down
kevin someone has a lovely video on youtube of controlling a stepper motor with switches.

stephen


tfried
Wed Dec 20, 2017 9:39 pm
Grasping for straws, but…

What happens, if you move “vl.begin();” (and the associated debug lines) above “display.begin()”?


stevestrong
Sat Dec 23, 2017 5:29 pm
Just thinking…

You start first library (let’s say) First.begin(), which will call Wire.begin().
The you call other “First” functions:
First.display();
First.blabla();

Then, you start “Second” library (let’s say): Second.begin(), which also calls same default (!) object Wire.begin();

Will this maybe clear (or conflict) the previous library variables/instances and reset the default Wire object?


Leave a Reply

Your email address will not be published. Required fields are marked *