韌體 | I2C通訊:樹莓派與Arduino---使用Python

韌體 | I2C通訊:樹莓派與Arduino---使用Python


樹莓派環境

作業系統:Raspbian
硬體:樹莓派3B

Arduino環境

硬體:Mega 2560開發板


步驟

使用Python中的I2C模組操作樹莓派當作Master(主機)與Arduino作為Slave(從機)進行通訊。

1.前期作業

樹莓派必須開啟I2C裝置,若不清楚如何開啟與設置,可以參考前文<Raspberry Pi | 樹莓派I2C設定>。

2.注意事項

樹莓派(3.3v)與Arduino(5v)的電位水平(邏輯准位)不一樣,不過經參考資料得知,當樹莓派作為Master,Arduino作為Slave是能夠直接通訊的,
可以工作的原因為Arduino開發板沒有上拉電阻,而樹莓派上有1.8K歐姆的上拉電阻,恰好能夠進行通訊,若是要在I2C總線上加入新的裝置,記得要拔下上拉電阻。

3.硬體設置

樹莓派與Arduino進行I2C線路連接,請見下表。

樹莓派腳位Arduino Mega2560
SDASDA
SCLSCL
GNDGND

4.樹莓派端Python程式

1.Python相關程式設定並執行
2.測試Python程式

Python程式是由參考資料中的程式碼加以修改而來,原先的程式碼適用於Python2.7,黑修斯將之改為Python3,詳細程式碼如下:
import smbus
import time
# 設定樹莓派I2C的總線
bus = smbus.SMBus(1)
# 設定Arduino 的I2C位置
address = 0x04
# 傳送訊息
def writeNumber(value):
bus.write_byte(address, value)
return -1
# 讀取訊息
def readNumber():
number = bus.read_byte(address)
return number
while True:
# 指定var接受使用者輸入的指令
var = int(input('Enter 1 – 9: '))
#寫入使用的輸入的指令Var
writeNumber(var)
print ('RPI: Hi Arduino, I sent you ', var)
# 等待1秒
time.sleep(1)
#接收Arduino回傳的訊息
number = readNumber()
print ('Arduino: Hey RPI, I received a digit ', number)


5.Arduino端C/C++程式

1.C/C++相關程式設定並執行
2.測試C/C++程式

Arduino 的程式碼,同樣是由參考資料中的程式碼加以修改而來,主要的程式碼作用為接收I2C訊號與回傳接收過的訊號,程式碼如下:
#include <Wire.h>
#define SLAVE_ADDRESS 0x04 // 設定Arduino開發板I2C的位址
int number = 0;
int state = 0;
void setup() {
pinMode(13, OUTPUT); // 設定pin13為輸出模式
Serial.begin(9600); // Serial通訊埠通訊設為9600速率
Wire.begin(SLAVE_ADDRESS); // 初始化Arduino的I2C位址
Wire.onReceive(receiveData); //I2C訊號接收時,啟用函式
Wire.onRequest(sendData); //主機要求讀取時,啟用函式
Serial.println("Ready!");
}
void loop() {
delay(100);
}
// callback for received data
void receiveData(int byteCount){
while(Wire.available()) { //當I2C的buffer中有資料時進入迴圈
number = Wire.read(); //指定nubmer 等於讀取的訊息
Serial.print("data received: ");
Serial.println(number);
if (number == 1){
if (state == 0){
digitalWrite(13, HIGH); // 致使 LED on
state = 1;
}else{
digitalWrite(13, LOW); // 致使 LED off
state = 0;
}
}
}
}
// callback for sending data
void sendData(){
Wire.write(number);
}
view raw I2C_Arduino.ino hosted with ❤ by GitHub

6.整合性測試

1.透過樹莓派Master(主機)經由I2C通訊發送指令給Arduino開發板slave(從機),並透過監測視窗觀看結果:
將樹莓派與Arduino開發板的程式都搞定後,便可以進行整合性測試,利用樹莓派的遠端桌面操作Python執行程式碼,而Arduino與電腦連接後開啟序列埠通訊視窗監測訊號,最終結果如下圖。


2.透過樹莓派Master(主機)發送指令控制Arduino開發板slave(從機)的LED開關:
這邊將樹莓派的5V電源供應給Arduinod開發板,直接透過樹莓派操作指令,輸入1可進行Arduinod開發板上的LED開關,如下圖。


當樹莓派輸入1,Arduino開發板的LED會亮起;再輸入一次1,Arduino開發板的LED會熄滅。



參考資料

RASPBERRY PI AND ARDUINO CONNECTED USING I2C


本篇程式放置的GitHub連結

轉貼本文時,需註明來自黑修斯的隨手札記原創作者 hughes chen(黑修斯),及附上原文連結,同時 禁止修改,禁止商業使用 。

張貼留言

2 留言

  1. 你好 在傳訊完成後可以將傳訊功能暫時停止,等待arduino將其他動作處理完後,再將傳訊功能開啟嗎

    回覆刪除
    回覆
    1. 這個問題有點難回答....
      1.理論上,arduino上面是有個暫存空間,可以讓你繼續接受訊號先不處理(但是,如果暫時存的資料超過記憶體就會覆蓋或著不寫,看硬體的設定)
      2.你可以想像line的傳訊息,你沒空的時候,他是先將訊息儲存到你的手機,等你有空再看
      ---------------
      另外,基本上通訊是可以暫停,沒有問題。

      刪除

不一定能即時回覆問題,有時間會盡量答覆。