úterý 8. března 2016

RoboCar: Arduino Motor Shield L293D with Raspberry Pi B+ (part 2)

Last time I wrote about the Motors Shield and I tried to describe how the L293D modul and the 74HC595 module work. And now is time for programming. But we have to wire it up first. You can connect PINs according this image. (image update - 05.09.2016 - fixed wiring of blue and brow wire on motor shield, thanks to Maxime)



And when you have it connected we can start talking about using python to run the motors.

Requirements

  1. Raspbery Pi with installed OS (I have Raspbian)
  2. Installed Git, Python3 and RPi.GPI - sudo aptitude install python3 python3-rpi.gpio
  3. Connectected Motor Shield to Raspberry Pi

Controlling motors from Python

I've wrote Python class for controlling motors using this Motor Shield. You can download it from my github.

git clone https://github.com/lipoja/AMSpi.git

Using AMSpi class

from AMSpi import AMSpi

# For BOARD pin numbering use AMSpi(True) otherwise BCM is used
with AMSpi() as amspi:
    # Set PINs for controlling shift register (GPIO numbering)
    amspi.set_74HC595_pins(21, 20, 16)
    # Set PINs for controlling all 4 motors (GPIO numbering)
    amspi.set_L293D_pins(5, 6, 13, 19)
    # Run motors
    amspi.run_dc_motors([amspi.DC_Motor_1, amspi.DC_Motor_2, amspi.DC_Motor_3, amspi.DC_Motor_4])

When you are creating object you can specify what pin numbering you will use.
  • AMSpi() - for GPIO.BCM
  • AMSpi(True) - for GPIO.BOARD
In this example I am using BCM. BCM is the GPIO number. BOARD is the number in the circle (on the image above). 

Then you have to set the pins for shift register. It is done by set_74HC595_pins method.
amspi.set_74HC595_pins(DIR_LATCH=21, DIR_CLK=20, DIR_SER=16)

After that you must specify used pins for enabling the motors. This is done by set_L293D_pins method.
amspi.set_L293D_pins(5, 6, 13, 19)

You can choose which motor do you want to use. If you have only two motors you can set it like this: 
amspi.set_L293D_pins(PWM2A=13, PWM2B=19)

Now the exciting part. Spinning the wheel :-]. You can start one or multiple motors at time. Using run_dc_motors method and specifying which motor you want to run.
For this you can use class variable DC_Motor_X where X is number of the motor.
(DC_Motor_1, DC_Motor_2, DC_Motor_3, DC_Motor_4)

Running all 4 motors:
amspi.run_dc_motors([amspi.DC_Motor_1, amspi.DC_Motor_2, amspi.DC_Motor_3, amspi.DC_Motor_4])

Running only two motors:
amspi.run_dc_motors([amspi.DC_Motor_1, amspi.DC_Motor_2])

If you want to run only one motor you can use same method:
amspi.run_dc_motors([amspi.DC_Motor_1])

Or you can use this method for running only one specific motor:
amspi.run_dc_motor(amspi.DC_Motor_1)

Now the direction of the motor. How do you switch it. Easily. 
Just add False as second parameter of method:
amspi.run_dc_motors([amspi.DC_Motor_1, amspi.DC_Motor_2, amspi.DC_Motor_3, amspi.DC_Motor_4], clockwise=False)

OK, now you car is driving super fast forward but how do you stop it? Piece of cake. Just call:
amspi.stop_dc_motors([amspi.DC_Motor_1, amspi.DC_Motor_2, amspi.DC_Motor_3, amspi.DC_Motor_4])

The metod stop_dc_motors works same as run_dc_motors. 
Just specify the motors which you want to stop.
On the git repository is commented example.py file. 
You can look at it and see what it can do.

OK, that was easy, right? If you have questions just ask me. I will try to answer them. 


39 komentářů:

  1. Hey Jan :) thank you for that great tutorial and the awesome library. I'm afraid that my motors doesn't stop turning after the stop_dc_motors call (i use the example.py). I already tried to clean up GPIO pins but that has no effect. Do you have any idea whats wrong? Best, Sascha

    OdpovědětSmazat
    Odpovědi
    1. It might be because of the shift register (74HC595) on the board. It has still set the pins to "HIGH". Can you try stop each motor separately using stop_dc_motor? Did they stop?

      Smazat
    2. I have the same problem. stop_dc_motor does not help.

      Smazat
    3. Same from my side. I stopped each motor separatly by calling the stop_dc_motor method. but nothing changed, all attached motors start turning.

      Smazat
    4. Hi, thank you for your reactions and testing. I've released newer version. It is on github. Can you test it, please?
      Thank you!

      Smazat
    5. hi
      i don't know if this was already fixed but i have same problem running the dc_example.py
      to fix this problem i added the next line at the end of the dc_example.py

      amspi.__exit__(1,1,1)

      it generate an error but it stop my motor after quit the script, as i understand it close the gpio ports

      Thanks jan for your program

      Smazat
  2. Hi, Thx for the tutorial! What's the pwm adjusted for the run_dc_motors? is it max speed?

    OdpovědětSmazat
    Odpovědi
    1. Hi, it is default for output. Probably the max speed. I will add speed (pwm) regulation in next update.

      Smazat
  3. Hi Jan, thank you for this tutorial, the only one found on internet to connect an arduino motor shield on a raspberry.
    In the next step, I would like to connect one stepper motor, do you think it's possible with your program ? how do for control the sens and the speed ?
    Regards

    OdpovědětSmazat
    Odpovědi
    1. Hi Kris,
      you can't use stepper motors, yet.
      I am going to write support for it. Same goes for speed control. I just need time to finished it, but as you can see I had no time in past few months.
      Controlling speed will use just software implementation of PWM. That means it is not as good as it is on Arduino.
      As far as I know Raspberry Pi has only one pin supporting PWM.

      Smazat
    2. sir it is already 2019 just asking. have you integrate it with servo ??

      Smazat
  4. Hi Jan,
    Thanks for the great work. Just a question, with the current wiring I don't have it working, I have weird behavior, motor working or not working... Therefore, I investigated the code proposed by the pigpio library:
    http://abyz.co.uk/rpi/pigpio/ex_motor_shield.html

    In this code one can see:
    D12 MOTORLATCH
    D11 PMW motor 1

    However, on your diagram LATCH is connected to 13 and PMW motor 1 to 12. Furthermore, I read that 13 is unused:

    http://playground.arduino.cc/Main/AdafruitMotorShield
    // Digital pins: used: 3,4,5,6,7,8,9,10,11,12
    // Pin 9 and 10 are only used for the servo motors.
    // Already in use: 0 (RX) and 1 (TX).
    // Unused: 2,13
    // Pin 2 has an soldering hole on the board,
    // easy to connect a wire.
    // Pin 13 is also connected to the system led.

    If I connect the blue wire to 11 (PMW motor 1) and the brown wire to 12 (latch), then everything works like a charm :-)

    Could you confirm it and evantually update the diagram?

    Thanks!
    Maxime

    OdpovědětSmazat
  5. Thank you Maxime! I was looking for this "bug" for long time and I did not see it :(
    I've updated the image here on blog and also on github giving you creadit. https://github.com/lipoja/AMSpi

    Thank you for your time and really good investigation of my mistake :)

    OdpovědětSmazat
  6. i wont work on my pi i have done everything right
    even used example code too

    OdpovědětSmazat
  7. Hello.
    First, thanks for library. I can to control my dc motors.
    Now, I like to control my servo motors.
    With this library is it possible to control my servo motors?

    OdpovědětSmazat
    Odpovědi
    1. Hi Mateus,
      not yet. I was working on that but it is not ready yet. But working with servo is little bit tricky. Because controlling server from raspi using RPi.GPIO does not work well as it works on Arduino (because of software PWM).

      Smazat
  8. How would you create a simple loop? I can get it to run with no issue, but once I put it into a if else statement it errors out.

    OdpovědětSmazat
    Odpovědi
    1. Could you send me the code, I will have a look on it.

      Smazat
  9. Hi, thanks for this python class, saved me a lot of work. However, when I wired everything up like in your diagram, the 74HC595 shift register didn't do anything (motors worked, speed changes worked, direction changes didn't). Only after I connected another ground to the gnd pin on the shield it started to function properly. I didnt realize this until I took out the 74HC595 and wired it up separately to see if it was faulty.

    OdpovědětSmazat
    Odpovědi
    1. Hi, thank you for your comment. To which pin on the shield did you connected the ground? To the GND pin next to 5V input?
      I will mark it in the picture maybe it will help others.
      Thanks

      Smazat
    2. I used the gnd header between pin 13 and aref for mine :)

      Smazat
  10. Zdravim Jan,

    diky za super navod. Velmi mi pomohol.

    OdpovědětSmazat
  11. Zdravim, chcel by som sa spytat uplne laicku otazku, zapojil som vsetko podla vasho obrazka, ako externe napajanie pre motor shield pouzivam 9v nabijaciu baterku, raspberry mam zapojene na micro-usb nabijacke v zasuvke. Ked pustim vas skript dc_example.py tak pocujem ze v motoroch cvaka ale nekruti sa nic, som uplne elektrotechnicke nemehlo, chcel by som vas poprosit o radu. Dakujem.

    OdpovědětSmazat
  12. Dobry den,
    a jake pouzivate motorky (jake vyzaduji napeti pro svuj chod)?

    OdpovědětSmazat
    Odpovědi
    1. Je to prava cina :) https://www.aliexpress.com/item/Damping-balance-Tank-Robot-Chassis-Platform-high-power-Remote-Control-DIY-crawle-SINONING/32449063532.html?spm=a2g0s.9042311.0.0.y7w3h2

      Uvadzaju tam nieco taketo:
      Motor: 260
      Voltage: 3V-9V

      Ked pripojim 9V baterku napriamo k jednemu alebo druhemu, tak funguju.

      Inak prepisal som vasu python classu do typescriptu pre nodejs ak by sa to niekedy niekomu zislo rad poskytnem... Motory sa snazim najprv ale rozchodit s vasimi skriptami.

      Dakujem za kazdu radu.

      M.

      Smazat
  13. Tuto chlapici rozoberaju podobny problem: https://www.raspberrypi.org/forums/viewtopic.php?f=45&t=16118

    vyzera ze dospeli k nazoru ze ta 9v baterka na to asi nestaci?

    OdpovědětSmazat
    Odpovědi
    1. Je to tak, ked som to cele pripojil namiesto 9v baterky na 5V/2A DC adapter tak to slape jak vinko...

      Smazat
  14. Super, tak to je dobre vedet. Dekuji za informaci. Asi je tam potreba vetsi proud nez ta baterka zvlada. Ja to mel pouze napajene tim 5V (2A) z powerbanky. A to asi bylo dostacujici.

    OdpovědětSmazat
  15. How to control Servo Motor 1 & 2 from your AMSpi Class ?

    OdpovědětSmazat
  16. Hi,

    Really great tutorial!! Looking forward for your update in controlling the servo.

    Thanks

    OdpovědětSmazat
  17. can it be used for the servo motor??

    OdpovědětSmazat
  18. Thanks for the great tutorial!
    I used your class to control two bipolar stepper motors. Unfortunately, it's not possible to tabulate in the blog. Therefore I deleted the posted program snippets.

    OdpovědětSmazat
  19. I also found that (as was written in a previous post) there is no regular ground connection between RaspberryPi and the motor shield. The only ground connection is used to pull pin 13 of IC 74HC595 to LOW. It would therefore be advisable to connect, for example, pin 6 (GND) from the RaspberryPi to one of the pins next to the 5V connection on the motor shield.

    OdpovědětSmazat
    Odpovědi
    1. Hi, thank you for using this library. Unfortunately I can not help you much. The car is already disassembled and I do not have free time to do updates. But if you have any suggestions/improvements (even of the picture as you mentioned) please send a Pull Request to Github repository. I will accept it right a way. https://github.com/lipoja/AMSpi

      Smazat
    2. Thanks for your comment, it worked after I connected pin 6 from RaspberryPI to GND pin next of 5V (74HC595).
      It would nice if you create an issue on Github. Because it was very hard to follow these comments.

      Smazat
  20. Hi,

    I found a solution for this problem, you just need to add time.sleep(1) in the last to allow for the python program to set the GPIO state before exiting

    Thanks jan for your program

    OdpovědětSmazat
  21. Tento komentář byl odstraněn autorem.

    OdpovědětSmazat
  22. Thanks alot Jan Lipovsky.
    This is a great work. Your script works like a charm.
    But there is just one ground connection missing in the diagram. Which is pin 13 of the L293D motorshield must be connected to any ground pin of raspberry pi. Example i connected an extra wire from pin 6 of pi to pin 13 of shiled. It works fine.
    I debugged the complete script and measured the voltage on motor terminals of the shiled, everything is as expected.
    Thanks again for great work.

    OdpovědětSmazat