#include <AccelStepper.h>
AccelStepper stepper(AccelStepper::DRIVER, 3, 2); // Initialize stepper with Step and Dir pins
String inputString = ""; // Buffer for incoming serial data
boolean stringComplete = false; // Flag to indicate if a complete command is received
int value[8] = {0}; // Array to store parsed values from commands
int32_t GR = 8; // Gear ratio or movement multiplier
int mode = 4; // Initial mode setting for the motor
int corner; // Stores corner value based on mode
bool moveComplete = false; // Flag to indicate if the motor has completed a move
void setup() {
stepper.setAcceleration(1200); // Set motor acceleration
stepper.setMaxSpeed(2500); // Set maximum speed for the stepper
Serial.begin(115200); // Initialize serial communication at 115200 baud
inputString.reserve(400); // Reserve 400 bytes for the input buffer
modeSwitch(mode); // Set initial motor mode
}
void loop() {
serialRead(); // Read and process serial input
MoveMotor(); // Handle motor movement
}
void serialRead() {
// Reads characters from the serial input buffer and builds the input string
while (Serial.available() > 0) {
char inChar = (char)Serial.read();
inputString += inChar; // Append each character to the input string
if (inChar == '\n') {
stringComplete = true; // Set flag when a full line is received
}
}
if (stringComplete) {
SerialProc(); // Process the completed command
inputString = ""; // Clear the input string after processing
stringComplete = false; // Reset flag for next command
}
}
void SerialProc() {
// Process commands based on specific string patterns
if (inputString.substring(0, 5) == "CT();") {
SendReply(); // Simple acknowledgment reply
} else if (inputString.substring(0, 8) == "CT+START") {
movetable(); // Parse table data from command
motor_X(); // Execute motor command based on parsed data
}
}
void movetable() {
// Parse comma-separated values from the command string
int index = inputString.lastIndexOf('(');
int index2 = inputString.lastIndexOf(')');
String sub_S = inputString.substring(index + 1, index2); // Extract values inside parentheses
for (int i = 0; i < 8; i++) {
int i2 = sub_S.indexOf(',');
if (i2 == -1) break; // Stop parsing if no more commas are found
value[i] = sub_S.substring(0, i2).toInt(); // Convert each value to integer
sub_S = sub_S.substring(i2 + 1); // Move to the next value
}
}
void SendReply() {
Serial.println("CR+OK;#"); // Send acknowledgment reply
}
void motor_X() {
// Set motor target position based on parsed values
int direction = value[0] ? 1 : -1; // Determine direction from value[0]
stepper.move(direction * value[3] * GR); // Set relative target position
moveComplete = false; // Reset completion flag when a new movement starts
stepper.runToPosition(); // Move motor to target position
}
void MoveMotor() {
// Control motor movement and send event when target is reached
stepper.runSpeed(); // Use runSpeed for constant speed movement
// Check if the motor has reached the target and if the message was not sent
if (stepper.distanceToGo() == 0 && !moveComplete) {
Serial.println("CR+OK;CR+EVENT=TB_PAUSE;CR+EVENT=TB_END;#"); // Notify when movement is done
moveComplete = true; // Set flag to indicate completion, preventing repeated messages
}
}
void modeSwitch(int f) {
// Update motor corner setting based on mode value 'f'
if (f > 6) f = 0; // Default to 0 if 'f' is out of range
switch(f) {
case 0: corner = 90; break; // Mode 0: 4 steps
case 1: corner = 60; break; // Mode 1: 6 steps
case 2: corner = 45; break; // Mode 2: 8 steps
case 3: corner = 30; break; // Mode 3: 12 steps
case 4: corner = 20; break; // Mode 4: 18 steps
case 5: corner = 15; break; // Mode 5: 15 steps
case 6: corner = 10; break; // Mode 6: 36 steps
}
}