====== 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}}