As I was waiting for my new PSoC to come, I decided to take some time to learn about gcode. For a long time I've wanted to know how CNC's work and what gcode really is. I figured it was a list of instructions like this, "go to (3, 2)" but I learned it's actually more complicated than that. Gcode is the language sent from a computer that instructs a CNC or XY plotter or 3D printer where and how to move. Typically an instruction starts with a letter of the alphabet and is followed by numbers. There are usually multiple of these letter-number combinations per line (usually called a block). For example "G00 X0 Y0 Z0" which tells each axis to go to the origin. Each letter is called a word and the numbers next to it are the address associated with that word. G is the go word, X controls the x-axis, Y controls the y-axis, and Z controls the z-axis. Every letter of the alphabet is used in gcode, but not all machines will use every letter. When a line of code is executed, it is not necessarily done left to right, it does the highest priority words first (like when doing math - you do multiplication before addition).
I figured that this would be a lot to code on my own and I could probably find some open source code I could use instead. As I looked around online, I came across PyCNC, which is a nifty program that actually uses python to do all the control. This program was developed so that a raspberry pi can control a CNC type of machine without a microcontroller! The way it works is by using DMA (direct memory accessing) to bypass the operating system. It basically stores the instructions in RAM and then sends those instructions directly to the GPIO pins. This allows for exact control of things like stepper motors and it uses a simple programming language - python. Since I originally intended to control the whole machine with just the raspberry pi, I'm going to use this (if it will really work).
I was excited to clone the github repository for PyCNC and test it out! I ran the update/ upgrade commands (which you're supposed to do pretty often):
sudo apt-get update
sudo apt-get upgrade
And it took forever! Apparently doing this every couple of months is not frequent enough. After quite some time waiting, my raspberry pi said the SD card had been removed. I checked - it was still there and nothing had moved. But, unfortunately, my raspberry pi would no longer respond. Since I've been running my raspberry pi headless (I only have a laptop), I had to go over to my in-laws and use their monitor, keyboard, and mouse to set up my pi again. Fortunately, I learned that SD cards installed with NOOBS have a set-up menu that you can access on start-up by holding the shift key. This allowed me to easily re-install Raspian. I also learned that with the new Raspian distro, Pixel, the upgrade command is now "sudo apt-get dist-upgrade" and I thought maybe that was my problem. So I ran the update/upgrade commands again, this time using "dist-upgrade" and it got farther, but still crashed. So finally I decided that my program will work just fine without the upgrade, and I re-installed Raspian. It's important to enable things like SSH and VNC if you're going to operate headless, otherwise you'll get home and realize you have no way of accessing your pi. At home I connected my raspberry pi to my router via ethernet cable and then remotely accessed my pi using VNC. I used that to hook up my pi to WiFi so I don't have to sit next to the router every time I want to work on my project.
Finally I could clone the github repository! Since I have never used github before, I had to do some rummaging online to figure this out. Github is an online host for private and public code. It stores original code and then any revisions that get pushed up to it. That way if you mess up your code, you can always download an old version that you know works. Cloning a repository is like downloading the code to your own computer. On the github page for the code you want, just above the list of what is stored in that repository, on the right, is a button that says "clone or download."
This will give you a web address such as https://github.com/Nikolay-Kha/PyCNC.git . On the raspberry pi, from the terminal you make sure you are in the directory where you want this code and then write the command "git clone https://github.com/Nikolay-Kha/PyCNC.git" and then it will copy the code onto your pi.
PyCNC gives step, direction, and enable outputs, so you have to use an A4988 or DRV8825 driver board to interface with the stepper motors. Here's the pinout from the readme section.
Circuit name | RPi pin name | RAMPSv1.4 board pin name | Note |
---|---|---|---|
X step | GPIO21 | A0 | |
X dir | GPIO20 | A1 | |
steppers enable | GPIO26 | A2, A8, D24, D30, D38 | all steppers |
Y step | GPIO16 | A6 | |
Y dir | GPIO19 | A7 | |
Z dir | GPIO13 | D48 | |
Z step | GPIO12 | D46 | |
E1 step | GPIO6 | D36 | reserve |
E1 dir | GPIO5 | D34 | reserve |
E0 dir | GPIO7 | D28 | |
E0 step | GPIO8 | D26 | |
Z max | GPIO11 | D19 | |
Z min | GPIO25 | D18 | |
Y max | GPIO9 | D15 | |
Y min | GPIO10 | D14 | |
X max | GPIO24 | D2 | |
X min | GPIO23 | D3 | |
heater bed | GPIO22 | D8 | |
heater 2 | GPIO27 | D9 | uses for fan |
heater 1 | GPIO18 | D10 | |
ser 1 | GPIO17 | D11 | reserve |
ser 2 | GPIO15 | D6 | reserve |
ser 3 | GPIO4 | D5 | reserve |
ser 4 | GPIO14 | D4 | reserve |
I2C SCL | GPIO3 | - | to ads111x |
I2C SDA | GPIO2 | - | to ads111x |
ads1115 ch0 | - | A15 | heater 2 - nc |
ads1115 ch1 | - | A14 | bed sensor |
ads1115 ch2 | - | A13 | extruder sensor |
ads1115 ch3 | - | - |
To test this, I decided to just hook up a motor to the x-axis. I wired my stepper motor to the driver board and the driver board to the pi as shown below.
To run the PyCNC file, you navigate into the PyCNC directory and run "sudo ./pycnc" and then you can enter gcode manually one line at a time. If you run "sudo ./pycnc filename" it will execute a whole file of gcode (where filename is the name of your file). When I tried running a simple command to move the x-axis, it didn't work and I double checked that my wires were connected correctly. 1A and 1B are for one coil and 2A and 2B connect to the other coil. So I changed my wires to be correct.
It still did not work. After reading some comments on the github page I played around with changing the stepper pulse length. This is done in the cnc folder in the file called config.py. When I changed the stepper pulse length to 10us it moved! The next thing to do will be to fine tune the dimensions such as how many steps per millimeter on each axis (that information is stored in the config file) and I'll have to test a whole file.