/* ========================================================== MAKIETA LINII ENERGETYCZNEJ Arduino Pro Mini / Nano / Uno STAN NORMALNY: - świeci LED OK - LED ALARM zgaszona - dzwonek wyłączony - linia LED wyłączona AWARIA: - LED OK gaśnie - wykonywane są cykle dzwonków Po wykonaniu wszystkich cykli: - dzwonek wyłącza się - LED ALARM świeci stale - linia LED świeci stale GRUSZKA: - kasuje alarm w dowolnym momencie ========================================================== */ // ========================================================== // PINY // ========================================================== const byte PIN_DZWONEK = 10; const byte PIN_LINIA = 11; const byte PIN_LED_ALARM = 12; const byte PIN_LED_OK = 13; const byte PIN_BTN_AWARIA = A1; const byte PIN_BTN_GRUSZKA = A2; // ========================================================== // LOGIKA WYJŚĆ // ========================================================== // Linia aktywny stanem NISKIM const byte LINIA_ON = LOW; const byte LINIA_OFF = HIGH; // Dzwonek aktywny stanem NISKIM const byte DZWONEK_ON = LOW; const byte DZWONEK_OFF = HIGH; // Dioda alarmowa aktywna stanem WYSOKIM const byte LED_ALARM_ON = HIGH; const byte LED_ALARM_OFF = LOW; // ========================================================== // USTAWIENIA SCENARIUSZA // ========================================================== // długość jednego dzwonka unsigned long CZAS_DZWONKA = 1200; // przerwa między dzwonkami unsigned long CZAS_PRZERWY = 800; // ile dzwonków w jednym cyklu byte DZWONKI_W_CYKLU = 3; // przerwa między cyklami unsigned long PRZERWA_MIEDZY_CYKLAMI = 4000; // ile pełnych cykli wykonać byte LICZBA_CYKLI = 2; // debounce przycisków unsigned long DEBOUNCE = 40; // miganie diody AWARIA unsigned long CZAS_MIGNIECIA = 200; // ========================================================== // STANY // ========================================================== enum Stan { NORMALNY, AWARIA_DZWONKI, ALARM_STALY }; Stan stan = NORMALNY; // ========================================================== // ZMIENNE // ========================================================== unsigned long znacznikCzasu = 0; byte numerDzwonka = 0; byte numerCyklu = 0; bool dzwonekAktywny = false; // ========================================================== // OBSŁUGA PRZYCISKU // ========================================================== bool buttonPressed(byte pin) { static unsigned long lastTime[20]; static bool lastState[20]; bool state = digitalRead(pin); if (state != lastState[pin]) { lastTime[pin] = millis(); lastState[pin] = state; } if ((millis() - lastTime[pin]) > DEBOUNCE) { if (state == LOW) { while (digitalRead(pin) == LOW); return true; } } return false; } // ========================================================== // WYJŚCIA // ========================================================== void dzwonek(bool stan) { digitalWrite(PIN_DZWONEK, stan ? DZWONEK_ON : DZWONEK_OFF); } void alarmLed(bool stan) { digitalWrite(PIN_LED_ALARM, stan ? LED_ALARM_ON : LED_ALARM_OFF); } void linia(bool stan) { digitalWrite(PIN_LINIA, stan ? LINIA_ON : LINIA_OFF); } // ========================================================== // STAN NORMALNY // ========================================================== void przejdzDoNormalnego() { stan = NORMALNY; dzwonek(false); alarmLed(false); linia(false); digitalWrite(PIN_LED_OK, HIGH); } // ========================================================== // START AWARII // ========================================================== void przejdzDoAwarii() { stan = AWARIA_DZWONKI; digitalWrite(PIN_LED_OK, LOW); dzwonek(true); alarmLed(true); numerCyklu = 0; numerDzwonka = 1; dzwonekAktywny = true; znacznikCzasu = millis(); } // ========================================================== // ALARM STAŁY // ========================================================== void przejdzDoAlarmuStalego() { stan = ALARM_STALY; dzwonek(false); alarmLed(true); linia(true); } // ========================================================== // MIGANIE AWARIA // ========================================================== void obslugaMiganiaAlarmu() { if (!dzwonekAktywny) { alarmLed(false); return; } unsigned long t = millis() - znacznikCzasu; if ( (t >= 0 && t < 200) || (t >= 400 && t < 600) || (t >= 800 && t < 1000) ) { alarmLed(true); } else { alarmLed(false); } } // ========================================================== // SETUP // ========================================================== void setup() { pinMode(PIN_DZWONEK, OUTPUT); pinMode(PIN_LINIA, OUTPUT); pinMode(PIN_LED_ALARM, OUTPUT); pinMode(PIN_LED_OK, OUTPUT); pinMode(PIN_BTN_AWARIA, INPUT_PULLUP); pinMode(PIN_BTN_GRUSZKA, INPUT_PULLUP); przejdzDoNormalnego(); } // ========================================================== // OBSŁUGA CYKLI DZWONKÓW // ========================================================== void obslugaAwarii() { unsigned long teraz = millis(); if (dzwonekAktywny) { if (teraz - znacznikCzasu >= CZAS_DZWONKA) { dzwonek(false); alarmLed(false); dzwonekAktywny = false; znacznikCzasu = teraz; } } else { if (numerDzwonka < DZWONKI_W_CYKLU) { if (teraz - znacznikCzasu >= CZAS_PRZERWY) { numerDzwonka++; dzwonek(true); alarmLed(true); dzwonekAktywny = true; znacznikCzasu = teraz; } } else { if (teraz - znacznikCzasu >= PRZERWA_MIEDZY_CYKLAMI) { numerCyklu++; if (numerCyklu >= LICZBA_CYKLI) { przejdzDoAlarmuStalego(); return; } numerDzwonka = 1; dzwonek(true); alarmLed(true); dzwonekAktywny = true; znacznikCzasu = teraz; } } } } // ========================================================== // LOOP // ========================================================== void loop() { if (buttonPressed(PIN_BTN_AWARIA)) { if (stan == NORMALNY) { przejdzDoAwarii(); } } if (buttonPressed(PIN_BTN_GRUSZKA)) { przejdzDoNormalnego(); } switch (stan) { case NORMALNY: break; case AWARIA_DZWONKI: obslugaMiganiaAlarmu(); obslugaAwarii(); break; case ALARM_STALY: break; } }