multiple I²C sur RPi4
Modérateur : Francois
multiple I²C sur RPi4
Bonjour à toutes et à tous,
Voilà, j'utilise des RPi 3 B+ depuis quelques années désormais; depuis peu, j'ai acheté la version 4 du RPi (1 Go de RAM).
J'ai acheté cette version de RPi car j'avais vu qu'il y a plusieurs ports I²C et non 1 seul comme sur la version 3; de ce que j'ai pu comprendre, il y a 6 ports I²C possible ?
De i2c-7 à i2c-3 et le i2c-1 déjà existant sans aucun rajout de résistance pull up, car j'ai déjà utilisé ce port par le passé sur RPi3 mais un seul périphérique.
Je suis donc en plein tests, et j'aimerais déjà brancher 2 Convertisseur Numérique Analogique type MCP4725. J'ai donc suivi un "tuto" sur le net pour paramétrer par exemple le port i2c-7.
https://www.instructables.com/id/Raspbe ... c-Devices/
Je réalise donc la modification à apporter dans le fichier de boot "config.txt", mais lors du re démarrage, le RPi 4 ne démarre plus ... écran noir ...
dtoverlay=i2c-gpio,bus=7,i2c_gpio_delay_us=1,i2c_gpio_sda=17,i2c_gpio_scl=27
J'ai testé en ajoutant 2 résistances de pull up de 10 KOhms ... mais pareil, black screen ... du coup, je ne comprends pas bien
Est-ce que quelqu'un a déjà paramétrer plusieurs ports I²C sur RPi 4.
Sinon en parallèle, j'ai commandé un multiplexeur I²C : https://learn.adafruit.com/adafruit-tca ... r-breakout
qui promet de pouvoir brancher plusieurs périphériques ayant la même adresse, ce qui est mon cas évidement car à terme 7 CNA
Merci beaucoup pour vos conseils et aide,
Bien à vous,
Voilà, j'utilise des RPi 3 B+ depuis quelques années désormais; depuis peu, j'ai acheté la version 4 du RPi (1 Go de RAM).
J'ai acheté cette version de RPi car j'avais vu qu'il y a plusieurs ports I²C et non 1 seul comme sur la version 3; de ce que j'ai pu comprendre, il y a 6 ports I²C possible ?
De i2c-7 à i2c-3 et le i2c-1 déjà existant sans aucun rajout de résistance pull up, car j'ai déjà utilisé ce port par le passé sur RPi3 mais un seul périphérique.
Je suis donc en plein tests, et j'aimerais déjà brancher 2 Convertisseur Numérique Analogique type MCP4725. J'ai donc suivi un "tuto" sur le net pour paramétrer par exemple le port i2c-7.
https://www.instructables.com/id/Raspbe ... c-Devices/
Je réalise donc la modification à apporter dans le fichier de boot "config.txt", mais lors du re démarrage, le RPi 4 ne démarre plus ... écran noir ...
dtoverlay=i2c-gpio,bus=7,i2c_gpio_delay_us=1,i2c_gpio_sda=17,i2c_gpio_scl=27
J'ai testé en ajoutant 2 résistances de pull up de 10 KOhms ... mais pareil, black screen ... du coup, je ne comprends pas bien
Est-ce que quelqu'un a déjà paramétrer plusieurs ports I²C sur RPi 4.
Sinon en parallèle, j'ai commandé un multiplexeur I²C : https://learn.adafruit.com/adafruit-tca ... r-breakout
qui promet de pouvoir brancher plusieurs périphériques ayant la même adresse, ce qui est mon cas évidement car à terme 7 CNA
Merci beaucoup pour vos conseils et aide,
Bien à vous,
-
- Raspinaute
- Messages : 1588
- Enregistré le : dim. 10 mai 2015 18:44
- Localisation : Dans la campagne à côté d'Annecy
- Contact :
Re: multiple I²C sur RPi4
Salut,
Ouai, c'est chiant les devices tree et surtout pas facile a débugger (je suis en train de me faire chier avec un écran 3.5 sur mon Banana ... quelle galère).
Comme ca, a brule pour point, je commencerai avec le port 3 et non le 7 comme tu le fais. A la lecture du lien que tu as donné, j'ai l'impression
(une idée comme ca, hein, je n'ai pas de rPI4 pour essayer).
A+
Ouai, c'est chiant les devices tree et surtout pas facile a débugger (je suis en train de me faire chier avec un écran 3.5 sur mon Banana ... quelle galère).
Comme ca, a brule pour point, je commencerai avec le port 3 et non le 7 comme tu le fais. A la lecture du lien que tu as donné, j'ai l'impression
- qu'il faut définir dans l'ordre inverse
- mais qu'il faut descendre jusqu'au 3
(une idée comme ca, hein, je n'ai pas de rPI4 pour essayer).
A+
- BananaPI : Gentoo, disque SATA de 2 To
- Domotique : 1-wire, TéléInfo, Tablette passée sous Gentoo, ESP8266
- Multimedia par DNLA
- Et pleins d'idées ... et bien sûr, pas assez de temps.
Re: multiple I²C sur RPi4
Bonjour,
Tout d'abord, merci pour votre réponse. Je viens de faire un test à l'instant et malheureusement cela ne fonctionne pas non plus
J'ai branché avec 2 résistances pull up de 1.8KOhms entre le 3.3V et les broches SDA et SCL du second MCP4725 et des GPIO 17 et 27 côté RPi4 ....
J'ai cherché sur le net et des personnes réussissent à paramétrer plusieurs I²C (au moins 4), sans aucun souci et surtout pas d'écran noir, du coup, je ne comprends pas bien ...
Tout d'abord, merci pour votre réponse. Je viens de faire un test à l'instant et malheureusement cela ne fonctionne pas non plus
J'ai branché avec 2 résistances pull up de 1.8KOhms entre le 3.3V et les broches SDA et SCL du second MCP4725 et des GPIO 17 et 27 côté RPi4 ....
J'ai cherché sur le net et des personnes réussissent à paramétrer plusieurs I²C (au moins 4), sans aucun souci et surtout pas d'écran noir, du coup, je ne comprends pas bien ...
-
- Raspinaute
- Messages : 1588
- Enregistré le : dim. 10 mai 2015 18:44
- Localisation : Dans la campagne à côté d'Annecy
- Contact :
Re: multiple I²C sur RPi4
L'écran noir n'a rien a voir avec la présence ou non de résistance a mon avis (au pire, son absence ferait que tu ne verrais aucun périph) : c'est plus qu'il y a qq chose qui ne va pas dans ton Device Tree.
Je pense qu'il faudrait que t'essaye de voir avec eux si :
* ils ont la meme version de l'OS et surtout du kernel
* s'ils ont changer qq chose dans le system (genre pas l'outils de configuration **-config dont le nom m'échappe).
A+
Je pense qu'il faudrait que t'essaye de voir avec eux si :
* ils ont la meme version de l'OS et surtout du kernel
* s'ils ont changer qq chose dans le system (genre pas l'outils de configuration **-config dont le nom m'échappe).
A+
- BananaPI : Gentoo, disque SATA de 2 To
- Domotique : 1-wire, TéléInfo, Tablette passée sous Gentoo, ESP8266
- Multimedia par DNLA
- Et pleins d'idées ... et bien sûr, pas assez de temps.
Re: multiple I²C sur RPi4
Re Bonjour,
J'avais eu justement la même idée, à savoir reprendre une ancienne version de Raspbian, et j'ai donc téléchargé la première version de Buster datant du 20/06/2019, et avec les mêmes manipulations, cela fonctionne, enfin pour 2 ports I²C pour l'instant, mais c'est déjà mieux
Pour cette version, le firmware est: Linux raspberrypi 4.19.50-v7l+ #895 SMP Thu Jun 20 16:03:42 BST 2019 armv7l GNU/Linux
PRETTY_NAME="Raspbian GNU/Linux 10 (buster)"
NAME="Raspbian GNU/Linux"
VERSION_ID="10"
VERSION="10 (buster)"
VERSION_CODENAME=buster
ID=raspbian
ID_LIKE=debian
HOME_URL="http://www.raspbian.org/"
SUPPORT_URL="http://www.raspbian.org/RaspbianForums"
BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs"
J'avais eu justement la même idée, à savoir reprendre une ancienne version de Raspbian, et j'ai donc téléchargé la première version de Buster datant du 20/06/2019, et avec les mêmes manipulations, cela fonctionne, enfin pour 2 ports I²C pour l'instant, mais c'est déjà mieux
Pour cette version, le firmware est: Linux raspberrypi 4.19.50-v7l+ #895 SMP Thu Jun 20 16:03:42 BST 2019 armv7l GNU/Linux
PRETTY_NAME="Raspbian GNU/Linux 10 (buster)"
NAME="Raspbian GNU/Linux"
VERSION_ID="10"
VERSION="10 (buster)"
VERSION_CODENAME=buster
ID=raspbian
ID_LIKE=debian
HOME_URL="http://www.raspbian.org/"
SUPPORT_URL="http://www.raspbian.org/RaspbianForums"
BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs"
Re: multiple I²C sur RPi4
Bon, j'ai même poussé le vice jusque réaliser un update/upgrade .... reboot, et hop ...écran noir ...
Re: multiple I²C sur RPi4
J'ai encore poussé le vice et j'ai testé avec les versions suivantes et cela fonctionne :
20/06/2019
10/07/2019
26/09/2019
05/02/2020
13/02/2020
Par contre, la dernière version du 20/06/2020 ne fonctionne pas
20/06/2019
10/07/2019
26/09/2019
05/02/2020
13/02/2020
Par contre, la dernière version du 20/06/2020 ne fonctionne pas
Re: multiple I²C sur RPi4
voilà une programme ne micropython mais très facielemnt adaptable pour python3 sur Raspi
Code : Tout sélectionner
""" attention ce programme contient l'exploitation d'une multiplexeur I2C TCA9548A
par défaut on ne connecte à A0 A1 A2 à rien , la connexion à 3,3volt de ces lignes d'adresse permet d'incrémenter l'adresse
du multiplexer dont l'adresse de base sur le bus I2C est 0x70 ainsi avec ces trois fils d'adresse
il est possible d'obtenir la communication avec 8 multiplexeurs qui redoivent dont on programme les adresses ainsi de 0xF0 à 0xF7.
Ceci étant l'ouverture d'un des port du multiplexeur se fait par une "commande envoyé sur le bus I2C lui même.
par exemple pour ouvrir le canal "0" du multiplexeur il faut en voyer sur le bus I2c par writeto(0xF0,1) ensuite on constate
par exemple en scanant le bus que c'est bien le composant qui répond sur ce canal et lui seul. un print du scan donne
la ou les adresses du composant connecté sur ce port suivi toujours de l'adresse du multiplexeur lui même, ici 112 puisque
les lignes d'adresse ne sont pas actives et que donc par de faut l'adresse I2c du multiplexeur est 0xF0 soit 112 valeur numérique.
par la on comprend que les autres ports étant isolés nous pourrons mettre ensuquer 8 de composants identique de mêmes adresses
sans générer de conflit. par exemple un write(0xf0, 128) permettra de communiquer uniquement avec le composant connecté au port 8.
la valeur transmise dans cette ordre de connexion est fait un octet donc chaque bit à 1 active un port
d'où les seules valeurs autorisées: 1,2,4,8,16,32,64,128. Un scan après un commande type write(0xF0, 5)
qui en valeur digitale donne 00000101 entre comme seule réponse invariable 112 qui indique que le mutiplexeur qui répond toujours
présent à son adresse n'a ouvert aucun de ses ports
"""
import time
from machine import I2C
import math
import utime
from machine import Pin
print("c'est fait")
# configure the I2C bus
bus = I2C(0,I2C.MASTER, baudrate=100000)
accel_address=25
mag_address=30
class lsm303DLHC:
# LSM303 Address definitions
LSM303Accel_ADDR = 25 # ou l'inverse
LSM303Mag_ADDR = 30
CTRL_REG1_A = 0x20
CTRL_REG2_A = 0x21
CTRL_REG3_A = 0x22
CTRL_REG4_A = 0x23
CTRL_REG5_A = 0x24
CTRL_REG6_A = 0x25
REFERENCE_A = 0x26
STATUS_REG_A = 0x27
OUT_X_L_A = 0x28
OUT_X_H_A = 0x29
OUT_Y_L_A = 0x2A
OUT_Y_H_A = 0x2B
OUT_Z_L_A = 0x2C
OUT_Z_H_A = 0x2D
FIFO_CTRL_REG_A = 0x2E
FIFO_SRC_REG_A = 0x2F
INT1_CFG_A = 0x30
INT1_SRC_A = 0x31
INT1_THS_A = 0x32
INT1_DURATION_A = 0x33
INT2_CFG_A = 0x34
INT2_SRC_A = 0x35
INT2_THS_A = 0x36
INT2_DURATION_A = 0x37
CLICK_CFG_A = 0x38
CLICK_SRC_A = 0x39
CLICK_THS_A = 0x3A
TIME_LIMIT_A = 0x3B
TIME_LATENCY_A = 0x3C
TIME_WINDOW_A = 0x3D
#Magnetic field sensing register description . . . . . . . . . . . . . . . . . . . . . . . 37
CRA_REG_M = 0x00
CRB_REG_M = 0x01
MR_REG_M = 0x02
OUT_X_H_M = 0x03
OUT_X_L_M = 0x04
OUT_Z_H_M = 0x05
OUT_Z_L_M = 0x06
OUT_Y_H_M = 0x07
OUT_Y_L_M = 0x08
SR_REG_M = 0x09
MAG_IRA_REG_M = 0x0A
MAG_IRB_REG_M = 0x0B
MAG_IRC_REG_M = 0x0C
TEMP_OUT_H_M = 0x31
TEMP_OUT_L_M = 0x32
####################""""
MAG_DEVICE_ID = 0b01000000
# Magnetometer gains
MAGGAIN_1_3 = 0x20 # +/- 1.3
MAGGAIN_1_9 = 0x40 # +/- 1.9
MAGGAIN_2_5 = 0x60 # +/- 2.5
MAGGAIN_4_0 = 0x80 # +/- 4.0
MAGGAIN_4_7 = 0xA0 # +/- 4.7
MAGGAIN_5_6 = 0xC0 # +/- 5.6
MAGGAIN_8_1 = 0xE0 # +/- 8.1
# Magentometer rates
MAGRATE_0_7 = 0x00 # 0.75 Hz
MAGRATE_1_5 = 0x01 # 1.5 Hz
MAGRATE_3_0 = 0x02 # 3.0 Hz
MAGRATE_7_5 = 0x03 # 7.5 Hz
MAGRATE_15 = 0x04 # 15 Hz
MAGRATE_30 = 0x05 # 30 Hz
MAGRATE_75 = 0x06 # 75 Hz
MAGRATE_220 = 0x07 # 220 Hz
# Conversion constants
GRAVITY_STANDARD = 9.80665 # Earth's gravity in m/s^2
GAUSS_TO_MICROTESLA = 100.0 # Gauss to micro-Tesla multiplier
###################""""""
ACCELE_SCALE = 2
X = 0
Y = 1
Z = 2
# Set up the sensor
def __init__(self,):
self.write_regAccel(0b01000111, self.CTRL_REG1_A) # 0x57 = ODR=50hz, all accel axes on
self.write_regAccel(0x00, self.CTRL_REG2_A) # set full-scale
self.write_regAccel(0x00, self.CTRL_REG3_A) # no interrupt
self.write_regAccel(0x00, self.CTRL_REG4_A) # no interrupt
self.write_regAccel(0x00, self.CTRL_REG5_A) # 0x10 = mag 50Hz output rate
self.write_regAccel(0x00, self.CTRL_REG6_A)
self.write_regMag(0b10010000,self.CRA_REG_M) # activation température et frequence mag à 35 Hz
self.write_regMag(0b00100000,self.CRB_REG_M) # +- 1,3 Gauss champ terrete 0,5 gauss
self.write_regMag(0b00000000,self.MR_REG_M) # pour mesure continuelle 00000011 pour mise en sommeil
self.lsm303mag_gauss_lsb_xy= 1100.0
self.lsm303mag_gauss_lsb_z= 980.0
print("toto")
# get the status of the sensor
def status(self):
if self.read_regAccel(self.STATUS_REG_A) !=73:
return -1
return 1
# Write data to a reg on the I2C device
def write_regAccel(self,data,reg):
bus.writeto_mem(self.LSM303Accel_ADDR, reg, data)
# Read data from the sensor
def read_regAccel(self,reg):
return bus.readfrom_mem(self.LSM303Accel_ADDR, reg,1)
# Write data to a reg on the I2C device
def write_regMag(self,data,reg):
bus.writeto_mem(self.LSM303Mag_ADDR, reg, data)
# Read data from the sensor
def read_regMag(self,reg):
return bus.readfrom_mem(self.LSM303Mag_ADDR, reg,1)
# Check if compass is ready
def isMagReady(self):
if int.from_bytes(self.read_regMag(self.SR_REG_M),"big") & 0x03 != 0 :
return 1
return 0
def dec2bin(self,d,nb):
#"""Représentation d'un nombre entier en chaine binaire (nb: nombre de bits du mot)"""
if d == 0:
return "0".zfill(nb)
if d<0:
d += 1<<nb
b=""
while d != 0:
d, r = divmod(d, 2)
b = "01"[r] + b
return '{:0>{w}}'.format(b, w=nb) # en effet en micropyhton il n'y a pas de fonction zfill
def temperature2(self):
temp=((int.from_bytes(self.read_regMag(self.TEMP_OUT_H_M),"big")<<8)|(int.from_bytes(self.read_regMag(self.TEMP_OUT_L_M),"big")))
if temp > 32767: # 2's complement
temp -= 65536
temperature = float( 20 + ( temp >> 4 )/ 8 )
return temperature
# Get raw accelerometer values
def getAccel(self):
raw_accel=[0,0,0]
#print("titi ",int.from_bytes(self.read_reg(self.OUT_X_H_A),"big"))
raw_accel[0]=((int.from_bytes(self.read_regAccel(self.OUT_X_H_A),"big")<<8)|int.from_bytes(self.read_regAccel(self.OUT_X_L_A),"big"))
raw_accel[1]=((int.from_bytes(self.read_regAccel(self.OUT_Y_H_A),"big")<<8)|int.from_bytes(self.read_regAccel(self.OUT_Y_L_A),"big"))
raw_accel[2]=((int.from_bytes(self.read_regAccel(self.OUT_Z_H_A),"big")<<8)|int.from_bytes(self.read_regAccel(self.OUT_Z_L_A),"big"))
#2's compiment
for i in range(3):
if raw_accel[i]>32767:
raw_accel[i]=raw_accel[i]-65536
return raw_accel
# Get accelerometer values in g
def getRealAccel(self):
realAccel=[0.0,0.0,0.0]
accel=self.getAccel()
for i in range(3):
realAccel[i] = round(accel[i] / math.pow(2, 15) * self.ACCELE_SCALE,3)
return realAccel
# Get compass raw values
def getMag(self):
raw_mag=[0,0,0]
raw_mag[0]=((int.from_bytes(self.read_regMag(self.OUT_X_H_M),"big")<<8)|int.from_bytes(self.read_regMag(self.OUT_X_L_M),"big"))
raw_mag[1]=((int.from_bytes(self.read_regMag(self.OUT_Y_H_M),"big")<<8)|int.from_bytes(self.read_regMag(self.OUT_Y_L_M),"big"))
raw_mag[2]=((int.from_bytes(self.read_regMag(self.OUT_Z_H_M),"big")<<8)|int.from_bytes(self.read_regMag(self.OUT_Z_L_M),"big"))
#2's compiment
for i in range(3):
if raw_mag[i]>32767:
raw_mag[i]=raw_mag[i]-65536
return raw_mag
# Get heading from the compass
def getHeading(self):
magValue=self.getMag()
print(magValue)
heading = 180*math.atan2(magValue[self.Y], magValue[self.X])/math.pi# // assume pitch, roll are 0
if (heading <0):
heading += 360
return round(heading,3)
def getTiltHeading(self):
magValue=self.getMag()
raw_accel=self.getAccel()
if [0.0,0.0,0.0] != raw_accel:
accXnorm= raw_accel[0]/math.sqrt(raw_accel[0]*raw_accel[0]+raw_accel[1]*raw_accel[1]+raw_accel[2]*raw_accel[2])
accYnorm= raw_accel[1]/math.sqrt(raw_accel[0]*raw_accel[0]+raw_accel[1]*raw_accel[1]+raw_accel[2]*raw_accel[2])
pitch = math.asin(accXnorm)
roll = -math.asin(accYnorm/math.cos(pitch))
#print(accelValue[Y],pitch,math.cos(pitch),accelValue[Y]/math.cos(pitch),math.asin(accelValue[Y]/math.cos(pitch)))
xh = (magValue[0] * math.cos(pitch)) +( magValue[2] * math.sin(pitch))
yh = (magValue[1] * math.sin(roll) * math.sin(pitch)) + (magValue[1] * math.cos(roll)) - (magValue[2] * math.sin(roll) * math.cos(pitch))
zh = (-magValue[0] * (roll) * math.sin(pitch)) +( magValue[1] * math.sin(roll)) +( magValue[2] * math.cos(roll) * math.cos(pitch))
heading = 180 * math.atan2(yh, xh)/math.pi
#heading = 180 * math.atan2(yh*zh, xh*zh)/math.pi
print("xh ", xh,"yh ",yh, "zh ",zh)
if (yh >= 0):
return heading
else:
return (360 + heading)
if __name__ == "__main__":
bus.writeto( 0x70, 1) # ouverture du bus N° 0
print(bus.scan()) # returns list of slave addresses
acc_mag=lsm303DLHC() # création de l'objet gérant le premier acc-mag
time.sleep(1)
bus.writeto( 0x70, 128) # ouverture du bus N° 7
print(bus.scan()) # returns list of slave addresses
acc_mag2=lsm303DLHC() # création de l'objet gérant le deuxième acc-mag
while True:
#if acc_mag.status()==1:
bus.writeto( 0x70, 1) # ouverture du bus N° 0
print("accélération",acc_mag.getRealAccel())
while True:
if acc_mag.isMagReady():
break
print("*")
print(acc_mag.getHeading())
print (acc_mag.getTiltHeading())
print("température2 ", acc_mag.temperature2())
time.sleep(5)
# ici on change de canal du multiplexeur I2c
bus.writeto( 0x70, 128) # ouverture du bus N° 0
print("accélération",acc_mag2.getRealAccel())
while True:
if acc_mag2.isMagReady():
break
print("*")
print(acc_mag2.getHeading())
print (acc_mag2.getTiltHeading())
print("température2 ", acc_mag2.temperature2())
time.sleep(5)