// CutterZsaw for for LLM Foam Cutter // Motion: cut downwards on Z, rotate 90°, repeat 4 times = 4 side faces, then cut top/bottom faces on X // Pins Mapping #define X_STEP 17 // X motor STEP pin #define X_DIR 16 // X motor DIR pin #define ENX 18 // X motor Enable pin #define Z_STEP 20 // Z motor STEP pin #define Z_DIR 19 // Z motor DIR pin #define ENZ 21 // Z motor Enable pin #define Y_STEP 5 // Y motor STEP pin #define Y_DIR 6 // Y motor DIR pin #define ENY 4 // Y motor Enable pin // Limit Switches #define LIMIT_X 9 #define LIMIT_Z 11 // Motion parameters const int steps_per_mm_z = 400; // Z motor 1/16 microstepping, 8 mm lead screw const int steps_per_mm_x = 80; // X motor 1/16 microstepping, rack & pinion const int rotation_steps_per_rev = 3200; // Y motor 1/16 microstepping const int cube_size_mm = 30; // Cube size in mm void setup() { Serial.begin(9600); // Start serial communication // Setup limit switches pinMode(LIMIT_X, INPUT_PULLUP); pinMode(LIMIT_Z, INPUT_PULLUP); // Stepper pins pinMode(X_STEP, OUTPUT); pinMode(X_DIR, OUTPUT); pinMode(ENX, OUTPUT); pinMode(Y_STEP, OUTPUT); pinMode(Y_DIR, OUTPUT); pinMode(ENY, OUTPUT); pinMode(Z_STEP, OUTPUT); pinMode(Z_DIR, OUTPUT); pinMode(ENZ, OUTPUT); // Enable motors digitalWrite(ENX, LOW); digitalWrite(ENY, LOW); digitalWrite(ENZ, LOW); Serial.println("Waiting 2 seconds before homing..."); delay(2000); homeX(); delay(5000); homeZ(); delay(50); Serial.println("Waiting 2 seconds... Homing complete. Ready to cut!"); delay(1000); // back off from switches Serial.println("Reference move: back off away from switches"); moveZ(true, steps_per_mm_z * 65); //upwards delay(50); moveX(false, steps_per_mm_x * 123); //backwards delay(50); moveZ(false, steps_per_mm_z * 13); //downwards delay(2000); //to start the cut moveX(true, steps_per_mm_x * 15); //forwards runCubeCut(); // done while (true) {} } void loop() { // Nothing! } // Homing functions // Home Z‑axis by moving up until limit switch triggers void homeZ() { Serial.print("Homing Z..."); digitalWrite(Z_DIR, LOW); // down while (digitalRead(LIMIT_Z) == HIGH) { step(Z_STEP); delayMicroseconds(200); } // bounce back 1 mm digitalWrite(Z_DIR, HIGH); // up for (int i = 0; i < steps_per_mm_z; i++) { step(Z_STEP); delayMicroseconds(200); } Serial.println(" homed and bounced"); } // Home X‑axis by moving backward until limit switch triggers void homeX() { Serial.print("Homing X..."); digitalWrite(X_DIR, HIGH); // forward while (digitalRead(LIMIT_X) == HIGH) { step(X_STEP); delayMicroseconds(200); } // bounce back 1 mm digitalWrite(X_DIR, LOW); // backward for (int i = 0; i < steps_per_mm_x; i++) { step(X_STEP); delayMicroseconds(200); } Serial.println(" X homed and bounced."); } void runCubeCut() { for (int face = 0; face < 4; face++) { // side cut moveZ(false, steps_per_mm_z * cube_size_mm); //down delay(200); moveZ(true, steps_per_mm_z * cube_size_mm); //up delay(200); rotateY(true, rotation_steps_per_rev / 4); //rotate 90° delay(250); } // top/bottom cut moveZ(false, steps_per_mm_z * cube_size_mm); //down delay(200); moveX(false, steps_per_mm_x * cube_size_mm); //backward delay(250); moveZ(true, steps_per_mm_z * cube_size_mm*2); //up delay(200); Serial.println("Cube cut complete."); } // Rotate Y‑axis table CW or CCW void rotateY(bool clockwise, int steps) { digitalWrite(Y_DIR, clockwise ? HIGH : LOW); for (int i = 0; i < steps; i++) { step(Y_STEP); delayMicroseconds(200); } } // Move Z‑axis alone (down/up) void moveZ(bool down, int steps) { digitalWrite(Z_DIR, down ? HIGH : LOW); for (int i = 0; i < steps; i++) { step(Z_STEP); delayMicroseconds(200); } } // Move X‑axis alone (inward/outward) void moveX(bool inward, int steps) { digitalWrite(X_DIR, inward ? HIGH : LOW); for (int i = 0; i < steps; i++) { step(X_STEP); delayMicroseconds(200); } } // Generic step pulse generator void step(int pin) { digitalWrite(pin, HIGH); delayMicroseconds(60); digitalWrite(pin, LOW); delayMicroseconds(600); }