170 lines
5.5 KiB
Plaintext
170 lines
5.5 KiB
Plaintext
// #include <Arduino.h>
|
|
|
|
// // --- Hardware Configuration ---
|
|
// #define IN1 9
|
|
// #define IN2 10
|
|
// #define IN3 11
|
|
// #define IN4 12
|
|
|
|
// // The step sequence (standard for 28BYJ-48 motors)
|
|
// int stepSequence[8][4] = {
|
|
// { 1, 0, 0, 0 },
|
|
// { 1, 1, 0, 0 },
|
|
// { 0, 1, 0, 0 },
|
|
// { 0, 1, 1, 0 },
|
|
// { 0, 0, 1, 0 },
|
|
// { 0, 0, 1, 1 },
|
|
// { 0, 0, 0, 1 },
|
|
// { 1, 0, 0, 1 }
|
|
// };
|
|
|
|
// // --- Configuration Constants ---
|
|
// const int STEPS_PER_REV = 4096;
|
|
// int stepInterval = 1;
|
|
// bool autoMode = true;
|
|
|
|
// // --- State Variables ---
|
|
// long targetSteps = 0;
|
|
// long currentStepCount = 0;
|
|
// unsigned long lastMoveTime = 0; // Timer for movement steps
|
|
// int speedScale = 1;
|
|
|
|
// // --- Auto Mode Specific Variables ---
|
|
// unsigned long autoTimer = 0; // Tracks time since last auto-move
|
|
// unsigned long autoInterval = 5000; // 5 seconds delay between moves
|
|
// int autoState = 0; // 0 = Waiting, 1 = Moving
|
|
// int autoStepsToMove = 0; // Calculated steps for 15 degrees
|
|
// int autoStepIndex = 0; // Current step index within the move
|
|
|
|
// void setStep(int a, int b, int c, int d) {
|
|
// digitalWrite(IN1, a);
|
|
// digitalWrite(IN2, b);
|
|
// digitalWrite(IN3, c);
|
|
// digitalWrite(IN4, d);
|
|
// }
|
|
|
|
// void setup() {
|
|
// pinMode(IN1, OUTPUT);
|
|
// pinMode(IN2, OUTPUT);
|
|
// pinMode(IN3, OUTPUT);
|
|
// pinMode(IN4, OUTPUT);
|
|
|
|
// Serial.begin(9600);
|
|
// while (!Serial) {};
|
|
|
|
// stepInterval = map(speedScale, 1, 50, 1, 100);
|
|
|
|
// // Calculate steps for 15 degrees once
|
|
// autoStepsToMove = (int)((15.0 / 360.0) * STEPS_PER_REV);
|
|
|
|
// autoTimer = millis(); // Start the 5s timer immediately
|
|
// Serial.println("System Started.");
|
|
// Serial.println("Current Mode: AUTO (15 degrees every 5 seconds)");
|
|
// Serial.println("Send a number or 's[1-50]' to switch to MANUAL mode.");
|
|
// }
|
|
|
|
// void loop() {
|
|
// // --- 1. SERIAL INPUT PROCESSING (HIGHEST PRIORITY) ---
|
|
// // If ANY input is received, switch to manual mode IMMEDIATELY.
|
|
// if (Serial.available() > 0) {
|
|
// String input = Serial.readString();
|
|
// input.trim();
|
|
|
|
// if (input.length() > 0) {
|
|
// if (input.startsWith("s")) {
|
|
// // Handle Speed change
|
|
// int newSpeed = input.substring(1).toInt();
|
|
// if (newSpeed >= 1 && newSpeed <= 50) {
|
|
// speedScale = newSpeed;
|
|
// stepInterval = map(speedScale, 1, 50, 1, 100);
|
|
|
|
// // If we were moving, stop immediately
|
|
// currentStepCount = targetSteps;
|
|
// autoStepIndex = autoStepsToMove; // Force auto move to finish logic (or reset)
|
|
|
|
// Serial.print("Success: Speed set to ");
|
|
// Serial.println(speedScale);
|
|
// } else {
|
|
// Serial.println("Error: Use scale 1-50.");
|
|
// }
|
|
// } else {
|
|
// // Handle Degree change
|
|
// float val = input.toFloat();
|
|
// if (val != 0) {
|
|
// targetSteps = (long)((val / 360.0) * STEPS_PER_REV);
|
|
// currentStepCount = 0; // Reset count to start from zero
|
|
// lastMoveTime = millis();
|
|
// autoMode = false; // SWITCH TO MANUAL MODE
|
|
// autoState = 0; // Reset auto state machine
|
|
|
|
// Serial.print("Switching to Manual Mode. Target: ");
|
|
// Serial.print(val);
|
|
// Serial.println(" degrees.");
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
|
|
// // --- 2. EXECUTION LOGIC ---
|
|
|
|
// if (autoMode) {
|
|
// /*
|
|
// NON-BLOCKING AUTO MODE:
|
|
// State Machine:
|
|
// 0: Waiting for 5 seconds
|
|
// 1: Moving the 15 degrees
|
|
// */
|
|
|
|
// if (autoState == 0) {
|
|
// // Check if 5 seconds have passed
|
|
// if (millis() - autoTimer >= autoInterval) {
|
|
// autoTimer = millis(); // Reset timer
|
|
// autoState = 1; // Start moving
|
|
// autoStepIndex = 0; // Reset step counter for this move
|
|
// lastMoveTime = millis(); // Start the step timer
|
|
// }
|
|
// }
|
|
// else if (autoState == 1) {
|
|
// // Move one step if enough time passed
|
|
// if (millis() - lastMoveTime >= (unsigned long)stepInterval) {
|
|
// lastMoveTime = millis();
|
|
|
|
// // Calculate sequence index
|
|
// int seqIdx = autoStepIndex % 8;
|
|
// setStep(stepSequence[seqIdx][0], stepSequence[seqIdx][1],
|
|
// stepSequence[seqIdx][2], stepSequence[seqIdx][3]);
|
|
|
|
// autoStepIndex++;
|
|
|
|
// // Check if we finished the 15-degree move
|
|
// if (autoStepIndex >= autoStepsToMove) {
|
|
// autoState = 0; // Back to waiting
|
|
// Serial.println("Auto move complete. Waiting 5s...");
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
// else {
|
|
// /*
|
|
// MANUAL MODE:
|
|
// Non-blocking movement toward target.
|
|
// */
|
|
// if (currentStepCount != targetSteps) {
|
|
// if (millis() - lastMoveTime >= (unsigned long)stepInterval) {
|
|
// lastMoveTime = millis();
|
|
|
|
// // Determine direction
|
|
// long direction = (targetSteps > currentStepCount) ? 1 : -1;
|
|
|
|
// // Calculate sequence index (handling negative modulo correctly)
|
|
// int seqIdx = (int)((currentStepCount % 8 + 8) % 8);
|
|
// setStep(stepSequence[seqIdx][0],
|
|
// stepSequence[seqIdx][1],
|
|
// stepSequence[seqIdx][2],
|
|
// stepSequence[seqIdx][3]);
|
|
|
|
// currentStepCount += direction;
|
|
// }
|
|
// }
|
|
// }
|
|
// } |