I used the MDD10 (instead of 2 MD10C's) on my omnibot project, and am happy with the functionality of it
Not quite so thrilled with the interface, but, that's another story
I'm using it with the raspberry pi3b, and it's working fine
My other thought is voltage, but I'm not sure about that
Supposedly, the Jetson's GPIO pins are basically the same as the RPi, but I can't seem to make the MDD10 work with the Jetson. My thought is that it has something to do with the GPIO
Why do I think that ?
Dunno. It's just a hunch
Here's a chart on the Nano pinouts...
And if that wasn't confusing enough, there's always this one...
There is a Jetson.GPIO library, which you'll find HERE (and that I've already installed, and replaced the RPi.GPIO with Jetson.GPIO in the code)
I tried the original GPIO pin numbers (using BCM) from the original code, which failed (Obviously, or I wouldn't be asking for help)
Then I tried replacing the pin numbers with the corresponding "linux" pin numbers, then I tried the GPIO.BOARD pin numbers
(I couldn't find enough info on the CVM or TEGRA numbers to try those)
I also added the # for the translation between the Pi and Jetson for personal reference so I didn't get confused when I change the numbers. You'll also notice from the charts that 168 and 38 are, in fact, PWM numbers
The program runs without errors, and the output on the ssh screen shows the correct output, but the motors don't move
Now for the fun part
The code...
from bottle import route, run, template, request #make sure bottle is installed
import Jetson.GPIO as GPIO
import time
# pi 26 = Jetson 12
# pi 24 = Jetson 15
# pi 12 = Jetson 168
# pi 13 = Jetson 38
GPIO.setmode(GPIO.BCM) #GPIO BCM pin layout
channels = [26, 24, 12, 13]
GPIO.setup(channels, GPIO.OUT)
dir1 = 26 #direction 1 pin
dir2 = 24 #direction 2 pin
pwm1 = 12 #pwm 1 pin
pwm2 = 13 #pwm 2 pin
#the above pins are reserved by the HAT
frequency = 20000 #pwm frequency
duty = 0 #pwm duty cycle 0 to 100
specialdelay = 2 #delay time for special moves
GPIO.setup(dir1, GPIO.OUT) #set pins as GPIO outputs
GPIO.setup(dir2, GPIO.OUT)
GPIO.setup(pwm1, GPIO.OUT)
GPIO.setup(pwm2, GPIO.OUT)
pwmout1 = GPIO.PWM(pwm1, frequency) #set pwm1 as pwm output
pwmout2 = GPIO.PWM(pwm2, frequency) #set pwm2 as pwm output
pwmout1.start(duty) #initializing pwm
pwmout2.start(duty)
@route('/') #root page on browser
def index():
return template('main.tpl')
@route('/1') #speed level 1 button
def index():
global duty
duty = 5
pwmout1.ChangeDutyCycle(duty)
pwmout2.ChangeDutyCycle(duty)
return template('main.tpl') #return to main page after button pressed
@route('/2') #speed level 2 button
def index():
global duty
duty = 10
pwmout1.ChangeDutyCycle(duty)
pwmout2.ChangeDutyCycle(duty)
return template('main.tpl')
@route('/3') #speed level 3 button
def index():
global duty
duty = 15
pwmout1.ChangeDutyCycle(duty)
pwmout2.ChangeDutyCycle(duty)
return template('main.tpl')
@route('/4') #speed level 4 button
def index():
global duty
duty = 20
pwmout1.ChangeDutyCycle(duty)
pwmout2.ChangeDutyCycle(duty)
return template('main.tpl')
@route('/5') #speed level 5 button
def index():
global duty
duty = 25
pwmout1.ChangeDutyCycle(duty)
pwmout2.ChangeDutyCycle(duty)
return template('main.tpl')
@route('/forward') #forward button
def index():
pwmout1.ChangeDutyCycle(duty)
pwmout2.ChangeDutyCycle(duty)
GPIO.output(dir1, 1)
GPIO.output(dir2, 1)
return template('main.tpl')
@route('/left') #rotate left button
def index():
pwmout1.ChangeDutyCycle(duty)
pwmout2.ChangeDutyCycle(duty)
GPIO.output(dir1, 0)
GPIO.output(dir2, 1)
return template('main.tpl')
@route('/right') #rotate right button
def index():
pwmout1.ChangeDutyCycle(duty)
pwmout2.ChangeDutyCycle(duty)
GPIO.output(dir1, 1)
GPIO.output(dir2, 0)
return template('main.tpl')
@route('/reverse') #reverse button
def index():
pwmout1.ChangeDutyCycle(duty)
pwmout2.ChangeDutyCycle(duty)
GPIO.output(dir1, 0)
GPIO.output(dir2, 0)
return template('main.tpl')
@route('/stop') #stop button
def index():
pwmout1.ChangeDutyCycle(0)
pwmout2.ChangeDutyCycle(0)
return template('main.tpl')
@route('/tornado') #tornado move
def index():
pwmout1.ChangeDutyCycle(100)
pwmout2.ChangeDutyCycle(100)
GPIO.output(dir1, 1)
GPIO.output(dir2, 0)
time.sleep(specialdelay) #you may tweak time of spinning from top of page
GPIO.output(dir1, 0)
GPIO.output(dir2, 1)
time.sleep(specialdelay)
pwmout1.ChangeDutyCycle(0)
pwmout2.ChangeDutyCycle(0)
return template('main.tpl')
@route('/ramp') #ramp special move
def index():
pwmout1.ChangeDutyCycle(duty) #back up with set speed level
pwmout2.ChangeDutyCycle(duty)
GPIO.output(dir1, 0)
GPIO.output(dir2, 0)
time.sleep(specialdelay)
GPIO.output(dir1, 1)
GPIO.output(dir2, 1)
pwmout1.ChangeDutyCycle(100) #forward with full speed
pwmout2.ChangeDutyCycle(100)
time.sleep(specialdelay)
pwmout1.ChangeDutyCycle(0)
pwmout2.ChangeDutyCycle(0)
return template('main.tpl')
try:
run(host='192.168.1.35', port=80) #be sure to put your pi's ip address here
finally:
GPIO.cleanup() #clear all GPIO's before terminating
from bottle import route, run, template, request #make sure bottle is installed
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM) #GPIO BCM pin layout
dir1 = 26 #direction 1 pin
dir2 = 24 #direction 2 pin
pwm1 = 12 #pwm 1 pin
pwm2 = 13 #pwm 2 pin
#the above pins are reserved by the HAT
frequency = 20000 #pwm frequency
duty = 0 #pwm duty cycle 0 to 100
specialdelay = 2 #delay time for special moves
GPIO.setup(dir1, GPIO.OUT) #set pins as GPIO outputs
GPIO.setup(dir2, GPIO.OUT)
GPIO.setup(pwm1, GPIO.OUT)
GPIO.setup(pwm2, GPIO.OUT)
And there's an HTML (tpl) file that goes with it, which I don't see as being the problem
<html>
<body>
<h1><center> ToolBot </center></h1>
<p><h2>
<center><b> Speed: </b></center><br>
<center> [<a href="/1">1</a>] | 
[<a href="/2">2</a>] | 
[<a href="/3">3</a>] | 
[<a href="/4">4</a>] | 
[<a href="/5">5</a>] </center><br><br>
<center><b> Directions: </b> </center><br>
<center> [<a href="/forward">Forward</a>] </center><br><br>
<center>[<a href="/left">Left</a>]  
[<a href="/stop">Stop</a>]  
[<a href="/right">Right</a>]</center><br><br>
<center> [<a href="/reverse">Reverse</a>] </center><br><br>
<center><b> Special Moves: </b></center><br>
<center>[<a href="/tornado">Tornado</a>]  
[<a href="/ramp">Ramp</a>]</center>
</h2></p>
</body>
</html>
I could say the heck with it, and just use a Pi4, but I really wanna use the jetson on this project
Oh, and if you use this code, don't ever click the tornado or the ramp buttons.
I should probably remove them entirely in fact
Scares the bejeebers outta the cat
UPDATE :
I sent an email to Cytron to see if they had any answers, but, it seems that they are focused on the Raspberry Pi for this board...
HOWEVER, they did give me some information that I think might be helpful
The DIR pins (26 & 24) are looking for 5V for HIGH and 0V for LOW, but when I put a meter on those pins, they are only outputting 3.3V. So, if it needs the full 5V in order to trigger the motors, then it won't work because it's not getting sufficient voltage, so, I guess I'll be going with the RPi, which is not at all what I wanted
Like a fool, even tho I was assured this wouldn't work, I kept on looking for an answer
First I found this...
https://www.seeedstudio.com/blog/2020/05/27/configure-pwm-output-on-jetson-nano-m/
This solution requires rebuilding the kernel, which I am in no way prepared to do, although, I was about to give it a shot anyway, thinking, what could I lose ? All I'd have to do is reflash the sd card. Still, I didn't like that option
Then, Paul McWhorter had something that looked much simpler, so I'm looking into that...
Here's his walk-thru...
(I'm following this as I type)
Okay... the test is working when I type the commands directly into python. Now all I need to do is make the right conversions in the code to match the commands that I typed in python.
Other than that, this works, and it's a solution to Jetson Nano PWM
YAY !

