// https://forum.arduino.cc/t/looking-for-wiring-and-a-code/1219905
// https://wokwi.com/projects/389441795099790337

// simple stepper demo with stand aside door simulator

# include <AccelStepper.h>
# include <Toggle.h>

// dDMotor for doorDoor
int dDMotor;

const byte dirPin             = 2;
const byte stepPin            = 3;

const byte cwButtonPin        = 4;
const byte ccwButtonPin       = 5;
const byte cwLimitSwitchPin   = 6;
const byte ccwLimitSwitchPin  = 7;
const byte stopButtonPin      = 8;

const byte solenoidPin        = 9;


const unsigned long cwTarget = 10000000;
const unsigned long ccwTarget = -10000000;

AccelStepper stepper = AccelStepper(AccelStepper::DRIVER, stepPin, dirPin);
Toggle cwButton, ccwButton, cwLimitSwitch, ccwLimitSwitch, stopButton;

enum MotorState {STOPPED, GOING_CW, GOING_CCW} motorState = STOPPED;

void activateSolenoids() {
  digitalWrite(solenoidPin, HIGH);
}

void deactivateSolenoids() {
  digitalWrite(solenoidPin, LOW);
}

void stop() {
  deactivateSolenoids();
  stepper.setCurrentPosition(0);
  stepper.moveTo(0);
  motorState = STOPPED;
}

void motorManagement() {

  cwButton.poll();
  ccwButton.poll();
  cwLimitSwitch.poll();
  ccwLimitSwitch.poll();
  stopButton.poll();

  switch (motorState) {
    case STOPPED:

dDMotor = 0;

      if (cwButton.onPress()) {
        stepper.moveTo(cwTarget);
        activateSolenoids();
        motorState = GOING_CW;
      } else if (ccwButton.onPress()) {
        stepper.moveTo(ccwTarget);
        activateSolenoids();
        motorState = GOING_CCW;
      }
      break;

    case GOING_CW:

dDMotor = 1;

      if (stopButton.onPress() || cwLimitSwitch.onPress()) stop();
      break;

    case GOING_CCW:

dDMotor = -1;

      if (stopButton.onPress() || ccwLimitSwitch.onPress()) stop();
      break;

  }

  stepper.run();
}


void setup() {
  Serial.begin(115200);
  Serial.println("Hello World!\n");

  setupSimulatedDoor();

  pinMode(solenoidPin, OUTPUT);

  cwButton.begin(cwButtonPin);
  ccwButton.begin(ccwButtonPin);
  cwLimitSwitch.begin(cwLimitSwitchPin);
  ccwLimitSwitch.begin(ccwLimitSwitchPin);
  stopButton.begin(stopButtonPin);

  stepper.setMaxSpeed(1000);
  stepper.setAcceleration(20);
  stop();
}

void loop() {
  motorManagement();

  runSimulatedDoor();
}



//////////////////////


/*
// library Adafruit_NeoPixel
// setup() +
  setupSimulatedDoor();
  runSimulatedDoor();   // step the machine so inouts and outpus make sense

// void loop() +
  runSimulatedDoor();

*/

// below here finds itself the door simulation machinery
// find five unused I/O pins

# define sDoorDown  A1
# define sDoorUp    A2
// # define doorX      18

# define sDoorDownMotorPin  A3
# define sDoorUpMotorPin    A4

# define door

# include <Adafruit_NeoPixel.h>
# define PIN A5          // the pin
# define NPIXELS 17     // number of LEDs on strip

Adafruit_NeoPixel doorBar(NPIXELS, PIN, NEO_GRB + NEO_KHZ800); 

int lPosition = 6;      // sim door starts at 6
unsigned char dir = 1;  // moving up. or is true down?

void setupSimulatedDoor()
{
  pinMode(sDoorDown, OUTPUT);
  pinMode(sDoorUp, OUTPUT);

  pinMode(sDoorDownMotorPin, INPUT);
  pinMode(sDoorUpMotorPin, INPUT);

  doorBar.begin();
  doorBar.setPixelColor(2, 0xff0000);
  doorBar.show();

  delay(777);
}

void runSimulatedDoor()
{
//  int doorPosition = analogRead(A0);
//  delay(20);  
//  digitalWrite(sDoorDown, doorPosition < 100 ? LOW : HIGH); // active low 
//  digitalWrite(sDoorUp, doorPosition > 923 ? LOW : HIGH);
   
  static unsigned long lastTime;
  if (millis() - lastTime < 333) return;
  lastTime = millis();

// this did work checking in this case. may not always
  if (0) {  // test - door will just cycle up and down all by itself
    lPosition += dir ? -1 : 1;
    if ((lPosition == -1) || (lPosition == NPIXELS)) dir = !dir;
  }
  else {    // read the main code outputs and run the door if

    if (dDMotor == 1) lPosition++;
    if (dDMotor == -1) lPosition--;

    if (digitalRead(sDoorDownMotorPin)) lPosition--;
    if (digitalRead(sDoorUpMotorPin)) lPosition++;


  }

  if (lPosition == -1) lPosition = 0;
  if (lPosition == NPIXELS) lPosition = NPIXELS - 1;

// argh! Serial.println(lPosition); delay(777);

  digitalWrite(sDoorDown, lPosition == 0 ? LOW : HIGH);
  digitalWrite(sDoorUp, lPosition == NPIXELS - 1 ? LOW : HIGH); 

// moved the output section here to keep everything in phase:

  doorBar.clear();
  doorBar.setPixelColor(lPosition, 0xff0000);
  doorBar.show();
}

A4988
CW limit
CCW limit
CW Button
NOCOMNCVCCGNDINLED1PWRRelay Module
NOCOMNCVCCGNDINLED1PWRRelay Module
Solenoids
CCW Button
STOP !!