使用 Arduino Mega 作为 I2C Slave 和 RPi3
Use Arduino Mega as I2C Slave with RPi3
我正在尝试使用 Arduino Mega 2560 扩展 I/Os 具有 PWM 和模拟输入的 RPi3。事实上,我根本没有使用 RPi3 GPIO 引脚,因为很难为输入 3.3 和 5 V 维持两个电压。
基本上,我正在尝试:
- 从 RPi3 发送一个数组来设置 Arduino 中的输出并且
- 从 Arduino 向 RPi3 发送一个数组,给出输入的状态。
数组中的某些值可能高达 10000。
我已经能够在没有高于 255 的值的情况下达到上面的数字 1。
Python代码
bus = smbus.SMBus(1)
address = 0x06
def writeNumber(value):
bus.write_i2c_block_data(address, 1, [5,0,1,255, 6]) #dummy array as of now. This can go upto 50 values
return -1
def readNumber():
# number = bus.read_byte(address)
data_received_from_Arduino = bus.read_byte(address)
for i in data_received_from_Arduino:
print(i)
return number
while i1:
writeNumber(1)
readNumber()
Arduino 代码
#include <Wire.h>
#define SLAVE_ADDRESS 0x06
int number[50] = {0};
int inputs[100] = {0};
int state = 0;
int p=0;
void setup() {
pinMode(13, OUTPUT);
Serial.begin(9600); // start serial for output
// initialize i2c as slave
Wire.begin(SLAVE_ADDRESS);
// define callbacks for i2c communication
Wire.onReceive(receiveData);
Wire.onRequest(sendData);
Serial.println('Ready!');
}
void loop() {
//delay(1);
}
// callback for received data
void receiveData(int byteCount){
Serial.println(byteCount);
int p=0;
while(Wire.available()) {
number[p] = Wire.read();
p++;
}
for(int k=0; k < 5; k++) {
Serial.print( k);
Serial.print( ":");
Serial.println(number[k]);
}
}
// callback for sending data
void sendData(){
for(int k=0; k < 56;k++) {
inputs[k] = digitalRead(k);
Serial.print( k ); Serial.print(" : "); Serial.print(inputs[k]);
Serial.println(digitalRead(k));
}
Wire.write( inputs,56);
}
有人可以指导吗?有谁知道实现上述目标的示例 Git。我可以为我的应用程序构建它,即使示例是针对小型阵列的。
与 raspberry pi 和 arduino 通信的最简单方法是使用串行协议。我一直用这个。
python 中有一个用于串行通信的模块 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 读取了四个 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
我正在尝试使用 Arduino Mega 2560 扩展 I/Os 具有 PWM 和模拟输入的 RPi3。事实上,我根本没有使用 RPi3 GPIO 引脚,因为很难为输入 3.3 和 5 V 维持两个电压。
基本上,我正在尝试:
- 从 RPi3 发送一个数组来设置 Arduino 中的输出并且
- 从 Arduino 向 RPi3 发送一个数组,给出输入的状态。
数组中的某些值可能高达 10000。
我已经能够在没有高于 255 的值的情况下达到上面的数字 1。
Python代码
bus = smbus.SMBus(1)
address = 0x06
def writeNumber(value):
bus.write_i2c_block_data(address, 1, [5,0,1,255, 6]) #dummy array as of now. This can go upto 50 values
return -1
def readNumber():
# number = bus.read_byte(address)
data_received_from_Arduino = bus.read_byte(address)
for i in data_received_from_Arduino:
print(i)
return number
while i1:
writeNumber(1)
readNumber()
Arduino 代码
#include <Wire.h>
#define SLAVE_ADDRESS 0x06
int number[50] = {0};
int inputs[100] = {0};
int state = 0;
int p=0;
void setup() {
pinMode(13, OUTPUT);
Serial.begin(9600); // start serial for output
// initialize i2c as slave
Wire.begin(SLAVE_ADDRESS);
// define callbacks for i2c communication
Wire.onReceive(receiveData);
Wire.onRequest(sendData);
Serial.println('Ready!');
}
void loop() {
//delay(1);
}
// callback for received data
void receiveData(int byteCount){
Serial.println(byteCount);
int p=0;
while(Wire.available()) {
number[p] = Wire.read();
p++;
}
for(int k=0; k < 5; k++) {
Serial.print( k);
Serial.print( ":");
Serial.println(number[k]);
}
}
// callback for sending data
void sendData(){
for(int k=0; k < 56;k++) {
inputs[k] = digitalRead(k);
Serial.print( k ); Serial.print(" : "); Serial.print(inputs[k]);
Serial.println(digitalRead(k));
}
Wire.write( inputs,56);
}
有人可以指导吗?有谁知道实现上述目标的示例 Git。我可以为我的应用程序构建它,即使示例是针对小型阵列的。
与 raspberry pi 和 arduino 通信的最简单方法是使用串行协议。我一直用这个。
python 中有一个用于串行通信的模块 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 读取了四个 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