using both i2c interfaces on stm32f104c8t6

Post here first, or if you can't find a relevant section!
Post Reply
Zter
Posts: 3
Joined: Tue Sep 20, 2022 4:23 pm

using both i2c interfaces on stm32f104c8t6

Post by Zter »

Good morning/evening to everyone. to those that will spare time to read this, you already have my thanks.
As a little exprerienced beginner in programmed electronics, I have the following problem :
I need to read in real time the data from 4 different accelerometers (MPU6050 as they are collecting dust in the drawer). The MPU6050 alreay contains a pin to select between 2 adressses (0x68 by default and 0x69 if ad0 is pulled up to vcc), but as I need to dialog with 4 I will need that my MCU communicates with 2 separate i2c buses as a master to collect the data (not to mention my need to ad an SPI communication to ad data-logging on an SD card).
I personally have 3 different type microcontrollers boards on hand :
-(4 in total) genuine arduino unos, but it seems that interfacing two i2c buses isn't possible
- a STM32F104C8T6 based blue pill board (a cheap chinese one, I bought it out of curiosity of the abilities of the board), that seems to feature 2 separate buses but I don't find how to use them separately
- a STM32F405 based genuine pyboard (runs micropython) : I know that it would work on it as I already used it when interfacing a single mpu6050 last year, but I don't really like python programming, using putty for interface doesn't give much help when debugging

My question is : how can I set up both i2c interfaces on the STM32F104C8T6 using the arduino ide to interact with two separate couples of accelerometers, and can I set the bus frequency to increase data rate ?
I wouldn't like to use an i2c multiplexer as it will ad complexity in the circuit and slow down the communication, my goal is to acheive the fastest data rate for the 4 accelerometers to decrease integration errors.

little note : I don't use librairies (out of the base for i2c communication) and instead directly write in the setting registers and read from the data registers of the MPU(s), as such I really know what's going on, and it's easier to purposefully set-up a sensor that way, and decrese program size.

Thanks a lot to those who will spare some time to read this and help me for this specific issue.

(french translation)
Bonjour/bonsoir à tous. A ceux qui prendrons du temps pour lire ceci, vous avez ,mes remerciements.
En tant que débutant dégrossi en électronique programmée, j'ai le problème suivant :
J'ai besoin de lire les données en temps réel de 4 accéléromètres (MPU6050 en l'occurrence vu que je les avait dans le tiroir). Les MPU6050 possèdent une broche pour choisir parmi deux adresses i2c (0x68 par défaut et 0x69 si la broche ad0 et tirée au vcc), mais vu que j'ai besoin de dialoguer avec 4 capteurs, je vais avoir besoin de deux bus I2C séparés, en tant que maître, pour récupérer les données (sans parler de la nécessité d'une communication SPI pour l'enregistrement des données sur carte SD).
Je dispose de trois type de cartes à microcontrôleur :

-(4) arduino unos officielles, mais il semble qu'interfacer 2 bus i2c est impossible
- une carte blue pill, basée sur le STM32F104C8T6 (une chinoise, je 'avais achetée par curiosité), il semblerait qu'elle comporte deux bus i2c séparés mais je trouve pas comment les configurer séparément.
- une pyboard officielle, basée sur STM32F405, tournant sous micropython : je sais qu'elle ferait l'affaire, vu que j'ai déjà réussi à dialoguer avec une MPU6050 l'année dernière, mais je n'aime pas vraiment la programmation sous micropython, l'interface de putty n'aide pas beaucoup pour le débuggage.

Ma question est : Comment pourrais-je activer les deucx bus I2C du STM32F104C8T6 via l'IDE d'arduino pour ialoguer avec les deux couples d'accéléromètres, et est-il possible de fixer la fréquence du bus pour augmenter le débit de données ?
Je voudrais éviter l'utilisation d'un multiplexeur i2c, pour limiter la complexité du circuit et éviter de ralentir la communication : atteindre la communication la plus rapide est nécessaire pour limiter les erreurs d'intégration).

Un granbd merci à tous ceux qui prendrons de leur temps pour lire ceci et m'aiderons dans mon projet.

PS j'évite l'utilisation de bibliothèques, en-dehors du nécessaire pour la communication i2c, j'écris directement dans les registres de configuration et lis dans ceux de données des MPU, je sais ainsi ce qui se passe, je peux ajuster les réglages des capteurs, et je limite la taille du programme.
ozcar
Posts: 143
Joined: Wed Apr 29, 2020 9:07 pm
Answers: 5

Re: using both i2c interfaces on stm32f104c8t6

Post by ozcar »

Maybe you mean STM32F103C8T6? If so that has two I2C peripherals, and you should be able to define a second "TwoWire" as shown here https://github.com/stm32duino/wiki/wiki/API#i2C.

For your STM32F405 pyboard, maybe you can use STM32DUINO and forget python? You might have to create your own board variant - https://github.com/stm32duino/wiki/wiki ... 28board%29. If you are serious about debugging, get a STLINK (usable with blue pill boards too),

There are additional possibilities as you would have with other boards too, but what I can think of might be contrary to your speed goal.
Zter
Posts: 3
Joined: Tue Sep 20, 2022 4:23 pm

Re: using both i2c interfaces on stm32f104c8t6

Post by Zter »

Thanks for the quick answer, and sorry for not having checked sooner.
As a mater of facts, I could go with the python board (simpler as most of the code and the pcb are already made from my previous project)
But I will be limited in terms of calculations possible / measuring cycle :
I will need to solve several linear equation systems (during each measuring cycle to process the data) and from personnal measures, loging a simple calculation result in a variable takes 6.5 microseconds (us for short) for the calculation and then 2.5 us more to record in a variable. As I would like to reduce the intervals beetween measures, using the C-programmed board may be quicker.

For the code needed, do you think that these lines would work ?

For initialising the two buses :
#include <Wire.h>

const byte SDA1 = PB7;
const byte SCL1 = PB6;

const byte SDA2 = PB11;
const byte SCL2 = PB10;

TwoWire I2C1(SCL1, SDA1);
TwoWire I2C2(SCL2, SDA2);

and for reading from one of the accelerometers (adress 0x68, from I2C1, the register 0x3b and the 5 following) :

I2C1.beginTransmission(0x68);
I2C1.write(0x3B);
I2C1.endTransmission();
I2C1.requestFrom(0x68,6);
while(I2C1.available() < 6);
accelX = I2C1.read()<<8|I2C1.read();
accelY = I2C1.read()<<8|I2C1.read();
accelZ = I2C1.read()<<8|I2C1.read();

using unsigned ints or directly floats for loging the raw data (floats will be needed anyway for the calculations afterwards)

Once again thanks a lot for your answer, I hope you are having a good day
ag123
Posts: 1653
Joined: Thu Dec 19, 2019 5:30 am
Answers: 24

Re: using both i2c interfaces on stm32f104c8t6

Post by ag123 »

i'd suggest stick with the stm32f405 micropython board too and use the 'official' core.
https://github.com/stm32duino/Arduino_Core_STM32
stm32f405(RG) is a *much faster* chip, 168 Mhz, has 'ART Accelerator' (on chip cache), if instructions/data is in cache, it can change like maybe 5 waits to 0 waits, think of it in terms of clock cycles saved. And it has an FPU, search "whetstone benchmark" here, they give 'impossible' speeds like those of the old Pentium 4 processor, but only for FP32. (the joke is that GCC "optimised away" all the calcs and pretend to be doing nothing.

now back to I2C.
For I2C, i commonly need to run an 'device probe' sketch, it needs to find the I2C devices on the bus. That is a usual starting point.
Next I2C is 400 khz serial, if you use a spinlock (i'm not too sure if it is there in the 'driver' codes, i.e. Wire), you may be *stuck* with 400 khz despite the extreme fast speeds of STM32F405.
codes like

Code: Select all

while( state != READY);
are spinlocks, waiting for a variable / register / gpio etc to change state. These things would *block* waiting there until it gets pass that while loop.

The time used to compute a result may be 'negligible' compared to waiting for a single data value to be received across I2C.

These are some of the things to look into. There are probably ways round it, e.g. interrupts etc, but that those means may detour from the '*duino' style api, possibly requires directly working with I2C hardware etc. e.g. use HAL API, or direct register access etc.
dannyf
Posts: 446
Joined: Sat Jul 04, 2020 7:46 pm

Re: using both i2c interfaces on stm32f104c8t6

Post by dannyf »

or with soft i2c - you can establish as many of them as you can.
ozcar
Posts: 143
Joined: Wed Apr 29, 2020 9:07 pm
Answers: 5

Re: using both i2c interfaces on stm32f104c8t6

Post by ozcar »

dannyf wrote: Wed Sep 28, 2022 4:35 pm or with soft i2c - you can establish as many of them as you can.
That is one of the other possibilities I had in mind when I said this:
ozcar wrote: Wed Sep 21, 2022 1:53 am There are additional possibilities as you would have with other boards too, but what I can think of might be contrary to your speed goal.
The other that often gets mentioned for MPU6050 is use the same i2c address for all of them, with AD0 effectively acting as a chip select (if you have some spare GPIOs for driving those).
dannyf
Posts: 446
Joined: Sat Jul 04, 2020 7:46 pm

Re: using both i2c interfaces on stm32f104c8t6

Post by dannyf »

or i2c switches / multiplexers.

you can probably code a mcu into such a beast.
Zter
Posts: 3
Joined: Tue Sep 20, 2022 4:23 pm

Re: using both i2c interfaces on stm32f104c8t6

Post by Zter »

Sorry to disturb, I some tests with the python board and became stuck because of memory issues :
I put a funtion in the main program, it works like a charm,
I moove it to a secodary program, serving as a library, the functions isn't found
Well I tried a complete reset, but I would like to keep a back up solution
(the board has suffered 10 parachute-landings, at 5m/s, on concrete, with and without a polystyrene cussion, so it may have aged prematurely )

As I said before I bought the blue pill board out of curiosity, and didn't used it before, so far I tried uploading the usb boatloader following Caleb Martin tutorial :
https://www.youtube.com/watch?v=Myon8H111PQ&t=276s
but after uploading it through the stm32cubeprogrammer, I couldn't flash a program more than once, the board doesn't get recognised by the computer, sometimes, not even once, I get this error message when I try to upload code having disconnected the FTDI adapter:

> Trying to open the [COM4]...
> Toggling DTR...
> Searching for [1209:BEBA] device...
##########
Error - [1209:BEBA] device is not found :(> Searching for [COM4] ...
> [COM4] is found !
> Finish
the selected serial port > Finish
does not exist or your board is not connected

If someone can help on such a silly rpoblem, I would appreciate
(on the fith line the ide give the character chain (":",")" ) which gets converted in an emoticon :(

PS : I won't convert the STM32F405 board to arduino compatibility, it has it's glitches but I prefer keeping a working python alternative (I only have 1 model of each stm32 boards)
GonzoG
Posts: 403
Joined: Wed Jan 15, 2020 11:30 am
Answers: 26
Location: Prudnik, Poland

Re: using both i2c interfaces on stm32f104c8t6

Post by GonzoG »

Zter wrote: Sun Oct 02, 2022 3:38 pm but after uploading it through the stm32cubeprogrammer, I couldn't flash a program more than once, the board doesn't get recognised by the computer, sometimes, not even once, I get this error message when I try to upload code having disconnected the FTDI adapter:

> Trying to open the [COM4]...
> Toggling DTR...
> Searching for [1209:BEBA] device...
##########
Error - [1209:BEBA] device is not found :(> Searching for [COM4] ...
> [COM4] is found !
> Finish
the selected serial port > Finish
does not exist or your board is not connected

If someone can help on such a silly rpoblem, I would appreciate
(on the fith line the ide give the character chain (":",")" ) which gets converted in an emoticon :(

PS : I won't convert the STM32F405 board to arduino compatibility, it has it's glitches but I prefer keeping a working python alternative (I only have 1 model of each stm32 boards)
To use HID bootloader and not to reset board manually into bootloader mode, you need to enable USB CDC in every sketch. Without it there won't be a COM port to communicate with board and reset it. And you need to select correct COM port in Arduino IDE.
Post Reply

Return to “General discussion”