Получение IOError: [Errno 121] Ошибка удаленного ввода-вывода с smbus на python (малина) при попытке получить данные через I2C от Arduino

Я сталкиваюсь с проблемами, что pyhton бросает меня на мой raspberry pi 3, иногда это IOError во время запуска скрипта, который запрашивает данные от Arduino через I2C.

Электрическое соединение идеальное, так что это не проблема. Кроме того, я также не получаю никаких ошибок при использовании i2cget -y 1 0x04

Только скрипты python иногда отстой, и я не знаю почему.

Это мой код Arduino:

Я регистрирую onReceive и onRequestEvent. onReceive Callback определит, какие данные следует отправить обратно в raspberry. onRequest Callback выполняет ответ.

    #include <CommonFunction.h>
#include <Wire.h>

#define I2C_ADDRESS 0x4

commonFunc GetCountsEverySecond;
int g_iOnRequestActionCode = 0;
unsigned long g_lSecondsSinceStart = 0;

void setup() 
{
    Wire.begin(I2C_ADDRESS);
    Wire.onRequest(sendDataOverI2CGateway);
    Wire.onReceive(defineOnRequestAction);
}


void loop() 
{
    tickSeconds();
}

void tickSeconds()
{
    if (GetCountsEverySecond.TimeTriggerAt(1000))
    {
        g_lSecondsSinceStart++;
    }
}

void sendOperationTimeDataOverI2C()
{
    unsigned long longInt = g_lSecondsSinceStart;
    byte size = sizeof(longInt);

    byte arr[size];
    for (int i = 0; i < size; i++)
    {
        int iBitShift = 8 * (size - i - 1);
        if (iBitShift >= 8)
            arr[i] = ((longInt >> iBitShift) & 0xFF);
        else
            arr[i] = (longInt & 0xFF);
    }
    Wire.write(arr, size);
    g_bI2CSending = true;
}

void sendDataOverI2CGateway()
{
    switch(g_iOnRequestActionCode)
    {
        case 0:
            sendRainDataOverI2C();
            break;
        case 1: // send firmware version
            sendVersionDataOverI2C();
            break;
        case 2: // send operation time of arduino in seconds from start
            sendOperationTimeDataOverI2C();
            break;
        default: break;
    }
}

void defineOnRequestAction(int iBuffer) 
{
    while (Wire.available())
    {
        g_iOnRequestActionCode = Wire.read();
    }
}

Вот мой код Python. Довольно прямолинейно, но вызывает некоторую головную боль.

import smbus
import time
bus = smbus.SMBus(1)
while True:
        data = bus.read_i2c_block_data(0x04,0x02,4)
        result = 0
        for b in data:
                result = result * 256 + int(b)
        print(result)
        time.sleep(1)

После выполнения моего скрипта python я иногда получаю эту ошибку:

pi@WeatherStation:~/workspace $ sudo python readTimeOperationData.py
Traceback (most recent call last):
  File "readTimeOperationData.py", line 5, in <module>
    data = bus.read_i2c_block_data(0x04,0x02,4)
IOError: [Errno 121] Remote I/O error

Может ли кто-нибудь помочь мне решить эту проблему?

Ура, Дитер


person d s    schedule 10.10.2018    source источник


Ответы (1)


Я решил !!

Я получил подсказку из этого сообщения: https://www.raspberrypi.org/forums/viewtopic.php?t=203286

Добавив задержку после bus = smbus.SMBus (1) решил эту проблему. Вроде как-то нужна небольшая задержка, чтобы I2C успокоился.

Рабочий код протестирован 100 раз вызовом скрипта без проблем.

import smbus
import time
bus = smbus.SMBus(1)
time.sleep(1) #wait here to avoid 121 IO Error
while True:
        data = bus.read_i2c_block_data(0x04,0x02,4)
        result = 0
        for b in data:
                result = result * 256 + int(b)
        print(result)
        time.sleep(1)
person d s    schedule 10.10.2018