fra589 / grbl-Mega-5X

5/6 Axis version of Grbl, the open source, embedded, high performance g-code-parser and CNC milling controller written in optimized C that will run on an Arduino Mega2560
https://github.com/fra589/grbl-Mega-5X/wiki
Other
341 stars 159 forks source link

RC-Servo on Spindle PWM? #323

Open svenhb opened 1 year ago

svenhb commented 1 year ago

Hi, can't find an option to change the spindle PWM generation like here: https://github.com/cprezzi/grbl-servo You may have a quick solution to solve this problem?: https://github.com/svenhb/GRBL-Plotter/issues/327#issuecomment-1484184685 User switches from Arduino-Uno with Servo-PWM to Mega2560 with your grbl version... Thanks

svenhb commented 1 year ago

I just recognized, that the user already made his own issue: https://github.com/fra589/grbl-Mega-5X/issues/322

fra589 commented 1 year ago

Hi @svenhb,

But your issue is better as it gives a clue for resolution :-)

Servo control is in my TODO list as accessory tool like the recently added functions digital and analog output.
It will probably use the same M67/M68 GCode functions than the analog output.

It's a rather bit complicated because we need to change some PWM registers and timers without made disruption on other timers functionalities. For this, we can't use the standard Arduino servo library.

The trick to do this is to modify the PWM register to obtain the right frequency usable by a servo (~50Hz?) and send pulses between about 1 and 2 ms. 1ms give a servo position close to one end of its travel, 2ms give the servo to go close to the other end.

For this, I plan to hack the servo library to understand how it exactly work on AtMega2560, then, write the optimized code for grbl-Mega-5X... It will take a while as like all other retired, I'm over-surbooked :-D

If you plan to work on this subject for a faster result, do not hesitate to come back here to share your progress.

@++;
Gauthier.
P.S. I closed the @Girishking's other issue, as it's duplicate of this one.

svenhb commented 1 year ago

Ok, I don't like it but I had to... look into the datasheet (https://ww1.microchip.com/downloads/en/devicedoc/atmel-2549-8-bit-avr-microcontroller-atmega640-1280-1281-2560-2561_datasheet.pdf). In theory the following should work, but I can't test: Setup now: using Timer 4, in fast PWM mode (WGMn3:0=15), prescaler = 1/8 (CSn1=1), top value 1024 -> PWM freq 1950Hz.

Setup for RC-Servo: prescaler = 1/1024 (CSn0,2=1), top value 512 -> PWM freq 30Hz.

This means, following changes are needed in cpu_map.h: line 333 #define SPINDLE_PWM_MAX_VALUE 512.0 // Translates to about 30 Hz PWM frequency at 1/1024 prescaler line 348 #define SPINDLE_TCCRB_INIT_MASK ((1<<WGM42) | (1<<WGM43) | (1<<CS40) | (1<<CS42)) line 350 #define SPINDLE_OCRA_TOP_VALUE 0x200 // PWM counter reset value. Should be the same as PWM_MAX_VALUE in hex.

This gives a step-width of 0,064 ms (1/30Hz / 512) For lower servo value of ~0.5ms try a value of 8, for ~2ms try a value of 32

I hope I'm right... @Girishking could you test this?