communication_protocole_i2c
Table des matières
Communication avec le protocole I2C
Ressources
Seulement 2 fils, les appareils sont définis par des adresses.
- I2C sur fr.wikipedia.org Les libs font le boulot, pas besoin d“apprendre la page par coeur. Par contre, le § sur les résistances de pull-up est important.
- I2C par Nick Gammon This post describes how the I2C (Inter-Integrated Circuit, or “Two-Wire”) interface works, with particular reference to the Arduino Uno which is based on the ATmega328P microprocessor chip. A lot of the details however will be of more general interest.
Installation sur une Pi
From https://gist.github.com/ribasco/c22ab6b791e681800df47dd0a46c7c3a
sudo nano /boot/config.txt # Find the line containing dtparam=i2c_arm=on # Add i2c_arm_baudrate=<new speed> (Separate with a Comma) dtparam=i2c_arm=on,i2c_arm_baudrate=400000
Reboot Raspberry Pi
Create a simple test script to verify the speed
Switch to home directory
cd ~
Create shell script
nano i2cspeed.sh
Copy and paste the following lines of code
#!/bin/bash var="$(xxd /sys/class/i2c-adapter/i2c-1/of_node/clock-frequency | awk -F': ' '{print $2}')" var=${var//[[:blank:].\}]/} printf "%d\n" 0x$var
Change file permissions
chmod +x i2cspeed.sh
Execute test script
./i2cspeed.sh
Installation sur Arduino
smbus2
La lib I2C python
Exemple à revérifier
- https://github.com/sergeLabo/furuta/tree/main/doc/NickGammon_I2C l'exemple de Nick simplifié
Exemple entre Raspberry Pi et Arduino Leonardo
Contexte: Le codeur 4000 points est complétement marabouté! La Leonardo ne peut pas être Slave en SPI, il faut faire la comm entre Pi et Arduino en I2C.
Code python pour la Pi en master
from time import time, sleep from smbus2 import SMBus addr = 44 bus = SMBus(1) sleep(0.1) E = 0 def request(): global E try: b2 = bus.read_i2c_block_data(addr, 0, 2) b = bytearray(b2) pos = (b[0] << 8) + b[1] except IOError: pos = None E += 1 return pos t = time() n = -1 e = 0 nbr = 1000 tempo = 0.03 pos = 0 while n < nbr: n += 1 pos1 = request() # #if n % 200 == 0: # #print(pos1) if pos1 != pos: pos = pos1 print(pos) sleep(tempo) d = ((((time() - t)/nbr) - tempo))*1000 print("Temps de transmission", round(d, 2), "ms") print("Nombre d'erreur:", E) bus.close() """ freq = 100 000 Hz avec adaptateur Temps de transmission 0.93 ms Nombre d'erreur: 2 freq = 100 000 Hz avec adaptateur et pull up Temps de transmission 1.02 ms Nombre d'erreur: 2 """
Code pour Arduino Leonardo
#include <Wire.h> #include <Encoder.h> // Interrupt const int ENC_Z = 7; // Objet Encoder Encoder myEnc(0, 1); // I2C const byte MY_ADDRESS = 44; // Variable globale long val = 0; int hi = 0; int lo = 0; void index_ISR(){ myEnc.write(0); } void setup() { //Serial.begin(115200); // I2C Wire.begin (MY_ADDRESS); Wire.onRequest(requestEvent); pinMode(ENC_Z, INPUT_PULLUP); attachInterrupt(digitalPinToInterrupt(ENC_Z), index_ISR, RISING); } void loop() { val = myEnc.read(); delayMicroseconds(500); //Serial.print("loop"); //Serial.println(val); //delay(100); } void requestEvent () { //val = myEnc.read(); byte buf [2]; buf [0] = val >> 8; buf [1] = val & 0xFF; Wire.write (buf, 2); }
Pull-up Resistors
communication_protocole_i2c.txt · Dernière modification : 2022/09/07 09:33 de serge