Week 15 - Machine Design

Assignment

Actuate and automate your machine

Process

Stepper motors, Grbl & g-code

After the mild accomplishment of the last assignment, I was ready to integrate the mechanic with all the necessary components to automate it. Actually, after sketching the design with already the actuation in my mind it was actually an easy task to accomplish, but first I had to understand what I was going to deal with.

The easiest way to move things in the world of making is with the help of stepper motors, which can rotate to a given degree with a given speed with relative easyness. Stepper motors are made out of several coils, which are polarized and synchronized in precise steps in order to move a shaft at the given parameters. To operate this coils is necessary an integrated driver which transforms a digital input from an interpreter into pulses of the voltage required by the motor.

This operation is often accomplished with the help of a shield which is nothing more than a breakout of the wires in a more significant and standard way.

So, to recap, to actuate a stepper motor what I needed and what I used were:

  • An interpreter - an Arduino Uno board;

  • A shield - a CNC Arduino-compatible shield;

  • Drivers - Pololu A4988 driver;

  • The stepper motor itself - a Jameco NEMA 14 200 step stepper motor;

  • A 12v power supply - for the motor;

Assembling this things together it’s quite easy, since they’re all just made for each other to fit on. You put the shield on the top of the Arduino, you put the driver on the top of the shield and you wire the stepper on the pins of the shield next to the driver. Furthermore, you wire up the 12v power supply in the proper slot of the CNC shield. The only thing to spend a little more care on is in the wiring of the stepper motor. Usually, stepper motors come in fashion of 4 or 6 colored leads used to operate the coils. Wire them up can be pretty confusing if a handy diagram like the one below isn’t used.

wiring diagram

Knowing that a stepper motor has two signals - A and B - and that they can be positive and negative, you get to plug 4 leads according the position marked on the driver and the color corresponding to the diagram. If you wire them incorrectly, the motor simply wont’ work.

There cases in which more leads are used, with drivers and interpreters of more complicated nature, but this isn’t the case of my machine and any extra cable coming out of the stepper can be just left to unplugged.

The picture below shows the full setup for operating a stepper motor.

stepper setup

This covered all that there’s to know about the hardware, but what about the software?

As I wrote, the Arduino will play as an interpreter and this is possible by flashing onto it a g-code parser anc CNC controller called Grbl. Grbl simply receives g-code instructions via the serial port and translate them on the Arduino designated pins for the drivers to be read. Beyond that, Grbl allows you to set up many technical parameters regarding the performance of the stepper motors and give you feedback on the status of the machine, with the help of a commands enabled with the $ character that are thoroughly exposed in the official repository.

Once loaded Grbl into the Arduino I had to figure out how to communicate with it and this was done firstly by understanding what g-code is. Essentially, g-code is a simple language that communicates straightforward commands for your machine to be exectued. This is done in the form of commands made of a letter and a number whose combination corresponds to a precise, finite behaviour.

For example, the commands:

G90
G0 X10 Y-10 Z5
G91
G1 x2 y5 f20

tells a machine to move to the position x=10, y=-10 and z=5 in absolute coordinates at the top of its speed, then it tells to move relatively to its position to x=2 and y=5 to a feedrate of 20.

This seems simple, and actually it is, but even in the most trivial g-code sequences you can easily get to have hundreds or thousands of commands and while most of them are relative to positioning and are procedurally-generated, many other aren’t and a general knowledge of their meaning is necessary.

For learning g-code, I found it really useful to both read fully the usual Tutorial and to skim through a more detailed and comprehensive list of commands - vocabulary-style - as the well-redacted one that I found on the machine building company website Tormach (most companies involved into machines uses g-code to operate them and everyone gives a full explaination on how every commands behaves on their machines).

Wanting to test my new-found g-code knowledge, I fired the Arduino IDE and opened the serial monitor to communicate with the grbl-enabled Arduino.

Before even starting, two very important things need to be set up. Grbl simply won’t work if the baudrate and end character aren’t set respectively to 115200and carriage return. By doing so you’ll get an easy to recognize message from the board ans you can start sending commands.

grbl baudrate

Precision is something trivially essential when dealing with machines, and Grbl won’t simply accept any command that isn’t written properly either as Grbl command or g-code . Fortunately, Grbl interface provides clear error messages in case of mistake that can be reviewed in the official repository.

grbl errors

For example, in the above gif I received the following errors (which are ones among the most common):

  • error:1:g-code words consist of a ltter and a value. Letter was not found - I submitted an unknown command

  • error:2:Numeric value format is not valid or missing an expected value - I submitted an incoherent movement

  • error:22:Feed rate has not yet been set or is undefined. - I submitted a G1 command without a feedrate but it’s expected. Instead a G0 command would have worked, since it orders to travel at highest speed possible.

If you send a properly written command, Grbl will parse and reply a reassuring feedback.

grbl ok

If everything is properly plugged and functioning, you can directly test the your stepper motor by hand writing g-code commands.

vimeo motor test

Integrate an actuator

As I wrote, when I sketched my mechanism I did it with motor, belt and bearings in my mind, so integrating them to my system was pretty easy. All I add to was to align the motor to the slide bearing and stretch and put the belt on its holder. Furthermore, since I was short on time and was tired of 3d-printing unhelpful pieces, I took a chance on the noble, underdog art of tie-zipping things thightly in the place you want them to be. That’s what I did with the stepper motor…

stepper

… and the upper pulley of the belt.

belt holder

please, note that I know that I should have not applied the zip tie to the bar, in order to not brake it, but I was really in a hurry and furthermore it worked just fine

This might sounds as really poor solutions, but the final assembly worked properly and in my opinion it had its kind of raw but useful dignity.

machine

Once everything was screwed properly on the machine base, I made few test to check if everything was working fine.

And it did!

vimeo working machine

Unity as interface

After my Interface week assignment I was really enticed to use Unity for purpose than game design. Considered that an grbl-loaded Arduino accepts nothing more that strings via serial communication, I took the same libraries used in my previous assignment and put it at work for this task.

But first I had to design an interface that could operate well the catapult we were assembling. Intentionally, a user should have been able to rotate the base of the catapult, adjust the height of the angle bar, set the force of the motor pulling the string and firing the catapult. Furthermore, the interface should have handled other functions such as resetting the catapult state and provide movement limits.

With the default assets of Unity, I set up very quickly a graphic interface with all the elements nedeed to operate the catapult. I also added a log textbox where to read the g-code instructions working on and the feedbacks from Grbl and input field to declare a different serial port from the default one (in case the application were to be used by someone else with a computer different than mine).

interface layout

Up to this point, everything was done without writing or debugging a single line of code, which is cool if you want to prototype quickly.

To make the interface work, I wrote up several scripts to make the various elements communicate and cooperate. To the core, the most essential script is the following.

Button script

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ButtonScript : MonoBehaviour {

	public float step = 1;
	public float feed = 5;
	public char axis = ' ';
	public SerialHandler serialHandler;

	public string ComposeGCcode(){
		return "G1 " + axis.ToString() + step.ToString("n2") + " F" + feed.ToString();
	}

	public void Clicked(){
		serialHandler.WriteAndRead(ComposeGCcode());
	}
}

This is attached to every button element in the scene and what it does is to generate a g-code instruction at runtime everytime the button is pressed. This instruction is composed of few public parameters set up in advance and is sent to a serial communication handle that sends it throught the serial prot to the Arduino.

For the slider element I had to add some more math, since I wanted to calculate a numerical amount according the position of the slider. However, the juice is still made of a class of the script previously written.

Slider script

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class ForceSliderScript : MonoBehaviour {

	public char axis = ' ';
	public float step = 0;
	public float feed = 5;

	ButtonScript button = new ButtonScript();

	void Start () {
		button.axis = axis;
		button.step = step;
		button.feed = feed;
	}

	public string GCodePull(){
		button.step = this.transform.GetComponent<Slider>().value;
		return button.ComposeGCcode();
	}

	public string GCodeRelease(){
		string tmp;
		button.step = -(this.transform.GetComponent<Slider>().value);
		tmp = button.ComposeGCcode();
		button.step = this.transform.GetComponent<Slider>().value;
		return tmp;
	}
}

And finally, another important script was the one handling all firing of the catapult. After reasoning a lot with my peers on how manage the catapult mechanims with stepper motors, we found a lovely solution with a forked version of Grbl called Grbl Servo, which enables you to use certain pins of the Z motor to activate a servo motor and rotate it up to a given degree with the M3 g-code commad. In combination with a stepper motor, this would be the best solution, and the related script would have only to deal with the order of commands.

public class FireScript : MonoBehaviour {

	public ForceSliderScript slider;
	public SerialHandler serial;

	public void Fire () {
		serial.WriteAndRead(slider.GCodePull());
		serial.WriteAndRead("M3 S1000");
		serial.WriteAndRead(slider.GCodeRelease());
		serial.WriteAndRead("M5");
	}
}

This script, activated by the push of the “Fire” button, first pulls the lever spring up to the desired stretch, unhook the lever, release the spring making the lever go down to its resting place and hook it again. Grbl features a very useful internal buffer, so you don’t have to worry about the timing while sending together several commands.

Finally, for debug purpose, I added a Log box where I could read all the commands sent to the serial port and the feedbacks by Grbl.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class LogScript : MonoBehaviour {

	Text text;
	List<string> log = new List<string>();

	int logSize = 5;

	void Awake () {
		text = this.transform.GetComponent<Text>();
	}

	public void UpdateLog(string msg) {
		if(log.Count >= logSize)
		{
			for (short i = 1; i <log.Count; i++)
				log[i-1] = log[i];
			log[log.Count - 1] = msg;
		}
		else
			log.Add(msg);
		Print();
	}

	void Print(){
		text.text = string.Empty;
		for(short i = 0; i < log.Count; i++)
			text.text += log[i] + "\n";
	}
}

This made use of few more technical features of both C# (using a List type for handling an array) and Unity (using the Awake() function to be sure to get the Log box active before the other components).

Result

I’m happy to say that the result is much more professional than my expectations, which might have been low, but still all the parts worked smooth as silk and were nice looking, even though I did almost none finishing.

vimeo result

Gist & Further development

Grbl was a lovely discover. It essentially covers all that is needed for a CNC machine but also provides you enough flexibility to adopt it nicely to your project.

Using Unity as an interface for the catapult was much more easy than I thought at first, with the only issues found relying more on programming technicalities than anything else.

I regret a little not having had the chance to experiment more on certain aspects of CNC machines which were totally dismissed for this catapult, like setting end runs, calculating steps, calibrating micro-steps, or exploring more g-code commands, but I won’t hide that making a machine was one of the most fascinating assignment of the whole Fab Academy and I long for when I could apply again the things I learned in these two weeks and learn many more regarding this exciting subject.

Tools and software used