/*
  Wokwi | questions
  Need some help for a arduino project for the FAS museum
  with a weather radar of an Boeing 737.

  Bwana — January 19, 2025 at 4:35 AM
  Hello, I am new here at wokwi and hope that this will help me to
  solve my problem. I am a volunteer guide and member of the FAS museum
  in Belgium's Wevelgem Airport. We have a weather radar from a
  Boeing 737 that we want to run with 2 stepper motors. I have a
  little knowledge of arduino but not enough. The setup is 1 PIR sensor
  to activate and deactivate the system, 4 optical sensors that detects
  end right / left and up / down and to change the direction of the stepper.
  As long as the PIR is active, the radar must turn left/right and keep
  turning and after e.g. 5 times left and right  activate the up/down
  stepper  and move it from e.g. up to center 2nd time center to bottom
  and 3rd time bottom to center etc. (The up down stepper only has 3 positions)
  as long as the PIR is active. I have already made a setup in wokwi,
  the optical sensors have been replaced by switches for testing.
  All tips and tricks are welcome.
  If everything works fine, it will be exhibited in the museum
  https://fasinfo.be/.
  https://wokwi.com/projects/420498213590653953
*/


/*Weather radar control FAS museum intention,
  after activation of PIR sensor red LED active green LED not active,
  turn radar stepper motor 1 left and right with 2 optical sensors to change direction,
  2nd stepper motor is up and down but is only  active after the 1st stepper motor
  has gone left and right 5 times, the 2nd stepper may only go from top to middle second time of 5 left
  and right of 1 stepper motor from center to bottom and this checked by optical sensor
  then next 5 times left right back to center etc.( the up and down stepper has only 3 positions Up, Middle and Down)
  both stepper motors stop when PIR sensor is not active.
*/

/*
  code by DWW
  DWW — 1/20/25 at 5:37 PM
  https://wokwi.com/projects/420562755175377921

  Interrupts on port B

*/


#include <Arduino.h>
#include <AccelStepper.h>

#define motorInterfaceType 1

// pin numbers lightly rearranged
const int pirPin = 8;         // PIR sensor output pin
const int opticalLeftPin = 12; // Optische sensor links
const int opticalRightPin = 11; // Optische sensor rechts
const int opticaldownPin = 10; // Optische sensor links
const int opticalupPin = 9; // Optische sensor rechts
const int greenLedPin = A0;    // Groene LED pin
const int redLedPin = A1;      // Rode LED pin
const int stepPin_UpDown = 3;        // STEP pin voor DRV8825
const int dirPin_UpDown = 2;         // DIR pin voor DRV8825
const int stepPin_LeftRight = 5;        // STEP pin voor DRV8825
const int dirPin_LeftRight = 4;         // DIR pin voor DRV8825

int max_LeftRight = 200;
int max_UpDown = 200;
int centre_LeftRight = 0;
int centre_UpDown = 0;
int initial_speed = 5;   // the speed when the system starts
int initial_accel = 5;   // the accel when the system starts
int run_speed_UpDown = 500;  // speed when running for up down
int run_speed_LeftRight = 500;  // speed when running for left right
int run_accel = 300;   // accel when running


// setup the booleans
volatile bool leftSensorState = false;
volatile bool rightSensorState = false;
volatile bool upSensorState = false;
volatile bool downSensorState = false;
volatile bool pirSensorState = false;


volatile int leftCount = 0; // Aantal keer dat links is gedraaid
volatile int rightCount = 0; // Aantal keer dat rechts is gedraaid
volatile int upCount = 0; // Aantal keer dat links is gedraaid
volatile int downCount = 0; // Aantal keer dat rechts is gedraaid

volatile unsigned long pir_detect_time = 0;
bool first_run = true;

AccelStepper stepperUpDown = AccelStepper(motorInterfaceType, stepPin_UpDown, dirPin_UpDown);
AccelStepper stepperLeftRight = AccelStepper(motorInterfaceType, stepPin_LeftRight, dirPin_LeftRight);


void error_blink_leds()
{
  while (1)
  {
    digitalWrite(greenLedPin, LOW);
    digitalWrite(redLedPin, HIGH);
    delay(500);
    digitalWrite(greenLedPin, HIGH);
    digitalWrite(redLedPin, LOW);
    delay(500);
  }
}

void initialise()
{
  stepperLeftRight.setSpeed( initial_speed);
  stepperUpDown.setSpeed( initial_speed);

  if (leftSensorState )
  {
    // check if we are at the sensor
    stepperLeftRight.setCurrentPosition(0);
    Serial.println("At leftSensor");
  }
  else
  {
    // move slowly to left until sensor is touched.
    stepperLeftRight.moveTo(-10000);
    while ( !leftSensorState)
    {
      stepperLeftRight.runSpeedToPosition();
    }
    stepperLeftRight.stop();
  }
  // mark position as zero_right_left = 0
  stepperLeftRight.setCurrentPosition(0);
  Serial.print("Minimum pan = " );
  Serial.println(stepperLeftRight.currentPosition() );
  //Serial.println( "Minimum pan marked" );
  // move slowly to the right until sensor is touched.
  stepperLeftRight.moveTo(10000);
  while ( !rightSensorState)
  {
    stepperLeftRight.runSpeedToPosition();;
  }
  stepperLeftRight.stop();
  max_LeftRight = stepperLeftRight.currentPosition();
  Serial.print("Maximum pan = ");
  Serial.println( max_LeftRight);
  //Serial.println("Maximum pan marked" );
  centre_LeftRight = max_LeftRight / 2;

  stepperLeftRight.moveTo(centre_LeftRight);
  while (stepperLeftRight.distanceToGo() > 0)
  {
    stepperLeftRight.runSpeedToPosition();
  }
  stepperLeftRight.stop();




  stepperLeftRight.moveTo(-10000);
  while ( !rightSensorState)
  {
    stepperLeftRight.runSpeedToPosition();;
  }
  stepperLeftRight.stop();


  // move slowly up until sensor is touched.
  if (upSensorState )
  {
    // check if we are at the sensor
    stepperUpDown.setCurrentPosition(0);
    Serial.println("At Up Sensor");
  }
  else
  {
    stepperUpDown.moveTo(10000);
    while ( !upSensorState)
    {
      // Serial.println(  stepperUpDown.currentPosition() );
      stepperUpDown.runSpeedToPosition();
    }
    stepperUpDown.stop();
  }
  // mark position as zero_Up_Down = 0
  stepperUpDown.setCurrentPosition(0);
  Serial.print("Minimum tilt = " );
  Serial.println( stepperUpDown.currentPosition() );
  //Serial.print( "0 Right Marked " );
  // move slowly to the right until sensor is touched.
  stepperUpDown.moveTo(-10000);
  while ( !downSensorState)
  {
    stepperUpDown.runSpeedToPosition();
  }
  stepperUpDown.stop();
  max_UpDown =  stepperUpDown.currentPosition();
  Serial.print( "Maximum tilt = ");
  Serial.println( max_UpDown);
  centre_UpDown = max_UpDown / 2;
  Serial.print("Centre tilt = ");
  Serial.println(centre_UpDown);

}

void move_centre_UpDown()
{
  stepperUpDown.moveTo(centre_UpDown);
  while (stepperUpDown.distanceToGo() != 0)
  {
    stepperUpDown.runSpeedToPosition();
  }
  stepperUpDown.stop();
}

void move_centre_LeftRight()
{
  stepperLeftRight.moveTo(centre_LeftRight);
  while (stepperLeftRight.distanceToGo() != 0)
  {
    stepperLeftRight.runSpeedToPosition();
  }
  stepperLeftRight.stop();
}


ISR (PCINT0_vect)
{
  // read the pins
  // Interrupt for Port B
  // note switch on is LOW so we use ! for not
  leftSensorState = !digitalRead(opticalLeftPin);
  rightSensorState = !digitalRead(opticalRightPin);
  upSensorState = !digitalRead(opticalupPin);
  downSensorState = !digitalRead(opticaldownPin);
  // pir HIGH

  pirSensorState = digitalRead(pirPin);
  if ( pirSensorState )
  {
    pir_detect_time = millis();
  }







}

void setup() {
  // Pin modes
  pinMode(pirPin, INPUT);
  pinMode(opticalLeftPin, INPUT_PULLUP);
  pinMode(opticalRightPin, INPUT_PULLUP);
  pinMode(opticaldownPin, INPUT_PULLUP);
  pinMode(opticalupPin, INPUT_PULLUP);
  pinMode(greenLedPin, OUTPUT);
  pinMode(redLedPin, OUTPUT);
  pinMode(stepPin_UpDown, OUTPUT);
  pinMode(dirPin_UpDown, OUTPUT);
  pinMode(stepPin_LeftRight, OUTPUT);
  pinMode(dirPin_LeftRight, OUTPUT);

  Serial.begin(9600);
  // Start met de groene LED aan
  digitalWrite(greenLedPin, HIGH);
  digitalWrite(redLedPin, LOW);

  leftSensorState = !digitalRead(opticalLeftPin);
  rightSensorState = !digitalRead(opticalRightPin);
  upSensorState = !digitalRead(opticalupPin);
  downSensorState = !digitalRead(opticaldownPin);

  // test sensors - if both triggered then there is issue with hardware
  if (leftSensorState && rightSensorState)
  {
    error_blink_leds();
  }
  // test sensors - if both triggered then there is issue with hardware
  if (upSensorState && downSensorState)
  {
    error_blink_leds();
  }

  // setup pin change interupts
  PCICR |= B00000001;   // port B for pin change
  PCMSK0 |= B00011111; // ports 12,11,10,9,8



  // Set the maximum speed in steps per second and accelleration (smooth)
  stepperLeftRight.setMaxSpeed(500);
  stepperLeftRight.setAcceleration(100);
  stepperUpDown.setMaxSpeed(500);
  stepperUpDown.setAcceleration(100);

  Serial.println("Press each limit switch as the arrow reaches the stop.");
  initialise();

  Serial.println("Moving to centre...");
  move_centre_LeftRight();
  move_centre_UpDown();
  delay(2000);
  Serial.println("Initialized!");
}



void run_LeftRight()
{
  stepperLeftRight.setSpeed(run_speed_LeftRight);
  stepperLeftRight.moveTo(1);
  while (stepperLeftRight.distanceToGo() != 0)
  {
    stepperLeftRight.runSpeedToPosition();
  }
  stepperLeftRight.stop();
  stepperLeftRight.moveTo(max_LeftRight);

  while (stepperLeftRight.distanceToGo() !=  0)
  {
    stepperLeftRight.runSpeedToPosition();
  }
  stepperLeftRight.stop();


}

void run_UpDown()
{

  stepperUpDown.setSpeed(run_speed_UpDown);
  stepperUpDown.moveTo(1);
  while (stepperUpDown.distanceToGo() > 0)
  {
    stepperUpDown.runSpeedToPosition();
  }
  stepperUpDown.stop();
  stepperUpDown.moveTo(max_UpDown);
  while (stepperUpDown.distanceToGo() < 0)
  {
    stepperUpDown.runSpeedToPosition();
  }
  stepperUpDown.stop();
}





void loop() {


  run_LeftRight();
  move_centre_LeftRight();
  run_UpDown();
  move_centre_UpDown();

  if (pirSensorState) {
    // PIR is actief
    digitalWrite(greenLedPin, LOW);
    digitalWrite(redLedPin, HIGH);
    Serial.print("Motion detected: ");
    Serial.println(pir_detect_time);
  }
  else
  {
    digitalWrite(greenLedPin, HIGH);
    digitalWrite(redLedPin, LOW);
  }




}



A4988
A4988
LF stop
RT stop
UP stop
DN stop
Pan
Tilt