Notifications
Clear all

Jetson Nano and the MDD10

3 Posts
1 Users
0 Reactions
5,217 Views
Spyder
(@spyder)
Member
Joined: 7 years ago
Posts: 856
Topic starter  

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...

image

And if that wasn't confusing enough, there's always this one...

image

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
 
The only difference in the Pi code is the very beginning...
 
 
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>]&emsp;|&emsp;
[<a href="/2">2</a>]&emsp;|&emsp;
[<a href="/3">3</a>]&emsp;|&emsp;
[<a href="/4">4</a>]&emsp;|&emsp;
[<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>]&emsp;&emsp;
[<a href="/stop">Stop</a>]&emsp;&emsp;
[<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>]&emsp;&emsp;
[<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



   
Quote
Spyder
(@spyder)
Member
Joined: 7 years ago
Posts: 856
Topic starter  

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



   
ReplyQuote
Spyder
(@spyder)
Member
Joined: 7 years ago
Posts: 856
Topic starter  

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...

https://docs.nvidia.com/jetson/l4t/index.html#page/Tegra%20Linux%20Driver%20Package%20Development%20Guide/hw_setup_jetson_io.html

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 !



   
ReplyQuote