Error de entrada / salida al usar el módulo Python SMBus, una Raspberry Pi y un Arduino

He conectado una Raspberry Pi y Rainbowduino junto con un cambiador de nivel I²C casero, e instalé el módulo Python SMBus , la Raspberry Pi puede comunicarse con el Rainbowduino, pero de vez en cuando recibo un mensaje de error de entrada / salida cuando bash el bus.write_i2c_block_data(address, signal, data) comando bus.write_i2c_block_data(address, signal, data) .

Dice:

IOError: [Errno 5] Error de entrada / salida

¿Por qué sucede y cómo soluciono o ignoro estos errores?

La larga historia corta, mucha gente está plagada de esto, encontré que un trabajo muy simple es el siguiente.

Le permitirá ignorar el error y mantener tx / rx-ing, lo que parece que llamar a i2cdetect reinicializa el bus de alguna manera en lugar de que el arduino desaparezca.

Publiqué una explicación de cómo encontré esta solución aquí (esperando la aprobación del mod en este momento) http://www.raspberrypi.org/phpBB3/viewtopic.php?f=41&t=52517

 try: bus.write_i2c_block_data(address, signal, data) except IOError: subprocess.call(['i2cdetect', '-y', '1']) flag = 1 #optional flag to signal your code to resend or something 

A pesar de que esto permite que la Pi siga transmitiendo datos erróneos, todavía se está enviando al arduino. La forma más sencilla que encontré para solucionar esto fue agregar un byte de sum de comprobación adicional al final de mis bloques de datos.

Sumé cada byte del mensaje dentro de una variable de byte que permite que el valor se transfiera, luego asigno el byte de sum de verificación al valor necesario para sumr todo el mensaje a cero.

El arduino puede entonces verificar cada transmisión entrante sumndo todos los bytes. Si el mensaje no sum cero, se ignora como una transmisión errónea.

También asigné a mis mensajes un ID de mensaje de un byte que se incrementa después de cada transmisión exitosa, eliminando la posibilidad de envíos dobles accidentales. Pero eso puede no ser realmente necesario.

Estoy creando un servidor de buzzing con una Raspberry Pi y Arduino UNO con i2c y he encontrado el mismo problema. Mi diseño es que cuando el Pi recibe una solicitud de conexión desde un socket (por algunas máquinas externas en la red), escribe ‘1’ en el Arduino y Arduino habilitará un bucle en loop () cambiando una variable global. después de la escritura Pi leerá continuamente el byte de Arduino para verificar el estado del botón. cuando la Pi quiere dejar de leer, envía ‘0’ para detener el bucle y restablecer todos los contadores y LED.

Lo que sucede es que Python lo hará a través de IOError aleatoriamente al escribir un byte. En el monitor Serial con Arduino noté que el último byte recibido es 1 en lugar de 0, que es lo que debería haber enviado el pi. Al mirar i2cdetect -y 1, noté que la dirección es incorrecta y probé el método de Jon, pero como mencionó el usuario3126397, los datos incorrectos se enviaron y el Arduino se detuvo. Intenté su modprobe y eso solo suprimió el mensaje de error y el Arduino todavía está en estado de parada.

Originalmente sospecho que los datos se agriaron debido a una lectura / escritura incompleta y, por lo tanto, agregué un Serial.println () para verificar el argumento byteCount en onReceive (). Sin alterar ningún otro código observé que el no. de operaciones exitosas antes de IOError aumentó mucho. Por lo tanto, intenté agregar más println () para probar la correlación y noté un aumento dramático en el fracaso. Finalmente, comenté todas las declaraciones en serie y pude usar el servidor sin fallas por un número considerable de veces (probé algo como 30 veces y aún no tengo IOError).

Sospecho, con respecto a la solución del usuario3126397 para restablecer la velocidad en baudios y mi observación sobre la relación Serial.println (), el error es causado por problemas de sincronización entre el pi y Arduino (ya que Serial es relativamente lento y causa más retraso en el progtwig). , así aumenta la posibilidad de fracaso.

Dependiendo de su RPi, puede usar bus = SMBus(0) o bus = SMBus(1) para inicializar SMBus.

Espero que esto resuelva tu problema.

Escribí esto hace 19 horas cuando pensé que tenía una solución para el problema IOError: ………………………….. ………………………………………

He estado plagado con el mismo error de Entrada / Salida cuando uso bus.write_byte hablando con un Arduino. Probé la solución i2cdetect de Jon, pero encontré que para ese momento en el código el daño ya estaba hecho, los números malos ya habían llegado al Arduino y de alguna manera lo habían desactivado.

Lo que funcionó fue reiniciar la tasa de baudios i2c, usando

  sudo modprobe -r i2c_bcm2708 sudo modprobe i2c_bcm2708 baudrate=100010 

Después de esto no hay más errores de E / S! Me interesarían mucho las teorías sobre qué podría causar este aparente desajuste en baudrate. ¡Espero que esto ayude!

………………………………………….. ………………………….

Bueno, después de probar mucho más, lo que encontré fue que la solución de la tasa de baudios hizo que la tasa de errores bajara pero no los eliminó.

Ahora parece claro que la llamada i2cdetect de Jon se aplicó justo después de que el error inicialice el RPi para que pueda continuar. Pero también tiene que lidiar con el hecho de que probablemente se enviaron datos incorrectos al Arduino y necesita detectar esto y solucionarlo, y también reinicializar Wire (y en mi caso el controlador servo), para que a pesar de que Pi haya recibido un error. , que los datos seguirán llegando y serán utilizables. Espero que esto ayude.

Recientemente me encontré con este mismo problema. Cuando deshabilité la interfaz serial de la adolescente, los errores desaparecieron por completo.

Estoy usando un RPi 2 con una versión 3.2 de teensy a través de i2c a 2,4 mhz, enviando cargas útiles de 33 bytes a una velocidad de aproximadamente 38 Kbps.