cloudapplepi
Posts: 17
Joined: Wed Dec 05, 2018 6:35 pm

Can't get robot motors to work (code issue?)

Wed Dec 05, 2018 7:06 pm

Hi.

I have assembled a robot tank consisting of the following parts:
  • A Raspberry PI3B+

I think everything should be connected properly, also the Raspberry Pins. The Rasberry is powered for testing the code by its standard PSU. The motor and the mtor driver are powere by a separate battery pack (6x1.5V AA). I could measure 9.5 V on the power input of the motor driver, also a small green LED (DS1) is on. Here is the Wiki for the motor driver: https://www.dfrobot.com/wiki/index.php/ ... U:_DRI0041 I access the Raspberry PI via Wifi and remote Desktop (Raspbian is installed on the Raspberry Pi). The motor driver's +5V is connected to the Raspberry PI pin 2 (+5V) and the GND pin to Raspberry PI's pin 5 (Ground).

I have tried two codes, but the motor doesn't react at all although the program works.

Code1 is a mix of two different codes that I copied and altered a bit:

Code: Select all

#!/usr/bin/python3
#Teil 1 Code

from time import sleep
# import curses and GPIO
import curses
import os #added so we can shut down OK
import time #import time module
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)

#def all_off():
    #GPIO.output(ENA, False)
    #GPIO.output(ENB, False)
    #GPIO.output(IN1, False)
    #GPIO.output(IN2, False)
    #GPIO.output(IN3, False)
    #GPIO.output(IN4, False)
    #return
    
ENA = 13
ENB = 15
IN1 = 37
IN2 = 35
IN3 = 7
IN4 = 11

GPIO.setup(ENA, GPIO.OUT)
GPIO.setup(ENB, GPIO.OUT)
GPIO.setup(IN1, GPIO.OUT)
GPIO.setup(IN2, GPIO.OUT)
GPIO.setup(IN3, GPIO.OUT)
GPIO.setup(IN4, GPIO.OUT)

#all_off()

# Get the curses window, turn off echoing of keyboard to screen, turn on
# instant (no waiting) key response, and use special values for cursor keys
screen = curses.initscr()
curses.noecho() 
curses.cbreak()
screen.keypad(True)

try:
        while True:
            char = screen.getch()
            if char == ord('q'):
                break
            if char == ord('S'): # Added for shutdown on capital S
                os.system ('sudo shutdown now') # shutdown right now!
            elif char == curses.KEY_UP:
                GPIO.output(IN1, GPIO.HIGH) #Here I tried if GPIO.HIGH and/or GPIO.LOW would do the trick
                GPIO.output(IN2, GPIO.LOW)
                GPIO.output(ENA, GPIO.HIGH)
                GPIO.output(IN3, True)
                GPIO.output(IN4, False)
                GPIO.output(ENB, True)
		print("Forward")
            elif char == curses.KEY_DOWN:
                GPIO.output(IN1, False)
                GPIO.output(IN2, True)
                GPIO.output(ENA, True)
                GPIO.output(IN3, False)
                GPIO.output(IN4, True)
                GPIO.output(ENB, True)
		print("Backwards")
            elif char == curses.KEY_RIGHT:
                GPIO.output(IN1, False)
                GPIO.output(IN2, False)
                GPIO.output(ENA, False)
                GPIO.output(IN3, True)
                GPIO.output(IN4, False)
                GPIO.output(ENB, True)
		print("Right")
            elif char == curses.KEY_LEFT:
                GPIO.output(IN1, True)
                GPIO.output(IN2, False)
                GPIO.output(ENA, True)
                GPIO.output(IN3, False)
                GPIO.output(IN4, False)
                GPIO.output(ENB, False)
		print("Left")
            elif char == ord('k'): #kill engines
                GPIO.output(IN1, False)
                GPIO.output(IN2, False)
                GPIO.output(ENA, False)
                GPIO.output(IN3, False)
                GPIO.output(IN4, False)
                GPIO.output(ENB, False)
		print("Engine off")
             
finally:
    #Close down curses properly, inc turn echo back on!
    curses.nocbreak(); screen.keypad(0); curses.echo()
    curses.endwin()
    GPIO.cleanup()
    #all_off()
When I run code 1 ("sudo python xyz.py"), it launches and it prints out correctly the outputs when I for example press KEY_UP (see in the code above), but the motor doesn't react at all. I also didn't measure any voltage on the power out connectors that lead to the motor when a key is pressed.

Code 2 is copy&pasted from a German Raspberry PI book that I have. In the book they used a L298 motor driver, but I though it should basically be the same as my motor driver.

Code 2:

Code: Select all

#!/usr/bin/python3
# Teil 1 des Codes
from time import sleep
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)



# Funktion , um alle genutzten Pins auf Low zu schalten

def all_off():
	GPIO.output (ENA, False)
	GPIO.output (ENB,False)
	GPIO.output (IN1,False)
	GPIO.output (IN2,False)
	GPIO.output (IN3,False)
	GPIO.output (IN4,False)
	return



# Den GPIO -Pins werden die Namen der L298 -Eingange zugewiesen .

ENA = 13
ENB = 15
IN1 = 37
IN2 = 35
IN3 = 7
IN4 = 11


# Alle genutzten GPIO -Pins als Ausgang deklarieren .

GPIO.setup (ENA,GPIO.OUT)
GPIO.setup (ENB,GPIO.OUT)
GPIO.setup (IN1,GPIO.OUT)
GPIO.setup (IN2,GPIO.OUT)
GPIO.setup (IN3,GPIO.OUT)
GPIO.setup (IN4,GPIO.OUT)



# Funktion "all_off" aufrufen
all_off()



try:
	while True:
		# Eingabefeld zur Motorauswahl .
		# Gross-/ Kleinschreibung beachten.
		motor = input ("Geben Sie den Motor ein: 'A' oder 'B': ")
		# Eingabefeld zur Richtungsauswahl .
		richtung = input ("Geben Sie die Drehrichtung ein: 'V' oder 'Z': ")
		# if-Schleifen zur Abfrage der vorherigen Eingabe

		if motor == "A" and richtung == "V":
			GPIO.output(ENA, True)
			GPIO.output(IN1, True)
			GPIO.output(IN2, False)
			sleep(5) # Motor dreht jeweils 5 Sekunden.
			GPIO.output(ENA, False)
			GPIO.output(IN1, False)

		if motor == "A" and richtung == "Z":
			GPIO.output(ENA, True)
			GPIO.output(IN1, False)
			GPIO.output(IN2, True)
			sleep(5)
			GPIO.output(ENA, False)
			GPIO.output(IN2, False)

		if motor == "B" and richtung == "V":
			GPIO.output(ENB, True)
			GPIO.output(IN3, True)
			GPIO.output(IN4, False)
			sleep(5)
			GPIO.output(ENB, False)
			GPIO.output(IN3, False)

		if motor == "B" and richtung == "Z":
			GPIO.output(ENB, True)
			GPIO.output(IN3, False)
			GPIO.output(IN4, True)
			sleep(5)
			GPIO.output(ENB, False)
			GPIO.output(IN4, False)

# beim Programmende durch Strg +C wird "all_off" ausgefuhrt

except KeyboardInterrupt :
	all_off()
Code 2 also asks for my input to specify the motor to use (A or B) and the direction (V= forward, Z=backwards), but the motor doesn't react either.

Does anybody have an idea what could help here? Is it my motor driver possibly broken? Has anybody else ever used this motor driver?
Is there a way to test the functionality of the motor driver?

I would really appreciate any help or hint. This is my first robot project and I'm relatively new to Raspberry Pi and Linux and only understand little Python.

pcmanbob
Posts: 5255
Joined: Fri May 31, 2013 9:28 pm
Location: Mansfield UK

Re: Can't get robot motors to work (code issue?)

Thu Dec 06, 2018 9:58 am

Hi.

The first thing you should do is post some pictures of your actual setup showing all the connection between the pi and the motor driver board , even if you think it correct it does not hurt to have it checked by someone else, many problems have been solved that way.

Also I have my doubts about using 5v for the control circuit as the pi has a 3.3v gpio which is not 5v tolerant and will be damage by connecting 5v to it.

from the wiki.
When the microcontroller operation voltage is 5V/3.3V, then please connect the reference voltage 5V/ 3.3V from the microcontroller. Or you will fail to control motors.

you could prove the motor driver board using an external 5v supply and a breadboard by just connecting the control input pins to the required voltage inputs to see if the motor board is actually working.
Remember we want information.......................no information no help
The use of crystal balls & mind reading is not supported

cloudapplepi
Posts: 17
Joined: Wed Dec 05, 2018 6:35 pm

Re: Can't get robot motors to work (code issue?)

Thu Dec 06, 2018 12:46 pm

Thanks @pcmanbob.

The 3.3 V thing as the issue. :D I just moved the wire from the Raspberry's 5V pin to a 3.3 V pin. Now it works and I can control the motors.
I actually thought about it at some point, but completely forgot about it. :D

Just noticed though that the tracks are moving to different directions. :D

Also it seems the motors shouldn't be switch from forward to backwards without some break.

Thanks again.

P.S.: I'm planning to make the robot autonomous at some point with sensors, but step by step.

pcmanbob
Posts: 5255
Joined: Fri May 31, 2013 9:28 pm
Location: Mansfield UK

Re: Can't get robot motors to work (code issue?)

Thu Dec 06, 2018 2:34 pm

cloudapplepi wrote:
Thu Dec 06, 2018 12:46 pm

Just noticed though that the tracks are moving to different directions. :D
That can be solved easily, the motor that's running the wrong , just swap the 2 wires round were the motor connects to the motor driver board.
Remember we want information.......................no information no help
The use of crystal balls & mind reading is not supported

cloudapplepi
Posts: 17
Joined: Wed Dec 05, 2018 6:35 pm

Re: Can't get robot motors to work (code issue?)

Fri Dec 07, 2018 10:34 am

pcmanbob wrote:
Thu Dec 06, 2018 2:34 pm
cloudapplepi wrote:
Thu Dec 06, 2018 12:46 pm

Just noticed though that the tracks are moving to different directions. :D
That can be solved easily, the motor that's running the wrong , just swap the 2 wires round were the motor connects to the motor driver board.
Yes, I did exactly that. :-)

Now it's driving nicely, but I try to figure out how to improve the control experience. I would like to steer the robot with my keyboard control and it should stop driving when I stop pressing the key.

Code: Select all

# Get the curses window, turn off echoing of keyboard to screen, turn on
# instant (no waiting) key response, and use special values for cursor keys
screen = curses.initscr()
curses.noecho() 
curses.cbreak()
screen.keypad(True)

try:
        while True:
            char = screen.getch()
            if char == ord('q'):
                break
            if char == ord('S'): # Added for shutdown on capital S
                os.system ('sudo shutdown now') # shutdown right now!
            elif char == curses.KEY_UP:
                GPIO.output(IN1, True)
                GPIO.output(IN2, False)
                GPIO.output(ENA, True)
                GPIO.output(IN3, True)
                GPIO.output(IN4, False)
                GPIO.output(ENB, True)
		print("Forward")
		#sleep(0.05)
		#GPIO.output(IN2, False)
		#GPIO.output(ENA, False)
		#GPIO.output(IN4, False)
		#GPIO.output(ENB, False)
Above is the code sample for controling the robot. Like this, the robot continues to drive forward until I press another key that is configured. When I remove the comment tags from the last lines, it drives for 0.05 seconds. I first thought maybe I could simulate the same as when I stop pressing a key, but it is not so good.

Is there a way to have it behave like in a videogame so that it stops moving when I stop pressing the button?
Edit: I would be good to have it slowly reduce the motor speed when I stop pressing the key instead of abruptly stopping it.

I would assume that there is a simple solution, but couldn't find aynthing yet in the internet.

Thanks.

pcmanbob
Posts: 5255
Joined: Fri May 31, 2013 9:28 pm
Location: Mansfield UK

Re: Can't get robot motors to work (code issue?)

Fri Dec 07, 2018 10:55 am

So all you need to do is check for your characters for forwards,backwards,left & right and if non of them are found then execute a stop.

like this

Code: Select all

# Get the curses window, turn off echoing of keyboard to screen, turn on
# instant (no waiting) key response, and use special values for cursor keys
screen = curses.initscr()
curses.noecho() 
curses.cbreak()
screen.keypad(True)

try:
        while True:
            char = screen.getch()
            if char == ord('q'):
                break
            if char == ord('S'): # Added for shutdown on capital S
                os.system ('sudo shutdown now') # shutdown right now!
            elif char == curses.KEY_UP:
                GPIO.output(IN1, True)
                GPIO.output(IN2, False)
                GPIO.output(ENA, True)
                GPIO.output(IN3, True)
                GPIO.output(IN4, False)
                GPIO.output(ENB, True)
                print("Forward")
		
        # put other elif statements here for left right backwards
        
            
            else:
                GPIO.output(ENA, False)
                GPIO.output(ENB, False)
                print("Stop")                
                
So the logic goes look for possible keys ( if & elif statements ) if non are found then execute the else statement to stop.
Remember we want information.......................no information no help
The use of crystal balls & mind reading is not supported

cloudapplepi
Posts: 17
Joined: Wed Dec 05, 2018 6:35 pm

Re: Can't get robot motors to work (code issue?)

Fri Dec 07, 2018 11:44 am

pcmanbob wrote:
Fri Dec 07, 2018 10:55 am
So all you need to do is check for your characters for forwards,backwards,left & right and if non of them are found then execute a stop.

like this

Code: Select all

# Get the curses window, turn off echoing of keyboard to screen, turn on
# instant (no waiting) key response, and use special values for cursor keys
screen = curses.initscr()
curses.noecho() 
curses.cbreak()
screen.keypad(True)

try:
        while True:
            char = screen.getch()
            if char == ord('q'):
                break
            if char == ord('S'): # Added for shutdown on capital S
                os.system ('sudo shutdown now') # shutdown right now!
            elif char == curses.KEY_UP:
                GPIO.output(IN1, True)
                GPIO.output(IN2, False)
                GPIO.output(ENA, True)
                GPIO.output(IN3, True)
                GPIO.output(IN4, False)
                GPIO.output(ENB, True)
                print("Forward")
		
        # put other elif statements here for left right backwards
        
            
            else:
                GPIO.output(ENA, False)
                GPIO.output(ENB, False)
                print("Stop")                
                
So the logic goes look for possible keys ( if & elif statements ) if non are found then execute the else statement to stop.
Okay, thanks. :-) This causes the motors to run out smoothly as soon as any key is pressed which is not defined/configured.

But is there a way to get the same result simply, by stop pressing any of the control buttons? I found this post from 2013: viewtopic.php?t=42608

A quote from that:
I think you are confused because you expect to hold the key down, and then release it to stop the maneuver. However a key-press as detected by curses is a single event. Holding the key down produces auto-repeat, and that has the effect of continually calling the maneuver, but with an uncertain delay. There is no way to detect that no key is pressed, because then your code is inside the call to screen.getch waiting for a key to be pressed.
So it doesn't seem to be that easy to get it wotk as I'd like to, or? Basically the control should be like in a video game car race where you control the car with the arrow keys: Once you stop pressin KEY_UP, it slows down.

Return to “Automation, sensing and robotics”