The task for the eleventh week is to design, build and program a CNC (Computer Numerical Control) machine. For this project, we will work in a group.
Our team Griffin decided to build a Sisyphus inpired table with a magnetic ball printing a pattern in sand. We used SCARA as our main machanism and utilized Raspberry Pi 5, Arduino Nano and Nema17 stepper motors for control. The team website in Czech is accessible via Team Griffin link. My part in this project was to develop the control application.
The Nema17 stepper motor 1 and 2 are connected to A4988 driver and the driver recieves steps and direction orders from Arduino Nano. Arduino is then connected via USB cable with Raspberry Pi 5, which sends control sequences to Arduino over serial communication. Raspberry Pi also hosts a server, which we can connect to over Wi-fi and operate the whole ZenBot including adding new patterns, choosing one and running the "printing" process.
Include the AccelStepper Library
#include <AccelStepper.h>
#define BAUD_RATE 115200
#define DIR_PIN1 2
#define STEP_PIN1 3
#define DIR_PIN2 4
#define STEP_PIN2 5
#define SPEED 6000
#define ACCEL 12000
// Define motor interface type
#define motorInterfaceType 1
// Creates an instance 1
AccelStepper myStepper1(motorInterfaceType, STEP_PIN1, DIR_PIN1);
// Creates an instance 2
AccelStepper myStepper2(motorInterfaceType, STEP_PIN2, DIR_PIN2);
bool sent_stepped = true;
bool stopped = false;
bool homing = false;
String line = "";
int dS1, dS2;
int goS1, goS2;
void setup() {
// set the maximum speed, acceleration and position
myStepper1.setMaxSpeed(SPEED);
myStepper1.setAcceleration(ACCEL);
myStepper1.setCurrentPosition(0);
myStepper2.setMaxSpeed(SPEED);
myStepper2.setAcceleration(ACCEL);
myStepper2.setCurrentPosition(0);
Serial.begin(BAUD_RATE);
Serial.println("SETUP COMPLETE");
}
void loop() {
if (Serial.available()) {
line = Serial.readStringUntil('\n'); // Read until newline
if (line == "STOP") {
myStepper1.moveTo(myStepper1.currentPosition());
myStepper2.moveTo(myStepper2.currentPosition());
stopped = true;
Serial.println("STOPPED");
}
// Parse the values
else if (sscanf(line.c_str(), "dS1:%d dS2:%d", &dS1, &dS2) == 2 and !stopped) {
myStepper1.move(dS1);
myStepper2.move(dS2);
sent_stepped = false;
}
else if (line == "START") {
stopped = false;
Serial.println("READY");
}
// set home position
else if (sscanf(line.c_str(), "HOME goS1:%d goS2:%d", &goS1, &goS2) == 2) {
myStepper1.move(goS1);
myStepper2.move(goS2);
homing = true;
stopped = false;
}
}
if (myStepper1.distanceToGo() == 0 and myStepper2.distanceToGo() == 0 and (!sent_stepped or homing)) {
if (homing) {
myStepper1.setCurrentPosition(0);
myStepper2.setCurrentPosition(0);
Serial.println("HOMED");
homing = false;
}
else {
Serial.println("STEPPED");
sent_stepped = true;
}
}
myStepper1.run();
myStepper2.run();
}
The frontend part offers GUI to control the ZenBot, its deployed as webapp and you can connect to it via local network. It also support adding new custom patterns generate over Sandify page with setting for SCARA g-code.
Due to the program complexity the source code is accessible at ZenBot.