I started this project more than a year ago. It was supposed to be the first Make with Ada project but it became the most challenging from both, the hardware and software side.

# CNC and Gcode

CNC stands for Computerized Numerical Control. It’s the automatic control of multi-axes machines, such as lathes, mills, laser cutters or 3D printers.

Most of the CNC machines are operated via the Gcode language. This language provides commands to move the machine tool along the different axes.

Here are some examples of commands:

```M17 ; Enable the motors
G28 ; Homing. Go to a known position, usually at the beginning of each axis
G00 X10.0 Y20.0 ; Fast positioning motion. Move to (X, Y) position as fast as possible
G01 X20.0 Y30.0 F50.0 ; Linear motion. Move to (X, Y) position at F speed (mm/sec)
G02 X20.0 Y10.0 J-10.0 I0.0 ; Circular motion. Starting from the current position, move to (X, Y) along the circle of center (Current_Position + (I, J))
M18 ; Disable the motors```

The Gcode above will produce this tool motion:

Most of the time, machinists will use a software to generate Gcode from a CAD design file. In my case, I used Inkscape (the vector graphics editor) and a plugin that generates Gcode from the graphics. Here is an example of Gcode which I used with my machine: make_with_ada.gcode.

# Hardware

To achieve precise movements, CNC machines use a special kind of electric motors: stepper motors. With the appropriate electronic driver, stepper motors rotate by a small fixed angle every time a step signal is received by the driver. (more info).

The rotation motion of the motor is translated to linear motion with a leadscrew. With the characteristic of both, the motor and leadscrew, we can determine the number of steps required to move one millimeter. This information is then used by the CNC controller to convert motion commands into a precise number of steps to be executed on each motor.

To create my own small CNC machine, I used tiny stepper motors from old DVD drives and floppy disk drives. I mounted them on the enclosure of one of the DVD drives. The motors are driven by low voltage stepper drivers from Pololu and the software is running on an STM32F4 Discovery.

# Software

My CNC controller is greatly inspired by the Grlb project. Besides the fact that my controller is running on an STM32F4 (ARM Cortex-M4F) and Grbl is running on an Arduino (AVR 8-bit), the main difference is the use of tasking provided by the Ada language and the Ravenscar run-time.

The embedded application is running in 3 tasks:

1. Gcode interpreter: This task waits for Gcode commands from the UART port, parses them and translates all the motion commands into absolute linear movements (Motion blocks). The circle interpolations are transformed into a list of linear motions that will approximate the circle.
2. The planner: This task takes motion blocks as an input and splits each one into multiple segments. A segment is a portion of a motion block with a constant speed. By setting the speed of each segment within a block, the planner can create acceleration and deceleration profiles (as seen in the video).
3. Stepper: This is a periodic task that will generate step signals to the motors. The frequency of the task will depend on the feed rate required for the motion and the acceleration profile computed by the planner. Higher frequency means more steps per second and therefore higher motion speed.

# Gcode simulator and machine interface

To be able to quickly evaluate my Gcode/Stepper algorithm and to be able to control my CNC machine, I developped a native (Linux/Windows) application.

The center part of the application shows the simulated motions from the Gcode.The top left button matrix provides manual control of the CNC machine, for example ‘move left’ by 10 mm. The left text view shows the Gcode to be simulated/executed. The bottom text view (empty on this screenshot) shows the message sent to us by the machine.