====== Communication avec le protocole I2C ====== {{ :media_16:2_codeurs_ok.png?600 |}} =====Ressources===== Seulement 2 fils, les appareils sont définis par des adresses. * **[[https://fr.wikipedia.org/wiki/I2C|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. * **[[https://www.gammon.com.au/i2c|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. * https://github.com/nickgammon/I2C_Anything =====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= (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===== * https://docs.arduino.cc/learn/communication/wire * https://radiostud.io/howto-i2c-communication-rpi/ * [[https://www.arduino.cc/reference/en/language/functions/communication/wire/|la doc arduino pour la lib Wire]] =====smbus2===== La lib I2C python * https://github.com/kplindegaard/smbus2 =====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 #include // 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===== * https://learn.sparkfun.com/tutorials/pull-up-resistors * **[[https://www.gammon.com.au/forum/?id=10896&reply=5#reply5|Nick explique tout]]** On tire le signal vers le **+** avec une résistance sur SDA et SDL: {{ :media_16:pull_up_resistor.png?200 |}} {{tag>communication sb i2c}}