RPi / Arduino I2C-一段时间后失去连接(C ++)

时间:2018-09-26 12:39:47

标签: c++ arduino raspberry-pi i2c

由于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字节),但我删除了那些不重要的消息。

问候。

0 个答案:

没有答案