与raspberry pi和arduino进行通信的最简单方法是使用串行协议。我一直都在用这个。
python中有一个用于串行通信的模块 pyserial 。
pyserial
https://www.electronicwings.com/raspberry-pi/raspberry-pi-uart-communication-using-python-and-c
我一直在尝试通过I2C发送和接收从Raspberry Pi到Arduino的四个16位数字,并得到以下工作。
请注意,我不是SMBus或I2C的专家,我不知道是否有更简单的方法可以做到这一点。如果有人知道的话,我很乐意收回我的答案!
这是Raspberry Pi的代码,它只发送四个16位数字100,200,1000,10000然后再读回来。
#!/usr/bin/env python3 from smbus import SMBus from time import sleep bus = SMBus(1) address = 0x08 def split(v): """Split 16-bit value into low and high bytes""" lobyte = v & 0xff hibyte = (v >> 8) & 0xff return lobyte, hibyte def join(lo,hi): return lo | (hi << 8) def Transmit(): """Send 100, 200, 1000, 10000 on I2C""" a,b = split(100) c,d = split(200) e,f = split(1000) g,h = split(10000) bus.write_i2c_block_data(address, a,[b, c, d, e, f, g, h]) def Receive(): block = bus.read_i2c_block_data(address, 0) i = join(block[0],block[1]) j = join(block[2],block[3]) k = join(block[4],block[5]) l = join(block[6],block[7]) print("{} {} {} {}".format(i,j,k,l)) Transmit() sleep(1) Receive()
在Arduino方面,我只是从I2C中读取了4个16位数字,将它们存储在一个数组中并递增每个数字。当读取请求进入时,我发回四个递增的数字:
#include <Wire.h> const int address= 8; #define N 4 // Last four 16-bit values we received int16_t values[N]; void setup() { Serial.begin(9600); Serial.print("Starting on i2c address:"); Serial.println(address,DEC); Wire.begin(address); Wire.onReceive(receiveEvent); Wire.onRequest(requestEvent); } void loop() { delay(100); } // callback for when data are received void receiveEvent(int nBytes) { Serial.print("Received: "); Serial.println(nBytes); if(nBytes != 2 *N){ Serial.print("I was expecting 8 bytes"); return; } unsigned char *p = (unsigned char *)&values; for(int i=0;i<2*N;i++){ *p++ = Wire.read(); } // Increment all the values we received for(int i=0;i<N;i++){ values[i]++; } } // Callback for when data are read void requestEvent() { Serial.println("Data requested"); // Send back Wire.write((const uint8_t*)&values, N*2); }
当我在Raspberry Pi上运行Python代码时,我得到:
./i2c.py 101 201 1001 10001