Libreria Wire: Arduino/STM32F103C8T6 Blue Pill - Cambio Pin SDA, SCL

Salve a tutti,

ho un grave problema per quanto riguarda la libreria Wire sull'IDE di Arduino.

Ho provato un semplice programma dove tramite la libreria Wire mi scrive e legge
su una EEPROM I2C esterna (24LC512) ed il tutto funziona.

Il problema si è posto quando sono passato sul microcontrollore STM32F103C8T6 denominato Blue Pill.
Tale controllore ha due porte I2C e non saprei come cambiare la porta come si fa sulle seriali.

Questa è la documentazione che ho trovato al riguardo:

https://danieleff.github.io/STM32GENERIC/i2c/

La documentazione mi spiega perfettamente come fare e mi dice di richiamare la funzione Wire.h
Però mi sono posto che non è la stessa libreria utilizzata in Arduino e su questo link:

https://danieleff.github.io/STM32GENERIC/#installation-users

Ho scaricato il pacchetto e come scritto l'ho inserito nella cartella
"Disco Rigido/Programmi/Arduino/HardWare" come spiegato.

Poi il punto 3 dice : "Installa Arduino Zero dal gestore della scheda per il compilatore arm-none-eabi-gcc"

Adesso sto eseguendo il punto 3 che non lo avevo eseguito.

Quando nel progetto ho aggiunto la libreria Wire.h mi ha aggiunto 3 funzioni diverse e quindi questo sta a dire che la libreria è stata aggiornata con le funzioni per STM32 ?

Perchè non avendo eseguito il punto 3 della documentazione mi da un errore di compilazione generico.

E chiedevo se secondo voi installando il compilatore arm-none-eabi-gcc come descritto l'errore sparisce.

Qualcuno si è imbattuto in questo ? Qualcuno conosce altre librerie i2c con pin modificabili SDA, SCL ?

Grazie in anticipo.

Non conosco quel core, io ho usato principalmente quello di Roger Clark e molto poco quello ufficiale STM.

Attualmente il forum originale è morto e sparito per una serie di questioni. E' in corso di creazione una copia statica.

Quello di riferimento, per adesso, è questo (solo inglese)
https://mcu.selfip.com/

e il post da cui partire sarebbe questo
https://mcu.selfip.com/viewtopic.php?f=49&t=130

Nel forum originale la questione delle due porte I2C era stata discussa ma purtroppo non ricordo dove.

Allora la comunicazione tra STM32 Blue Pille ed EEPROM 24LC512 o 256 l'ho risolta.

Soluzione:

dovevo mettere le resistenze di pullup da 3.3K perche tale micro le sue sono troppo alte e le transizioni di alto basso nel filo SDA non vengono calcolate.

ULTIMO PROBLEMA :

Io cercando, ho persino trovato un'altro utente penso inglse sempre su questo che forum di Arduino

Using 2nd I2C peripheral with STM32 - Microcontrollers - Arduino Forum

Ha posto la domanda e poi ha risolto scrivendo questa risposta:


EDIT, solution:

Treat "wire2" as regular "wire".

Code:

TwoWire Wire2 (2, I2C_FAST_MODE); // I2C_2 (PB11-SDA, PB10-SCL )


Ho provato a farlo ed il compilatore me lo compila poichè la funzione TwoWire viene riconoscita.

Domande:

Come potrei usare quel codice che tale utente in una'altro post ha scritto che ha risolto ?

Cosa va a fare la funzione Two Wire ?

Perchè in rete trovo TWI che è Wire e non la funzione Two Wire ?

Grazie zoomx ! :smiley: Adesso mi vado a leggere i tuoi link citati :wink: !!!

Giusto per farti capire e far capire a tutti ho trovato adesso ben 3 pacchetti sul gestore schede.


Quello che ho sempre usato è questo usato in questo video tutorial :

Video > STM32 Arduino Tutorial - How to use the STM32F103C8T6 board with the Arduino IDE - YouTube

Codice su gestore schede > http://dan.drown.org/stm32duino/package_STM32duino_index.json

Non mai avuto problemi ha praticamente tutto UPLOAD via seriale FTDI ecc velocità di clock ecc ma
per quanto riguarda la libreria Wire() sto ancora cercando un modo per usare la seconda porta i2c... :frowning:


Poi ho trovato questo pacchetto dal sito:

https://danieleff.github.io/STM32GENERIC/

e qui la libreria Wire() ha le funzioni che cerco : I2C - STM32GENERIC

Con questo pacchetto il tutto funziona ma c'è un grave problema di compilazione
quando uso la funzione shiftOut() e forse anche altre...

L'errore che mi da è al quanto noto ma al quanto generale e non so come posso risolverlo :

ERRORE : collect2.exe: error: ld returned 1 exit status


Adesso in questo momento ho trovato un'altro pacchetto di supporto della STM32duino
che è la versione più recente:

Anche questo ha delle funzioni come Wire.setSDA() / setSCL() ma rispetto agli altri non posso programmare la scheda STM32 Blue Pill perchè non supporta il caricamento seriale nativo nel mio caso con un classico FTDI e c'è scritto che devo scaricare STM32Programmer ecc ecc...

Che adesso proverò, tentar non nuoce...


In conclusone nessuno di questi 3 e praticamente perfetto e spero di sbagliarmi perchè se riesco a risolvere il problema con il primo pacchetto

  1. ovvero di trovare il modo di capire come utilizzare la funzione TwoWire() per cambiare i pin della i2c 2

  2. o risolvere il problema del secondo pacchetto che mi da l'errore di compilazione "collect2.exe: error"


Grazie ancora, adesso vado a cercare altre informazioni al riguardo...

In breve:
Una ditta che si chiamava Maple sviluppò delle schede con STM32 compatibili con arduino. Attualmente esistono dei cloni, noti come Maple Mini, che sono in vendita in Cina. Tale scheda ha un bootloader.
Maple sviluppò anche un core ma poi l'attività cessò. Il core venne scritto perché alcune librerie STM non potevano essere redistribuite.

I cinesi intanto tirarono fuori alcune schede simili alcune con il PCB blu (le Blue Pill, nome preso dal film Matrix), oggi molto comuni, altre dal PCB rosso (le Red Pill) e ultimamente con il PCB nero. Le Blue Pill sono le più diffuse nonché molto economiche.

Roger Clarck riprese il core Maple e iniziò ad aggiornarlo, contemporaneamente mise su un forum e con l'aiuto degli utenti venne fuori un core decente soprattutto con parecchie librerie.

Altri core furono in seguitop sviluppati, alcuni derivati da quello di Roger, altri totalmente indipendenti come quello di danielef.

Infine è arrivata STM che ha messo su un core prncipalmente per le schede Nucleo ma che grazie all'imput degli utenti del forum di Roger, cui alcuni impiegati STM erano iscritti, venne ampliato anche alla Blue Pill. Questo core non ha ancora tutto quanto c'è nel core di Roger, essendo nato con anni di ritardo, ma si ritiene che sia il futuro perché usa delle librerie STM più recenti e perché ha il supporto STM.

Roger non aveva più tempo per tenere dietro al forum e voleva cederlo ad STM ma non è stato possibile a causa di problemi legali dovuti al GDPR (legati ai dati degli utenti) e ha dovuto chiuderlo.

Non so se STM userà un nuovo forum o il forum che già ha.

Il link del core che hai trovato riguarda quello STM, quello di Roger è qui

RISOLTO TUTTO ! :smiley: :wink:

Ho visto un semplice esempio dove la funzione:

TwoWire WIRE2 (2, I2C_FAST_MODE);

Deve essere messa esterna prima del void setup();

Quindi il codice è:

Nome file: STM32_Blue_Pill_Read_Write_EEPROM_24LC512_256_with_i2c_2


#include <Wire.h>

//Indirizzo della EEPROM 24LC512
#define EEPROM_I2C_ADDRESS 0x50

//Cambiare la porta i2c standard (PB6, PB7) con la seconda porta i2c (PB11, PB10)
TwoWire WIRE2 (2, I2C_FAST_MODE);
#define Wire WIRE2

//Led debug
#define Q1 PC15

void setup() {

  disableDebugPorts();

  Wire.begin();

  Serial.begin(115200);

  pinMode(Q1, OUTPUT);

  writeAddress(0, 23);

  byte readVal = readAddress(0);

  Serial.print("The returned value is ");
  Serial.println(readVal);

}

void loop() {

  delay(1000);
  byte Memoria = readAddress(0);
  Serial.print("The returned value is ");
  Serial.println(Memoria);
  digitalWrite(Q1, HIGH);
  delay(80);
  digitalWrite(Q1, LOW);
  

}

//Scrive dati nella EEPROM
void writeAddress(int address, byte val) {
  Wire.beginTransmission(EEPROM_I2C_ADDRESS);
  Wire.write((int)(address >> 8));   // MSB
  Wire.write((int)(address & 0xFF)); // LSB

  Wire.write(val);
  Wire.endTransmission();

  delay(5);
}

//Riceve dati dalla EEPROM
byte readAddress(int address) {
  byte rData = 0xFF;

  Wire.beginTransmission(EEPROM_I2C_ADDRESS);

  Wire.write((int)(address >> 8));   // MSB
  Wire.write((int)(address & 0xFF)); // LSB
  Wire.endTransmission();

  Wire.requestFrom(EEPROM_I2C_ADDRESS, 1);

  rData =  Wire.read();

  return rData;
}

Spero che questo post serva a chi s’imbatte in questo problema. :smiley:

[/code]

Grazie per la condivisione!