hal_pru_generic stepgen strange dir signal

58 views
Skip to first unread message

jgnoss

unread,
Jan 30, 2020, 11:26:46 PM1/30/20
to Machinekit


I'm playing around with hal_pru_generic and it's stepgen.

here the config

loadusr -w ./setup.sh
loadusr -w config-pin -f ./pru_stepgen.bbio

loadrt threads name1=fast period1=100000
# loadrt hal_bb_gpio input_pins=817 output_pins=912,817,818,923
loadrt hal_bb_gpio output_pins=912,923
loadrt hal_pru_generic prucode=/usr/lib/linuxcnc/rt-preempt/pru_generic.bin pru=1 halname=hpg num_stepgens=1  pru_period=2500
loadrt hal_arm335xQEP encoders=eQEP0


setp eQEP0.position-scale 13.33333

net enable bb_gpio.p9.out-12 => hpg.stepgen.00.enable
net pulse eQEP0.position => hpg.stepgen.00.position-cmd

setp hpg.stepgen.00.dirpin 817
setp hpg.stepgen.00.steppin 818
setp hpg.stepgen.00.stepinvert 1
setp hpg.stepgen.00.steplen 500
setp hpg.stepgen.00.stepspace 500
setp hpg.stepgen.00.dirsetup 500
setp hpg.stepgen.00.maxvel 10000
setp hpg.stepgen.00.maxaccel 15000
setp hpg.stepgen.00.position-scale 8.88888

addf bb_gpio.read fast
addf eqep.update  fast
addf hpg.capture-position fast
addf bb_gpio.write fast
addf hpg.update fast

and .bbio

overlay cape-universal
overlay cape-bone-iio
#overlay cape-univ-emmc


P9_12 low #enable
P8_17 low #dir
P8_18 low #step
P9_23 low #Machine Power
P8_26 high #Estop out

You might see, idea of that test is, to move the step motor as the encoder turns

The motor doesn't turn, he just sits there wiggling and making strange noise.

going behind that, I see a strange behavior on the dir signal, see pictures.

Any idea why is that?

ju
dirsig_01.png
dirsig_02.png
dirsig_03.png
dirsig_04.png

Damien Dando

unread,
Jan 31, 2020, 4:33:13 AM1/31/20
to Machinekit
Hi,

It look like a "PRU hunting" issue. When the stepgen try to reach "position-cmd", due to internal calculation with float variables, it is common that the stepgen algo. cannot reach a stable state at 0 speed. It sort oscillate between fraction of +/-0.0...1 "step" and trigger a direction change every period of the servo loop.
A "minvel" parameters has been added to the stepgen to avoid that, to try it add the line:
setp hpg.stepgen.00.minvel 0.001
This will "stop" the stepgen to generate step&direction change when the velocity goes bellow 0.001 (in practice it means a null velocity - motor stopped).
Try with higher values (0.01, 0.1) if you still see the problem. To find a "good" value, you can decrease this value until the problem appear again, and multiply by a factor 10 that limit value. 

Another more proper way is to use the halscope and look at the signal "hpg.stepgen.00.velocity-fb", you will probably see this value going a little positive and negative at "0" speed, you need to set "hpg.stepgen.00.minvel" above the maximum/minimum value "hpg.stepgen.00.velocity-fb" at 0 speed, do x2 or x3 on this value for some margin and use that for minvel.

Hope this will solve your problem.
/Damien

jgnoss

unread,
Jan 31, 2020, 5:47:12 AM1/31/20
to Machinekit


Damien you are my hero.
Yes, that did the trick. Still necessary a bit of fine tuning but it goes in the direction I want.
And with your description of the proper way, I'll be there in no time.

I was wondering what that minvel parameter is for, but now it makes a lot of sense.

thanks a lot,
Ju

Damien Dando

unread,
Jan 31, 2020, 7:00:56 AM1/31/20
to Machinekit
Glad to hear it worked!

As for more detailed explanation, the stepgen is made of 2 distinct software parts:
  • stepgen.c that run on the main beagle board black CPU and handle all acceleration/velocity/position calculations from the following inputs data/parameters: position-cmd, minvel, maxvel, maxaccel, position-scale. This calculate the velocity and then the "step rate". This calculation is done every is 100000ns/0.1ms in your case (loadrt threads name1=fast period1=100000) - which seems btw a little fast to me for the beagle bone black but I don't know what other use.. (I typically use 1ms).
  • pru_stepdir.p that run on the dedicate PRU processor and generate the actual step and direction signals from the "step rate" input calculated by the part above.
This architecture setup make it possible to generate quite high step rate with the beagle bone black. This is because the pru_stepdir.p can run much faster (pru_period=2500 => 2500ns in your case) than the stepgen.c loop. There is also some error compensation in the stepgen.c algorithm so the feedback position (ie number of steps) where pru_stepdir.p is at is also taken into consideration when recalculating the velocity and step rate.
When your stepper is stopped, if you do not set minvel (it will use the default value: 0), the velocity/"step rate" passed to pru_stepdir.p will be very close to 0 (maybe something like 0.000001) but most likely never actually be 0. Then at the next iteration of the loop, it will compensate from the feedback position error, and the velocity/"step rate" will be about the same but opposite sign so it oscillate between something like -0.000001, and then +0.0000001, keeping alternating between +/- and triggering a direction change on the dir pin every period stepgen.c runs (0.1ms in your case).
For example, if you move +100 steps, it will oscillate between something 99.999 and 100.001 steps. You might not see any step on the step pin as 0.001 is far less than 1 step but the dir pin will switch direction all the time.
By setting minvel to a non null value, stepgen.c will first check if the calculated velocity (in absolute value) is greater than minvel before passing it to pru_stepdir.p and if it is bellow that it will set the velocity to exactly 0.0 calculate the "step rate" and  the pru_stepdir.p will not trigger any change on the dir pin.

/Damien

jgnoss

unread,
Jan 31, 2020, 8:44:13 AM1/31/20
to Machinekit
Thanks for detailed explanation.
I had a look at the code before, got kind of lost, so I decided to post here.
Now it makes more sense too.
So I may also go back and further investigate that glitchy PWM signal I got from the hal_pru_generic pwmgen.


about the thread period1=100000

I know it's fast, it's a copy/paste left over from my hardware encoder testing.
Since I'm not doing something useful here other than see how the components behave, it's not that critical.
If it comes to constructing something useful, I'll do the math again.

thanks a lot
Ju
Reply all
Reply to author
Forward
0 new messages