Programming Tutorial
Estimated Time: 2 hours | Difficulty: Intermediate
1. GCode Basics
What is GCode?
GCode is a standard programming language for CNC machines. Delta Robot also uses GCode for motion control.
1.1 Basic Motion Commands
| Command | Description | Parameters | Example |
|---|---|---|---|
G0 |
Rapid positioning | X, Y, Z, F | G0 X10 Y20 Z-200 |
G1 |
Linear interpolation | X, Y, Z, F | G1 X50 F1000 |
G28 |
Homing | None | G28 |
G90 |
Absolute positioning | None | G90 |
G91 |
Relative positioning | None | G91 |
1.2 M Commands (Auxiliary Functions)
| Command | Function | Example |
|---|---|---|
M3 |
Pump ON | M3 |
M5 |
Pump OFF | M5 |
M7 |
Valve ON (suction) | M7 |
M9 |
Valve OFF (release) | M9 |
M17 |
Enable motors | M17 |
M18 |
Disable motors | M18 |
1.3 Complete Pick Sequence Example
# Step 1: Home
G28
# Step 2: Move above object
G0 X30 Y-20 Z-160
# Step 3: Descend to pick height
G0 Z-200
# Step 4: Activate pump and valve (suction)
M3
M7
G4 P500 # Wait 500ms
# Step 5: Rise
G0 Z-160
# Step 6: Move to target
G0 X-50 Y30
# Step 7: Descend
G0 Z-200
# Step 8: Release
M9
G4 P300
# Step 9: Rise and turn off pump
G0 Z-160
M5
2. Python API
2.1 Serial Communication
from serial import Serial
import time
# Connect to ESP32
robot = Serial('COM3', 115200, timeout=1)
time.sleep(2) # Wait for stable connection
# Send GCode command
def send_gcode(command):
robot.write((command + '\n').encode())
response = robot.readline().decode().strip()
print(f"Sent: {command} | Response: {response}")
return response
# Usage example
send_gcode("G28")
send_gcode("G0 X10 Y20 Z-200")
2.2 Vision Processing (YOLOv8)
import cv2
from ultralytics import YOLO
# Load YOLOv8 model
model = YOLO('yolov8n.pt')
# Open camera
cap = cv2.VideoCapture(0)
while True:
ret, frame = cap.read()
if not ret:
break
# Object detection
results = model(frame)
# Get detection results
for r in results:
boxes = r.boxes
for box in boxes:
x1, y1, x2, y2 = box.xyxy[0].tolist()
conf = box.conf[0].item()
cls = int(box.cls[0].item())
# Calculate object center
cx = int((x1 + x2) / 2)
cy = int((y1 + y2) / 2)
print(f"Object at pixel: ({cx}, {cy})")
# Display results
annotated = results[0].plot()
cv2.imshow('Detection', annotated)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
2.3 Coordinate Transformation
import numpy as np
# Load perspective transform matrix (generated during calibration)
H = np.load('homography_matrix.npy')
def pixel_to_robot(px, py):
"""Convert pixel coordinates to robot coordinates"""
# Input: pixel coordinates (px, py)
# Output: robot coordinates (x, y) in mm
pixel_point = np.array([[px, py]], dtype='float32')
pixel_point = np.array([pixel_point])
robot_point = cv2.perspectiveTransform(pixel_point, H)
x = robot_point[0][0][0]
y = robot_point[0][0][1]
return x, y
# Usage example
px, py = 320, 240 # Image center
x, y = pixel_to_robot(px, py)
print(f"Robot coordinate: X={x:.1f}, Y={y:.1f}")
3. Firmware Development
3.1 Kinematics Solving (robotGeometry.cpp)
Delta robot uses inverse kinematics: given end effector coordinates (x, y, z), calculate 3 motor angles (θ1, θ2, θ3).
// Core function: Inverse kinematics solving
int delta_calcInverse(float x0, float y0, float z0,
float &theta1, float &theta2, float &theta3) {
// Detailed math derivation see robotGeometry.cpp
// Return: 0 success, -1 out of range
}
3.2 Interpolation Algorithm (interpolation.cpp)
Uses cosine acceleration profile for smooth motion:
// SPEED_PROFILE = 2 (cosine acceleration)
// Features: Smooth start and stop, no jerk
float Interpolation::cosineApproximation(float t) {
if (t < 0.25) {
return t * t * 8.0;
} else if (t < 0.75) {
return 2.0 * t - 0.25;
} else {
return 1.0 - (1.0 - t) * (1.0 - t) * 8.0;
}
}
4. Code Examples
Example 1: Hello World (Move to Position)
from serial import Serial
import time
robot = Serial('COM3', 115200, timeout=1)
time.sleep(2)
robot.write(b'G28\n') # Home
time.sleep(3)
robot.write(b'G0 X10 Y20 Z-200\n') # Move
print("Hello, Delta Robot!")
Example 2: Draw Square
def draw_square(size=40):
send_gcode("G28")
send_gcode("G0 X0 Y0 Z-200")
# 4 vertices
corners = [
(size/2, size/2),
(-size/2, size/2),
(-size/2, -size/2),
(size/2, -size/2),
]
for x, y in corners:
send_gcode(f"G1 X{x} Y{y} F1000")
time.sleep(1)
send_gcode(f"G1 X{size/2} Y{size/2}") # Return to start
draw_square()