// #include // // --- 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; // } // } // } // }