RPi / Arduino I2C - Потеря соединения через некоторое время (C ++) - PullRequest
0 голосов
/ 26 сентября 2018

У меня Raspberry Pi 3, модель B, подключенная к Arduino Mega 2560 через I2C с использованием сдвига уровня из-за различных напряжений GPIO.

Raspberry Pi --- 3.3V --- Shifter уровня -- 5V --- Arduino Mega

В моем коде Arduino считывает аналоговое значение потенциометра и отправляет его Raspberry Pi в 2 байта (максимальное значение = 1023).Raspberry Pi получает 2 байта и объединяет их в 16 бит и делит значение на 4, чтобы получить максимальное значение 255.

Raspberry Pi отправляет это значение обратно в Arduino, который устанавливаетЗначение ШИМ светодиода для его затемнения.

Код работает нормально, но только если у меня задержка 2 секунды на главном цикле Raspberry Pi.Пока я его удаляю, код работает всего 1-2 секунды, прежде чем замораживает шину I2C.Если я запускаю i2cdetect на терминале после того, как I2C перестает работать, я не могу больше видеть его адрес, пока не удалю Соединения I2C и не соберу его заново, прежде чем снова запустить Программу.

Наименьшее значение для сна, в котором работает кодбез потери I2C Соединение ist 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;
}

Slave Code (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 байт), но я удалил те, которые не важны.

поздравил.

...