terjeio / grblHAL

This repo has moved to a new home https://github.com/grblHAL
231 stars 90 forks source link

Manual Jog using Rotary Encoder #332

Closed atlesg closed 2 years ago

atlesg commented 2 years ago

Hello, I need to implement 3 rotary encoders as 3 manual jogging wheel for my old CNC. I don't know if GRBLHal supports this nor anyone has done this before so I will ask here. I saw some guys on Youtube making the Jog controller using ESP32 but most of them send serial commands to jog, that introduce latency, which is not very good for manual machinists.

I am using my own STM32F407 board with encoder inputs, and has successfully remapped pinouts to actuate the motors. Please give me some advice about what/how should I do/read/modify the source code or any sample projects so I can do this.

Thank you!

dresco commented 2 years ago

I wouldn't write off serial, I'm not keen on routing TTL level signals from the grbl controller outside of the cabinet, so I think industrial standards like RS-485 & modbus have their place for controls.

Am in the early stages - but currently working on a control panel design (buttons, encoders, display etc), which uses modbus to talk back to a grblHAL plugin. I think once you're < 100ms for responsiveness then it's not going to be noticeable.

But yes, if you have the spare timers/pins directly on your board, then nothing to stop you attaching the encoders directly, with a plugin to process the encoder values and enqueue the jogging commands. Just wouldn't be as portable..

terjeio commented 2 years ago

There is likely no need to modify the source, you can add your code as a plugin. To move the motors set up a stepper_t struct and call hal.stepper.pulse_start for each pulse to send. IIRC you only have populate a few fields, check which are used in a driver.c implementation, this is a typical one. You will have to keep sys.position in sync when you do this. And you may also have to power up the motors beforehand depending on settings.

Sending jog commands may be easier though, I am looking forward to what @dresco comes up with. Other than that I have made one standalone implementation that works reasonably well, and there is an encoder plugin that has some basic and incomplete support for jogging. Both these sends jog commands. I have a link somewhere to a project for linking MPG wheel movement to motor movement, I'll see if I can dig that up again. It performed very well from what I saw on an embedded video, however, IIRC, a problem with that project is it was not open source.

FYI this project is no longer updated, the new home is here.

atlesg commented 2 years ago

I wouldn't write off serial, I'm not keen on routing TTL level signals from the grbl controller outside of the cabinet, so I think industrial standards like RS-485 & modbus have their place for controls.

Am in the early stages - but currently working on a control panel design (buttons, encoders, display etc), which uses modbus to talk back to a grblHAL plugin. I think once you're < 100ms for responsiveness then it's not going to be noticeable.

But yes, if you have the spare timers/pins directly on your board, then nothing to stop you attaching the encoders directly, with a plugin to process the encoder values and enqueue the jogging commands. Just wouldn't be as portable..

Yes, Modbus with RS485 physical layer is one of the best choices for industrial application. For 3d printer or laser stuffs, serial jog (jog by command no matter what the communication layer is) is enough. Thing is I want to use GRBL for NC machine, and mixing CNC at some points, and for manual machinists. So the feeling is very important. For 100ms communicate rate, it's okay if you move some long distance with slow rotating (using the hand) however, for manual machining, sometimes you need to do super small steps, and then you will rotate really fast or really slow, that will make the communication overflow. In the other hand, there will be lag, so it's not good for the feeling :3

I agree this encoder method is not generic, and not easy. But if we can do that, then it would be good :p

atlesg commented 2 years ago

There is likely no need to modify the source, you can add your code as a plugin. To move the motors set up a stepper_t struct and call hal.stepper.pulse_start for each pulse to send. IIRC you only have populate a few fields, check which are used in a driver.c implementation, this is a typical one. You will have to keep sys.position in sync when you do this. And you may also have to power up the motors beforehand depending on settings.

Sending jog commands may be easier though, I am looking forward to what @dresco comes up with. Other than that I have made one standalone implementation that works reasonably well, and there is an encoder plugin that has some basic and incomplete support for jogging. Both these sends jog commands. I have a link somewhere to a project for linking MPG wheel movement to motor movement, I'll see if I can dig that up again. It performed very well from what I saw on an embedded video, however, IIRC, a problem with that project is it was not open source.

FYI this project is no longer updated, the new home is here.

Thank you so much! I will check everything information you gave me here. I will update with you later if I make any progress. Guess in the future I will create issue in the box Plugin of the new home github yeah?

I've always wanted to talk to you via some sort of social network. Your work is super impressive and I hope I can learn a thing or two from you as I also want to use GRBL for some robotics stuffs. Thank you for everything you did there!

dresco commented 2 years ago

for manual machining, sometimes you need to do super small steps, and then you will rotate really fast or really slow, that will make the communication overflow

I think you are worrying about exactly the right thing, but perhaps in the wrong area. The amount of encoder movement will make no difference to the serial traffic (as the modbus master is simply polling for encoder position every x ms, so that stays consistent).

More important is how those position changes are then enqueued into grbl - as you do have to worry about filling the planner buffer. But you will face that same issue whether you're getting the encoder position over modbus, or directly from local timer registers.

phil-barrett commented 2 years ago

For what it's worth, I generally bump the planner buffer up to 1K in size on the T4.1. Since there is plenty of RAM, I don't see a penalty in that.

What is a good size of planner buffer to avoid filling it? (I realize there is no one-size-fits-all answer)

terjeio commented 2 years ago

Guess in the future I will create issue in the box Plugin of the new home github yeah?

You can can start a discussion there, issues should be used for problems related to existing code.

I've always wanted to talk to you via some sort of social network.

I do not like social networks... I am on Line and Skype though.

More important is how those position changes are then enqueued into grbl - as you do have to worry about filling the planner buffer.

My suggestion above was to bypass the planner and sends steps directly. If from a manually operated encoder accel/decel should not be a problem? I forgot to mention that a call to sync_position() has to be done at the end of movement if this method is selected.

What is a good size of planner buffer to avoid filling it? (I realize there is no one-size-fits-all answer)

Whatever gives you the max feedrate you are after? There is a tradeoff between max planner buffer size and the time the processor spends recalculating (to a full stop). And this only becomes an issue when the gcode contains a lot of short moves limiting the programmed feedrate. I think this is only likely when laser engraving bitmaps at high speed. I did some measurements earlier by adding a counter to the main protocol loop and checking the count regularly - can't remember how often, every 10ms? If this count drops significantly under load then perhaps the planner buffer is too large...