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

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

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

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

Это мой код Arduino:

Я регистрирую onReceive и onRequestEvent.OnReceive Callback определит, какие данные следует отправлять обратно в малину.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

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

Приветствия Дитера

1 Ответ

0 голосов
/ 10 октября 2018

Я решил это !!

Я получил подсказку из этого поста: 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)
...