3 lutego, 2021 Autor admin Wyłączony

Arduino i czuwak

Zdarzyło się wam zasnąć przy makiecie? Mnie tak.
Całe szczęście nic się w tym czasie nie wydarzyło. A mogło.

I to zdarzenie zainspirowało mnie do nowego projektu na Arduino, oczywiście połączonego z centralą DCC (w moim przypadku Roco z21).

Ideą urządzenia jest sprawdzanie reakcji co określony czas i w przypadku braku reakcji (drzemka 🙂 ) automatyczne wyłączenie makiety. Sam projekt, jaki i obsługujący go program są banalnie proste.

Co potrzeba do czuwaka?
– Arduino + program
– konwerter sygnału TTL na RS485
– przycisk, dioda led, buzzer (opcjonalnie)

Całość połączona jest wg poniższego schematu a dokładny opis podłączenia przedstawiony został w artykule Arduino i Multimaus.

Zasilanie układu pobierane jest z centralki.
Dodatkowo pod piny Arduino podłączyłem:
– pin 6 – dioda led sygnalizująca
– pin 7 – buzzer sygnalizujący
– pin 8 – przycisk czuwaka.

Zasada działania jest następująca. Układ co określony czas (ja wybrałem 10 minut) zapala diodę i generuje sygnał dźwiękowy. Od tego momentu jest określony czas (u mnie 10 sekund) na naciśnięcie przycisku czuwaka. Po naciśnięciu przycisku cała procedura zaczyna się od nowa. Gdy jednak w czasie 10 sek nie nacisnę przycisku układ wysyła do centralki komendę „STOP” i wszystko co na makiecie znajduje się w ruchu jest zatrzymywane.

Program wygląda następująco:

#include <XpressNetMaster.h>

#define LINIA_XP 9
#define BUZZER 7
#define PRZYCISK 8
#define DIODA 6

XpressNetMasterClass XpressNet;

unsigned long czas = 0;
unsigned long poprzedni_czas = 0;
unsigned long czas3 = 0;
unsigned long czas4 = 0;
byte guzik = 1;
byte stop1 = 0;

void setup()  
{
  XpressNet.setup(Loco128, LINIA_XP);    //Inicjalizacja linii Xpressnet  

  pinMode(BUZZER, OUTPUT);          //buzzer jako wyjscie
  pinMode(PRZYCISK, INPUT_PULLUP);  //przycisk jako wejscie
  pinMode(DIODA, OUTPUT);           //dioda led jako wyjscie

  tone(BUZZER, 1047, 1000);        //sygnal dzwiekowy oznajmiajacy start
}

void zatrzymaj()
{
  digitalWrite(DIODA, LOW);       //wygaszenie LED
  XpressNet.setPower(csEmergencyStop);  //wyslanie komendy "STOP"
  stop1=1;
}

void loop()  
{
  czas=millis();
  if (czas - poprzedni_czas >= 600000UL)
  {
    digitalWrite(DIODA, HIGH);
    tone(BUZZER, 165, 1000);
    czas4=millis();
    czas3=millis();
    while (digitalRead(PRZYCISK) == HIGH)
    {
        if(stop1==0)
        {
          czas3 = millis();
          if(czas3 - czas4 >= 10000UL)
          {
            //Serial.println("STOP");
            //stop1=1;
            zatrzymaj();
            czas4 = czas3;
          }
        }
    }
    poprzedni_czas = czas;
    digitalWrite(DIODA, LOW);
    stop1=0;
  }
}