Making a Rpi Pico Based Smart Vehicle

I am going start a project on a Pico based smart vehicle. The project will be in many parts. The first part is summarized below.

Pico Smart Vehicle, Part 1 - Controlling a DC motor.

Introduction

This project is on how to use the Rpi Pico with a DC motor controller, such as L298N, to drive a toy DC motor with a speed encoder, such as the N20.

This first part of the project is focused on Pico, Motor Controller, and DC motor.

Rpi4B or Pi-Top 4 would be used as the master controller to communicate with this motor controller, and also controllers of other actuators and senors.

Update 2021jun30hkt2044

When I said above that I would use Rpi4B or Pi-Top 4 as the master controller, I had little confidence I was saying something sensible, because I never saw a Pi-Top 4 before. So I watched a recent video ([Ref 4])((https://www.youtube.com/watch?v=wFWbuj9JdiQ)) to make sure I know what is going on recently.

I was glad to see the video title “Rpi 4 on the Go” and that I can use Rpi OS instead of Pi-Top OS. The touch screen and BlueTooth keyboard also look impressive.

However, I am a very slow guy, so I will be going very slowly, with this Part 1 of controlling a DC motor. :slight_smile:

One other thing is that I am not too sure that I am doing the right thing in this forum. I used to write sort of blogs in rpi.org forum, and also short answers in StackOverflow and Stack Exchange Q&A sites such as for Rpi… So this kind of project discussion topic looks very new to me. I guess I need to search to find out how should I start a project discussion topic.

So I searched and found this post about projects category (Ref 5). I am glad to know that this is a new thing, so I arrived in good time.


References

  1. Compatible motors/cabling - @Ltrain, 2021may25

  2. N20 Gear Motor (50:1 Ratio, 460 rpm, with Encoder) - Servo City

  3. How to Use Your Raspberry Pi Pico With DC Motors (Using DRV8833, L298 or L9110S) - By Les Pounder, Tom’s Hardware 2021jan30

  4. Raspberry Pi 4 On The Go! Pi-Top 4 FHD Touch Display & Bluetooth Keyboard Review - 2021jan25, 74,468 views

  5. About the Projects category post - pi-topTEAM, 2021mar19

  6. Dr. William Rankin Lecture (On Design etc) 1:18 hrs - Arkansas State 1.2K subscribers, 579 views, 2014sep05

1 Like

Pico Smart Vehicle, Part 1 - Controlling a DC motor.

(1) How do I describe my project?

Just now I browsed the projects category here and found not too many examples for me to learn how to properly present my project work in progress.

I jumped to the quick conclusion that there are no strict and fast rules on how to describe your work in progress projects. For one project I saw a brief introduction post, followed by short replies of comments and discussions. For another project I saw the project proposer posts some videos in his Instagram.

My feeling is that the general rule is to post short messages on my work in progress, so other interested readers might comment and make suggestions, so I can modify my project specification and requirements for along the way.

For my previous Micky Mouse toy Rpi projects, I used to post messages in forums, such as in rpi.org, and my favourite section is “Automation, sensing and robotics”.

An example post is this DC Motor Post

The rpi.org forum accepts imgur.com images, but does not entertain videos. So I usually upload YouTube videos about my work in progress. such as this:

tlfong01’s Step Motor Test Youtube Video 2021may1501


(2) Now I am reading the following tutorial to learn how to use Pico to control a DC motor.

How to Use Your Raspberry Pi Pico With DC Motors (Using DRV8833, L298 or L9110S) - By Les Pounder, Tom’s Hardware 2021jan30

I usually summarize what I have learned by a sequence of pictures which also are useful for refreshing memory later, or for newbie readers to get a rough picture of what I am doing.

And I usually modify slightly or sometimes heavily the tutorial’s hardware setup and software configurations etc. By not just blindly following everything in the tutorial but trying new things make me learn things deeper and remember ideas harder.




I also study the tutorial’s software code twice, the first time separate code segments and explanations, and the second time, the complete code. I make sure I understand every statement of the complete code, before I modify it for my version of project. Now the complete code listing below.

import utime
from machine import Pin

motor1a = Pin(14, Pin.OUT)
motor1b = Pin(15, Pin.OUT)

def forward():
   motor1a.high()
   motor1b.low()

def backward():
   motor1a.low()
   motor1b.high()

def stop():
   motor1a.low()
   motor1b.low()

def test():
   forward()
   utime.sleep(2)
   backward()
   utime.sleep(2)
   stop()

for i in range(5):
	test()

(3) Now I following the above Tom’s Harware tutorial to use the Pico and a DC motor driver to move a motor.



(3.1) I am using the Chinese Windows 10 Thonny python IDE. This way everything is simple: (a) No external power supply is needed for now. Of course an external power supply for the motor is required later.

(3.2) I am using a simple “toggle the system LED” program to make sure the Pico hardware is setup more or less OK. The test program listing and a run program sample output is shown below.

# Program Name
#   toggle_pico_system_led_v03.py - tlfong01 2021jul01hkt1531
# Configuration
#   Thonny 3.3.3, Windows 10 (64-bit), Python 3.7.9 (32-bit), Tk 8.6.9, USB COM Port #3
# Intepreter
#   Micropython (Rapsberry Pi Pico)
# Program Function
#   Toggle Pico system LED at GPIO pin 15
# User Guide
#   Run code to toggle LED from On to Off or Off to On

from machine import Pin

systemLed = Pin(25, Pin.OUT)
systemLed.toggle()

# END

# Sample Output - tlfong01 2021jul01hkt1537
# MicroPython v1.14 on 2021-02-02; Raspberry Pi Pico with RP2040

# Type "help()" for more information.
# >>> %Run -c $EDITOR_CONTENT
# >>> 

(4) Now I using a modified version of Tom’s Hardware tutorial demo program to move a DC motor. To make things as simple, as cheap, and as newbie safe/proof as possible, for this prototyping stage, I am not using the very popular L298N motor driver, but MX1509, which is more efficient. And for the motor, not that expensive N20 gear motor with encoder, but the cheapest TT130 yellow toy motor.

The basic test of driving only one motor is OK. The program listing is shown below. More documentation will come later.


# Program Name
#   move_dc_motor_v01.py - tlfong01 2021jul01hkt1629
# Configuration
#   Thonny 3.3.3, Windows 10 (64-bit), Python 3.7.9 (32-bit), Tk 8.6.9, USB COM Port #3
# Intepreter
#   Micropython (Rapsberry Pi Pico)
# DC Motor
#   TT130 DC3~6V DC Gear Motor - AliEXpress US$1
#   https://www.aliexpress.com/item/32855311589.html
# DC Motor Driver
#   MX1508 2~10V, 1.5A, Dual H-Bridge DC Motor Driver - AliExpress US$1
#   https://www.aliexpress.com/item/32688083107.html

# Program Function
#   Move DC motor forward, backward, and stop
# User Guide
#   Run code to move motor

import utime
from machine import Pin

motor1a = Pin(10, Pin.OUT)
motor1b = Pin(11, Pin.OUT)

def moveMotorForward():
    motor1a.high()
    motor1b.low()

def moveMotorBackward():
    motor1a.low()
    motor1b.high()

def stopMotor():
    motor1a.low()
    motor1b.low()

def test():
    print('  Begin move motor test()')
    moveMotorForward()
    utime.sleep(1)
    moveMotorBackward()
    utime.sleep(1)
    stopMotor()
    print('  End   test()')

for i in range(2):
    print('Test ', i)
    test()

# *** End of program ***

# *** Sample Output - tlfong01  2021jul01hkt1707
'''
>>> %Run -c $EDITOR_CONTENT
Test  0
  Begin move motor test()
  End   test()
Test  1
  Begin move motor test()
  End   test()
>>> 
'''


Pico, MX1508 motor driver, TT130 motor test video


References

(1) MX1508 2~10V, 1.5A, Dual H-Bridge DC Motor Driver - AliExpress US$1

/ to continue, …

Pico Smart Vehicle, Part 2 - Controlling Two DC Motors.

  1. For Part 2 Controlling Two Motors, I will be using Piromoni Tiny2040 and N20 motors.


Testing Plan of Pico Smart Vehicle Part 2, Moving Two Motors

My testing/development plan is something like below.

(1) Modify the move one motor program to move two motors.

(2) Mount two TT130 motors on a TWD (TWo Wheel Driver) body, and write a small program to turn the robot car, first turn left, then turn right, then stop.

(3) Repeat Test (2) above, replacing TT130 motors by N2 motors.

/ to continue, …


References

(1) N20 DC3V/6V/12V RPM 7.5 to 6000 Micro Gear Motor - Amazon

It appears that I can no more edit/append my own post if it is two or three days old . So my workaround is “quote something and reply”. This makes my incremental short project progress report like a long blog, where other readers can comment and make suggestion in time. I am thinking of later using a blog site to report my progress, so the late readers can read a coherent article.

Update 2021jul04hkt1307

Errata: I just found out that this pi-top forum is using the Discourse software: Discourse (Software 2013 by Jeff Atwoodet al) - Wikipedia, which I never heard of, and therefore have misunderstood the working and restriction of newbie/low level users. Eg, I wrongly thought that I could not edit my own posts after a couple of days. Actually if I have gone up high levels, I can edit my own post within 30 days. Also Discourse seems to encourage “long form” input, and “infinite scrolling”, which I don’t have any idea about. I am used to StackExchange’s short form Q&A (Question and Answers), not discussion forums, so I need to change my mindset. Anyway, I need to know more about Discourse, before I can make up my mind how to present my project.


Anyway, now I am reading pi-top 4 DIY/Robotic Kit’s documents to get a rough idea of how their rovers look like, so my Smart Pico Vehicle (SPV v1.0) can follow their ideas somewhat. Here are the pi-top 4 references I am reading:

(1)

(2) pi-top 4 DIY

It appears that the pi-top 4 DIY edition is still a work in progress. So I think I can for now DIY my project Smart Pico Vehicle flexibly, perhaps also let other readers give brainstorming ideas.


So I am now reading more N20 motor documentation, and perhaps rapid prototyping a 4WD, ie Four Wheel Drive, with four N20 motors.


This gloomy lock down Sunday morning I was browsing casually around the forum and I was glad to see other users also making 4WDs, using pi-top Robotic kits. I found them using “Mecanum Wheels” which I read long time ago, but never have a chance playing with the real thing. I think these strange looking wheels need advanced, scary maths. So for now, humble me will stick to simple, plain wheels.


SPV (Smart Pico Vehicle) v0.1 Assembly Notes


/ to continue, …


References

(1) How to use motor drivers with H-bridge and PWM input, to control direction and speed of DC motors? - EE SE Q&A, Asked 2020jul16, Viewed 1k times

(2) 10 Software Packages You Can Add to Your Pi-Top [4] - Elijah Phillips, 2020jun15

(3) Further - Easy to Use STEM Software for Schools - pi-top.com

(4) Raspberry Pi Pico by Raspberry Pi - ClassRoomEshop Hongkong/Taiwan HK$40


I can no longer edit/append to my old post, so I continue by a reply.

I found Pi-top [4] Rover with ultrasonic sensor and camera too complicated. So I am thinking of using the simpler MMK (Motors and Motion Kit) as a reference.


In other words, I am starting off with a 2WD, and only later scale it up to a 4WD.


So I am assembling my Pico 2WD with 47mm diameter simple plain wheels. But I am jealous seeing other guys building 4WD’s with Mecannum wheels of 60mm diameter, I think. So I have decided to also use 60mm plain wheels, to make it easier to convert to Mecanum later.



Which Motor Driver for SPV (Smart Pico Vehicle) v0.1 2WD

Last time I used the simple and newbie friendly MX1508 motor driver for basic testing and found everything OK. MX1508 does not have easy PWM speed control features. So this time I am using a more sophisticated motor driver, the
Toshiba TB6612FNG Dual DC Motor Driver.


References

(1) Moebius 60mm Mecanum Wheel Omni Tire Compatible with TT Motor LEGOs for Arduino DIY Robot STEM Toy Parts - AliExpress US$25

(2) Pi-top [4] 4WD Mecannum - forum.pi-top.com 2021may25

(3) TB6612FNG Dual Motor Driver Carrier - Pololu Robotic and Electronics

(4) The Review of DC Motor Drivers: L298N, TB6612FNG and LV8406T - MakeBlock, 2014jan

(5) TB6612FNG Dual DC Motor Driver IC Datasheet, Toshiba, 2007jun

(6) TB6612FNG Dual DC Motor Driver Module - AliExpress, US$1.5

1 Like

Now I am testing the N20 motor with encoder. I found the tutorials below on encoders and kit very useful

I used 6V to power both N20 motors, and used a scope to display the quadrature motor encoder outputs A, B of both motors, as shown below.


This is the hardware setup of SPV 2WD v0.1, with two N20 motors and 60mm simple plain wheels.


Next step is to setup and test the Toshiba TB6612FNG Dual DC Motor Driver, to control the direction and speed (using PWM) of the SPV 2WD’s two N20 DC motors.


Appendices

Appendix A - TB6612FNG Programming Cheat Sheet



/ to continue, …


References

(1) Motor Encoders with Arduino - Andrew Kramer’s Research, 2016jan

(2) Magnetic Encoder Pair Kit for Micro Metal Gearmotors, 12 CPR, 2.7-18V (old version) - Pololu


Now I am assembling the TB6612FNG test rig board



Design note:

I have selected TB6612FNG which has separate PWM speed control for each motor, and not RDV8833 which does not have separate motor speed control.


TB6612FNG Programming Cheat Sheet

Next step is doing the wring, and try PWM speed control.


References

(1) pi-top/pi-top-Python-SDK - pi-top

(2) pi-top Python SDK (Preview)

(3) pi-top Python SDK - 6.3 Encoder Motor

Note from SDK 6.3: pi-top motor encoders use a built-in closed-loop control system, that feeds the readings from an encoder sensor to an PID controller. This controller will actively modify the motor’s current to move at the desired speed or position, even if a load is applied to the shaft.


Appendices

Appendix A - pi-top Python SDK (Preview) - DIY Rover API

  1. A simple, modular interface for interacting with a pi-top and its related accessories and components.

  2. This SDK aims to provide an easy-to-use framework for managing a pi-top. It includes a Python 3 package (pitop), with several modules for interfacing with a range of pi-top devices and peripherals It also contains CLI utilities, to interact with your pi-top using the terminal.

  3. Status: Active Development - This SDK is currently in active development.

  4. Supports all pi-top devices:

  5. Supports pi-top Maker Architecture (PMA)

  6. Supports all pi-top peripherals

  7. Backwards Compatibility

  8. The SDK is included out-of-the-box with pi-topOS.

  9. This library is installed as a Python 3 module called pitop. It includes several submodules that allow you to easily interact with most of the hardware inside a pi-top.

  10. Getting started docs

  11. 4.2. Robotics Kit: DIY Rover API

$ 4.2.1 Import modules
from pitop import
(
EncoderMotor,
ForwardDirection,
BrakingType
)

$ 4.2.2 Setup the motors for the rover configuration
motor_left = EncoderMotor(“M3”, ForwardDirection.CLOCKWISE)
motor_right = EncoderMotor(“M0”, ForwardDirection.COUNTER_CLOCKWISE)
motor_left.braking_type = BrakingType.COAST
motor_right.braking_type = BrakingType.COAST

$ 4.2.3 Define some functions for easily controlling the rover

  def drive(target_rpm: float):
      print("Start driving at target", target_rpm, "rpm...")
      motor_left.set_target_rpm(target_rpm)
      motor_right.set_target_rpm(target_rpm)

  def stop_rover():
      print("Stopping rover...")
      motor_left.stop()
      motor_right.stop()

 def turn_left(rotation_speed: float):
     print("Turning left...")
     motor_left.stop()
     motor_right.set_target_rpm(rotation_speed)

 def turn_right(rotation_speed: float):
     print("Turning right...")
     motor_right.stop()
     motor_left.set_target_rpm(rotation_speed)

 $ 4.2.4 Start a thread to monitor the rover

  def monitor_rover():
      while True:
      print("> Rover motor RPM's (L,R):", round(motor_left.current_rpm, 2), round(motor_right.current_rpm, 2))
      sleep(1)

  monitor_thread = Thread(target=monitor_rover, daemon=True)
  monitor_thread.start()
  # Go!

  rpm_speed = 100
  for _ in range(4):
      drive(rpm_speed)
      sleep(5)

  turn_left(rpm_speed)
  sleep(5)

  stop_rover()

2[quote=“tlfong01, post:7, topic:924”]
TB6612FNG Programming Cheat Sheet

Next step is doing the wring, and try PWM speed control.
[/quote]


Now that I have skimmed the Pi-Top Python 3 SDK’s DIY Rover APIs doc, the time has come for me to write little test programs and APIs for the TB6612FNG based SPV (Smart Pico Vehicle) 0.1 2WD.

I will be using pico and Windows 10 Thonny Python 3.9.3 IDE. In other words, no Rpi4B or Pi-Top [4] will be used in this prototyping stage.



Now I am testing the TB6612FNG Dual DC Motor driving two N20 gear motors and finding everything OK.

The TB6612FNG power and control signals are summarized below.

1. Motor power = 6V, connected to pins VM and Ground

2. Logic powr = 5V, connected to pins Vcc and Ground

3. Standby logical control = H (no stand by, normal operation)

4. PWM signal = High (100% duty cycle, full speed)

5. IN1 = Low, IN2 = High (CW)

6. AO1, AO2 connected to N20 gear motor 1

7. BO1, BO2 connected to N20 gear motor 2 

Testing Results

Both N20 motor turn CW, as expected.



YouTube video of TB6612FNG Dual DC Motor Driver Driving Two N20 Motors


Next step

Next step is to write a little python program for Pico to control the TB6612FNG motor driver control the two N20 gear motors to move the 2WD forward, backward, turn left, turn right etc.

Desgin note: pi-top [4] python SDK has APIs of similar vehicle moving functions, but I think they are using the servo motor to steer the vehicle to turn left or right. My SPV 2WD APIs to write next are using the two motors’ differential speeds to turn left or right.


/ to continue, …


Now I have stacked all three modules to start python programming:

(1) Motor (N20 x 2), 

(2) Motor Driver (TB66112FNG x 1)

(3) MCU (Pico x 1)


/ to continue, …

I am reading my old post to refresh memory on how to drive a DC motor. Last time I followed Tom’s Hardware tutorial to use Pico and MX1508 motor driver to drive only one motor TT130. Everything goes well.

This time I am modifying Tom’s Hardware’s python program to control my 2WD’s two N20 motors. I am also using the TB6612FNG motor controller. As I understand, for my simple applications, any common driver (L298N, DRV8833), and common motors TT130, N20) can be used.


Now I am testing moving only one N20 motor, and using Pico to control only IN1, IN2. The Standby and PWM signals are manually hardwired.



And the full program listing.

# Program Name
#   move_dc_motor_v02.py - tlfong01 2021jul10hkt1132
# Reference
#   Pi-Top Forum - making-a-rpi-pico-based-smart-vehicle/924
#   https://forum.pi-top.com/t/making-a-rpi-pico-based-smart-vehicle/924
# Configuration
#   Thonny 3.3.3, Windows 10 (64-bit), Python 3.7.9 (32-bit), Tk 8.6.9, USB COM Port #4
# Intepreter
#   Micropython (Rapsberry Pi Pico)
# DC Motor
#   (a) TT130 DC3~6V DC Gear Motor - AliEXpress US$1
#       https://www.aliexpress.com/item/32855311589.html
#   (b) N20 Gear Motor
#   
# DC Motor Driver
#   (a) MX1508 2~10V, 1.5A, Dual H-Bridge DC Motor Driver - AliExpress US$1
#         https://www.aliexpress.com/item/32688083107.html
#   (b) TB6612FNG Dual DC Motor Driver

# Program Function
#   Move DC motor forward, backward, and stop

# User Guide
#   (a) Connect PWMA to High (Vcc) 
#   (b) Connect Standby to High
#   (c) Run code to move motor forward, backward, and stop

import utime
from machine import Pin

motor1a = Pin(10, Pin.OUT)
motor1b = Pin(11, Pin.OUT)

def moveMotorForward():
    motor1a.low()
    motor1b.high()

def moveMotorBackward():
    motor1a.high()
    motor1b.low()

def stopMotor():
    motor1a.low()
    motor1b.low()

def test():
    print('  Begin move motor test()')
    moveMotorForward()
    utime.sleep(1)
    moveMotorBackward()
    utime.sleep(1)
    stopMotor()
    print('  End   test()')

for i in range(2):
    print('Test ', i)
    test()

# *** End of program ***

# *** Sample Output - tlfong01  2021jul01hkt1707
'''
>>> %Run -c $EDITOR_CONTENT
Test  0
  Begin move motor test()
  End   test()
Test  1
  Begin move motor test()
  End   test()
>>> 
'''

Now I have written motor driver dictionaries and tested them OK, to make it easy to scale up 1WD to 2WD for two motors, and later 4WD for four motors. The program is fully listed below:

$ Program Name
$ move_dc_motor_v04.py - tlfong01 2021jul10hkt1558
$ Reference
$ Pi-Top Forum - making-a-rpi-pico-based-smart-vehicle/924
$ Making a Rpi Pico Based Smart Vehicle
$ Configuration
$ Thonny 3.3.3, Windows 10 (64-bit), Python 3.7.9 (32-bit), Tk 8.6.9, USB COM Port #4
$ Intepreter
$ Micropython (Rapsberry Pi Pico)
$ DC Motor
$ (a) TT130 DC3~6V DC Gear Motor - AliEXpress US$1
$ https://www.aliexpress.com/item/32855311589.html
$ (b) N20 Gear Motor x 2
$
$ DC Motor Driver
$ (a) MX1508 2~10V, 1.5A, Dual H-Bridge DC Motor Driver - AliExpress US$1
$ https://www.aliexpress.com/item/32688083107.html
$ (b) TB6612FNG Dual DC Motor Driver

$ Program Function
$ Move two N20 DC motors forward, backward, and stop

$ User Guide
$ (a) Configuration
$ GP10 - Motor1 IN1
$ GP11 - Motor1 IN2
$ GP12 - Motor1 PWMA
$ GP13 - Motor2 IN1
$ GP14 - Motor2 IN2
$ GP15 - Motor2 PWMB
$ GP9 - Motor1, 2, Standby
$ (b) Run program to move in sequence, two motors forward, backward, and stop

import utime
from machine import Pin

$ Configuration

multiMotorDriverDict01 = {
‘Title’ : ‘Motor Driver Dict For 4WD’,
‘STBY’ : 9,
‘1’ : {‘IN1’ : 10,
‘IN2’ : 11,
‘PWM’ : 12,
},
‘2’ : {‘IN1’ : 13,
‘IN2’ : 14,
‘PWM’ : 15,
},
‘3’ : {‘IN1’ : 0,
‘IN2’ : 0,
‘PWM’ : 0,
},
‘4’ : {‘IN1’ : 0,
‘IN2’ : 0,
‘PWM’ : 0,
},
}

multiMotorDriverDictDict = {
‘1’: multiMotorDriverDict01,
‘1’: multiMotorDriverDict01,
}

def setupMotor(multiMotorDriverDictDictNum, motorDriverNum):
motorDriverDict = multiMotorDriverDictDict[str(multiMotorDriverDictDictNum)]

in1PinNum = motorDriverDict[str(motorDriverNum)]['IN1']
in2PinNum = motorDriverDict[str(motorDriverNum)]['IN2']
pwmPinNum = motorDriverDict[str(motorDriverNum)]['PWM']

print('In1PinNum =', in1PinNum)
print('In2PinNum =', in2PinNum)
print('pwmPinNum =', pwmPinNum)

in1Pin = Pin(in1PinNum, Pin.OUT)
in2Pin = Pin(in2PinNum, Pin.OUT)
pwmPin = Pin(pwmPinNum, Pin.OUT)

picoMotorDriverControlPinDict = {'IN1': in1Pin, 'IN2': in2Pin, 'PWM': pwmPin}

return picoMotorDriverControlPinDict

def moveMotorForward(motorDriverDict):
in1Pin = motorDriverDict[‘IN1’]
in2Pin = motorDriverDict[‘IN2’]
pwmPin = motorDriverDict[‘PWM’]

in1Pin.low()
in2Pin.high()
pwmPin.high()    
return

def moveMotorBackward(motorDriverDict):
in1Pin = motorDriverDict[‘IN1’]
in2Pin = motorDriverDict[‘IN2’]
pwmPin = motorDriverDict[‘PWM’]

in1Pin.high()
in2Pin.low()
pwmPin.high()    
return

def stopMotor(motorDriverDict):
in1Pin = motorDriverDict[‘IN1’]
in2Pin = motorDriverDict[‘IN2’]
pwmPin = motorDriverDict[‘PWM’]

in1Pin.low()
in2Pin.low()
pwmPin.high()    
return

$ Main $

$ Test Motors #1, #2

motorDictDictNum = 1
motorNumList = [1, 2]

for motorNum in motorNumList:
motorDriverDict = setupMotor(motorDictDictNum, motorNum)
moveMotorForward(motorDriverDict)
utime.sleep(1)
moveMotorBackward(motorDriverDict)
utime.sleep(1)
stopMotor(motorDriverDict)

$ End of program


Next step is writing functions to turn vehicle right and left.

/ to continue, …

The turn right/left functions are easy to write and test. The ‘#’ symbol crashes with the forum editor. So I replaced the symbol to ‘$’

$ Program Name
$   move_dc_motor_v08.py - tlfong01 2021jul10hkt1625
$ Reference
$   Pi-Top Forum - making-a-rpi-pico-based-smart-vehicle/924
$   https://forum.pi-top.com/t/making-a-rpi-pico-based-smart-vehicle/924
$ Configuration
$   Thonny 3.3.3, Windows 10 (64-bit), Python 3.7.9 (32-bit), Tk 8.6.9, USB COM Port $4
$ Intepreter
$   Micropython (Rapsberry Pi Pico)
$ DC Motor
$   (a) TT130 DC3~6V DC Gear Motor - AliEXpress US$1$       
$   (b) N20 Gear Motor x 2
$   
$ DC Motor Driver
$   (a) MX1508 2~10V, 1.5A, Dual H-Bridge DC Motor Driver - AliExpress US$1
$         https://www.aliexpress.com/item/32688083107.html
$   (b) TB6612FNG Dual DC Motor Driver

$ Program Functions
$   (a) Move two N20 DC motors forward, backward, and stop.
$   (b) Move left motor forward, right motor backward, so to turn vehicle right.
$   (c) Similarly, left motor backward, right motor forward, so to turn vehicle left

$ User Guide
$   (a) Configuration
$       GP10 - Motor1 IN1
$       GP11 - Motor1 IN2
$       GP12 - Motor1 PWMA
$       GP13 - Motor2 IN1
$       GP14 - Motor2 IN2
$       GP15 - Motor2 PWMB
$       GP9  - Motor1, 2, Standby
$   (b) Run program to move in sequence, two motors forward, backward, and stop

import utime
from machine import Pin

$ Configuration

multiMotorDriverDict01 = {
    'Title'   : 'Motor Driver Dict For 4WD',
    'STBY'    : 9,
    '1' : {'IN1'    : 10,
           'IN2'    : 11,
           'PWM'    : 12,
          },
    '2' : {'IN1'    : 13,
           'IN2'    : 14,
           'PWM'    : 15,
          },
    '3' : {'IN1'    : 0,
           'IN2'    : 0,
           'PWM'    : 0,
          },
    '4' : {'IN1'    : 0,
           'IN2'    : 0,
           'PWM'    : 0,
          },
    }

multiMotorDriverDictDict = {
    '1': multiMotorDriverDict01,
    '1': multiMotorDriverDict01,
    }
    
$ *** 
 
def setupMotor(multiMotorDriverDictDictNum, motorDriverNum):
    motorDriverDict = multiMotorDriverDictDict[str(multiMotorDriverDictDictNum)]
    
    in1PinNum = motorDriverDict[str(motorDriverNum)]['IN1']
    in2PinNum = motorDriverDict[str(motorDriverNum)]['IN2']
    pwmPinNum = motorDriverDict[str(motorDriverNum)]['PWM']
    
    print('In1PinNum =', in1PinNum)
    print('In2PinNum =', in2PinNum)
    print('pwmPinNum =', pwmPinNum)
    
    in1Pin = Pin(in1PinNum, Pin.OUT)
    in2Pin = Pin(in2PinNum, Pin.OUT)
    pwmPin = Pin(pwmPinNum, Pin.OUT)
    
    picoMotorDriverControlPinDict = {'IN1': in1Pin, 'IN2': in2Pin, 'PWM': pwmPin}
    
    return picoMotorDriverControlPinDict

def moveMotorForward(motorDriverDict):
    in1Pin = motorDriverDict['IN1']
    in2Pin = motorDriverDict['IN2']    
    pwmPin = motorDriverDict['PWM']
    
    in1Pin.low()
    in2Pin.high()
    pwmPin.high()    
    return

def moveMotorBackward(motorDriverDict):
    in1Pin = motorDriverDict['IN1']
    in2Pin = motorDriverDict['IN2']    
    pwmPin = motorDriverDict['PWM']
    
    in1Pin.high()
    in2Pin.low()
    pwmPin.high()    
    return

def stopMotor(motorDriverDict):
    in1Pin = motorDriverDict['IN1']
    in2Pin = motorDriverDict['IN2']    
    pwmPin = motorDriverDict['PWM']
    
    in1Pin.low()
    in2Pin.low()
    pwmPin.high()    
    return

def turnVehicleRight(motorDriverDictLeft, motorDriverDictRight):
    moveMotorForward(motorDriverDictLeft)
    moveMotorBackward(motorDriverDictRight)
    return    
    
def turnVehicleLeft(motorDriverDictLeft, motorDriverDictRight):
    moveMotorForward(motorDriverDictRight)
    moveMotorBackward(motorDriverDictLeft)
    return        
    
$ Main test functions

def testSequentiallyMoveTwoMotorsForwardBackwardAndStop():
    motorDictDictNum = 1
    motorNumList = [1, 2]

    for motorNum in motorNumList:
        motorDriverDict = setupMotor(motorDictDictNum, motorNum)
        moveMotorForward(motorDriverDict)
        utime.sleep(1)
        moveMotorBackward(motorDriverDict)
        utime.sleep(1)
        stopMotor(motorDriverDict)    
    return

def testTurnVehicleRightOneSecondThenLeftOneSecond():
    motorDictDictNum = 1       
    leftMotorDriverDict = setupMotor(motorDictDictNum, 1)    
    rightMotorDriverDict = setupMotor(motorDictDictNum, 2)
    
    turnVehicleRight(leftMotorDriverDict, rightMotorDriverDict)    
    utime.sleep(2)
    turnVehicleLeft(leftMotorDriverDict, rightMotorDriverDict)    
    utime.sleep(2)
    stopMotor(leftMotorDriverDict)
    stopMotor(rightMotorDriverDict)
    

$ Main $

$ testSequentiallyMoveTwoMotorsForwardBackwardAndStop()

testTurnVehicleRightOneSecondThenLeftOneSecond()

$ End of program

Now that I have completed the point to point wiring of Pico GB6~9 pins to the two N20 encoder outputs. Next step is to write a Pico microPython to do all motor control in software.


I forgot I need first to do some calibration of the N20 motor encoder signal vs speed (rpm) off line (ie no Pico software). So I disconnect the Pico GP signal and use manual jumper wires to give the control signals, and use my 50MHz scope to check the motor speed. as shown below.


Now I am analysing the N20 Motor 1 Encoder signal Output 1, and see if we can calculate the motor speed from this signal. Avery rough formula is 600uS ~= 30 rpm. Next step is is see how to do the time stamping use micro python.



MicroPython utime – time related functions
https://docs.micropython.org/en/latest/library/utime.html

Description - The utime module provides functions for getting the current time and date, measuring time intervals, and for delays.


I read the docs for utime and found it similar to Thonny python, except a little bet smaller. I found user friendly examples on how to use the utime (now I know the “u” of utime means “micro”! :grinning:). One good such example has limit of time calculation less than 500us, but N20 motor’s timing is of the order of 600uS, in other words, just NOT make. I am too lazy to modify my demo programs to it my N20 applications. So lazy me go to Tom’s Hardware for help. I remember Tom;s Hardware has developed a big number of tutorials for newbies, as listed below.


Tom’s Hardware Tutorials on Rpi Pico

In the relatively short time that the Pico has been on the market, the Raspberry Pi community has already developed a ton of resources. At Tom’s Hardware, we’ve been publishing our fair share of Pico how-tos, which you can find below.

Tutorial #7 on DC motors is useful for my N20 motor 2WD project here. There is also a useful demo program on the use of buttons. The critical statements are highlighted in pink.