Skip to content

Update G33 for virtual encoder indexes - #104

Open
staskaaa-netizen wants to merge 2 commits into
Paciente8159:masterfrom
staskaaa-netizen:g33-virtual-index
Open

staskaaa-netizen wants to merge 2 commits into
Paciente8159:masterfrom
staskaaa-netizen:g33-virtual-index

Conversation

@staskaaa-netizen

Copy link
Copy Markdown

No description provided.

@Paciente8159 Paciente8159 added the needs: testing needs: testing label May 27, 2026
@HuubBuis

HuubBuis commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

I want to bench test this G33 module using my spindle simulator on an ESP32 (RP2350 is ordered). The idea is to set the actual PPR to 16 and ENCODER0_VIRTUAL_INDEX_CPR to 2 or 4; That would result in a 8 or 4 PPR virtual encoder. The synchronization can than be compared to the current (latest) G33 module.

When I compile I get an error:
uCNC/src/modules/g33/parser_g33.c:402: undefined reference to `encoder_virtual_index_unarm'
I used the same code to load the modules in cnc_hal_overrides:
#define LOAD_MODULES_OVERRIDE() ({LOAD_MODULE(g33);LOAD_MODULE(single_axis_homing);})

When I use the G33 and esp32_pcnt_encoder module from your pull request staskaaa-netizen:encoder-backends-g33 #105 it does compile.

cnc_hal_overrides.h changes
// #define G33_ENCODER ENC0
#define ENC0_VIRTUAL_INDEX 1
#define ENC0_VIRTUAL_INDEX_CPR 4
#define ENC0_VIRTUAL_INDEX_OFFSET 0
#define LOAD_MODULES_OVERRIDE() ({LOAD_MODULE(esp32_pcnt_encoder);LOAD_MODULE(g33);LOAD_MODULE(single_axis_homing);})

@staskaaa-netizen

Copy link
Copy Markdown
Author

Will look into it. esp32 was orphaned/not hard tested on my side after discovering rp2350. Just two different worlds.

@HuubBuis

HuubBuis commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

I will test your fix tomorrow.

Why favor the RP2350 and not the RP2040?

@staskaaa-netizen

staskaaa-netizen commented Jul 4, 2026

Copy link
Copy Markdown
Author

More Sram. I need 234.4 KiB ~ half of total of 520 for last mile video buffer . And 12 Pio.

External ram is present too, but i cant make it work nicely with DMA. Only drawing buffers.

@HuubBuis

HuubBuis commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

I compared (bench test) the G33 synchronization PR #104 to the current #107 release. I simulated a 4 PPR and 8 PPR encoder with index and used an ESP32 processor.
The same tests have also be performed on RP2040, STM32 bluepill, SAMD21, and Arduino Mega. All perform well and equal on the bench and real tests on the lathe.

It seems #104 is partially based on #103 and has the same "issues": Synchronization can't handle well RPM speed changes during the initial ramp up and PPR changes requires tuning of the error correction speed. These issues are solved in #107.

If your goal is to implement virtual encoder indexes, than adding this feature to the #107 release would be an option. If you would like me to test using a different setup, let me know.

Below you find my test results and the configuration I used to test #104. Check my config because it is possible the issues are due to my configuration.

MyConfiguration.zip

Results:
Testing using UGS, ESP32, synchronization is done when (Se) error < 0.01 mm
SS=G33_SYNCHRONIZATION_SPEED
MF=Max feed rate
Current G33 release #107
G33 no RPM step
PPR 4, SS8, MF700, RPM 150, K1; 01.53 mm
PPR 4, SS8, MF700, RPM 150, K2; 04.63 mm
PPR 4, SS8, MF700, RPM 150, K3; 08.75 mm
G33 with RPM step 0.25%.
PPR 8, SS8, MF700, RPM 150, K1; 00.97 mm
PPR 8, SS8, MF700, RPM 150, K2; 02.66 mm
PPR 8, SS8, MF700, RPM 150, K3; 05.70 mm

Pull request G33 release #104
G33 no RPM step, G33_FEEDBACK_LOOP_USE_ENC_PULSE defined (always in #107)
PPR 4, SS8, MF700, RPM 150, K1; 03.54 mm
PPR 4, SS8, MF700, RPM 150, K2; 07.82 mm
PPR 4, SS8, MF700, RPM 150, K3; 15.25 mm
G33 no RPM step, G33_FEEDBACK_LOOP_USE_ENC_PULSE defined (always in #107)
PPR 8, SS8, MF700, RPM 150, K1; not stable at all, see log

<Idle|MPos:0.000,0.000,0.000|FS:0.000,149|Buf:19,128>
<Run|MPos:0.000,0.000,-0.030|FS:25.633,150|Buf:19,128>
<Run|MPos:0.000,0.000,-0.185|FS:63.608,149|Buf:19,128>
<Run|MPos:0.000,0.000,-0.448|FS:99.685,150|Buf:19,128>
<Run|MPos:0.000,0.000,-0.844|FS:137.660,149|Buf:19,128>
<Run|MPos:0.000,0.000,-1.357|FS:168.157,149|Ov:100,100,100|Buf:19,128>
<Run|MPos:0.000,0.000,-1.960|FS:201.600,150|Se:0.108|Buf:19,128>
<Run|MPos:0.000,0.000,-2.612|FS:174.051,149|Buf:19,128>
<Run|MPos:0.000,0.000,-3.132|FS:136.053,150|Buf:19,128>
<Run|MPos:0.000,0.000,-3.544|FS:114.835,150|Buf:19,128>
<Run|MPos:0.000,0.000,-3.866|FS:81.000,150|Se:-0.144|Buf:19,128>
<Run|MPos:0.000,0.000,-4.168|FS:108.419,150|Buf:19,128>
<Run|MPos:0.000,0.000,-4.602|FS:148.129,149|Buf:19,128>
<Run|MPos:0.000,0.000,-5.136|FS:184.057,149|Buf:19,128>
<Run|MPos:0.000,0.000,-5.807|FS:206.778,150|Buf:19,128>
<Run|MPos:0.000,0.000,-6.563|FS:243.825,149|Buf:19,128>
<Run|MPos:0.000,0.000,-7.347|FS:215.409,150|WCO:0.000,0.000,0.000|Buf:19,128>

@staskaaa-netizen

Copy link
Copy Markdown
Author

Question - mine does not work / was not designed for scenario for spindle on/off just before sync. it may not not ram normally. it was made for all time running one. So this one will be an issue. Or some paramas must be adjusted

On setup - this is minimal setup for rp2350 one, should be same for rp2040 too. : `

#define ENABLE_RP2350_PIO_ENCODER

#ifdef ENABLE_RP2350_PIO_ENCODER

#define ENCODERS 1
#define ENC0_TYPE ENC_TYPE_CUSTOM

//pins should be not arvitrary order, B must follow A
#define ENC0_PULSE_GPIO 20 // A
// B must be GPIO21
#define ENC0_INDEX 255
#define ENC0_INDEX_GPIO 26

//pio setup
#define ENC0_PIO_INDEX 0
#define ENC0_PIO_SM 0
#define ENC0_MAX_STEP_RATE 0
#define ENC0_PIO_PROGRAM_OFFSET 0

#define ENC0_IS_INCREMENTAL
#define ENC0_CPR 4000 //this is for 1000 ppr quadrature one, should be entered in grbl settings too as 4000 number

//#define ENCODER_DEBUG_PRINT_100MS 1 // optional test only

#define SPINDLE_PWM_RPM_ENCODER ENC0

#define G33_ENCODER ENC0
#define G33_FEEDBACK_LOOP_USE_HW_COUNTER
#define G33_CORRECTION_GAIN 1.0f

#define G33_DEBUG
#define G33_DEBUG_EVERY_N 5

#define ENC0_VIRTUAL_INDEX 1
#define ENC0_VIRTUAL_INDEX_CPR (ENC0_CPR / 10)
#define ENC0_VIRTUAL_INDEX_OFFSET 0
#define ENC0_VIRTUAL_INDEX_HYSTERESIS 1
#endif

Later grbl should send back all 3 counters + spindle rpm : ?23:52:11.332 > <Idle|MPos:0.000,0.000,0.000|FS:0.000,197|EC:3298985|ECB:89|ECI:800,-8400,800,3849|Ln:0|Pn:XZ|WCO:0.000,0.000,0.000>

@HuubBuis

HuubBuis commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

Question - mine does not work / was not designed for scenario for spindle on/off just before sync. it may not not ram normally. it was made for all time running one.

The bench test was performed using the spindle simulator that doesn't stop between passes. The simulator is an ESP32-C3 that continuously generates index and sync pulses. I can publish the code if you want it.
If the spindle can't be stopped between passes, than the thread can't be checked between passes. Making a good thread without test fitting is way beyond the capabilities of most hobby users.

//pins should be not arvitrary order, B must follow A
#define ENC0_PULSE_GPIO 20 // A
// B must be GPIO21

My spindle simulator only generates a synchronization pulse on 1 channel. It does not simulate a quadrature encoder. My lathe also has an index pulse and a single synchronization pulse. In the encoder configuration channel B is not assigned.

#define ENCODERS 1
#define ENC0_PULSE DIN0
#define ENC0_DIR DIN0
#define ENC0_INDEX DIN1

Since it is all about changing the behavior of the encoder module, I wonder if it is not possible to get the same results by just changing the encoder module. I am thinking about binding the encoder pin interrupt to the counter interrupt.

Maybe I am confused because I thought you wanted to reduce the encoder sync pulses by counting them using a timer.

@HuubBuis

Copy link
Copy Markdown
Contributor

I finished testing the #107 G33 module using different PPR encoder settings and different pitches. I tested using 2 to 16 PPR and G33_SYNCHRONIZATION_SPEED settings of 4 to 16.

Previous testing showed that the time to synchronize does not change when the RPM changes. So at higher RPM the distance to synchronize will increase. Also all tested processors (Aruino Mega, STM32 bluepill, RP2040, ESP32, SAMD21) perform the same.

Based on the results below I found that:

  • The minimum is 4 PPR
  • The optimal is 8 to 16 PPR
  • There will be not much to gain above 16 PPR
  • The current default G33_SYNCHRONIZATION_SPEED settings of 8 is OK
#107 G33 module bench testing using a spindle simulator and UGS on an ESP32
Synchronization is done when the synchronization error is less than 0.01 mm
SS=G33_SYNCHRONIZATION_SPEED  
MF=Max feed rate Z (mm/min)
K=pitch

Current G33 release #107

PPR 02, SS08, MF700, RPM 150, K1; 04.78
PPR 02, SS08, MF700, RPM 150, K#107 G33 module testing using UGS on ESP32
Synchronization is done when the synchronization error (Se) is less than 0.01 mm
SS=G33_SYNCHRONIZATION_SPEED  
MF=Max feed rate Z

PPR 02, SS08, MF700, RPM 150, K1; 04.78
PPR 02, SS08, MF700, RPM 150, K2; 13.08
PPR 02, SS08, MF700, RPM 150, K3; 21.90  ; Se not stable, just over 0.015 mm **

PPR 04, SS08, MF700, RPM 150, K1; 01.43
PPR 04, SS08, MF700, RPM 150, K2; 05.17
PPR 04, SS08, MF700, RPM 150, K3; 08.59

PPR 08, SS08, MF700, RPM 150, K1; 01.27
PPR 08, SS08, MF700, RPM 150, K2; 03.53
PPR 08, SS08, MF700, RPM 150, K3; 05.19

PPR 12, SS08, MF700, RPM 150, K1; 01.22
PPR 12, SS08, MF700, RPM 150, K2; 01.69
PPR 12, SS08, MF700, RPM 150, K3; 05.36

PPR 16, SS08, MF700, RPM 150, K1; 00.76
PPR 16, SS08, MF700, RPM 150, K2; 02.36
PPR 16, SS08, MF700, RPM 150, K3; 03.41

I included the full test results:
G33 #107 test PPR d.txt

For the record, I still think it is a good idea to use encoder pulses for G33 synchronization as long as there is a hardware index pulse.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs: testing needs: testing

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants