Grove I2C motor driver and ultrasonic ranger

grovepi
#1

Hello!

I have rasberry pi 3B+ and grovepi+. I attached a grove i2c motor driver v. 1.3 to my system. If the motor driver is attached, the ultrasonic ranger freezes after every 10th or 20th read.
I tryed various combinations, and there are the same problem with other sensors as well, but this is the main issue.
The same program runs perfectly, if I disconnect the i2c port of the motor driver. If I press the reset button on the motor driver the program starts again well for 10-20 read, then it stops again. It is annoying, because a continuous work is impossible.
Can you, please, help me?
Istvan

This is the failure message I got:

Traceback (most recent call last):
  File "/home/pi/Desktop/GrovePi/Software/Python/grovepi.py", line 199, in read_i2c_block
    data = i2c.read_list(reg = None, len = no_bytes)
  File "/usr/local/lib/python3.5/dist-packages/Dexter_AutoDetection_and_I2C_Mutex-0.0.0-py3.5.egg/di_i2c.py", line 373, in read_list
    return self.transfer(outArr, len)
  File "/usr/local/lib/python3.5/dist-packages/Dexter_AutoDetection_and_I2C_Mutex-0.0.0-py3.5.egg/di_i2c.py", line 185, in transfer
    return_val = self.i2c_bus.transfer(self.address, outArr, inBytes)
  File "/usr/local/lib/python3.5/dist-packages/Dexter_AutoDetection_and_I2C_Mutex-0.0.0-py3.5.egg/di_i2c.py", line 475, in transfer
    raise IOError("[Errno 5] Input/output error")
OSError: [Errno 5] Input/output error

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/pi/Desktop/GrovePi/Software/Python/grove_ultrasonic.py", line 45, in <module>
    print(grovepi.ultrasonicRead(ultrasonic_ranger))
  File "/home/pi/Desktop/GrovePi/Software/Python/grovepi.py", line 269, in ultrasonicRead
    number = read_identified_i2c_block(uRead_cmd, no_bytes = 2)
  File "/home/pi/Desktop/GrovePi/Software/Python/grovepi.py", line 212, in read_identified_i2c_block
    data = read_i2c_block(no_bytes + 1)
  File "/home/pi/Desktop/GrovePi/Software/Python/grovepi.py", line 205, in read_i2c_block
    time.sleep(0.003)
KeyboardInterrupt
>>>
0 Likes

#2

Hi @vidist,

Can you confirm me you are using this Grove I2C motor driver?

And also if you’re using this library for it?

I’m asking you this so I can be sure what needs to be tested in case I have to do that.

Next, can you show me your code for both things, for the ultrasonic sensor and the I2C motor driver? My gut tells me you are running both of them in separate threads/processes and depending on how rare each call to the resources is, you might get this delayed exception that only occurs after 10-20 reads.

Just to make it clear, the grovepi library is not thread-safe so you’re going to have to employ locks/mutexes around the resource calls to prevent getting into a blocked state.

Check this thread to find more about this:

And you can also check this part of the GrovePi’s documentation that says the library is not thread-safe.
https://dexterind.github.io/GrovePi/api/gpio/

Thank you!

0 Likes

#3

Hello Robert Lucian,

Thank you for your answer.
My motor drive is Grove I2C Motor Driver v1.3, totally similar to the one at the link, just a newer release, and I used the linked library.
I also used Grove-LCD_RGB_Backlight v4.0 and grove button v1.2. in my system, here is my code:

from grove_rgb_lcd import*
import grovepi
from grovepi import *
import time
import grove_i2c_motor_driver

button = 3
ultrasonic_ranger = 4

grovepi.pinMode(button,"INPUT")
setRGB(80,100,20)


while True:
    try:
              
        buttonvalue = grovepi.digitalRead(button)
            
        if buttonvalue == 0:
            setText("Press button to start!")
            time.sleep(2)
        else:
            setText("Starting robot..")
            time.sleep(2)
                
            while True:
                try:
                    m = grove_i2c_motor_driver.motor_driver(0x0f)
                    distant = ultrasonicRead(ultrasonic_ranger)
                    time.sleep(0.1)
                                                
                    if distant >= 20:
                        setText_norefresh("Running forwards")
                        m.MotorSpeedSetAB(50,50)
                        m.MotorDirectionSet(0b1010)
                        
                    else:
                        m.MotorSpeedSetAB(0,0)
                        setText("Obstacle        Running back")
                        time.sleep(0.5)
                        m.MotorSpeedSetAB(50,50)
                        m.MotorDirectionSet(0b0101)
                        time.sleep(1)
                        m.MotorSpeedSetAB(0,0)
                        time.sleep(0.01)
                        m.MotorSpeedSetAB(50,50)
                        setText("Turning...")
                        m.MotorDirectionSet(0b0110)
                        time.sleep(0.3)
                        m.MotorSpeedSetAB(0,0)    
                    
                except (IOError, TypeError) as e:
                    print(str(e))
                    setText("IOError/TypError")
                    m.MotorSpeedSetAB(0,0)
                    time.sleep(1)
                    break
                except KeyboardInterrupt as e:
                    print(str(e))
                    setText("Keyboard stop")
                    m.MotorSpeedSetAB(0,0)
                    time.sleep(1)
                    setText("")
                    break
    except (IOError, TypeError) as e:
        print(str(e))
        setText("IOError/TypError")
        m.MotorSpeedSetAB(0,0)
        time.sleep(1)
        break        
    except KeyboardInterrupt as e:
        print(str(e))
        setText("Keyboard stop")
        m.MotorSpeedSetAB(0,0)
        time.sleep(1)
        setText("")
        break

m.MotorSpeedSetAB(0,0)
setText("");

Thanks once more if you can analyse it,
best regards:

Istvan

0 Likes

#4

Okay. So you’re not doing anything in parallel, which is good. I’m gonna have this tested and get back to you with an answer.

Thank you!

0 Likes

#5

I have tested it and I don’t see the same problem here.
I don’t see any conflicts in the address space of the I2C: the GrovePi is on address 0x04, the motor driver on address 0x0f and the RGB LCD on different addresses too.

And these 2 devices, the GrovePi (and by extension the Ultrasonic Sensor), and the motor driver are very independent devices, so they shouldn’t even interfere. The only issue could only come if multiple agents try to access a device on the I2C line at the same time. Have you ruled this out? Are you somehow running multiple scripts at the same time? This might explain why you showed me the error you get when you run grove_ultrasonic.py.

Thank you!

0 Likes

#6

Hello!

Thank you for testing it.
You I right I have multiply libraries installed, which could cause multiplied script runing. I would never realise…I try to delete the supplementary one, and I refer about the results.
Best regards

0 Likes

#7

Hello again!

I tryed several things. No multiplied files anymore, but the problem stays.
Appling the grove_ultrasonic.py (not even my code), even if I plug out everithing from the Grovepi (apart ultrasonc ranger), even using another digital port (D3), another cable, etc. the ultrasonic ranger stops after a while, and when it stops it freezes the python frame too, No Ctrl+C no interruption form menu is working. You have to kill running by closing the window.
I have a bad feeling, that the sensor is might be slightly damaged.
The other problem:
I also tryed to change the ultrasonic ranger (which was unplugged) with a Grove line finder v 1.1. It distinguishes surface and depth so I can run the robot on a platform, and instead of turning at the walls it turns at the edges (basically the same code is applyed).
Same problem with the motor again: sometimes the motor driver freezes and it is running wild, can be swithed off by reset button only - it is less often as it was with the ultrasonic ranger, but after 2-3 minutes of runnning it happens:

My “new” failure code:

Traceback (most recent call last):
  File "/home/pi/Desktop/Programok/black mark robot 1.py", line 40, in <module>
    m.MotorSpeedSetAB(50,50)
  File "/usr/local/lib/python3.5/dist-packages/grovepi-1.0.4-py3.5.egg/grove_i2c_motor_driver.py", line 57, in MotorSpeedSetAB
    bus.write_i2c_block_data(self.I2CMotorDriverAdd, self.MotorSpeedSet, [MotorSpeedA,MotorSpeedB])
  File "/usr/local/lib/python3.5/dist-packages/smbus_cffi-0.5.1-py3.5-linux-armv7l.egg/smbus/util.py", line 59, in validator
    return fn(*args, **kwdefaults)
  File "/usr/local/lib/python3.5/dist-packages/smbus_cffi-0.5.1-py3.5-linux-armv7l.egg/smbus/smbus.py", line 275, in write_i2c_block_data
    raise IOError(ffi.errno)
OSError: 121

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/pi/Desktop/Programok/black mark robot 1.py", line 58, in <module>
    m.MotorSpeedSetAB(0,0)
  File "/usr/local/lib/python3.5/dist-packages/grovepi-1.0.4-py3.5.egg/grove_i2c_motor_driver.py", line 57, in MotorSpeedSetAB
    bus.write_i2c_block_data(self.I2CMotorDriverAdd, self.MotorSpeedSet, [MotorSpeedA,MotorSpeedB])
  File "/usr/local/lib/python3.5/dist-packages/smbus_cffi-0.5.1-py3.5-linux-armv7l.egg/smbus/util.py", line 59, in validator
    return fn(*args, **kwdefaults)
  File "/usr/local/lib/python3.5/dist-packages/smbus_cffi-0.5.1-py3.5-linux-armv7l.egg/smbus/smbus.py", line 275, in write_i2c_block_data
    raise IOError(ffi.errno)
OSError: 121

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/pi/Desktop/Programok/black mark robot 1.py", line 73, in <module>
    m.MotorSpeedSetAB(0,0)
  File "/usr/local/lib/python3.5/dist-packages/grovepi-1.0.4-py3.5.egg/grove_i2c_motor_driver.py", line 57, in MotorSpeedSetAB
    bus.write_i2c_block_data(self.I2CMotorDriverAdd, self.MotorSpeedSet, [MotorSpeedA,MotorSpeedB])
  File "/usr/local/lib/python3.5/dist-packages/smbus_cffi-0.5.1-py3.5-linux-armv7l.egg/smbus/util.py", line 59, in validator
    return fn(*args, **kwdefaults)
  File "/usr/local/lib/python3.5/dist-packages/smbus_cffi-0.5.1-py3.5-linux-armv7l.egg/smbus/smbus.py", line 275, in write_i2c_block_data
    raise IOError(ffi.errno)
OSError: 121

So not too much result up to now…

Best regards:

Istvan

0 Likes

#8

Hello!

I have made further tests, in all cases only the mentioned items were connected:
Motor driver + button or moisture sensor causes the known problem, after a few minutes (longer time).
Motor driver running alone - works fine, no freeze.
Surprisingly motor driver + grove servo!!! on port rpser works fine.
Motor driver + relay. Well the relay works only if the motor driver is unplugged.
Do you have any idea?

Best regards:
I.

0 Likes

#9

Hi @vidist,

I might have an idea: leave the motor driver connected to the board, but don’t try actuating anything (like issuing commands to the motor driver) and see if the problem persists.

Apart from trying that out, can you also try changing the bus for the GrovePi? You can do that by calling the following function right after the grovepi module gets imported:

import grovepi
grovepi.set_bus("RPI_1")

Can you try that?

0 Likes

#10

Hello Robert!

For the first thing:
I made a few test. Between the tests I pressed the reset button of the motor driver:

Test 1 – i2c motor driver & ultrasonic ranger attached – script: grove_ultrasonic.py (so motor does not run): ultrasonic ranger freezes within 1 minute – after pressing reset the script runs again (I tried a few times)

Test 2 – i2c motor driver & line finder attached – script: grove_line_finder.py (motor does not run again), line finder freezes within 2 minutes – after pressing reset the script continues running again

Test 3 – i2c motor driver & relay attached – script: grove_relay.py (motor does not run), relay does not switch after 2 minute – after pressing reset the script continues running again, relay works again

Test 4 – i2c motor driver & ledbar attached – script: grove_ledbar.py (motor does not run), ledbar freezes soon – after pressing reset the script continues running again but very soon it freezes again, reset had to be pressed 5-6times till the script was finished

I will try the other thing soon.

Best regards:
I.

0 Likes

#11

Hello Robert!

Success!!!
Your second idea seem to work!
Continuous runnig for about ten minutes.
Thanks a lot!
I really would like to learn from the case. I am wondering if I still can bother you with the question what was wrong?

Best regards:

Istvan

0 Likes