- Posts: 52
- Thank you received: 0
Gearchange help controlling a BLDC motor
- tacklem60
- Offline
- Senior Member
-
Less
More
7 years 1 month ago #146446
by tacklem60
Replied by tacklem60 on topic Gearchange help controlling a BLDC motor
I tried to find a few similar applications for what I am doing but keep getting results who try to use lincurve for PWM. I think I am like 60% there, but I am having issues with the correct terms to put in the outputs of lincurve and inputs of my spindle speed out commands. Below is the majority of my hal file, if you have a second to look at what I am doing wrong.
I basically just put my spindle in low gear and started at S250 (which actually yielded 85RPM) and moved up from there writing down the actual speed that came back at each requested value. I made 16 total data points which looked like the max for lincurve. I put 2 points right next to each other at 1300 and 1301 so it wouldnt try to interpolate at the transition between low and high gear.
#This adds a velocity controlled 4th axis
loadrt stepgen step_type=0,0,0,0 ctrl_type=p,p,p,v
loadrt scale count=1
#setup for scaling
setp scale.0.in 0
#must be tuned
setp scale.0.gain 0.885
#no current offset
setp scale.0.offset 0
#connect scale to servo clock thread
addf scale.0 servo-thread
#setup for stepgen to drive spindle
setp stepgen.3.position-scale 1.83
#max RPM of Spindle
setp stepgen.3.maxvel 2950
setp stepgen.3.steplen 1
setp stepgen.3.stepspace 0
setp stepgen.3.dirhold 28000
setp stepgen.3.dirsetup 23000
#max accel for spindle
setp stepgen.3.maxaccel 800
net spindle-enable <= motion.spindle-on => stepgen.3.enable
#sends the speed request from EMC to scale module
net spindle-cmd motion.spindle-speed-out => scale.0.in
#sends scaled spindle speed to EMC and spindle stepgen for requested speed
net spindle-freq <= scale.0.out => stepgen.3.velocity-cmd
#sends frequency out to par port 16 and to EMC
net spindle-out <= stepgen.3.step => parport.0.pin-16-out
loadrt lincurve personality=16
addf lincurve.0 servo-thread
setp lincurve.0.x-val-00 0
setp lincurve.0.y-val-00 0
setp lincurve.0.x-val-01 85
setp lincurve.0.y-val-01 250
setp lincurve.0.x-val-02 182
setp lincurve.0.y-val-02 550
setp lincurve.0.x-val-03 290
setp lincurve.0.y-val-03 700
setp lincurve.0.x-val-04 340
setp lincurve.0.y-val-04 850
setp lincurve.0.x-val-05 395
setp lincurve.0.y-val-05 1000
setp lincurve.0.x-val-06 500
setp lincurve.0.y-val-06 1150
setp lincurve.0.x-val-07 550
setp lincurve.0.y-val-07 1300
setp lincurve.0.x-val-08 1237
setp lincurve.0.y-val-08 1301
setp lincurve.0.x-val-09 1360
setp lincurve.0.y-val-09 1450
setp lincurve.0.x-val-10 1575
setp lincurve.0.y-val-10 1600
setp lincurve.0.x-val-11 1709
setp lincurve.0.y-val-11 1750
setp lincurve.0.x-val-12 1930
setp lincurve.0.y-val-12 2000
setp lincurve.0.x-val-13 2271
setp lincurve.0.y-val-13 2300
setp lincurve.0.x-val-14 2611
setp lincurve.0.y-val-14 2600
setp lincurve.0.x-val-15 2950
setp lincurve.0.y-val-15 2950
net spindle-raw motion.spindle-out => lincurve.0.in
net spindle-corrected lincurve.0.out => pwmgen.0.in
addf parport.0.read base-thread
addf stepgen.make-pulses base-thread
addf parport.0.write base-thread
addf parport.0.reset base-thread
addf stepgen.capture-position servo-thread
addf motion-command-handler servo-thread
addf motion-controller servo-thread
addf stepgen.update-freq servo-thread
#net spindle-cmd-rpm <= motion.spindle-speed-out
#net spindle-cmd-rpm-abs <= motion.spindle-speed-out-abs
#net spindle-cmd-rps <= motion.spindle-speed-out-rps
#net spindle-cmd-rps-abs <= motion.spindle-speed-out-rps-abs
net spindle-cmd <= motion.spindle-speed-out
net spindle-cw <= motion.spindle-forward
net spindle-ccw <= motion.spindle-reverse
net coolant-mist <= iocontrol.0.coolant-mist
I basically just put my spindle in low gear and started at S250 (which actually yielded 85RPM) and moved up from there writing down the actual speed that came back at each requested value. I made 16 total data points which looked like the max for lincurve. I put 2 points right next to each other at 1300 and 1301 so it wouldnt try to interpolate at the transition between low and high gear.
#This adds a velocity controlled 4th axis
loadrt stepgen step_type=0,0,0,0 ctrl_type=p,p,p,v
loadrt scale count=1
#setup for scaling
setp scale.0.in 0
#must be tuned
setp scale.0.gain 0.885
#no current offset
setp scale.0.offset 0
#connect scale to servo clock thread
addf scale.0 servo-thread
#setup for stepgen to drive spindle
setp stepgen.3.position-scale 1.83
#max RPM of Spindle
setp stepgen.3.maxvel 2950
setp stepgen.3.steplen 1
setp stepgen.3.stepspace 0
setp stepgen.3.dirhold 28000
setp stepgen.3.dirsetup 23000
#max accel for spindle
setp stepgen.3.maxaccel 800
net spindle-enable <= motion.spindle-on => stepgen.3.enable
#sends the speed request from EMC to scale module
net spindle-cmd motion.spindle-speed-out => scale.0.in
#sends scaled spindle speed to EMC and spindle stepgen for requested speed
net spindle-freq <= scale.0.out => stepgen.3.velocity-cmd
#sends frequency out to par port 16 and to EMC
net spindle-out <= stepgen.3.step => parport.0.pin-16-out
loadrt lincurve personality=16
addf lincurve.0 servo-thread
setp lincurve.0.x-val-00 0
setp lincurve.0.y-val-00 0
setp lincurve.0.x-val-01 85
setp lincurve.0.y-val-01 250
setp lincurve.0.x-val-02 182
setp lincurve.0.y-val-02 550
setp lincurve.0.x-val-03 290
setp lincurve.0.y-val-03 700
setp lincurve.0.x-val-04 340
setp lincurve.0.y-val-04 850
setp lincurve.0.x-val-05 395
setp lincurve.0.y-val-05 1000
setp lincurve.0.x-val-06 500
setp lincurve.0.y-val-06 1150
setp lincurve.0.x-val-07 550
setp lincurve.0.y-val-07 1300
setp lincurve.0.x-val-08 1237
setp lincurve.0.y-val-08 1301
setp lincurve.0.x-val-09 1360
setp lincurve.0.y-val-09 1450
setp lincurve.0.x-val-10 1575
setp lincurve.0.y-val-10 1600
setp lincurve.0.x-val-11 1709
setp lincurve.0.y-val-11 1750
setp lincurve.0.x-val-12 1930
setp lincurve.0.y-val-12 2000
setp lincurve.0.x-val-13 2271
setp lincurve.0.y-val-13 2300
setp lincurve.0.x-val-14 2611
setp lincurve.0.y-val-14 2600
setp lincurve.0.x-val-15 2950
setp lincurve.0.y-val-15 2950
net spindle-raw motion.spindle-out => lincurve.0.in
net spindle-corrected lincurve.0.out => pwmgen.0.in
addf parport.0.read base-thread
addf stepgen.make-pulses base-thread
addf parport.0.write base-thread
addf parport.0.reset base-thread
addf stepgen.capture-position servo-thread
addf motion-command-handler servo-thread
addf motion-controller servo-thread
addf stepgen.update-freq servo-thread
#net spindle-cmd-rpm <= motion.spindle-speed-out
#net spindle-cmd-rpm-abs <= motion.spindle-speed-out-abs
#net spindle-cmd-rps <= motion.spindle-speed-out-rps
#net spindle-cmd-rps-abs <= motion.spindle-speed-out-rps-abs
net spindle-cmd <= motion.spindle-speed-out
net spindle-cw <= motion.spindle-forward
net spindle-ccw <= motion.spindle-reverse
net coolant-mist <= iocontrol.0.coolant-mist
Please Log in or Create an account to join the conversation.
- andypugh
- Offline
- Moderator
-
Less
More
- Posts: 19899
- Thank you received: 4655
7 years 4 weeks ago #146858
by andypugh
Replied by andypugh on topic Gearchange help controlling a BLDC motor
You say that sample configs that output PWM are not suitable.
So what output from HAL would be suitable to control the speed of your motor?
So what output from HAL would be suitable to control the speed of your motor?
Please Log in or Create an account to join the conversation.
- tacklem60
- Offline
- Senior Member
-
Less
More
- Posts: 52
- Thank you received: 0
7 years 4 weeks ago #146872
by tacklem60
Replied by tacklem60 on topic Gearchange help controlling a BLDC motor
Thank you very much for getting back to me. I have been having a bear of a time wrapping my head around this but I am finally making a little progress. I know you replied to both of my threads but I am going to keep the replies on here from now on because I think I am back in the boat of needing to use Gearchange and have (mostly) figured out the lincurve aspect of tuning the spindle. Hopefully the moderators will just delete the other thread because this one should contain all of the information once I figure out the issue for future people to reference if they find themselves as confused as I am.
To answer your question, there really isnt a reason that PWM isn't suitable for my application. I am using a C6 variable speed control board from CNC4PC to output my 0-10V signal to my BLDC motor controller. Right now I have it configured to output from LinuxCNC using stepgen set up in velocity mode for my spindle and that has been working great with the minor issue of my low speed belt not corresponding. Since my last post I have figured out enough syntax to be able to get lincurve to work for my application but it is not 100%.
I will paste my hal file below and maybe you can help me. I realize now that I should probably be putting all of this in the customhal file but I don't ever rerun stepconfig so I am not super worried about losing the data.
The way I have it set up now, lincurve has corrected the issue with spindle speed not matching the requested S value from LinuxCNC while in low range and it is quite accurate from 0-550RPM. The issue I have now is that the accuracy entirely falls off after 550RPM and from 550-1300 RPM there is essentially no change in actual speed when I raise commanded speed. The actual speed actually tops at 550 rpm no matter what I command from 550-1300 RPM. After 550RPM, I have to continue doing what I used to do to get the actual speed any faster (i.e. to get it to actually rotate at 1300RPM I have to command max spindle speed of 2950 or command around 2200RPM to get 1000 RPM actual speed).
I think my issue is that the lincurve function is attempting to make linear the numbers between 550-1450 or so due to the fact that I have a 1300RPM value in low range and a 1301 value in high. It sees that there is a step jump there and I assume it is trying to make a line of best fit which essentially results in no change in the output for any value in that range. In high range, the spindle speed control is now better than ever before and like I said, between 0-550RPM in low range it is now extremely accurate.
I think now I either need to find a better way to input the lincurve values or use a combination of the gearchange comp and 2 separate scaling features with lincurve so I can tune the 2 ranges in the end. I unfortunately have no idea how I would accomplish this and that is where I need help. I would like the gearchange comp to be 0-1300RPM in first gear and 1301-2950 in second with a separate lincurve for both low and high so I can fine tune the values after the gearchange comp does it's magic if that makes any sense. Sorry for the super long reply, but my lack of knowledge means I have to try to explain all of this like a 4th grader. Thanks so much if you can lend a hand.
#This adds a velocity controlled 4th axis
loadrt stepgen step_type=0,0,0,0 ctrl_type=p,p,p,v
loadrt scale count=1
#setup for scaling
setp scale.0.in 0
#must be tuned
setp scale.0.gain 0.885
#no current offset
setp scale.0.offset 0
#connect scale to servo clock thread
addf scale.0 servo-thread
#setup for stepgen to drive spindle
setp stepgen.3.position-scale 1.83
#max RPM of Spindle
setp stepgen.3.maxvel 2950
setp stepgen.3.steplen 1
setp stepgen.3.stepspace 0
setp stepgen.3.dirhold 28000
setp stepgen.3.dirsetup 23000
#max accel for spindle
setp stepgen.3.maxaccel 800
net spindle-enable <= motion.spindle-on => stepgen.3.enable
loadrt lincurve personality=16
addf lincurve.0 servo-thread
setp lincurve.0.x-val-00 0
setp lincurve.0.y-val-00 0
setp lincurve.0.x-val-01 85
setp lincurve.0.y-val-01 250
setp lincurve.0.x-val-02 182
setp lincurve.0.y-val-02 550
setp lincurve.0.x-val-03 290
setp lincurve.0.y-val-03 700
setp lincurve.0.x-val-04 340
setp lincurve.0.y-val-04 850
setp lincurve.0.x-val-05 395
setp lincurve.0.y-val-05 1000
setp lincurve.0.x-val-06 500
setp lincurve.0.y-val-06 1150
setp lincurve.0.x-val-07 550
setp lincurve.0.y-val-07 1300
setp lincurve.0.x-val-08 1237
# high speed
setp lincurve.0.y-val-08 1301
setp lincurve.0.x-val-09 1360
setp lincurve.0.y-val-09 1450
setp lincurve.0.x-val-10 1575
setp lincurve.0.y-val-10 1600
setp lincurve.0.x-val-11 1709
setp lincurve.0.y-val-11 1750
setp lincurve.0.x-val-12 1930
setp lincurve.0.y-val-12 2000
setp lincurve.0.x-val-13 2271
setp lincurve.0.y-val-13 2300
setp lincurve.0.x-val-14 2611
setp lincurve.0.y-val-14 2600
setp lincurve.0.x-val-15 2950
setp lincurve.0.y-val-15 2950
#sends the speed request from EMC to scale module
net spindle-cmd motion.spindle-speed-out => lincurve.0.in
#sends scaled spindle speed to EMC and spindle stepgen for requested speed
net spindle-corrected lincurve.0.out => scale.0.in
net spindle-freq <= scale.0.out => stepgen.3.velocity-cmd
#sends frequency out to par port 16 and to EMC
net spindle-out <= stepgen.3.step => parport.0.pin-16-out
To answer your question, there really isnt a reason that PWM isn't suitable for my application. I am using a C6 variable speed control board from CNC4PC to output my 0-10V signal to my BLDC motor controller. Right now I have it configured to output from LinuxCNC using stepgen set up in velocity mode for my spindle and that has been working great with the minor issue of my low speed belt not corresponding. Since my last post I have figured out enough syntax to be able to get lincurve to work for my application but it is not 100%.
I will paste my hal file below and maybe you can help me. I realize now that I should probably be putting all of this in the customhal file but I don't ever rerun stepconfig so I am not super worried about losing the data.
The way I have it set up now, lincurve has corrected the issue with spindle speed not matching the requested S value from LinuxCNC while in low range and it is quite accurate from 0-550RPM. The issue I have now is that the accuracy entirely falls off after 550RPM and from 550-1300 RPM there is essentially no change in actual speed when I raise commanded speed. The actual speed actually tops at 550 rpm no matter what I command from 550-1300 RPM. After 550RPM, I have to continue doing what I used to do to get the actual speed any faster (i.e. to get it to actually rotate at 1300RPM I have to command max spindle speed of 2950 or command around 2200RPM to get 1000 RPM actual speed).
I think my issue is that the lincurve function is attempting to make linear the numbers between 550-1450 or so due to the fact that I have a 1300RPM value in low range and a 1301 value in high. It sees that there is a step jump there and I assume it is trying to make a line of best fit which essentially results in no change in the output for any value in that range. In high range, the spindle speed control is now better than ever before and like I said, between 0-550RPM in low range it is now extremely accurate.
I think now I either need to find a better way to input the lincurve values or use a combination of the gearchange comp and 2 separate scaling features with lincurve so I can tune the 2 ranges in the end. I unfortunately have no idea how I would accomplish this and that is where I need help. I would like the gearchange comp to be 0-1300RPM in first gear and 1301-2950 in second with a separate lincurve for both low and high so I can fine tune the values after the gearchange comp does it's magic if that makes any sense. Sorry for the super long reply, but my lack of knowledge means I have to try to explain all of this like a 4th grader. Thanks so much if you can lend a hand.
#This adds a velocity controlled 4th axis
loadrt stepgen step_type=0,0,0,0 ctrl_type=p,p,p,v
loadrt scale count=1
#setup for scaling
setp scale.0.in 0
#must be tuned
setp scale.0.gain 0.885
#no current offset
setp scale.0.offset 0
#connect scale to servo clock thread
addf scale.0 servo-thread
#setup for stepgen to drive spindle
setp stepgen.3.position-scale 1.83
#max RPM of Spindle
setp stepgen.3.maxvel 2950
setp stepgen.3.steplen 1
setp stepgen.3.stepspace 0
setp stepgen.3.dirhold 28000
setp stepgen.3.dirsetup 23000
#max accel for spindle
setp stepgen.3.maxaccel 800
net spindle-enable <= motion.spindle-on => stepgen.3.enable
loadrt lincurve personality=16
addf lincurve.0 servo-thread
setp lincurve.0.x-val-00 0
setp lincurve.0.y-val-00 0
setp lincurve.0.x-val-01 85
setp lincurve.0.y-val-01 250
setp lincurve.0.x-val-02 182
setp lincurve.0.y-val-02 550
setp lincurve.0.x-val-03 290
setp lincurve.0.y-val-03 700
setp lincurve.0.x-val-04 340
setp lincurve.0.y-val-04 850
setp lincurve.0.x-val-05 395
setp lincurve.0.y-val-05 1000
setp lincurve.0.x-val-06 500
setp lincurve.0.y-val-06 1150
setp lincurve.0.x-val-07 550
setp lincurve.0.y-val-07 1300
setp lincurve.0.x-val-08 1237
# high speed
setp lincurve.0.y-val-08 1301
setp lincurve.0.x-val-09 1360
setp lincurve.0.y-val-09 1450
setp lincurve.0.x-val-10 1575
setp lincurve.0.y-val-10 1600
setp lincurve.0.x-val-11 1709
setp lincurve.0.y-val-11 1750
setp lincurve.0.x-val-12 1930
setp lincurve.0.y-val-12 2000
setp lincurve.0.x-val-13 2271
setp lincurve.0.y-val-13 2300
setp lincurve.0.x-val-14 2611
setp lincurve.0.y-val-14 2600
setp lincurve.0.x-val-15 2950
setp lincurve.0.y-val-15 2950
#sends the speed request from EMC to scale module
net spindle-cmd motion.spindle-speed-out => lincurve.0.in
#sends scaled spindle speed to EMC and spindle stepgen for requested speed
net spindle-corrected lincurve.0.out => scale.0.in
net spindle-freq <= scale.0.out => stepgen.3.velocity-cmd
#sends frequency out to par port 16 and to EMC
net spindle-out <= stepgen.3.step => parport.0.pin-16-out
Please Log in or Create an account to join the conversation.
- andypugh
- Offline
- Moderator
-
Less
More
- Posts: 19899
- Thank you received: 4655
7 years 4 weeks ago #146876
by andypugh
Replied by andypugh on topic Gearchange help controlling a BLDC motor
If you are using a velocity mode stepgen then just replace any PWM entries with the corresponding stepgen pin.
The setup you have should work equally well with the output going to stepgen or pwm input pins. (or, in fact, to both)
The setup you have should work equally well with the output going to stepgen or pwm input pins. (or, in fact, to both)
Please Log in or Create an account to join the conversation.
- tacklem60
- Offline
- Senior Member
-
Less
More
- Posts: 52
- Thank you received: 0
7 years 4 weeks ago #146887
by tacklem60
Replied by tacklem60 on topic Gearchange help controlling a BLDC motor
Do you happen to know how I could fix the issue where my speed seems to flatten out near 550 RPM?
Like I said, I'm assuming it's because I have 2 points near 1300RPM with very different actual speeds but I don't know how I would work around that.
Like I said, I'm assuming it's because I have 2 points near 1300RPM with very different actual speeds but I don't know how I would work around that.
Please Log in or Create an account to join the conversation.
- andypugh
- Offline
- Moderator
-
Less
More
- Posts: 19899
- Thank you received: 4655
7 years 4 weeks ago #146950
by andypugh
Replied by andypugh on topic Gearchange help controlling a BLDC motor
Do you have any sort of input that tells the system which gear is engaged?
I think I would use two lincurves, one for each gear, then switch between their outputs using a mux2 operated by the gear switch.
I think I would use two lincurves, one for each gear, then switch between their outputs using a mux2 operated by the gear switch.
Please Log in or Create an account to join the conversation.
Time to create page: 1.068 seconds