Ошибка в связи I2C Между Arduino и Raspberry Pi

Приведенный ниже код отправляет данные на Raspberry Pi каждые 20 миллисекунд. Код работает нормально, но иногда python выдает ошибку. Почему это происходит? Должен ли я уделять больше времени между написанными данными?

Ошибка:

> Traceback (most recent call last):   File "rpi-I2C.py", line 33, in
> <module>
> writeData("360")   File "rpi-I2C.py", line 12, in writeData
> bus.write_i2c_block_data(address,0x00,byteValue) OSError: [Errno 121] Remote I/O error

Код Python:

import smbus
import time
# for RPI version 1, use bus = smbus.SMBus(0)
bus = smbus.SMBus(1)

# This is the address we setup in the Arduino Program
address = 0x04

#http://www.raspberry-projects.com/pi/programming-in-python/i2c-programming-in-python/using-the-i2c-interface-2
def writeData(value):
    byteValue = StringToBytes(value)    
    bus.write_i2c_block_data(address,0x00,byteValue)
    #first byte is 0=command byte.. just is.
    return -1


def StringToBytes(val):
        retVal = []
        for c in val:
                retVal.append(ord(c))
        return retVal

while True:
    print("sending test")
    writeData("left")   
    time.sleep(0.02)

    #print('Sending OPEN-00-00');
    writeData("right")
    time.sleep(0.02)

    #print('Sending WIN-12-200');
    writeData("360")
    time.sleep(0.02)

Код Arduino:

#include <Wire.h>
#define SLAVE_ADDRESS 0x04

volatile boolean receiveFlag = false;
char temp[32];
String command;

void setup() {
  Wire.begin(SLAVE_ADDRESS);
  // define callbacks for i2c communication    
  Wire.onReceive(receiveEvent);    
  Serial.begin(115200);    
  Serial.println("Ready!");    
}

void loop() {    
  if (receiveFlag == true) {    
    Serial.println(temp);    
    receiveFlag = false;    
  }    
}

void receiveEvent(int howMany) {    
  for (int i = 0; i < howMany; i++) {          
    temp[i] = Wire.read();    
    temp[i + 1] = '\0';  //add null after ea. char    
  }
    
  //RPi first byte is cmd byte so shift everything to the left 1 pos so temp contains our string    
  for (int i = 0; i < howMany; ++i)    
    temp[i] = temp[i + 1];    
    receiveFlag = true;    
  }

, 👍1

Обсуждение

Первое, что я попробую сделать, - это немного замедлить его, например, довести до 5 секунд . Если это все исправит, вы поймете, что это проблема времени. Вы также можете ускорить работу Arduino, временно удалив "Serial.println", потому что это может быть просто Arduino не может идти в ногу, так как он последовательный, пока хост все еще взрывает данные I2C. (Очевидно, делайте только одно изменение за раз)., @Dave Newton

Изменение времени сна на 0,5 секунды работает, но я хочу отправлять данные каждые 20 мс. Есть ли какой-нибудь способ сделать это? Что именно вызывает эту проблему? Arduino считывает данные медленнее, чем ожидалось?, @Shyam3089

Последовательный вывод происходит относительно медленно., @Dave Newton

Понял. Спасибо., @Shyam3089

Используете ли вы активный транслятор уровней для Arduino и Pi? Этого я и ожидал бы от пассивного (резисторного) преобразователя уровня. Простой трюк состоит в том, чтобы передавать с помощью 2 стоп-битов и принимать с помощью 1. Это дает вам немного свободного времени для каждого персонажа., @Gil


1 ответ


1

RPI использует логику 3,3 В, в то время как arduino использует логику 5 В, вы можете использовать логический преобразователь, но сейчас уже, вероятно, поздно, и, возможно, ваш arduino или RPI сломаны (извините!)

,