Closed reynolds087 closed 3 years ago
People have made pendants that communicate via telnet. There is some code for displaying stuff on an oled display in the code base, enabled via #defines in Config.cpp. I have a long-term plan to make a menu system that is controlled from a rotary encoder, but it is taking back seat to a whole raft of other tasks including bug fixing. There is a Makerbase product that uses Grbl_Esp32 and includes a touchscreen, but they have not yet released the source code so we don't know exactly what they did.
This is definitely something that some of us are interested in, but right now we do not want the distraction of thinking about it because we are up to our eyeballs in more urgent tasks.
I came here looking for this. We need pendant support in a lower layer, not over uart (or other channels that transmit gcode).
Just an idea: it could be done with USB Host HID on the main mcu and a simple gamepad. Analog joysticks on a gamepad could move an axis with variable feed.
I would love to jog my machines accurately
Esp32 does not have a USB interface. The modules usually have a USB to serial chip that connects to the UART serial lines on the ESP32
I think it might be useful to clarify what you see the problem as being.
It sounds like one complaint is queuing up too many jog operations?
Or is the problem the latency of response to a jog request?
But it's a bit confusing because you're mentioning accuracy at the end.
Maybe it can't be solved in the short term, but expressing the problem clearly would be useful for future reference. :)
I think it might be useful to clarify what you see the problem as being.
It sounds like one complaint is queuing up too many jog operations?
Or is the problem the latency of response to a jog request?
But it's a bit confusing because you're mentioning accuracy at the end.
Maybe it can't be solved in the short term, but expressing the problem clearly would be useful for future reference. :)
I think it could be a combination of both, particularly with telnet. The web interface is not responsive enough, and it's easy to accidentally click too many times or in the wrong spot, which is why a pendant would be much better.
A UART pendant might work ok, but it is a huge undertaking for me to try and write arduino code to convert the pendant input to g code and interface to the ESP32. So I can't really say if that will solve the problem or not until I try it.
So it takes too long to start the motion after you press the button? I hadn't noticed that being an issue, it seemed pretty responsive.
Or is it that it lets you queue jogs up while in motion?
Or is it about being difficult to cancel the jogs when they become excessive?
For me, the issue is probably just a combination of network latency and the inherent potential for mistakes interacting with a webpage using a pc or tablet.
I can queue up 5 jog moves and it might take 10 or 15 seconds before it starts to execute the first one. Hardware inputs directly connected to the board would be way faster, and that immediate feedback is helpful.
There is also something to be said for the tactile feedback of a handheld controller while actually looking at the machine in motion. That is how most machine operators in real shops jog the machine around, and I think it is a more intuitive and "accurate" way or doing it vs looking back and forth between the computer screen and the machine and trying to guess how many clicks you need.
Jogging - especially the realtime kind where the user presses a button to start and releases to stop - is more complicated that you would think due to the latencies in the various steps and queues from input acquisition, gcode parsing, motion planning, and motion execution.
That said, here is an idea for a quick and dirty way to hack in sort of a pendant. The idea is that you use some ordinary channel like serial or telnet or web to set up the parameters - axis. direction, and scaling - then have a single "go" button that is directly connected to a GPIO pin. When that button is depressed, insert a $J= jog start command into the queue via the same method that is used for macro buttons, and when it is released, do the same thing that the JogCancel realtime character does, namely set the rtMotionCancel flag.
Esp32 does not have a USB interface. The modules usually have a USB to serial chip that connects to the UART serial lines on the ESP32
I can see that ESP32-S2 has USB On-The-Go.
I think it might be useful to clarify what you see the problem as being.
It sounds like one complaint is queuing up too many jog operations?
Or is the problem the latency of response to a jog request?
But it's a bit confusing because you're mentioning accuracy at the end.
Maybe it can't be solved in the short term, but expressing the problem clearly would be useful for future reference. :)
A useful jog controller should provide the following functionallity (speaking of experience):
What we experience is that if we 'continously' press the jog button, commands stack up, thus we are unable to determine when/where the machine will stop.
Personally, I strongly believe this can only be solved by providing an extra header on the expansion board for connecting a jogging controller or an MPG pendant. All the commands (jog controller interface) should be processed at the core level e.g. if the machine is not executing g-code then the jog controller can be activated, if the machine is executing g-code the jog controller would be deactivated. The updated position is polled via UART so no issue on the UI side.
This is the way the jog controller is implemented by PlanetCNC controller and it is working amazingly:
https://planet-cnc.com/using-jogging-keyboard-with-planetcnc-controllers/
I would like to lay my hands on this and try to implement it but I am just jumping in the ESP32 world, meaning it will take some time.
That's giving a much clearer picture :)
We're talking about human response times here, which are pretty slow. I imagine that if the machine is idle, then it should be possible to have a good response time even via a network interface. I think using the realtime jog cancel that Mitch mentioned above this sounds doable.
I've been playing around with network io -- I'll see if I can put together a proof of concept in a couple of days that lets it be controlled from a web browser.
Jogging - especially the realtime kind where the user presses a button to start and releases to stop - is more complicated that you would think due to the latencies in the various steps and queues from input acquisition, gcode parsing, motion planning, and motion execution.
That said, here is an idea for a quick and dirty way to hack in sort of a pendant. The idea is that you use some ordinary channel like serial or telnet or web to set up the parameters - axis. direction, and scaling - then have a single "go" button that is directly connected to a GPIO pin. When that button is depressed, insert a $J= jog start command into the queue via the same method that is used for macro buttons, and when it is released, do the same thing that the JogCancel realtime character does, namely set the rtMotionCancel flag.
Seems to me towards the right direction.
I think what someone alluded to earlier in the conversation, and I share this thought, is that the latency could potentially be minimized by controlling the jogging on the hardware level? If we had GPIO inputs for an encoder or even just a jog button with direction and step count controls, wouldn't that lower level signaling be more responsive than converting to gcode, sending across the UART, then decoding again?
Solving this problem will require analysis of the system at various points. So far what I have seen in the commentary above is guesswork and wishful thinking that some shiny new thing will magically solve the problem.
1. The key to preventing too many jog commands from queuing up is to make each command move only a short distance. 2. USB is a huge can of worms 3. Support for the S2 in and of itself is a substantial task. Maybe somebody could get a demo working quickly, but there is a world of difference between a demo and a supportable product. 4. Human response time to seeing an event and pressing a button is on the order of 300 milliseconds - an eternity of computer time. But see (1) above. If the motions that are initiated by individual jogging step events are longer than the auto-repetition rate of the events, overrun will occur. The key is to either make the individual motion times correspond to the repetition rate, or else use jog cancel.
Solving this problem will require analysis of the system at various points. So far what I have seen in the commentary above is guesswork and wishful thinking that some shiny new thing will magically solve the problem.
It sounds like the implementation is more complex than I thought. I travel to different machine shops for work, and am used to seeing almost every CNC equipped with a jog wheel. I guess I assumed there was a straightforward methodology to how they control the motion of the machine.
I think I would prefer to pursue something home brewed using the UART connection on the micro USB port rather than anything telnet-based, because of the latency I experience in ESP3D. I am guessing from what you mentioned about the 300ms response time, that some kind of debounce would fix the problem of queuing too many commands. The hard part for me is writing the code to convert the hardware inputs to G Code, but with some time, I think I can make it work.
Commercial grade CNC machines are not made with software and hardware that was originally written for Arduino toy computers. On a commercial grade machine, everything runs on the same computer. In the GRBL world, the machine control is done on a tiny processor with limited, bordering on nonexistent, user display capability. We are trying to fix that with FluidNC, but the fundamental disconnect between the user control surface hardware and the motion control hardware remains, as does the deep architecture of the grbl motion engine.
The problem is not debouncing at all. Please read what I said carefully. The problem is elucidated in items 1 and 4 - a disconnect between the repetition rate of the jog command device and the jog increment. With WebUI and the unpredictable latency of WiFi, it is hard bordering on impossible to tune those to match. It should be possible to do it with something directly connected - but it is not bouncing that is the problem, it is tuning the rates.
Can we please stop speculating?
@MitchBradley
For (1) as you wrote, I would like to understand what happens in the following scenario:
Let's say we provide the following commands (in metric) for jogging
G1X100.0F500
G1X100.1F500
G1X100.2F500
...
G1X101.1F500
and so on, so that we command the machine to move in small steps. Will the machine actually reach the feed of 500 mm/min? Or accelerating and decelerating will prevent this from happening?
I don't know how this will behave in order to understand if:
The key to preventing too many jog commands from queuing up is to make each command move only a short distance.
is the solution to jogging at a desirable feedrate without overstacking move commands.
The second thing I see is that the "sender" of these commands needs to know how much time each command will last in order to push new commands at a desirable pace. Since the "sender" knows the GRBL configuration it could calculate the rate at which commands should be sent. Is this valid thinking?
I am trying to think towards a software/host only solution to the matter.
You are correct that there is an interaction with acceleration. Making jogging work with exactly the right "feel" is quite difficult without very tight integration of the machine and the pendant, and even then it can get tricky. I have seen cases where Mach 3 stalls stepper motors if you release the continuous jog key in the wrong motion phase.
At this point, the only way to solve the problem is to engage with the code at the lowest levels and try stuff. There is no way that I can explain it deeply enough here.
Maybe this could help with MPG handwheel jogging? https://github.com/bdurbrow/grbl-Mega I love to see such feature in Fluidnc
If I may suggest solution that shouldn't be extremely difficult to implement and at the same time very cheap option would be misusing Wii Nunchuck. It's I2C so no problem there and connector adapter are cheap plain PCBs. There is plenty of code available and I think it's very intuitive to use. I used it with my LinuxCNC CoreXY Setup. Joystick for XY axis, for Z axis Joystick + pressed Z button ;) but some other combinations with holding the C button as unlock or fine movement or something could be done.
Until someone actually forks the repo and puts in the work to achieve it, it’ll be neither cheap nor not extremely difficult
Coding is dead easy compared to architecture and support. By architecture, I mean ensuring that a feature works well with other aspects of the system, extends gracefully to similar use cases, can be configured, and any number of other interactions. Supporting something like this would involve getting into an entirely different ecosystem of Wiis and joysticks of various flavors. I2C is not "no problem". It is a can of worms that we need to address but have been putting off because the can has so many worms in it. Stuff like this tends to snowball. In the CNCjs world, somebody created a seemingly-simple pendant that used a small wireless keyboard. It was utterly unsupportable because there are dozens of such keyboards that all look the same but are entirely different at the USB HID level. The point being that stuff that you might think is easy can become a nightmare.
I'm coming from the hardware space so my coding skills are far of this master piece. I mentioned that I2C should not be a problem because the OLED Module for the 6-Pack hangs on I2C so I assumed that addressing and all that stuff is already implemented. There are Arduino libraries for the Wii Nunchuck which are cpp so this is why my naïve thinking that it shouldn't be so hard. But yeah abstracting things to be universal and possible to support is extremely challenging.
A proof of concept would not be difficult. Hooking one thing up to I2C is relatively easy. It is all of the stuff around the edges that is hard. To deploy it in a way that does not cause endless support hassle, it must work seamlessly in real time, not conflict temporally and configuration-wise with other uses of I2C like OLED and the input expander work that Stefan is doing, and be expandable to other similar devices, and support a number of input scenarios. As soon as the feature is announced with one device, 6 people will appear each of whom wants to use it not with the supported device, but with whatever device they already have or whatever cool device they just saw announced.
The problem with display and pendant options, is FluidNC is pre-compiled. They all need to be compiled. This can lead a growing file where most people don't use most of the stuff. You also need to be able to enable them via the config file.
Using a a smart device and a standard interface works well to reduce that. This is how the WebUI and Web Sockets based things work.
I am currently exploring a few compiled and optional configured displays. It is a low priority compared to many other things we are working on. It will likely have to wait for major architecture changes on how things like I2C are shared across the config file.
Here is a [link to my thread in Discord}(https://discord.com/channels/780079161460916227/939545664227016714).
I'm looking into adding Wii jogging support. I'm coming from the Marlin and BigTreeTech TFT ecosystem, so this shouldn't be too much of a switch. That way the main devs can focus on bug fixes and core features.
I'm also going to add support for the PCF8574 IO Expansion Board to extend the useful GPIOs (Link: https://www.amazon.com/gp/product/B07XD2K4GH) since the ESP32 is super lacking in usable GPIOs after the base CNC functions are accounted for.
Expect it to take about 2-3 weeks for any real progress. I'll create a fresh Wii Support (and GPIO Extender) issue once I have working prototypes.
I'm also a web dev, so I can redo the web interface to be much prettier/feature rich, but that'll be low priority for me, since I'm mainly wanting a functional CNC controller (that isn't running Marlin) first.
Even lower on the priority list is LCD2004 (4 row x 20 char LCD) and rotary dial support, just because I hate how excessively tiny the OLED displays are, and I like the rotary dial features of Marlin, so I'll port some of them over.
So what is your end game? A fork that you will support?
So what is your end game? A fork that you will support?
No, just optional features to make FluidNC more feature rich. Whether they're included in the pre-compiled firmware or not I'll leave to you. I'll submit the usual pull requests once each feature is finished.
You risk colliding with IO expander work that Stefan has in progress and smooth jogging support that Bart is working on.
How far along are we talking?
Also, are you talking about creating OOP frameworks which will accommodate various hardware options? Or are they hard coding specific hardware support?
If the former, assuming the ETA isn't far off I can wait. If the latter I can simply code in support and the two shouldn't really interact (or the interactions can be handled as they get merged).
Not looking to step on toes or reinvent wheels if I can avoid it, but also don't want to wait 6-9 months for support I can develop in one. I'm definitely not looking to split the user base this early in the game, as that never turns out well for anybody.
For long term viability, we are always looking at OOP frameworks. In a few cases we add in prototype code that has to be enabled via compile time defines, but that inevitably creates support problems so we do not like to do it much.
Stefan is pretty far along on the I2C expander work; I think he is on like the third version of the code so he has learned from the mistakes of the first two versions.
You are of course free to hard code anything you want but the changes of getting it merged are approximately nil. At this point in the project, coding something that works in a specific set of circumstances is not the problem. The problem is architecting how the new capability fits in with everything else and how it works when, inevitably, the next person comes along and wants it to work ever so slightly differently. Based on recent experience, the mean time for that next person to appear is about one day.
The best way to approach this is to talk about it on Discord.
Sounds good. I'll swing by Discord over the next few days.
As to prototyping, I love your config file approach. It effectively replaces the need for the compile time defines, as anything not activated in the config never gets called in the code, so defines are rendered obsolete (or at least made dynamic). It's really the feature that brought me here: Test features can be added without risking release stability.
So it takes too long to start the motion after you press the button? I hadn't noticed that being an issue, it seemed pretty responsive.
Or is it that it lets you queue jogs up while in motion?
Or is it about being difficult to cancel the jogs when they become excessive?
I agree, the WebUI can be very unresponsive. When you click on a jog, the expected motion can be seriously delayed (sometimes up to 10 seconds). The problem is that you can think that you missed the button, or it has not been recorded... So you click again, andwhen the motion is starting, it does 2 times the jog, and you can hit an obstacle.
This is something I noticed on my xpro v5 from Spark-concept, running on GRBL ESP32 (not FluidNC). But both FluidNC and GRBL ESP32 are running the same WebUI server... So I imagine same problem can happen.
WebUI is reasonably responsive if the WiFi network is good. There is a delay at the end related to the status polling interval, which can be reduced by setting that interval to 1 second instead of the default 3. We are looking into automatic status reports on state change, which should reduce that.
I never tried to decrease the polling interval (always 3 seconds), I may give it a try. It can explain some lags, but not thous of more than 6 seconds.
And my WIFI access point is 3 meter away from my ESP32... It shouldn't be the problem. (it's Mesh WIFI, so maybe it is not recommanded ???)
My shop is 10 meters from the nearest Mesh AP, and I have no problems, so there is nothing wrong with the broad category "Mesh". I suppose there could be problems related to a crowded WiFi spectrum, or other heavy users of the network, or electrical interference from other tools or spindles or motors, or shielding because the ESP32 is inside a metal box, or a dozen other factors.
I might also be how the ESP32 is included in the xPro V5...
I never mentionned this problem, because I thought it was a natural inconvenience of the WebUI feature. But when I read you, I understand that something is wrong on my side. It's one of the main reason why I lastly switched to CNCjs over USB.
Possibly relevant: UGS has support for game controllers. That's the main reason I use it. I use a bluetooth Xbox One controller and it's been totally fine. The joysticks do rapid movement and the buttons make little steps.
I use Candle 1.1.7 with fluidnc and (when motion in Candle is set to 'continuous' obviously) it jogs very smoothly on every speed setting. It has a hard-coded keymap which enables a numeric keypad to use as pendant. The latest beta-version of Candle does not work as well (i assume because they made keymapping user-configurable). My point is that it apparently is possible. Don't know how they did it though.
I know this is an old and closed thread, but I thought I would share my journey in getting a "pendant" on FluidNC. I have so far settled on a wireless numeric keypad as it is cheap, readily available and does what I need.
In all cases, I have leveraged the continuous jogging technique described in the FluidNC wiki, i.e. send a jog command for a large value on key press and send a jog cancel on key released.
The three things I have tried so far:
I have injected a snippet of Javascript in the WebUI to respond to key events. It uses the Web UI SendJogCommand function. This was rather simple to write and works fine. However, responsiveness is dependent on a lot of layers (no an issue for me so far) AND requires that the WebUI is in focus on the computer to which the keypad is connected. Note that the version 3 of ESP3d_WEBUI seem to include keyboard support. I guess this will also translate into FluidNC when it is made compatible with the latest WEBUI version.
I have started writing (a very much incomplete) and Windows app that listens to RawInputDevices events and connects to the Telnet port on FluidNC. It generates Jog commands and pushes them in the telnet socket. It allows the keypad to be bonded to the CNC in a permanent fashion and does not require the app to be in focus. It fixes main gripe with the JavaScript solution. Still no satisfactory for me as it relies on a PC and the local network.
I have build a prototype FluidNC module that uses an Arduino Pro Mini and USB Host Shield mini. It receives keyboard events and connects to FluidNC via I2C to send Jog commands. I wrote a Channel in FluidNC that receives the events from the Arduino on I2C and pushes commands on the queue. I originally wanted to use a bluetooth keypad, but the USB Host Shield library does not support simple pairing, which has become the norm for readily available keypads these days. I tried to make it work, but ended up opting for a keypad with a 2.4g dongle. I guess it's even better as the bluetooth stack is quite complex and adds unnecessary complexity.
I experimented on using a second ESP32 as a bluetooth host with a bluetooth keyboard. This is promising, but it felt strange to have a second ESP32 as a module just for that. There is also the idea of creating a RPI Zero W 2 module that would do the same and use I2C or UART to connect to FluidNC, This would open a lot of possibilities, but at the current prices, it is not worth it.
So far, the USB Host Shield seems the best solution. One could even build a module with a MAX3421 and MCU baked on board that would do the same on a more compact form factor. USB Host Shield boards are not that easy to get by, unless you order on Ali and wait forever. This solution opens the door to many types of controllers. Any HID device could be used as a pendant provided that the Arduino code is written to translate events to Jog commands.
Sorry for the long writeup, but I thought this could help someone on the same journey.
ESP32-S2 has USB OTG support. $1.62 qty 1. https://www.aliexpress.us/item/3256804794766205.html
Many listings on amazon for $5-6/ea in qty 2 or 3.
I tried different solutions making a pendant for fluidnc and ended up building one around an esp32 (actualy a Lilygo T4 1.3, which has a little integrated tft-screen). It sends grbl-commands and receives status-updates over (serial) bluetooth. It has buttons, a joy-stick for XY-movement as wel as a rotary encoder for moving Z (or per choice X or Y) and for navigating a simple menu. It's battery-driven in a 3d-printed enclosure. Happy to share details if anyone is interested.
@gjkrediet - sounds like you have built something valuable that others might be able to use. Perhaps you should create a github repository with all of your design files and code.
ESP32-S2 has USB OTG support. $1.62 qty 1. https://www.aliexpress.us/item/3256804794766205.html
Many listings on amazon for $5-6/ea in qty 2 or 3.
The ESP32 has BT Host HID support. I have a working version with it. The ideal solution would be to have the pendant code running on the same esp as fluidnc, but bt and wifi don’t coexist very well.
For some incoherent reason, it feels odd to me to have a second esp just for that. I think I will wait for decent prices on Pi Zeros, which would also open the door to a more powerful onboard web ui in a ecosystem à la Klipper. But I digress…
The ideal solution would be to have the pendant code running on the same esp as fluidnc
No, that would not be ideal at all. It would be a support disaster because everybody would want it to behave just a little differently. The developers are already overwhelmed with requests for help debugging their machines and custom controllers and new drivers that they got from China, with questions about basic GCode and Grbl behavior, and with suggestions about how things could be done differently (often without actual understanding of how they currently work). Adding a pendant capability into the core code would open up a Pandora's box of bikeshedding and an entirely new source of bugs.
We do plan to make it easier to connect pendants via a secondary UART channel or an I2C channel, but the design, implementation. and support of such pendants will be left to other projects and their maintainers. The "second ESP" or whatever MCU one chooses to use, is a way of maintaining a separation of responsibility.
@MitchBradley I already imagined you'd say that. But you are right of course. I hardly used github before and that lack of experience kept me from starting with it for earlier projects. I will seriously look into it now. Might take some time though.
The ideal solution would be to have the pendant code running on the same esp as fluidnc
No, that would not be ideal at all. It would be a support disaster because everybody would want it to behave just a little differently. The developers are already overwhelmed with requests for help debugging their machines and custom controllers and new drivers that they got from China, with questions about basic GCode and Grbl behavior, and with suggestions about how things could be done differently (often without actual understanding of how they currently work). Adding a pendant capability into the core code would open up a Pandora's box of bikeshedding and an entirely new source of bugs.
We do plan to make it easier to connect pendants via a secondary UART channel or an I2C channel, but the design, implementation. and support of such pendants will be left to other projects and their maintainers. The "second ESP" or whatever MCU one chooses to use, is a way of maintaining a separation of responsibility.
I was thinking in terms of keyboard events, which could be standardized. To have any and every variations of jog controller would be a mess, I agree. I fully understand your concern about support. I am in software engineering myself. My comment was more related to my implementation, for which I had no intention of merging. I meant ideal in terms of closest to the core code for the less latency possible, not ideal in terms of the evolution of Fluidnc.
But if you are going the direction you mentionned, it is already not far off. All that would be needed is a new Serial channel configurable in the config.yaml with either uart or i2c pins and expect valid grbl commands.
I tried different solutions making a pendant for fluidnc and ended up building one around an esp32 (actualy a Lilygo T4 1.3, which has a little integrated tft-screen). It sends grbl-commands and receives status-updates over (serial) bluetooth. It has buttons, a joy-stick for XY-movement as wel as a rotary encoder for moving Z (or per choice X or Y) and for navigating a simple menu. It's battery-driven in a 3d-printed enclosure. Happy to share details if anyone is interested.
Hi, I would love to repeat your design, please share details.
I will put a description on github, I promise. May take some time.
Is there currently support to add a control pendant for manual jogging and basic controls? Ideally it could also have an lcd display with some general info.
My main problem that I'm trying to solve is that esp3d can be quite inconsistent with the processing times when jogging or sending commands through the terminal. I've crashed the machine on a number of occasions because I ended up sending the same command too many times while it was already in the "buffer".
A control pendant hard-wired to the esp32 would presumably be almost instantaneous, and would provide a lot better feedback to avoid overtravel into obstacles.
One of those jogging handwheels would be the icing on the cake if there was a way to implement that.