Monday, August 21, 2006
Assuming the data that Forrest gave is typical, it appears the motor velocity vs PWM is anything but simple. I've tried a few expressions, and the one that came the closest is hard to explain (There isn't really enough data points or test runs to come to any conclusions; I'm going on what is available right now.)
The blue squares show the measured motor speed for a specified PWM value.
The red squares are: PWM = SPEED * 16 / 21 + 50
The green triangles are: PWM = SPEED^2 * 172 / 17 + 70
The yellow triangles are: PWM = SPEED^1.6 * 172 / 17 + 70
Very puzzling. In any case, it appears it won't be easy to try to get exact equations of this nature.
I have been considering using splines computed on the host being sent to the motor controllers, instead of linear segments. I believe this is possible, and the microcontroller code very straightforward (So far, compiled C methods consume 26 bytes of RAM, and take about 90 instructions to execute the spline logic, and to decode the next spline messages from the host. This code should have worst case spline sample positions on the order of .04mm for a head moving at 50mm/second in the extreme degenerate case. More typically, a head speed of 5mm/sec would be from 0.02mm to 0.04mm per sample, depending on the number of steps in the spline.
As such, I think that position can be tracked directly. At every pulse from the motor sensor, or whenever the computed spline position changes, simply send the appropriate Power Left, Power Right, or Coast command to the motor control, based on whether the current position is too far left, too far right, or spot on the spline desired position. I predict such a scheme will emulate exactly the pulse width modulations needed. I'm not certain whether you'd need to send the 'brake' command -- I guess it depends on how much better it is at stopping the motor than simply putting it in reverse? Anyone know if this would cause problems?
NOTE: I can increase spline resolution even further, but this might require doing greater than int32 additions; there isn't a lot of compiler support for 40, 48, or 56 bit integer arithmetic. If this was necessary, a few hand coded spline cascade addition methods would need to be created.
"I think that position can be tracked directly. At every pulse from the motor sensor, or whenever the computed spline position changes, simply send the appropriate Power Left, Power Right, or Coast command to the motor control, based on whether the current position is too far left, too far right, or spot on the spline desired position."
-DesiredPosition (in pulses)
-ActualPosition (in pulses)
-Correction (correction rate, 0-254)
If correction=10, will result in a +- 1pwm for every pulse that it is off by.
Pretty easy. This kind of thing might even come in handy for stepper motors to correct any slippage that might occur at higher torques.
I mean it's not like we can specify a PWM setting of something like 17.258 or the like. They're all integers.
Mind, I do understand that if I slap a 4096 resolution shaft encoder on this thing or drop down below a Mode 7 PWM scale which is 8 bit to a 9 or 10 bit one there will be more data points than can be easily put in a lookup table.
Hi Forrest. I'm not trying to get spline curves to match curves for motor readings and characteristics; I'm trying to see if they could be used to control the motor directly. Instead of sending "MOVE X,Y" from host to microcontroller, you'd send "FOLLOW_SPLINE_CURVE DX,DDX,DDDX,TICKS". Depending on the shape, I think you would increase how quickly you could print the same part. The motor would likely be moving continuously, and you don't have to solve any "When do I need to slow down to hit point X,Y" questions on the microcontroller -- The spline curve already answers this question, and it can be computed by the more powerful host computer.
*** motorPWM correction:
Is there any reason you'd need to set up a PWM at all? Assumming you have 3 output ports: LEFT, ENABLE, and RIGHT, why couldn't you just set LEFT=1,ENABLE=1, and RIGHT=0 when you want to move left; LEFT=0,ENABLE=1, and RIGHT=1 when you want to move right, and LEFT=0, ENABLE=0, and RIGHT=0 when you want to coast? Theoretically, as long as your feedback was high enough resolution, you'd get **position** within +/-1 from where you want it to be (Who cares how fast the motor is moving as long as it is moving exactly to where you want it to go.)
I'm not certain if the feedback is high enough resolution to do this, though. This is really the biggest question with the 'simple position tracking' mechanism I'm proposing.
To be more explicit, this is the control logic I think might work:
DesiredPosition (in pulses)
-ActualPosition (in pulses)
IF DesiredPosition < ActualPosition
Set LEFT_Port = 1
Set RIGHT_Port = 0
Set ENABLE_Port = 1
ELSE IF DesiredPosition > ActualPosition
SET RIGHT_Port = 1
SET LEFT_Port = 0
SET ENABLE_Port = 1
SET ENABLE_Port = 0
Execute this logic whenever DesiredPosition changes, or whenever ActualPosition changes.
As long as the motor isn't too strong, and the sensor is high enough resolution, you should end up automagically getting the desired pulse width modulation on the enable port, without using any timers or pulse width percentages at all.
It should be possible to use EMC to drive this thing. At any rate, PID + feedforward control is pretty easy to do, and is standard for machine control using servos.
If the controller can't run a simple PID loop, a 'smarter' processor should be used.
Occasionally, we even find something that the guys who made something a "solved problem" missed.
If you have some references to some open source code that could be used in a low cost microcontroller environment, it would seem this would be more productive than saying the obvious (that there are propriety machines and copyrighted source that do what we are trying to do -- you only need to shell out the US$1000+ to buy them.)
Links to this post: