由于GPIO电压不同,我使用电平转换器将Raspberry Pi 3 B型连接到Arduino Mega 2560槽式I2C。
Raspberry Pi --- 3.3V ---电平转换器--- 5V --- Arduino Mega
在我的代码中,我让Arduino读取电位计的模拟值并将其以2个字节的形式发送到Raspberry Pi(最大值= 1023)。 Raspberry Pi接收2字节并将它们组合成16位,然后将其除以4,以达到最大值255。
Raspberry Pi将这个值发送回Arduino,后者将LED的PWM值设置为变暗。
代码工作正常,但是即使我在Raspberry Pi的主循环上有2秒的延迟。只要我删除它,代码在冻结I2C总线之前仅运行1-2秒。如果我在I2C停止工作后在终端上运行i2cdetect,则在删除I2C连接并重新构建它之前,我将无法再看到其地址。
代码在不丢失I2C连接5毫秒的情况下正常工作的休眠值。
主密码(RPi):
#include <unistd.h>
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <linux/i2c-dev.h>
using namespace std;
int file_i2c;
int length_rcv = 30;
int length_snd = 9;
unsigned char buffer_rcv[30] = {0};
unsigned char buffer_snd[9] = {0};
uint8_t addr = 0x06;
using namespace std;
uint16_t ang;
int main(void)
{
char *filename = (char*)"/dev/i2c-1";
if((file_i2c = open(filename, O_RDWR))< 0 ){
cout << "Failed to open the i2c bus" << endl;
return 0;
}
while(1){
//Acquires buss access
if (ioctl(file_i2c, I2C_SLAVE, addr) < 0){
cout << "Failed to acquire bus access and/or talk to slave" << endl;
}
//Reads buffer
if (read(file_i2c, buffer_rcv, length_rcv) != length_rcv){
cout <<"Failed to read from the i2c bus" << endl;
} else {
cout << "Data read:" << buffer_rcv[0] << endl;
}
//Combine Bytes in 16 Bits and divide by 4
ang = ((uint16_t)buffer_rcv[0] << 8 | (uint16_t)msg_rcv[1];
ang = ang/4;
cout << ang << endl;
buffer_snd[0] = ang;
//Writes buffer
if (write(file_i2c, buffer_snd, length_snd) != length_snd){
cout << "Failed to write to the i2c bus " << endl;
}
}
usleep(50000);
return 0;
}
从站代码(Arduino):
#include <Wire.h>
//Input Pins
int angPin = 8;
//Output Pins
int pwmVLPin = 10;
//Input Values
volatile int ang;
//Byte Values
volatile byte ang_H, ang_L;
//Output Values
volatile byte pwmVL;
//Buffer for receiving I2C
volatile byte msg_rcv[9];
//Counter
volatile int i = 0;
void setup() {
//I2C
Wire.begin(6);
Wire.onReceive(receiveData);
Wire.onRequest(sendData);
//Serial.begin(9600);
//Input Pins
pinMode(angPin, INPUT);
//Output Pins
pinMode(pwmVLPin, OUTPUT);
}
void loop() {
//Read Inputs
ang = analogRead(angPin);
//Write Outputs
analogWrite(pwmVLPin, pwmVL);
}
void receiveData(int HowMany) {
//Read bytes
while (1 <= Wire.available()) {
byte c = Wire.read();
msg_rcv[i] = c;
i++;
}
//Assings each byte of the incoming message to each output variable
pwmVL = msg_rcv[0];
//Serial.println(pwmVL);
i = 0;
}
void sendData() {
//Split the values in bytes
ang_H = (ang >> 8) & 0xFF;
ang_L = ang & 0xFF;
//Serial.println(ang);
//Save Inputs into the message
byte msg_snd[30] = {ang_H, ang_L, ...};
//Send the message
Wire.write(msg_snd,30);
}
有人知道如何解决吗?它应该能够进行通信,而不会在main()上造成很大的延迟。
PS:要发送的消息通常更大(30字节),但我删除了那些不重要的消息。
问候。