PWM motor control
woody363
Posts: 7
I think I am misunderstanding some features of the timers and getting some outputs that I am struggling to explain...
I am trying to control a 4 phase stepper motor with variable speed and voltage, sending a PWM signal alternately to the four outputs. Im testing the outputs using LEDs for now and havent been able to control the output signal to alternating pins as I am looking for. when pressing the button: very occasionally it gives the pwm pulses to alternating pins as desired, but more often does nothing or gives short flashes and sometimes gets 'stuck' on one pin and needs resetting.
can anyone tell me what Ive missed? All the other posts seem to talk about cogging, but I cant see how it would help here.
thanks guys,
Woody
the code im using is as follows... (sorry it probably has some unnecessary lines since I have been modifying the examples)
I am trying to control a 4 phase stepper motor with variable speed and voltage, sending a PWM signal alternately to the four outputs. Im testing the outputs using LEDs for now and havent been able to control the output signal to alternating pins as I am looking for. when pressing the button: very occasionally it gives the pwm pulses to alternating pins as desired, but more often does nothing or gives short flashes and sometimes gets 'stuck' on one pin and needs resetting.
can anyone tell me what Ive missed? All the other posts seem to talk about cogging, but I cant see how it would help here.
thanks guys,
Woody
the code im using is as follows... (sorry it probably has some unnecessary lines since I have been modifying the examples)
CON _clkmode = xtal1 + pll16x ' Feedback and PLL multiplier _xinfreq = 5_000_000 ' External oscillator = 5 MHz LEDs_START = 0 ' Start of I/O pin group for on/off signals LEDs_END = 15 ' End of I/O pin group for on/off signals PUSHBUTTON = 18 VAR long speed PUB Motor ' Main method '' Sends on/off (3.3 V / 0 V) signals at approximately 2 Hz. dira[LEDs_START..LEDs_END]~~ ' Set entire pin group to output speed := 8 repeat ' Endless loop if ina[16] == 1 speed := speed + 10 !outa[4] if ina[17] == 1 speed := speed - 10 ' Change the state of pin group if ina[19] == 1 ' If pushbutton pressed PWM(8,clkfreq/speed + cnt) PWM(9,clkfreq/speed + cnt) PWM(10,clkfreq/speed + cnt) PWM(11,clkfreq/speed + cnt) else ' If pushbutton not pressed waitcnt(clkfreq / 20 + cnt) ' Wait 1/20 second -> 10 Hz PUB PWM(PIN, Delay)| tc, tHa, t ctra[30..26] := %00100 ' Configure Counter A to NCO ctra[5..0] := PIN frqa := 1 dira[4]~~ tC := clkfreq/10000 ' Set up cycle and high times tHa := clkfreq/10000 t := cnt ' Mark counter time repeat Delay/cnt ' Repeat PWM signal phsa := -tHa ' Set up the pulse t += tC ' Calculate next cycle repeat waitcnt(t) ' Wait for next cycle 'ctra[5..0] := 5 'change output to different pin since i havent found off command yet 'outa[PIN]:=0 waitcnt(Delay) return
Comments
1. Your button-handling.
A button handling routine has to take care of bouncing, otherwise you get strange behaviour.
And it has to wait for a release of the button before it accepts the next button input - or an automatic repeat rate.
2. Try to run the stepper without PWM.
The stepper does not need PWM. Switching the outputs in the right sequence is the trick. This way you operate the stepper in so called full-step mode. Start slow. When you want speed you have to add ramping up and ramping down.
What's the purpose of the PWM? You want to control the voltage but keep the motors running in full step mode (to increase torque when running on higher speed)? Or is the PWM for microstepping?
Did you search for stepper in the forum? Recently we had threads dealing with stepper mototrs.
In your case it could continuously check the input-buttons, only accepting an input in case the button has been released before .... only triggering the PWM if the previous cycle is done ...
Another COG is waiting for a signal to run the series of PWM-calls. As a signal you can use a global variable, where the glue-COG sets a specific value and the PWM-COG clears that value after the job is done. This way the glue-COG can sync with it, if needed.
For example you can start a COG which has a repeat loop around your 4 PWM-calls. Before the PWM-calls you only wait for the signal and after the PWM-calls you set the signal back to 0.
Keep in mind that in this case you need to shift the DIRA definitions of the PINs that should be used by PWM-COG in front of the loop.
And thank you for sharing your working code! It's always helpfull to not only show the problem but show the sollution as well.