Home
JAQForum Ver 20.06
Log In or Join  
Active Topics
Local Time 18:56 07 May 2024 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : PWM gaps?

     Page 2 of 5    
Author Message
Malibu
Senior Member

Joined: 07/07/2018
Location: Australia
Posts: 158
Posted: 06:47am 27 Jul 2018
Copy link to clipboard 
Print this post

  Quote  It can be worked out by by coming up with the max coil RPM you need/want, multiplying by the motor steps per revolution and again by the microstep mode. If there are any pulleys/gearing their drive ratios need to also be included.

Max Rpm's on the output shaft I'm looking at is around 1500 RPM... so it's 1500 div 60 * 200(PPS) gives me around 5kHz
A stepper doing 1500 RPM is near on useless because there will be little torque, so I'll probably need a pulley ratio to drive a final shaft. Hence the testing

I looked at the SETTICK command briefly and a resolution of 1mS won't be good enough I don't think, but it was a busy day so didn't have much time to play.

  Quote  Running the test code above did not show any glitching.

I was wondering earlier, what crystal frequency are you using on you MM? Maybe it has a bearing on the result.

For now, I need to settle in and relax! With 6 double glazed windows out and in, a roomful of furniture moved (yet to be moved back) I'm done for!
Is it Scotch-o-clock yet??

John

John
 
Geoffg

Guru

Joined: 06/06/2011
Location: Australia
Posts: 3165
Posted: 07:23am 27 Jul 2018
Copy link to clipboard 
Print this post

I can see the output stalling. Even this little program will cause it:
Do
PWM 1, 1000, 25
PWM 1, 1001, 25
Loop

Each time the output stalls the signal is low (never high) and each time it lasts for 84mS regardless of the PWM frequency. The occurrence appears to be random. SERVO does the same.

This is going to take some serious debugging as it involves the PIC32 hardware and its documentation (the latter is problematical). Leave it with me.

Geoff

Geoff Graham - http://geoffg.net
 
Azure

Guru

Joined: 09/11/2017
Location: Australia
Posts: 446
Posted: 07:30am 27 Jul 2018
Copy link to clipboard 
Print this post

  Geoffg said   I can see the output stalling. Even this little program will cause it:
Do
PWM 1, 1000, 25
PWM 1, 1001, 25
Loop

Each time the output stalls the signal is low (never high) and each time it lasts for 84mS regardless of the PWM frequency. The occurrence appears to be random. SERVO does the same.


Geoff, I'll setup my unit again and try that code as well. That way there will be more than 1 unit to verify things on.

That probably answers my question about whether the PWM/SERVO freq is reloaded in sync with the signal pulse.

How did you determine it was stalling (ie what are you using to measure it)?
 
Geoffg

Guru

Joined: 06/06/2011
Location: Australia
Posts: 3165
Posted: 08:36am 27 Jul 2018
Copy link to clipboard 
Print this post

I think that the fix will be to generate a PIC32 interrupt when the timer count wraps back to zero and then update the timer's period register The code is already there for updating the SERVO pulse width. The question will be how much does this load down the CPU.

I used a digital scope running a 10mS/div timebase.
Geoff Graham - http://geoffg.net
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 8598
Posted: 08:54am 27 Jul 2018
Copy link to clipboard 
Print this post

I'm away from home - can someone test this on the MMX and let me know results - thanks
 
Malibu
Senior Member

Joined: 07/07/2018
Location: Australia
Posts: 158
Posted: 09:10am 27 Jul 2018
Copy link to clipboard 
Print this post

  Quote  Each time the output stalls the signal is low (never high) and each time it lasts for 84mS regardless of the PWM frequency. The occurrence appears to be random. SERVO does the same.

That's great Geoff (errr... figuratively speaking of course)
I really appreciate you're looking into this.

What you have described confirms what I saw happening on PWM and SERVO commands - I put the time at around 90ms, but that's probably my DSO setup.
Just out of interest, does it happen with the other PWM and SERVO outputs?

Please let me know if I can do something to assist

John

John
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 8598
Posted: 09:44am 27 Jul 2018
Copy link to clipboard 
Print this post

Geoff

I've just remembered something and I think I know the cause.

The problem happens when you change the timer compare value to less than the current value of the timer. In this case the timer runs until it hits 0xFFFF and goes back to zero and then continues until it finally reaches the new value before triggering. The solution is to wait in the PWM command until the last cycle completes and then change the values early in the cycle (before the next pulse starts) - no interrupts needed.
 
Malibu
Senior Member

Joined: 07/07/2018
Location: Australia
Posts: 158
Posted: 11:29pm 27 Jul 2018
Copy link to clipboard 
Print this post

Morning all

Some experimental observations from this morning...
Here's the code I used (with my running notes as I monitored on the DSO)


Option Explicit

Dim i,j As integer

DecreaseForLoop '<<--- Change here

'<<==============================================

Sub DecreaseForLoop
Do
For i = 100 To 20 Step -1 'Setup the next decreasing PWM frequency
PWM 1,i,10 ' PWM output 1.. the new frequency.. Duty cycle
' NOTES: The first pulse duty cycle is alway 3.2 times longer than
' the next pulse duty cycle.
' Any higher than 30% duty, pulses 1 & 2 blend into a single wide pulse.
For j = 1 To 400
' j give the HZ time to settle
' higher value gives more pulse of the same Hz
Next j
Next i
PWM 1, stop ' Stop the PWM to create a LOW gap in the signal
Pause 100 ' A good size gap to easily see
Loop
End Sub

'<<==============================================

Sub IncreaseForLoop
Do
For i = 20 To 100 'Setup the next decreasing PWM frequency
PWM 1,i,10 ' PWM output 1.. the current set Hz.. Duty cycle
'NOTES: The first pulse duty cycle width is always 10%(mS) of the
'set duty cycle. ie: Set=10,pulse=1mS.. Set=70,pulse=7mS
For j = 1 To 400
'NOTES: Unrepeatable gaps, but are consistant with values
Next j
Next i
PWM 1, stop ' Stop the PWM to create a 0V gap in the signal
Pause 100 ' A good size gap to easily see
Loop
End Sub

'<<==============================================

Sub IncreasePause
Do
For i = 20 To 100 'Setup the next decreasing PWM frequency
PWM 1,i,10 ' PWM output 1.. the current set Hz.. Duty cycle
'NOTES: The first pulse duty cycle width is always 10%(mS) of the
'set duty cycle. ie: Set=10,pulse=1mS.. Set=70,pulse=7mS
Pause 10
'NOTES: Consistantly positioned gaps, consistant with the PAUSE value
'Doesn't appear random and can be repeatable
'PAUSE=10 looks perfect
Next i
PWM 1, stop ' Stop the PWM to create a 0V gap in the signal
Pause 100 ' A good size gap to easily see
Loop
End Sub


Running the "DecreaseForLoop" (which is for decreasing frequency with a j variable) I made a few observations:
1) The first pulse in the sequence is always 3.2 times the width of the second pulse. That's OK for my projected use (I only need the rising edge), but when the duty cycle setting reaches about 30%, the 1st and 2nd pulse merge into a single wide pulse.
2)Setting j to whatever value makes no difference to the final outcome, but it allows more PWM pulses over a longer total time period (more pulses of the same frequency.
3) this works perfectly
(--- I used the j variable to introduce a delay as with the PAUSE statement, but to isolate if PAUSE was an issue, I tried a substitute ---)

Running the "IncreaseForLoop" (Increasing frequency with a j variable)
1) The first pulse is always 10% (in mS) of the set value of the duty cycle. So, if I set the duty to 70, I see a 1st pulse width of 7mS... set it to 20%, I see 2mS.
I didn't try a duty of 25 - presumable I would get 2.5mS, but it may turn out that the first pulse is an integer and will round up to 3mS?
2) Here it gets a little confusing! For the most part, I saw the gaps in the waveform, BUT, changing the j value would produce gaps in random positions but seemingly consistently across the wave form...
So, if I enter a j value of 400 'this' time and run the code, the gap will be in a certain position right across the repeating waveform. I change j to 600 (for example) and I get different gap positions, consistent across all the waveform as long as I ran with 'that' value of 600.
OK, change back to 400 and I get gaps in a DIFFERENT position to the last 400 I ran, but consistent across the waveform for as long as I ran that one!
Sometimes I would change back and forth to all different values and eventually get back to a value of 400, and it would be a perfect signal!
Are we all confused yet with my blabbering, because I sure was doing all this!?

So, running "IncreasePause" (just to triple check the PAUSE statement)
1) The same 10% duty cycle on the first pulse as above
2) PAUSE would create gaps in the waveform and, as above would be in a seemingly random position, but identical across the stream of waveforms. Change the PAUSE value, and I get a different position to the last, but consistent for the time I ran it.
OK, set PAUSE to 10 and I watch the pattern, change to PAUSE 5 and I get a different pattern. Change back to PAUSE 10 - and I get the same gap position as the LAST time i ran with a PAUSE 10 statement!

So, what does all this mean?
I've NO idea

I just wanted to try and learn a bit more on what was happening, but now I'm more confused than ever!
Any interpretations on my observations?

John

John
 
isochronic
Guru

Joined: 21/01/2012
Location: Australia
Posts: 689
Posted: 02:20am 28 Jul 2018
Copy link to clipboard 
Print this post

I know it is not the point, but it would be worth delegating the stepper drive to something like grbl, and sending the commands to it from the MM.
 
Malibu
Senior Member

Joined: 07/07/2018
Location: Australia
Posts: 158
Posted: 04:25am 28 Jul 2018
Copy link to clipboard 
Print this post

  Quote  delegating the stepper drive to something like grbl, and sending the commands to it from the MM.

Not sure about a GRBL... I didn't find a whole lot of info on it. The little bit I did find seems to be that it's a board that gets attached to a Uno uCOntroller and takes step/direction signals.
Is that right?

That's what I'm using here but it's a DRV8825 instead. The signals are all controlled by the MM+ which are Step, Direction, Enable and step modes. The 8825 board does all the hard yakka.

(Unless I understand the GRBL wrong?)

John
 
MicroBlocks

Guru

Joined: 12/05/2012
Location: Thailand
Posts: 2209
Posted: 05:18am 28 Jul 2018
Copy link to clipboard 
Print this post

GRBL is a combination of an Arduino and the motor drivers.
You then connect through a serial port and just send GCODE commands.
GRBL also has ramp up and ramp down support which can be adjusted with parameters.
Then it will just do it for you.
Works pretty well and it is used in many DIY CNC machines.
It also takes the really difficult nitty gritty parts out of your code.
This is a blessing for many but if you are really into getting as close to the hardware then it takes away the challange.
All depends on how much time and effort you want to put into which part of the development.


Microblocks. Build with logic.
 
Azure

Guru

Joined: 09/11/2017
Location: Australia
Posts: 446
Posted: 07:28am 28 Jul 2018
Copy link to clipboard 
Print this post

I have repeated the code mentioned before. I added a little to display what the waveform is doing and recorded a quick video of the computer screen showing the bitscope and MM console output.

Here is the modified code (added variables for slow and fast and a pause at each end)
Option Explicit

Dim integer i, slow=20, fast=5000

Do
Print "Ramp Up to "; fast; "Hz"
For i = slow To fast Step 1
PWM 1,i,25
Pause 5
Next i

Print "High Speed "; fast; "Hz"
PWM 1, fast,25
Pause 5000

Print "Ramp Down to "; slow; "Hz"
For i = fast To slow Step -1
PWM 1,i,25
Pause 5
Next i

Print "Low Speed "; slow; "Hz"
PWM 1, slow, 25
Pause 5000
Loop


Here is the MM+64 BP PWM Test video (quickly recorded using my phone) so please bear with the rough handheld look, wanted to show it appears to be working in this setup with no glitches.
 
isochronic
Guru

Joined: 21/01/2012
Location: Australia
Posts: 689
Posted: 09:46am 28 Jul 2018
Copy link to clipboard 
Print this post

To expand a bit, the genre is based on a board/s that reads simple ascii commands (g-code) on its serial input. The board/s then generates the pulses required for the stepper motors. The gcodes specify movements, origins, scales, arcs, etc and the system can look-ahead for accelerations and so on. Typically the boards have connections and power ics for three or so stepper motors (x,y,z) and also control some auxiliaries. Grbl itself uses compiled c on an arduino hardware base and shield, there are very similar systems utilising gcode on other platforms like pi linux etc as well.

 
Malibu
Senior Member

Joined: 07/07/2018
Location: Australia
Posts: 158
Posted: 09:24pm 01 Aug 2018
Copy link to clipboard 
Print this post

I doubt this will be presented as a 'good coding example', but as a temporary solution this seems to do the trick...

option explicit

dim i, j as integer '<< declares
const min=20 '<< minimum frequency
const max=5000 '<< maximum frequency

setpin 49, inth, PulseInt '<< define the interrupt

i = min '<< Set the initial minimum frequency
j = 0 '<< set a dummy variable

do
pwm 1, min, 50 '<< start the PWM at minimum frequency
do while i < max '<< Have we reached the maximum?
j = j + 1 '<< fill in time while waiting
loop '<< no, wait here
pwm 1, stop '<< Stop the PWM
i = min '<< reset the minimum
j = 0 '<< reset the dummy variable
pause 100 'Wait here and create a trace marker on the DSO
loop '<< do it again

Sub PulseInt '<< do this interrupt
pwm 1, i, 50 '<< set the PWM to the valie of i
i = i + 1 '<< increase i for next frequency
end sub


Simply put, the PWM is setup and run as you would expect, but the difference is that I've looped PWM output to an input declared as an interrupt.
The initial frequency of the PWM is set to minimum and when the output goes high, it triggers the interrupt. Only THEN will the PWM parameters get changed to the next value.
The idea is to write the PWM parameters at a point in time that the PIC can deal with it and it seems to work OK from 20Hz to 5KHz
At least it gives me a smooth ramp up in frequency I can play with

John
 
Malibu
Senior Member

Joined: 07/07/2018
Location: Australia
Posts: 158
Posted: 09:38pm 01 Aug 2018
Copy link to clipboard 
Print this post

Sorry, I meant to put up the resultant waveform...



That's with MIN=20 & MAX=100

John
 
viscomjim
Guru

Joined: 08/01/2014
Location: United States
Posts: 925
Posted: 12:15pm 02 Aug 2018
Copy link to clipboard 
Print this post

Not related to original post, but I have used a few boards from here with great success using the micromite to send commands to run steppers. Works quite well and made my life a bit easier. Just send commands over serial. Even has feedback using serial or a "profile done" pin. Just a thought.
 
Geoffg

Guru

Joined: 06/06/2011
Location: Australia
Posts: 3165
Posted: 07:29am 05 Aug 2018
Copy link to clipboard 
Print this post

I have updated the beta version to fix the PWM gaps issue (it is now at beta 5).

It can be downloaded from: http://geoffg.net/micromite.html#Downloads
Look for "Micromite Firmware V5.04.10 Beta Test Version"

I have done a lot of testing on it and it runs smoothly on both ascending and descending frequencies. Please give it a run and let me know if you find anything else (fingers crossed that that will not happen).

Geoff
Geoff Graham - http://geoffg.net
 
Malibu
Senior Member

Joined: 07/07/2018
Location: Australia
Posts: 158
Posted: 11:38pm 05 Aug 2018
Copy link to clipboard 
Print this post

Thanks for the effort you put in Geoff!
I've hammered your new version pretty hard this morning and it's a BIG improvement!
I started off with Ramp Up, Hold Speed, Ramp Down, Hold Speed in a DO: LOOP routine. I kept my eyes on the DSO and it all seemed good, but I could still hear a tiny <clunk> in the motor occasionally.
I figured that it was probably my hardware and/or code that I had, but as I was going glassy-eyed watching the pulses, I THOUGHT that I saw a glitch...
I whittled down the code and ran this...
Const mStep=48, mDirection=50, mEnable=54 <<- Set Constants

SetPin 50, dout <<-- Set Pins
SetPin 51, dout
SetPin 52, dout
SetPin 53, dout
SetPin 54, dout

Pin(mDirection)=Low <<-- CW Rotation
Pin(mEnable)=High <<-- Enable DRV882
Port (51,3)= &B101 <<-- Set to 1/32 Mode

do
for i = 20 to 25000
pwm 1, i, 50
pause 1
next i
loop

Most is to setup the DRV8825 board and I have limited the mode to 1/32 micro-stepping. I've also upped the PWM frequency to 25K, but that's because I've set 1/32 mode.

I kept my eyes glued to the DSO, ready to pounce on the pause icon and finally here's the capture I got.


This is at around 3.7Khz and 1.45mS wide, but I've also captured 1.3mS at various other frequencies too
Again, there seems to be no set pattern or frequency for the gap. Edit: Again, only low, never highs.
With my USB DSO, it could be a limitation of that setup. It could also be my hardware/code, so I'll keep going and see where it ends up.
No doubt, a big improvement on what was prior with a much smoother and sweeter sounding stepper motor.
Edited by Malibu 2018-08-07

John
 
Geoffg

Guru

Joined: 06/06/2011
Location: Australia
Posts: 3165
Posted: 11:54pm 05 Aug 2018
Copy link to clipboard 
Print this post

Thanks, I can guess what is causing this one and it is a bit more complicated. I will have a go at it over the next day or two and report back.
Geoff Graham - http://geoffg.net
 
Malibu
Senior Member

Joined: 07/07/2018
Location: Australia
Posts: 158
Posted: 11:58pm 05 Aug 2018
Copy link to clipboard 
Print this post

A little more...
Here's the code - an adaption of your test code Geoff
Do
PWM 1, 3000, 25
PWM 1, 3010, 25
Loop

That should be (3000/200PPR)*60 = 900RPM... confirmed by the digital tacho.

While I run the code, the motor goes crazy by stopping, starting, hunt forward, run reverse, stop, hunt backward... and so on (It's hard to explain, but it does what motors shouldn't do!)
So, clicking ^C in MMchat, will do one of two things:
1) the Motor runs perfectly sweet.
2) the Motor squeals in a stalled position.
Whichever one happens, the frequency continues smooth and steady at 3Khz and physically, the motor runs according to what it was doing when I actually click ^C.

Still fiddling - I'll keep you updated!

John
 
     Page 2 of 5    
Print this page
© JAQ Software 2024