Select Git revision
WINDER_ADV.ino
WINDER_ADV.ino 5.07 KiB
#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;
Continue = 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;
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 (temp > (delta * long(PAUSE_MIN))) // ms per minute
{
WState = W_IDLE;
Continue = true;
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 ...");
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;
break;
default:
break;
}
break;
case AceButton::kEventClicked:
Serial.println("SW CLICK");
pwr_led.Reset();
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;
}
}