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;
}
}