#include "LowPower.h"

const int brightnessPin = A1;      //
const int limitSwitchDownPin = 7;  // bottom end switch
const int limitSwitchUpPin = 8;    // top end switch
const int motorPin = 5;            // DC motor power Relay, or pin 3 for MOSFET, 5 relay
const int relayDirectionPin = 6;   // relay for direction change, activate in cause of opening
//const int activateInductionSensor = 2;
//const int inductionSensor = 4;
const int inductionSensor = A2;
const int errorPin = 1;  //error pin for error LED, blink in cause of abnormal situation = protection

// Intitialize switches
int limitSwitchUpState = 0;
int limitSwitchDownState = 0;
int motor = 0;
int motorPrevious = 0;
int relayDirection = 0;
int relayDirectionPrevious = 0;

//Calibrate brightness  - Max voltage corresponds to min brightness of LDR
float brightnessMinVoltage = 5;
float brightnessMaxVoltage = 0;
float brightnessMin = 0.0;    //%
float brightnessMax = 100.0;  //%
int brightness = 0;

//Threshold brightness to open/close door
int brightnessLowThreshold = 30;    //solar voltage ~1V
int brightnessHighThreshold = 100;  //( 133  ~0.65V), šero 6-7 bitů ADC
int hysteresisOpenDelay = 5000;     //5 sec
int hysteresisCloseDelay = 5000;    //5 sec          30 minutes ~ 1800000
int movementProtection = 8000;
int errorLED = 0;
int errorBlink = 800;
unsigned long int hysteresisMillis = 0;
unsigned long int motorRunMillis = 0;

//Movement speed
int motorPWM = 255;  //  max 255

//State
short state = 0;  // 0 - default, 1 - check opening hysteresis delay, 2 - start opening, 3 - opening, 4 - open
                  //11 - check close hysteresis delay, 12 - start closing, 13 - closing, 14 - closed
                  // 10 - error

short inductSens = 0;
short inductSensPrevious = 1;
short manual = 0;

//debug
unsigned long int serialMillis = 0;
short prevState = 0;
const int LEDPin = 13;
bool LEDState = 0;
bool first = 1;

/////////////////////////////////////////////////////////
//----------------------FUNCTIONS----------------------//
/////////////////////////////////////////////////////////

// Function to open or close the door
// To reverse engine rotation, juste activate directionRelay on pin 6:

void sensors() {
  limitSwitchUpState = digitalRead(limitSwitchUpPin);
  limitSwitchDownState = digitalRead(limitSwitchDownPin);
  if (analogRead(inductionSensor) >= 250) {
    inductSens = 0;       //no touch with metal
  } else inductSens = 1;  //touch of sensor with metal - closed
  brightness = analogRead(brightnessPin);
}

void movement() {
  if (relayDirection != relayDirectionPrevious) {
    relayDirectionPrevious = relayDirection;
    digitalWrite(relayDirectionPin, relayDirection);  //Establishes reverse direction of motor
    delay(50);
  }
  if (motorPrevious != motor) {
    motorPrevious = motor;
    digitalWrite(motorPin, motor);  //activate / deactivate motor
    digitalWrite(LEDPin, motor);    //development signalization
  }
}
void stop() {
  digitalWrite(relayDirectionPin, 0);  //Establishes reverse direction of motor
  analogWrite(motorPin, 0);            //Spins the motor at PWM speed
  digitalWrite(LEDPin, 0);
  relayDirection = 0;
  relayDirectionPrevious = 0;
  motor = 0;
  motorPrevious = 0;
}

void openClose() {
  if (((millis() - hysteresisMillis) >= 1000) & ((millis() - hysteresisMillis) < movementProtection)) {
    if (limitSwitchUpState == 1) {
      relayDirection = 0;
      motor = 0;
      state = 4;  //open
    } else if (limitSwitchDownState == 1) {
      relayDirection = 0;
      motor = 0;
      state = 14;  //closed
    } else if (inductSens == 1) {
      relayDirection = 0;
      motor = 0;
      state = 14;  //closed
    }
  } else if ((millis() - hysteresisMillis) >= movementProtection) {
    relayDirection = 0;
    motor = 0;
  }
}

void setup() {

  //CLKPR = 0x80; // (1000 0000) enable change in clock frequency
  //CLKPR = 0x01; // (0000 0001) use clock division factor 2 to reduce the frequency from 16 MHz to 8 MHz

  pinMode(LEDPin, OUTPUT);
  pinMode(errorLED, OUTPUT);
  Serial.begin(9600);
  Serial.println("Start");

  //run sensors
/*  sensors();

  //set default position to run open
  if (limitSwitchUpState == 1) {
    state = 4;  //open
    Serial.println(state);
  } else if (limitSwitchDownState == 1) {
    state = 14;  //closed
    Serial.println(state);
  } else if (inductSens == 1) {
    state = 14;  //closed
    Serial.println(state);
  } else {  //no fixed position, do opening
    state = 2;
  }*/
  motorRunMillis = millis();
}

void loop()
{
  sensors ();
  if ((inductSens == 1 && inductSensPrevious == 0 ) || ((millis() - motorRunMillis) >= 10000))
  {
    if (first) {
      Serial.println("stop");
      first = 0;
    }
    
  } else if ((inductSens == 0 && inductSensPrevious == 0 )|| ((millis() - motorRunMillis) >= 20000)) {
    motorRunMillis = millis();
    if(fist==0) {
      first=1;
      Serial.println("start");
      }
  }
  inductSensPrevious = inductSens;
}

/*void loop() {
  sensors();  ///read sensors each loop
  if (manual == 1) {
    ///programm manual remote, probably with 3 state switch

  } else if (manual == 0) {
    if (state == 14) {  //closed
      if (brightness >= brightnessHighThreshold) {
        hysteresisMillis = millis();
        state = 1;
      }
    } else if (state == 1) {  //check opening + delay
      if (brightness >= brightnessHighThreshold) {
        if ((millis() - hysteresisMillis) >= hysteresisOpenDelay) {
          state = 2;
        }

      } else {  //lower brightness than required for opening
        state = 14;
      }

    } else if (state == 2) {  //start opening
      state = 3;
      hysteresisMillis = millis();
      relayDirection = 1;
      motor = 1;

    } else if (state == 3) {  // opening           motor relayDirection
      openClose();

    } else if (state == 4) {  // open
      if (brightness <= brightnessLowThreshold) {
        hysteresisMillis = millis();
        state = 11;
      }

    } else if (state == 11) {  //check closing + delay
      if (brightness <= brightnessLowThreshold) {
        if ((millis() - hysteresisMillis) >= hysteresisCloseDelay) {
          state = 12;
        }
      } else {  //higher brightness than required for closing
        state = 4;
      }

    } else if (state == 12) {  //start closing
      state = 13;
      hysteresisMillis = millis();
      relayDirection = 0;
      motor = 1;

    } else if (state == 13) {  //closing        motor
      openClose();
    } else if (state == 10) {  //error, blink error LED
      if (millis() >= (serialMillis + errorBlink)) {
        serialMillis = millis();
        Serial.print("Error");
        if (errorLED) errorLED = 0;
        else errorLED = 1;
      }
    }
  }
  movement();  // activate motor and relayDirection

  //sleep only if it is opened or closed
  if (state == 14 || state == 4) {
    //LowPower.idle(SLEEP_2S, ADC_OFF, TIMER2_OFF, TIMER1_OFF, TIMER0_OFF, SPI_OFF, USART0_OFF, TWI_OFF);  // ATmega328P, ATmega168
  }

  /////// serial report
  if (millis() >= (serialMillis + 800)) {
    serialMillis = millis();
    Serial.print("State: ");
    Serial.print(state);
    Serial.print(", solar: ");
    Serial.print(brightness);
    Serial.print(", Up: ");
    Serial.print(limitSwitchUpState);
    Serial.print(", Down: ");
    Serial.print(limitSwitchDownState);
    Serial.print(", Induct: ");
    Serial.println(inductSens);
  }
}*/
Switch-up
Switch-down
Orange - opening orange + white - closing
Tma
Světlo
1 _ _ _ _ 0