Having problem using PWM to control a futaba servo motor

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Having problem using PWM to control a futaba servo motor

5,386 Views
cramis1
Contributor I
I am using a MC9S12DP256C with an E-clock of 8MHz, the servo motor requires a
period of 20ms(50Hz) with a minimum pulse of 0.5ms and a max pulse of
2.5ms. The problem is that when I hook it up to the motor it just kinda
squirms rapidly, I ckecked it out with a scope and found that the period
coming out is something like 2.5Hz. I can't seem to see where my code or
calculations went wrong.

I divided the 8Mhz clock by 64 to get 125kHz, then divided that by 50Hz
to get that I need a 2500 period. That can fit into the period register
if I concactinate channel 0 and 1. However it doesnt seem to be working
out for some reason.

Any help is much appreciated.

Here is my code:

//start of code


$HC12

; Test program for servos

PWEN: equ $00A0 ; PWM enable register
PWPER0: equ $00B4 ; PWM period channel for channel 0
PWPER1: equ $00B5
PWPER2: equ $00B6
PWCLK: equ $00A2 ; PWM clocks and concatenate (used to
concat ch0 and ch1)
PWDTY0: equ $00BC ; PWM duty cycle for channel 1
PWDTY1: equ $00BD
PWDTY2: equ $00BE
PWPOL: equ $00A1 ; PWM clock select and polarity
PWSCAL0:equ $00A8 ; PWM Scale register 0
PWPRCLK:equ $00A3
PWCAE: equ $00A4
PWCTL: equ $00A5 ; PWM control register


org $08FA


MOVB #%00010000,PWCTL ; concate 0 and 1
MOVB #$00,PWCLK ; clock select
MOVB #$02,PWPOL ; Polarity
MOVB #%00000110,PWPRCLK; Set up an initial frequency
MOVB #$00,PWCAE ; Left-Aligned
MOVB #$00,PWSCAL0 ; Do not further scale clock
MOVB #$02,PWEN ; Enable PWM
MOVB #$09,PWPER0 ; Set channel 0 period
MOVB #$C3,PWPER1

middle: MOVB #$49,PWDTY0 ; Set channel 0 duty cycle -(straight
ahead)-
MOVB #$3D,PWDTY1

ldaa #$FF
JSR delay ;32ms delay

MOVB #$00,PWEN ; Disable PWM

right: MOVB #$2B,PWDTY0 ; Set channel 0 duty cycle -(right
turn)-
MOVB #$F1,PWDTY1

MOVB #$02,PWEN ; Enable PWM

ldaa #$FF
JSR delay ;32ms delay

MOVB #$00,PWEN ; Disable PWM

BRA middle


delay: LDX #$F0FF
delay1: DEX
BNE delay1
DBNE A,delay
RTS
end

//end of code

Thanks
Labels (1)
0 Kudos
7 Replies

856 Views
bigmac
Specialist III
Hello,
 
I think your problem may be that the 16-bit values in the PWM duty registers (11249 or 18749) exceed the value in the PWM period registers (2499).  If my understanding of the data sheet is correct, this will result in a continuous high level at the PWM output. (for polarity bit = 1).
 
But since you are disabling the PWM channel after a timeout period (32ms), this may be what you are actually observing.
 
For 0.5 ms ON period, I would suspect the 16-bit duty register setting should be 63 (2500*0.5/20), and for 2.5 ms the setting ahould be 313.
 
Regards,
Mac
 
0 Kudos

856 Views
cramis1
Contributor I
Thanks for the help but it still doesnt seem to be working, the motor just seems to squirm there even if I put those new values in for the duty.
0 Kudos

856 Views
bigmac
Specialist III
Hello,
 
I would assume that your servo motor device actually requires a number of 20 millisecond cycles to stabilize to the set position.  However, you apparently provide a delay of only 32 milliseconds (less than two cycles) before changing the setting.  Try increasing this delay to one second, or more.  You might also try just changing the duty cycle register value, without disabling and re-enabling the PWM channel - this might avoid timing discontinuity of the output waveform (gaps between pulses shorter than 20 ms at the transition).
 
Regards,
Mac
 
0 Kudos

856 Views
cramis1
Contributor I
Thanks again for the reply, I put in two second delays for it to establish a position however It still just squirms there unfortunetly. Maybe I'll write my calculations here and if possible you can tell me if you see anything wrong with them.

I am using an 8MHZ E-clock which I divided by 64 to get 125000HZ
I want a 50ms period for the motor so my period register will be:
0.050=(1/125000)*2*PWMPERx
which gives PWMPERx=3125

Then for the duty register I want 0.5ms out of 20 ms period which is a duty of 2.5%
so 0.025=PWMDTY/3125
PWMDTY=78

Thanks
Marc
0 Kudos

856 Views
bigmac
Specialist III
Hello Marc,
 
Actually, I could previously see no problem with your original calculation of a PWMPER value of 2499, for a PWM period of 20 ms.  However, there now seems to be some ambiguity whether the period should be 20 ms or 50 ms, and you now use a different method of calculation.  If you really need a 50 ms period, I would have expected a PWMPER value of 6249.  I also note that you are basing your duty cycle calculation on a 20 ms period, rather that the 50 ms.
 
I might suggest you confirm the PWM period requirement from the data sheet for the servo device.  I would also suggest that you examine the PWM output you are actually getting, using an oscilloscope.  This will quickly confirm whether your calculations are correct.
 
If you are presenting the correct timing, but the servo remains unstable, this may indicate a faulty servo.  Do you have any independent means of checking the operation of the servo?
 
Regards,
Mac
 
0 Kudos

856 Views
cramis1
Contributor I
Thanks, I seem to have it working, looks like it was a simple mistake of mixing up 50Hz and 50ms, doh.

But I have one more question maybe you can help me out with, between the positions at 0.5ms period and 2.5ms period (the max and min) there is only about 50 degrees of rotation, if I wanted to get that up to 180 degrees, how could I make it do sucessive rotations?

Thanks Again,
Marc
0 Kudos

856 Views
bigmac
Specialist III
Hello Marc,
 
I would assume that the angular rotation limit is dictated by the design of the servo unit - you would need to check the specified limits for the model you are using.  Ultimately you are likely to reach a mechanical stop.  If the current rotation is somewhat less than the specified limit, you could try slightly reducing the minimum pulse period, and slightly increasing the maximum pulse period - nothing too drastic - and see if the amount of rotation increases, and remains linear.
 
To achieve rotation of 180 degrees, I presume you will need to select a servo model that is capable of this rotation.
 
Regards,
Mac
 
0 Kudos