Em alguns projetos, pode ser interessante estabelecer uma comunicação I2C entre Raspberry Pi e Arduino. A potência de computação e as capacidades sem fios do Raspberry Pi, aliadas à capacidade de entrada e saída do Arduino, resultam num sistema de controle completo que permite pilotar qualquer projeto. Se a placa Raspberry Pi e a placa Arduino estiverem próximas, o barramento I2C é uma boa escolha como protocolo de comunicação. Isso também permite adicionar vários dispositivos no mesmo barramento e aumentar em dez vezes as capacidades do RaspberryPi.
Pré-requisitos: comunicação I2C com Arduino, Acesso remoto do Raspberry Pi com VNC
Material
- Computador
- Arduino UNO
- Raspberry Pi 3B+
- 3 Cabos jumper
Esquema de ligação
Para estabelecer a comunicação I2C entre Raspberry Pi e Arduino, é preciso ligar fisicamente o barramento que utiliza 3 pinos. A comunicação I2C se define por um barramento de dois fios (também chamado de TWI, Two Wire Interface) e um endereço. Os pinos utilizados para a comunicação I2C são normalmente fixados para cada dispositivo. Os dados (SDA Serial Data Line) são enviados para um pino e o relógio de sincronização (SLC Serial Clock Line), para o outro. As terras de ambas as placas devem estar conectadas para estabelecer uma referência comum de potencial.
- SDA BCM2(RPI) <-> SDA A4(Arduino)
- SCL BCM3(RPI) <-> SCL A5(Arduino)
- GND (RPI) <-> GND(Arduino)

Configuração do Raspberry Pi
Para utilizar a interface I2C do Raspberry Pi, deve-se ativá-la no menu de configuração. Para isso, introduza o seguinte comando num terminal:
sudo raspi-config
No menu, selecione “5 – Opções de Interface” e em seguida “P5 I2C”, então valide.
Uma vez efetuada a ligação, é possível verificar os dispositivos conectados ao barramento digitando o seguinte comando no terminal:
i2cdetect -y 1
O Raspberry Pi devolve a lista de endereços detectados no barramento.
pi@raspberrypi:~ $ i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- 0b -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
Vamos instalar a biblioteca smbus2, que permite gerenciar a comunicação I2C pelo lado do Raspberry Pi
pip3 install smbus2
Código
Código “Master” Python
Neste tutorial, vamos adotar a linguagem Python para o Raspberry Pi. A biblioteca utilizada para gerenciar a comunicação I2C é a smbus2.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Raspberry Pi to Arduino I2C Communication
#i2cdetect -y 1
#library
import sys
import smbus2 as smbus#,smbus2
import time
# Slave Addresses
I2C_SLAVE_ADDRESS = 11 #0x0b ou 11
I2C_SLAVE2_ADDRESS = 12
I2C_SLAVE3_ADDRESS = 13
# This function converts a string to an array of bytes.
def ConvertStringsToBytes(src):
converted = []
for b in src:
converted.append(ord(b))
return converted
def main(args):
# Create the I2C bus
I2Cbus = smbus.SMBus(1)
with smbus.SMBus(1) as I2Cbus:
slaveSelect = input("Which Arduino (1-3): ")
cmd = input("Enter command: ")
if slaveSelect == "1":
slaveAddress = I2C_SLAVE_ADDRESS
elif slaveSelect == "2":
slaveAddress = I2C_SLAVE2_ADDRESS
elif slaveSelect == "3":
slaveAddress = I2C_SLAVE3_ADDRESS
else:
# quit if you messed up
print(slaveSelect== "1")
print(type(slaveSelect))
print("no slave selected")
quit()
BytesToSend = ConvertStringsToBytes(cmd)
print("Sent " + str(slaveAddress) + " the " + str(cmd) + " command.")
print(BytesToSend )
I2Cbus.write_i2c_block_data(slaveAddress, 0x00, BytesToSend)
time.sleep(0.5)
while True:
try:
data=I2Cbus.read_i2c_block_data(slaveAddress,0x00,16)
print("recieve from slave:")
print(data)
except:
print("remote i/o error")
time.sleep(0.5)
return 0
if __name__ == '__main__':
try:
main(sys.argv)
except KeyboardInterrupt:
print("program was stopped manually")
input()
Código “Slave” Arduino
A biblioteca utilizada para gerir a comunicação I2C no lado Arduino é a Wire.h.
#include <Wire.h> # define I2C_SLAVE_ADDRESS 11 // 12 pour l'esclave 2 et ainsi de suite #define PAYLOAD_SIZE 2 void setup() { Wire.begin(I2C_SLAVE_ADDRESS); Serial.begin(9600); Serial.println("-------------------------------------I am Slave1"); delay(1000); Wire.onRequest(requestEvents); Wire.onReceive(receiveEvents); } void loop(){} int n = 0; void requestEvents() { Serial.println(F("---> recieved request")); Serial.print(F("sending value : ")); Serial.println(n); Wire.write(n); } void receiveEvents(int numBytes) { Serial.println(F("---> recieved events")); n = Wire.read(); Serial.print(numBytes); Serial.println(F("bytes recieved")); Serial.print(F("recieved value : ")); Serial.println(n); }
Resultado
O Raspberry Pi envia o comando “slave” ao Arduino e recebe um quadro de dados proveniente do Arduino.

O Arduino recebe o comando “slave” e envia dois valores atualizados assim que recebe um comando do Raspberry Pi

Aplicação
- Reconhecimento visual com Raspberry Pi; controle de servomotores e sensores com Arduino
Fontes
Retrouvez nos tutoriels et d’autres exemples dans notre générateur automatique de code
La Programmerie