#include <jled.h> #include <AccelStepper.h> #include <MultiStepper.h> #include <AceButton.h> using namespace ace_button; #define ROTATIONS 1 #define ROT_R 2 #define ROT_L 2 #define ROT_STEPS 4096 #define ROT_SPEED 1000 #define ROT_ACCEL 800 #define ROT_PAUSE 4000 #define PAUSE_MIN 2 #define LED_PIN 5 #define SW_PIN 4 enum StateType { W_INIT, // 0 W_SETUP, // 1 W_IDLE, // 2 W_CYCLE, // 3 W_LEFT, // 4 W_RIGHT, // 5 W_STOP, // 6 W_PAUSE // 7 }; AccelStepper winder(8, 8, 10, 9, 11, false); JLed pwr_led = JLed(LED_PIN).FadeOn(1000); AceButton pwr_sw(SW_PIN); int TargetPos = 0; long StartTime = 0; int Rotations = ROTATIONS; StateType WState = W_INIT; int Restart = false; int Continue = false; int StopWind = false; int WaitMin = PAUSE_MIN; void handleSwEvent(AceButton *, uint8_t, uint8_t); void setup() { ButtonConfig *buttonConfig = pwr_sw.getButtonConfig(); WState = W_SETUP; Serial.begin(9600); pinMode(SW_PIN, INPUT_PULLUP); buttonConfig->setEventHandler(handleSwEvent); buttonConfig->setFeature(ButtonConfig::kFeatureClick); buttonConfig->setFeature(ButtonConfig::kFeatureLongPress); buttonConfig->setFeature(ButtonConfig::kFeatureSuppressAfterLongPress); buttonConfig->setClickDelay(500); winder.setMaxSpeed(ROT_SPEED); winder.setAcceleration(ROT_ACCEL); WState = W_IDLE; } void loop() { StateType old_state = WState; static long act_sec = 0; pwr_sw.check(); pwr_led.Update(); switch (WState) { case W_IDLE: if (Restart || Continue) { WState = W_CYCLE; Restart = false; } StartTime = millis(); winder.enableOutputs(); Rotations = ROTATIONS; break; case W_CYCLE: pwr_led.Blink(1000, 500).Forever(); if (StopWind) { WState = W_STOP; } else if ((Rotations--) > 0) { Serial.print("Counter : "); Serial.println(Rotations); #if (ROT_R > 0) WState = W_RIGHT; TargetPos -= (ROT_R * ROT_STEPS); //-4096; // Une rotation complète avec 2048 pas (1 tour environ 4.5sec) winder.moveTo(TargetPos); #elif (ROT_L > 0) WState = W_LEFT; TargetPos += (ROT_R * ROT_STEPS); //-4096; // Une rotation complète avec 2048 pas (1 tour environ 4.5sec) winder.moveTo(TargetPos); #endif } else { WState = W_STOP; } break; // case W_CYCLE case W_RIGHT: if (winder.distanceToGo() != 0) { winder.run(); } else if (StopWind) { WState = W_STOP; } #if (ROT_L > 0) else { WState = W_LEFT; TargetPos += (ROT_R * ROT_STEPS); //-4096; // Une rotation complète avec 2048 pas (1 tour environ 4.5sec) winder.moveTo(TargetPos); } #else else { WState = W_CYCLE; } #endif break; // case W_RIGHT case W_LEFT: if (winder.distanceToGo() != 0) { winder.run(); } else if (StopWind) { WState = W_STOP; } else { WState = W_CYCLE; } break; // case W_LEFT case W_STOP: StopWind = false; winder.disableOutputs(); StartTime = millis(); WState = W_PAUSE; if (Continue) { pwr_led.Breathe(5000).Forever(); } break; // case W_STOP case W_PAUSE: { long temp = millis() - StartTime; long delta = 60L * 1000L; static long old_sec; static int last_min = false; if (Restart) { WState = W_IDLE; } else if (Continue && temp > (delta * long(PAUSE_MIN))) // ms per minute { WState = W_IDLE; last_min = false; Serial.print("d_time : "); Serial.print(temp); Serial.print(" > "); Serial.println(delta); } else if ((!last_min) && (temp > (delta * long(PAUSE_MIN - 1)))) // ms per minute { Serial.println("Last Minute ..."); if (Continue) { pwr_led.Breathe(1000).Forever(); } last_min = true; } else { act_sec = millis() / 1000; if (act_sec != old_sec) { Serial.println(act_sec); old_sec = act_sec; } } } break; // W_PAUSE case W_INIT: case W_SETUP: default: winder.disableOutputs(); break; } // switch if (WState != old_state) { Serial.print("STATE : "); Serial.print(old_state); Serial.print(" >> "); Serial.println(WState); } } // loop void handleSwEvent(AceButton *button, uint8_t eventType, uint8_t buttonState) { switch (eventType) { case AceButton::kEventLongPressed: Serial.println("SW LONG"); pwr_led.Reset(); switch (WState) { case W_LEFT: case W_RIGHT: Serial.println(">>Stop Winding<<"); StopWind = true; Continue = false; pwr_led.On(); break; default: break; } break; case AceButton::kEventClicked: Serial.println("SW CLICK"); pwr_led.Reset(); Continue = true; switch (WState) { case W_IDLE: Serial.println(">>Start Winding<<"); WState = W_CYCLE; break; case W_PAUSE: Serial.println(">>Restart Winding<<"); Restart = true; break; default: break; } break; default: Serial.print("SW: "); Serial.print(eventType); Serial.print(", "); Serial.println(buttonState); break; } }