1

The code below sends data to Raspberry Pi every 20 millisecond. The code works fine but sometimes python throws an error. Why this is happening? Should I give more time between writeData?

Error:

> 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 code:

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 code:

#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;    
  }
5
  • Slowing it down a bit would be the first thing I'd try, e.g., crank it up to .5sec. If that fixes it you'll know it's a timing issue. You could also speed up the Arduino side by temporarily removing the Serial.println because it could just be the Arduino can't keep up since it's serial-ing while the host is still blasting I2C data. (Only do one change at a time, obviously). May 18 '21 at 14:27
  • Changing sleep time to 0.5Sec works but I want to send data every 20ms. Is there any way to do this? What causes the problem exactly? Is Arduino reading data slower than expected?
    – Shyam3089
    May 18 '21 at 15:02
  • Serial output is relatively slow. May 18 '21 at 16:14
  • Got it. Thanks.
    – Shyam3089
    May 18 '21 at 16:19
  • Are you using an active level translator for the Arduino and the Pi. This I would expect with a passive (resistor) level translator. A simple trick is to transmit with 2 stop bits and receive with 1. This gives you a free bit time for each character.
    – Gil
    May 20 '21 at 5:15
1

A RPI uses 3.3v logic while an arduino uses 5v logic you can use a logic converter but by now it's probly to late and maybe your arduino or RPI is broken (Sorry!)

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.