DRV8835 for Rpi3B+

Hi Folks,
tried your DRV8835 with example code on a Rpi3B+
Worked a charm… once I re-flowed my dry solder joints :wink:

DRV8835-PiCart

2 Likes

Hello.

I am glad to hear that your motor driver is working well!

You put your post in a support category; are you having any trouble with the board, or do you have a question about it? If not, we can move it to the “Share your projects” section.

- Patrick

1 Like

hi @PatrickM thanks for the reply. Twaz my first time using your forum. Apologies for the misplaced post. If you would move it to “share your projects” I would be grateful
thanks
Alan

1 Like

Hi there,

I have tried using parts of the example.py code available on Python library

I have combined it with Object Following Robot code to make the following below. In short the Object following Robot code can detect a yellow ball using OpenCV. The Pololu example.py can run motors as per video above.

Can anyone advise on why the Motor control calls are not working with the ball detect routines in the python3 code below?

from __future__ import print_function
import cv2
import numpy as np
import imutils
from imutils.video import WebcamVideoStream
from _thread import *
import time
from pololu_drv8835_rpi import motors, MAX_SPEED

# Set up sequences of motor speeds.
test_forward_speeds = list(range(0, MAX_SPEED, 1)) + \
  [MAX_SPEED] * 200 + list(range(MAX_SPEED, 0, -1)) + [0]  

test_reverse_speeds = list(range(0, -MAX_SPEED, -1)) + \
  [-MAX_SPEED] * 200 + list(range(-MAX_SPEED, 0, 1)) + [0]  


def stopMotor():
    # Stop the motors, even if there is an exception
    # or the user presses Ctrl+C to kill the process.
    motors.setSpeeds(0, 0)

def right():
    print("right")
    for s in test_forward_speeds:
        motors.motor1.setSpeed(s)
        time.sleep(0.005)
    for s in test_reverse_speeds:
        motors.motor2.setSpeed(s)
        time.sleep(0.005)

def left():
    print("left")
    for s in test_reverse_speeds:
        motors.motor1.setSpeed(s)
        time.sleep(0.005)
    for s in test_forward_speeds:
        motors.motor2.setSpeed(s)
        time.sleep(0.005)

def forward():
    print("forward")
    for s in test_forward_speeds:
        motors.motor1.setSpeed(s)
        time.sleep(0.005)
    for s in test_forward_speeds:
        motors.motor2.setSpeed(s)
        time.sleep(0.005)

def backward():
    print("reverse")
    for s in test_reverse_speeds:
        motors.motor1.setSpeed(s)
        time.sleep(0.005)
    for s in test_reverse_speeds:
        motors.motor2.setSpeed(s)
        time.sleep(0.005)

def drive():
    global cx,fw,w,h,minArea,maxArea,flag,lock
    while not threadStop:
        if flag==1 and lock:
            if cx > 3*fw/4:
                #print("Right")
                right()
                time.sleep(0.015)
            elif cx < fw/4:
                #print("Left")
                left()
                time.sleep(0.015)
            elif w*h > maxArea:
                #print("Back")
                backward()
                time.sleep(0.025)
            elif w*h < minArea:
                #print("Forward")
                forward()
                time.sleep(0.025)
            
            stopMotor()
            time.sleep(0.0125)

        else:
            #print("Stop")
            stopMotor()
    GPIO.cleanup()
            


if __name__ == "__main__":

    global cx,w,h,flag,minArea,maxArea,lock,fw,threadStop
    threadStop = False #To terminate the thread which drives the robot whenever the user quits

    lock = False #To lock the object

    flag = 0 #Its 1 whenever the object is detected

    #Range of the colors to detect an Object in this range
    lower_thresh = np.array([95, 122, 122])
    high_thresh = np.array([42, 255, 255])
    
    #To stream the video from the webcam
    device = WebcamVideoStream(src=0).start()
  
    first = True
    start_new_thread(drive,()) #Thread to drive the robot
    
    while True:
        frame = device.read() #It reads frames from the video
        #_, frame = device.read()
        #frame = cv2.flip(frame,1)

        #Pre-processing of the frame to detect the object
        blurred = cv2.GaussianBlur(frame, (11, 11), 0)
        hsv = cv2.cvtColor(blurred, cv2.COLOR_BGR2HSV)

        mask = cv2.inRange(hsv, lower_thresh, high_thresh)
        mask = cv2.erode(mask, None, iterations=2)
        mask = cv2.dilate(mask, None, iterations=2)
    
        cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
        cnts = imutils.grab_contours(cnts)

        fh,fw,_ = frame.shape
        cv2.rectangle(frame,(int(fw/5),0),(int(4*fw/5),fh),(0,0,255),3)
        cv2.rectangle(frame,(int(fw/4),0),(int(3*fw/4),fh),(0,255,255),3)

        #It draws rectangle around the object and finds its centre co-ordinates
        if len(cnts)>0:
            flag = 1
            c = max(cnts, key=cv2.contourArea)
            x,y,w,h = cv2.boundingRect(c)
            cv2.rectangle(frame,(x,y),(x+w,y+h),(0,0,255),2)
            M = cv2.moments(c)
            cx = int(M['m10']/M['m00'])
            cy = int(M['m01']/M['m00'])
            cv2.circle(frame,(cx,cy),3,(0,255,255),-1)

            if first:
                print("Area = ",w*h)
                #exit(0)
                maxArea = 3*w*h/2
                minArea = w*h/2

        else:
            flag = 0

        

        cv2.imshow("Frame",frame)
        # cv2.imshow("Mask", mask)

        k = cv2.waitKey(1) & 0xFF

        if k == ord('q'):
            threadStop = True
            break
        elif k == ord('l') and flag==1:
            print("Locked")
            print("Fw = ",fw)
            print("Fh = ",fh)
            first = False
            lock = True

device.release()
device.stop()
cv2.destroyAllWindows()

PS, latest errors are as follows when both code bases are combined

pi@picart53:~/Object-Following-Robot $ sudo python3 RobotCode3Yel.py
Traceback (most recent call last):
  File "RobotCode3Yel.py", line 2, in <module>
    import cv2
  File "/usr/local/lib/python3.7/dist-packages/cv2/__init__.py", line 3, in <module>
    from .cv2 import *
ImportError: /usr/local/lib/python3.7/dist-packages/cv2/cv2.cpython-37m-arm-linux-gnueabihf.so: undefined symbol: __atomic_fetch_add_8
pi@picart53:~/Object-Following-Robot $ python3 RobotCode3Yel.py
pinMode PWM: Unable to do this when using /dev/gpiomem. Try sudo?

Hi, Alan.

It seems like it’s failing to import the cv2 module at all. Are you able to run the unmodified “Object Following Robot” code by itself without any errors (or any other programs that use OpenCV)? What about if you use sudo to run it?

Kevin

Hi Kevin,
sorry for not getting back. I found the message below unsent. I have since had to spend my free time fixing up an old compaq laptop after it got a bad case of black screen then a bad case of bluescreen. All is well now and it is time to get back up on the OpenCV cart again :wink:

“Hi Kevin,
the CV module worked fine with the original “object following robot” code.
I am able to get an image and yellow ball detection working ok”

When running that program worked for you, was it also run with Python 3 (python3, as opposed to just python, which is usually Python 2) and does it still work when run with sudo? If that’s the case, I’m not sure why your new program wouldn’t also work. However, I searched for the error message you got and found some info about it that looks relevant, such as this Stack Overflow question and its answers. It seems like it might have to do with a version mismatch or other OpenCV installation issue.

Kevin