Consumer CNC machines and open source firmwares have come a long way in a short amount of time but still lack some features that I wanted after obtaining my first CNC.  Although MPG handwheels are common on machines running Mach or LinuxCNC, they were mostly missing from USB based CNC machines.  They are also typically driven by laptop machines instead of single purpose industrial devices.  I began this project in order to use a MPG with Grbl but it quickly grew into a full fledged CNC control panel.

Hardware

The hardware consists of a 10" resistive touchscreen, hardware led cycle start, feed hold, and cycle stop buttons, custom macro buttons, spindle on and spindle off, analog jog joystick, jog control knobs, feed override and spindle override knobs, an emergency stop, and of course a MPG handwheel.  The hardware inputs all feed into an ATmega328P microcontroller.  The digital inputs are passed through 3 daisy chained 8-bit shift registers. The ATmega328P sends the state of all the buttons, touchscreen, knobs, etc to the Raspberry Pi at regular intervals over the Pi's hardware serial pins.  The entire board sits on top if the Pi as a Hat.

After selecting components, the PCB design was laid out in KiCAD and a couple of weeks later the PCBs arrived with an aluminum SMT stencil.  The stencil made it was easy to solder all the surface mount components in a toaster oven based reflow oven.


While waiting on the PCBs, work began on the CAD modelling of the enclosure in FreeCAD.  All of the numeric constants utilized in the design were stored in a FreeCAD spreadsheet.  The various files in the design all linked to the same spreadsheet so that changing a design parameter in one place would instantly update all the files in the design.

The enclosure was cut from a single 12"x24" 1/4" ABS sheet on the CNC.  The CAM work for it was performed using the FreeCAD Path workbench.  Having both CAD and CAM in the same application allowed for design parameter changes to also automatically update the tool paths.  The Path workbench supports most common machining operations as well as adaptive clearing and dressups.

Touchscreen Integration

The software is written in C++ with a heavily utilization of Qt.  The software reads the touchscreen events from the microcontroller and submits them to the Linux kernel by creating a uinput device with libevdev.  This allows the resistive touchscreen to be seen as a normal input device to the application.

General Interface

The application has page navigation buttons on the left and an status widget on the right that is available on all pages.  It features a DRO and buttons for the features most commonly used.

Visual Window

The Visual window shows a 3D preview of the tool paths.  Feeds are in green and rapids are red.  The cursor shows the current machine position.

Running State

While running, visual feedback is given on the current feedrate and spindle RPM as blue bar that shows the current value with respect to the max.

MDI Window

The MDI window allows for manual commands and viewing the information going to and from the machine.


Program Window

The program window shows the G-Code loaded into the program.


Onscreen Keyboard

Modern platforms such as iOS and Android, that were originally designed around a touchscreen, integrate the onscreen keyboard so well that it's mostly taken for granted. Since classic platforms such as Windows and Linux/X were designed long before touchscreens were common, their integration of onscreen keyboards is often non-intuitive by comparison. On these platforms, the keyboard usually has to be manually brought up by clicking a button in the toolbar before typing can begin.  Since the platforms were not designed with onscreen keyboards in mind, most applications are not written to send the special signals to notify the system that the keyboard is needed for typing. As a result, although there is often a setting to "automatically bring up the keyboard", in practice it rarely works. Once the keyboard is displayed, it can appear in positions that cover the area that the user is typing into, requiring the user to (often repeatedly) move the keyboard to another screen location to see their typed characters.

The onscreen keyboard in this project seeks to operate more like an iOS or Android keyboard and avoid the issues of Windows and Linux/X ones.

The goals of the onscreen keyboard were as follows:
1. Automatically appear when an input box has focus
2. Directly input into UI controls and not via separate Input Box
3. Go away when the input box loses focus
4. Keep the control receiving input visible without moving the keyboard
5. Be flexible enough to support multiple languages

Before Keyboard is Displayed

After Clicking the MDI Input Box

Since the application operates fullscreen and is the only running program, the aforementioned issues can be avoided by directly implementing the keyboard into the application instead of relying upon an external platform provided keyboard. The GUI structure of the application is setup where all the main content exists in a scrollable area other than the main menu and the keyboard widget itself. A keyboard focus change listener is installed at the global level to allow the keyboard to tell when a control has received keyboard focus. Once focus is received, it makes itself visible at the bottom of the screen which compresses the content area and activates its scrolling behavior.

It then sends a signal to scroll the content area to a point where the input box is visible. All key presses on the onscreen keyboard emit a global key-code that appears as if it came from a normal USB keyboard to the rest of the application. Once keyboard focus is lost, the keyboard widget hides itself and the application appears as normal again.