Controlling hobby servos

Questions and discussion about The WiPy 1.0 board and CC3200 boards.
Target audience: Users with a WiPy 1.0 or CC3200 board.
User avatar
deshipu
Posts: 1374
Joined: Thu May 28, 2015 5:54 pm

Controlling hobby servos

Post by deshipu » Sun Dec 20, 2015 11:08 am

I bought my WiPy boards with one goal in mind -- to use them for controlling my robots. In order to do that, I need to generate a 50Hz PWM signal with duty between 600 and 2400µs. Sounds simple? After waiting for the promised Timer class overhaul (after which I would have to rewrite everything) I decided that I can't wait any longer, and tried to make it work with the current API. So I went to the official documentation at http://micropython.org/resources/docs/e ... modulation and tried to get this to work:

Code: Select all

>>> from machine import Timer
>>> from machine import Pin
>>> p_out = Pin('GP1', mode=Pin.AF, alt=9)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: no such attribute
>>> dir(Pin)
['init', 'value', 'toggle', 'id', 'mode', 'pull', 'drive', 'alt_list', 'irq', 'board', 'IN', 'OUT', 'OPEN_DRAIN', 'ALT', 'ALT_OPEN_DRAIN', 'PULL_UP', 'PULL_DOWN', 'LOW_POWER', 'MED_POWER', 'HIGH_POWER', 'IRQ_FALLING', 'IRQ_RISING', 'IRQ_LOW_LEVEL', 'IRQ_HIGH_LEVEL']
>>> p_out = Pin('GP1', mode=Pin.ALT, alt=9)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: invalid argument(s) value
>>> p_out = Pin('GP1', mode=Pin.ALT, alt=7)
>>> tim = Timer(2, mode=Timer.PWM, width=16)
>>> tim_a = tim.channel(Timer.A, freq=50, duty_cycle=11)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: invalid argument(s) value
>>> tim_a = tim.channel(Timer.A, freq=50)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: invalid argument(s) value
Either I'm doing some trivial mistake here, or this doesn't work?

RinusW
Posts: 9
Joined: Wed Oct 07, 2015 10:51 am

Re: Controlling hobby servos

Post by RinusW » Tue Feb 09, 2016 9:01 pm

In my experience PWM works only with a freq > 1100 Hz.

User avatar
dhylands
Posts: 3457
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: Controlling hobby servos

Post by dhylands » Tue Feb 09, 2016 10:51 pm

RinusW wrote:In my experience PWM works only with a freq > 1100 Hz.
That would be for using PWM to control a regular DC motor using an H-Bridge. For hobby servos, the PWM frequency is typically in the 50-60 Hz range.

mdgart
Posts: 10
Joined: Mon Feb 08, 2016 8:04 pm

Re: Controlling hobby servos

Post by mdgart » Thu Feb 11, 2016 8:19 pm

dhylands, I'll bought a DRV8833 H-Bridge to control two DC Motors, I'm newbie I want to ask you if you have any advice on how to do that, I'm not sure I understand how PWM works, the wipy documentation it's not very clear for me:

from machine import Timer
from machine import Pin

# assign GP25 to alternate function 9 (PWM)
p_out = Pin('GP25', mode=Pin.AF, alt=9)

# timer 2 in PWM mode and width must be 16 buts
tim = Timer(2, mode=Timer.PWM, width=16)

# enable channel A @1KHz with a 50% duty cycle
tim_a = tim.channel(Timer.A, freq=1000, duty_cycle=50)

In particular, this code create a new Pin object p_out, but then is not used anywhere in the Timer object, so my question is: how do I setup p_out frequency etc.? I would need to setup different GPIO to different frequency if I want to control the two motors independently, how can I do that?

User avatar
dhylands
Posts: 3457
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: Controlling hobby servos

Post by dhylands » Thu Feb 11, 2016 8:32 pm

I have lots of examples for the pyboard, but I haven't had a chance to look at the timer stuff for the WiPy, so I can't really help you there.

User avatar
deshipu
Posts: 1374
Joined: Thu May 28, 2015 5:54 pm

Re: Controlling hobby servos

Post by deshipu » Fri Feb 12, 2016 8:31 am

You create the pin object just to set the pin in the AF mode 9, which is PWM. Then it's bound to a specific channel of a specific timer.

mdgart
Posts: 10
Joined: Mon Feb 08, 2016 8:04 pm

Re: Controlling hobby servos

Post by mdgart » Fri Feb 12, 2016 5:58 pm

Thanks deshipu,

I got it eventually, I just received the H Bridge yesterday, I'll do some experiments this weekend and let you guys know how it goes. I'm also trying to write up some tutorials for the wipy, since there is nothing out there.

mdgart
Posts: 10
Joined: Mon Feb 08, 2016 8:04 pm

Re: Controlling hobby servos

Post by mdgart » Thu Feb 18, 2016 1:54 am

I was able to control the DC motors with PWM, but now I'm having a lot of issue trying to control a Servo.
I need a PWM that produce this signal:

The pulses are 20ms apart (50Hz).
1.0ms to 1.25ms pulse length produces 0 degrees.
1.5ms pulse length produces 90 degrees (neutral).
1.75ms to 2.0ms pulse length produces 180 degrees.

Now the problem is that I can't setup PWD at 50Hz with a duty cycle from 5% to 17%, I got weird error like the ones that you indicate.
I tried to simulate the PWM in plan python, like this:

Code: Select all

from machine import Pin
import time
g = Pin('GP9', mode=Pin.OUT, drive=Pin.HIGH_POWER)
pos = 1500

for x in range(0, 100):
   g(1)
   time.sleep_us(pos)
   g(0)
   time.sleep_us(5000-pos); 
   time.sleep_ms(15)
It doesn't work either. Any suggestion?

RinusW
Posts: 9
Joined: Wed Oct 07, 2015 10:51 am

Re: Controlling hobby servos

Post by RinusW » Thu Feb 18, 2016 12:05 pm

dhylands wrote:
RinusW wrote:In my experience PWM works only with a freq > 1100 Hz.
That would be for using PWM to control a regular DC motor using an H-Bridge. For hobby servos, the PWM frequency is typically in the 50-60 Hz range.
The thing I wanted to say is that while experimenting with PWM output on the WiPy I only got good results for frequencies above 1100 Hz. If I tried to use frequencies well below this 1100 Hz, I got all kind of error messages.
A short example:

Code: Select all

>>> from machine import Pin,Timer                                               
>>> led=Pin('GP24', Pin.ALT, alt=5)                                             
>>> tim=Timer(1,mode=Timer.PWM)                                                 
>>> tch=tim.channel(Timer.A, freq=10000, duty_cycle=10)                         
>>> tch.duty_cycle(70)                                                          
>>> tch.duty_cycle(100)                                                         
>>> tch=tim.channel(Timer.A, freq=50, duty_cycle=10)                            
Traceback (most recent call last):                                              
  File "<stdin>", line 1, in <module>                                           
ValueError: invalid argument(s) value                                           
TDM with a frequency of 10kHz works, but selecting a frequency of 50 Hz gives this error message. My experiments indicated that the lowest frequency one could use without error messages is around 1100 Hz

RinusW
Posts: 9
Joined: Wed Oct 07, 2015 10:51 am

Re: Controlling hobby servos

Post by RinusW » Thu Feb 18, 2016 12:58 pm

mdgart wrote:

Code: Select all

from machine import Pin
import time
g = Pin('GP9', mode=Pin.OUT, drive=Pin.HIGH_POWER)
pos = 1500

for x in range(0, 100):
   g(1)
   time.sleep_us(pos)
   g(0)
   time.sleep_us(5000-pos); 
   time.sleep_ms(15)
It doesn't work either. Any suggestion?
This code works with my WiPy. See for yourself, what my scope shows at 'GP9':
Image
Notice the 1,5 ms pulse with a repetition period of 20 ms, exactly as you programmed it.

hmmm, apparently the image doesn't show. You can use the next url also:
https://drive.google.com/file/d/0B94MI7 ... sp=sharing

Post Reply