I2C Examples

zmemw16
Thu Apr 27, 2017 11:05 am
I2C Scanner
code is the discovery scanner with their specific I2S stuff etc commented out
i have a tmp102 and a 128×64 0.98 I2C oled SSD1306, with 4k7 pullups and 3v3 plugged in
this is SERIALINTERFACE #defined as SerialUSB

...
0 Unknown error at address 0x3B
0 I2C device found at address 0x3C !
0 Unknown error at address 0x3D
...
...
0 Unknown error at address 0x47
0 I2C device found at address 0x48 !
0 Unknown error at address 0x49
...
0 Unknown error at address 0x7E


zmemw16
Thu Apr 27, 2017 12:47 pm
looking in Wire.cpp, the return values are
0 ok
1 timeout
4 default for other

danieleff
Thu Apr 27, 2017 12:52 pm
zmemw16 wrote:I2C Scanner
code is the discovery scanner with their specific I2S stuff etc commented out
i have a tmp102 and a 128×64 0.98 I2C oled SSD1306, with 4k7 pullups and 3v3 plugged in
this is SERIALINTERFACE #defined as SerialUSB

...
0 Unknown error at address 0x3B
0 I2C device found at address 0x3C !
0 Unknown error at address 0x3D
...
...
0 Unknown error at address 0x47
0 I2C device found at address 0x48 !
0 Unknown error at address 0x49
...
0 Unknown error at address 0x7E


ChrisMicro
Thu Apr 27, 2017 4:28 pm
On the STM32F4 Discovery it shows the same behaviour.
“Unknown error at address 0x..” when there is no device responding.

zmemw16
Thu Apr 27, 2017 5:17 pm
but 124 times? as i recall todbot’s didn’t
stephen

ChrisMicro
Fri Apr 28, 2017 8:05 am
but 124 times? as i recall todbot’s didn’t
stephen

The STM32GENERIC example is originally from this Arduino site and is modified for the STM.

Hmm .. the I2C address field is 7 bits witch gives use 128 addresses. I know, not all are usable.

0 Unknown error at address 0x47
Probably the I2C driver is working different compared to the Arduino-Uno implementation and returns different status messages ?


zmemw16
Fri Apr 28, 2017 10:04 am
apols, i harkened back to my AVR days and then it was Todbot’s that i used.
istr trying 3 or 4 before finding one that worked at all on STM, even then it wasn’t both hard and soft i2c.
btw that’s a get out for not remembering which :D

there seem to be 3 responses from the HAL routine
0. ok – definitely a device present
4. nothing there
1. timeout – but what then, something possibly there

i can understand reporting the first and last, but why report nothing?

stephen


ChrisMicro
Fri Apr 28, 2017 1:03 pm
The Arduino I2C API Specification says for endTransmission()

Returns

byte, which indicates the status of the transmission:

0:success
1:data too long to fit in transmit buffer
2:received NACK on transmit of address
3:received NACK on transmit of data
4:other error

So we should probably alter the text message ( into “other error” ) in the I2C scanner program.


Pito
Fri Apr 28, 2017 2:43 pm
With I2C2 on PB10 clk and PB11 data.
// --------------------------------------
// i2c_scanner
..
#include <Wire.h>

TwoWire Wire2(I2C2, PB11, PB10);

#define Wire Wire2
#define Serial SerialUART1

void setup()
..
else if (error==4)
{
//Serial.print("Unknow error at address 0x");
//if (address<16)
// Serial.print("0");
//Serial.println(address,HEX);
}
}
..


Pito
Fri Apr 28, 2017 10:20 pm
I’ve spent 5h messing with the DS3232RTC library I like :)
The issue is following:
How to build a demo, reading time off DS3231/2, when using I2C2 (not the default I2C1).
When playing with simple stuff like above, no prob, but this is a chicken-egg-situation (or Catch22 one)..

TwoWire Wire2(I2C2, pina, pinb); creates a new instance Wire2 on the second I2C controller.
Tried with #define Wire2 Wire, but after a hundred various combinations I still get an error with Wire redefinition..

But how to organize the code such it compiles with the DS3232RTC library????
PS: with I2C1 and with the default Wire it compiles fine.. (except you have to adjust for our __STM32F4__ and add the _BV macro definition)..
22:24:50
28/4/2017
22:24:51
28/4/2017


danieleff
Sat Apr 29, 2017 3:21 am
For existing libraries that use hardcoded Wire:
Wire.stm32SetInstance(I2Cx);
Wire.stm32SetSDA(sda);
Wire.stm32SetSCL(scl);
rtc....()
...

Pito
Sat Apr 29, 2017 5:02 am
Ok, thanks it works :)

FYI – an enhanced I2C library which supports master/slave in immediate/interrupt/dma mode – for Teensy CM4 however.. https://github.com/nox771/i2c_t3


ChrisMicro
Sat Jul 01, 2017 6:39 am
I just encountered a problem:

How can I use 2 I2C interfaces?

E.g. F7 Disco has an internal I2C bus for the touch which is use in the form

Wire.stm32SetInstance(I2C3);
Wire.stm32SetSDA(PH8);
Wire.stm32SetSCL(PH7);
Wire.begin();


danieleff
Sat Jul 01, 2017 7:04 am
TwoWire Wire2(I2C2, sda2, scl2); // check chip documentation and board schematic
TwoWire Wire3(I2C3, sda3, scl3); // check chip documentation and board schematic
TwoWire Wire4(I2C4, sda4, scl4); // check chip documentation and board schematic

zmemw16
Sat Jul 01, 2017 12:46 pm
how is it done with HAL ?
i suspect they’ll have completely separate i2c structures.

for us, why not do it in same way as multiple spi usage.

stephen


ChrisMicro
Sun Jul 02, 2017 5:06 am
Thank your for the response :D

“Problem is every library is written with the assumption that there is only one I2C, and it is called Wire.
Disclaimer: I actually not tried to use multiple at once.”

For me it seems quite clear on how to handle it: On boards which have a Arduino compatible connector the I2C which is connected to this connector shall have the name “Wire”.
The names of the others shall be based on the interface number.

E.g.

Wire1
Wire2 ==> Wire on this exampel board
Wire3


chrissb
Thu Jul 20, 2017 12:32 pm
Has anyone done any testing on the I2C slave side of things?

I’m trying to use this functionality on an F0, and it seems that on address match SCK is held low indefinitely. Is this the intended behaviour, and if so is there something I should be doing in a callback to release the bus?

Simple example with nothing more than initializing the Wire library as an I2C slave shows this behaviour for me:

#include "Wire.h"

void setup() {
Wire.begin(30);
}

void loop() { }


danieleff
Thu Jul 20, 2017 3:28 pm
Try to respond to the request

void receive(int bytes) {
// Received bytes
}

void request() {
uint8_t response[1] = {9};
Wire.write(response, sizeof(response)); // responding
}

void setup() {
Wire.onReceive(receive);
Wire.onRequest(request);

Wire.begin(30);
}


caniggia
Wed Nov 15, 2017 1:49 pm
Hi

With changes(26 Sep) to Wire.cpp it won’t compile I2C examples for any board (except F0 probably):
https://github.com/danieleff/STM32GENER … ire.cpp#L7

You cannot check #ifndef I2C1_EV_IRQn, because I2C1_EV_IRQn is enum not #define.

The same for #ifndef I2C2_EV_IRQn.

Maybe change it to:
#if defined(STM32F0)
#define I2C1_EV_IRQn I2C1_IRQn
#define I2C2_EV_IRQn I2C1_IRQn
#endif


FiveO
Sun Jan 28, 2018 6:12 pm
Sry for noob question but from where and how I can change the I2C speed?

Wire.begin(); is default 100Khz, I want 400Khz?


FiveO
Sun Jan 28, 2018 6:25 pm
Ok figured out :D

Wire.begin();
Wire.setClock(400000);

Problem was, that in the docs there is SetClock() , not setClock()


zmemw16
Sun Jan 28, 2018 6:47 pm
i think you’ll have more success opening a new topic, advanced search for ‘i2c clock speed’ gives 64 mentions,
scroll down a bit

stephen


Leave a Reply

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