Загрузка данных


// ================== Пины ==================
const int IGN_PIN        = 2;   // Оптопара зажигания (инвертировано!)
const int CLOSE_PIN      = 3;   // Масса, LOW = закрытие
const int OPEN_PIN       = 4;   // Масса, LOW = открытие
const int OIL_PIN        = 5;   // Масса, LOW = маслёнка
const int START_PIN      = 6;   // Оптопара стартера (инвертировано!)

const int RELAY_BLOCK_CLOSE = 7;   // NC — разрыв закрытия
const int RELAY_BLOCK_OPEN  = 8;   // NC — разрыв открытия
const int RELAY_STARTER     = 9;   // Реле стартера (LOW = включить)
const int RELAY_LIGHT       = 10;  // Свет

// ================== Переменные ==================
unsigned long closeWaitTimer = 0;
unsigned long oilIgnoreTimer = 0;
unsigned long starterTimer = 0;
unsigned long oilLightTimer = 0;

bool ignitionWasOn = false;
bool autostartFlag = false;
int ignoreOpenCount = 0;
int ignoreCloseCount = 0;
bool ignoreCloseFlag = false;

void setup() {
  pinMode(IGN_PIN, INPUT_PULLUP);
  pinMode(CLOSE_PIN, INPUT_PULLUP);
  pinMode(OPEN_PIN, INPUT_PULLUP);
  pinMode(OIL_PIN, INPUT_PULLUP);
  pinMode(START_PIN, INPUT_PULLUP);

  pinMode(RELAY_BLOCK_CLOSE, OUTPUT);
  pinMode(RELAY_BLOCK_OPEN, OUTPUT);
  pinMode(RELAY_STARTER, OUTPUT);
  pinMode(RELAY_LIGHT, OUTPUT);

  digitalWrite(RELAY_BLOCK_CLOSE, HIGH);  // NC замкнуты
  digitalWrite(RELAY_BLOCK_OPEN, HIGH);
  digitalWrite(RELAY_STARTER, HIGH);      
  digitalWrite(RELAY_LIGHT, HIGH);
}

void loop() {
  // === ИНВЕРТИРОВАННАЯ ЛОГИКА ДЛЯ ОПТОПАР ===
  bool ignition = digitalRead(IGN_PIN) == LOW;   // LOW = зажигание ВКЛЮЧЕНО
  bool closeTrig = digitalRead(CLOSE_PIN) == LOW;
  bool openTrig  = digitalRead(OPEN_PIN) == LOW;
  bool oilTrig   = digitalRead(OIL_PIN) == LOW;
  bool startTrig = digitalRead(START_PIN) == LOW; // LOW = старт-сигнал пришёл

  // Сброс флагов при выключении зажигания
  if (!ignition && ignitionWasOn) {
    resetAllFlags();
    ignoreOpenCount = 1;        // разрешаем 1 открытие при выкл заж.
    ignitionWasOn = false;
  }
  if (ignition) ignitionWasOn = true;

  // ================== Автозапуск (5 сек) ==================
  static bool waitingAutoStart = false;
  if (closeTrig && !waitingAutoStart && !autostartFlag) {
    waitingAutoStart = true;
    closeWaitTimer = millis();
    digitalWrite(RELAY_BLOCK_CLOSE, LOW);   // разрываем закрытие
  }

  if (waitingAutoStart) {
    if (millis() - closeWaitTimer < 5000) {
      if (ignition || openTrig) {
        autostartFlag = true;
        ignoreOpenCount = 1;
        ignoreCloseCount = 1;
        digitalWrite(RELAY_BLOCK_CLOSE, HIGH);
        waitingAutoStart = false;
      }
    } else {
      digitalWrite(RELAY_BLOCK_CLOSE, HIGH);
      waitingAutoStart = false;
    }
  }

  if (autostartFlag) {
    if (openTrig && ignoreOpenCount > 0) ignoreOpenCount--;
    if (closeTrig && ignoreCloseCount > 0) ignoreCloseCount--;
    if (ignoreOpenCount == 0 && ignoreCloseCount == 0) autostartFlag = false;
  }

  // ================== Игнор закрытия после открытия ==================
  if (openTrig && ignoreOpenCount == 0 && !ignoreCloseFlag) {
    ignoreCloseFlag = true;
    oilIgnoreTimer = millis();
  }

  if (ignoreCloseFlag) {
    if (oilTrig && (millis() - oilIgnoreTimer >= 2000)) {
      ignoreCloseCount = 1;
      ignoreCloseFlag = false;
    }
    if (millis() - oilIgnoreTimer > 15000) ignoreCloseFlag = false;
  }

  // ================== ЗАДЕРЖКА СТАРТЕРА ==================
  static unsigned long startDetected = 0;
  
  if (startTrig && startDetected == 0) {
    startDetected = millis();           // зафиксировали сигнал старта
  }

  if (startDetected > 0) {
    if (millis() - startDetected >= 1000 && starterTimer == 0) {
      starterTimer = millis();
      digitalWrite(RELAY_STARTER, LOW); // замыкаем реле стартера
    }

    if (starterTimer > 0) {
      if (oilTrig || (millis() - starterTimer >= 3000)) {
        digitalWrite(RELAY_STARTER, HIGH);
        starterTimer = 0;
        startDetected = 0;
      }
    }
  }

  // ================== Свет при долгой маслёнке ==================
  if (oilTrig) {
    if (oilLightTimer == 0) oilLightTimer = millis();
    if (millis() - oilLightTimer >= 5000) {
      digitalWrite(RELAY_LIGHT, LOW);
    }
  } else {
    oilLightTimer = 0;
    digitalWrite(RELAY_LIGHT, HIGH);
  }

  delay(20);
}

void resetAllFlags() {
  autostartFlag = false;
  ignoreCloseFlag = false;
  ignoreOpenCount = 0;
  ignoreCloseCount = 0;
  closeWaitTimer = 0;
  starterTimer = 0;
}