PWM Problem with G codes
Quote from Bernat on December 6, 2019, 6:53 amHi,
I recently got a K40 CO2 machine, and I compiled the SuperGerbil to work over a STM32F103C8. Everything seems to work fine with the PWM, except when I use, for example, the G1 code to move the head. What happens is that the PWM is very low, even setting the maximum power using the S255. What I did to check it works correctly is:
1- After reset, it is homing OK. In "Capture1" you can see the Laser Enable from the power source (green trace) and the PWM (blue trace)
2- Then I send M3. Same oscilloscope capture, since the spindle is S0 by default
3- Then I send S1. In "Capture2" you can see the PWM, where I defined the SPINDLE_PWM_MIN_VALUE to get the minimum laser ionization. The "Capture 3" shows the PWM of the S250 command. For these tests I set the laser mode off ($32=0), and the S-value max set to 255 ($30=255)So, at this point we already know the PWM is working. Next steps:
4- Then I send "G1 X10 S128 F100". So I would expect the laser to move 10mm with a PWM of 50%. But What I get is a PWM even lower than the SPINDLE_PWM_MIN_VALUE! See "Capture4". I thought it might be the power adaptation because of the acceleration, but it keeps the same PWM all the entire 10mm, moving really slow at 2mm/s. I tried to debug the code, but I couldn't.
As fas as I could check, the PWM is calculated in the method "spindle_compute_pwm_value", of the file "spindle_control.c", in line:
pwm_value = (SPINDLE_PWM_TYPE)floorf((rpm - settings.rpm_min)*pwm_gradient) + SPINDLE_PWM_MIN_VALUE;
so, unless "rpm" becomes negative, I don't understand how the PWM can be lower than SPINDLE_PWM_MIN_VALUE...
The strange thing is that when I send a M3 command, the PWM jumps to 50% like expected. I hope it's just a configuration issue, but it's getting me crazy.
Have you any idea about what it might be happening?
Thanks,
Hi,
I recently got a K40 CO2 machine, and I compiled the SuperGerbil to work over a STM32F103C8. Everything seems to work fine with the PWM, except when I use, for example, the G1 code to move the head. What happens is that the PWM is very low, even setting the maximum power using the S255. What I did to check it works correctly is:
1- After reset, it is homing OK. In "Capture1" you can see the Laser Enable from the power source (green trace) and the PWM (blue trace)
2- Then I send M3. Same oscilloscope capture, since the spindle is S0 by default
3- Then I send S1. In "Capture2" you can see the PWM, where I defined the SPINDLE_PWM_MIN_VALUE to get the minimum laser ionization. The "Capture 3" shows the PWM of the S250 command. For these tests I set the laser mode off ($32=0), and the S-value max set to 255 ($30=255)
So, at this point we already know the PWM is working. Next steps:
4- Then I send "G1 X10 S128 F100". So I would expect the laser to move 10mm with a PWM of 50%. But What I get is a PWM even lower than the SPINDLE_PWM_MIN_VALUE! See "Capture4". I thought it might be the power adaptation because of the acceleration, but it keeps the same PWM all the entire 10mm, moving really slow at 2mm/s. I tried to debug the code, but I couldn't.
As fas as I could check, the PWM is calculated in the method "spindle_compute_pwm_value", of the file "spindle_control.c", in line:
pwm_value = (SPINDLE_PWM_TYPE)floorf((rpm - settings.rpm_min)*pwm_gradient) + SPINDLE_PWM_MIN_VALUE;
so, unless "rpm" becomes negative, I don't understand how the PWM can be lower than SPINDLE_PWM_MIN_VALUE...
The strange thing is that when I send a M3 command, the PWM jumps to 50% like expected. I hope it's just a configuration issue, but it's getting me crazy.
Have you any idea about what it might be happening?
Thanks,
Uploaded files:Quote from Paul De Groot on December 6, 2019, 9:52 amHi, the PWM is 16 bits and not 8 bits. So may be that's where the problem is. Set $30 = e.g. 1000 and repeat the scope tests.
cheers, Paul
Hi, the PWM is 16 bits and not 8 bits. So may be that's where the problem is. Set $30 = e.g. 1000 and repeat the scope tests.
cheers, Paul
Quote from Bernat on December 6, 2019, 12:21 pmHi Paul,
Thanks for you fast response. I already did the test, but I just went back to 255 when it didn't work, because the original code was written in 8 bits, so I just wanted to make sure there was no truncated values in the way.
Actually, just as a comment, the default SPINDLE_PWM_FREQUENCY in "cpu_map.h" was 10kHz, but with the timer working @ 1MHz (prescaler of 71) there are just 100 different values available in the TIM1->CCR1 register (i.e. AAR register), making it even worse than a 8 bits PWM. Since the rpm in a laser module has no meaning, I just set the PWM frequency to 500Hz (to get 2000 different values, almost 11 bits of resolution), and then I also set $30=2000 to match it. So, I have 2000 different real power states. Despite all this, I also tried the default 10kHz PWM frequency, and there is the same problem.
Anyway, I'm just trying to simplify as maximum as possible to test it, but I run out of ideas 🙁 I'm gonna try to debug the code, it would be really helpful to know which rpm value I receive in the "spindle_compute_pwm_value" method, but I have problems with CooCox and the ST-Link GDB server... I guess I can use the same USB serial port to send data in debug mode, since for these simple tests I'm just using Realterm instead of LightBurn.
Thanks,
Hi Paul,
Thanks for you fast response. I already did the test, but I just went back to 255 when it didn't work, because the original code was written in 8 bits, so I just wanted to make sure there was no truncated values in the way.
Actually, just as a comment, the default SPINDLE_PWM_FREQUENCY in "cpu_map.h" was 10kHz, but with the timer working @ 1MHz (prescaler of 71) there are just 100 different values available in the TIM1->CCR1 register (i.e. AAR register), making it even worse than a 8 bits PWM. Since the rpm in a laser module has no meaning, I just set the PWM frequency to 500Hz (to get 2000 different values, almost 11 bits of resolution), and then I also set $30=2000 to match it. So, I have 2000 different real power states. Despite all this, I also tried the default 10kHz PWM frequency, and there is the same problem.
Anyway, I'm just trying to simplify as maximum as possible to test it, but I run out of ideas 🙁 I'm gonna try to debug the code, it would be really helpful to know which rpm value I receive in the "spindle_compute_pwm_value" method, but I have problems with CooCox and the ST-Link GDB server... I guess I can use the same USB serial port to send data in debug mode, since for these simple tests I'm just using Realterm instead of LightBurn.
Thanks,
Quote from Bernat on December 7, 2019, 1:14 amHi Paul,
I found the problem, but I don't understand which version I got... The problem was:
#ifdef VARIABLE_SPINDLE
uint16_t spindle_pwm; // uint8_t spindle_pwm;
#endifI don't know why, I had a version where the spindle_pwm was set as uint8_t. I see your code is OK, I will download your code and readapt it for my machine, since I don't know what else might be wrong.
Thank you,
Hi Paul,
I found the problem, but I don't understand which version I got... The problem was:
#ifdef VARIABLE_SPINDLE
uint16_t spindle_pwm; // uint8_t spindle_pwm;
#endif
I don't know why, I had a version where the spindle_pwm was set as uint8_t. I see your code is OK, I will download your code and readapt it for my machine, since I don't know what else might be wrong.
Thank you,