Hallo, ich hoffe, ihr könnt mir hier weiterhelfen. Aktuell bin ich an einem Spaßprojekt, einem Art "Bombenkoffer". Ist für ein Spiel, eine Seite muss diesen vor Ablauf des Timers finden. Andernfalls geht eine Sirene los.
Bedienung wie folgt:
Es gibt einen Hauptschalter. Anschließend ist der Arduino mit Spannung versorgt. Wird nun ein Taster für mehrere Sekunden gedrückt gehalten, wird ein externer Timer mit Spannung versorgt. Dieser hat einen Relaisausgang, welcher wiederum auf einen Eingang des Arduino geht (Hinweis: invertierter Eingang, da während der Timerlaufzeit das Relais geschlossen ist und erst bei Zeitablauf öffnet). Über diesen Eingang wird wiederum ein Ausgang angesteuert (die Sirene).
Vor Ablauf der Zeit kann mit dem gleichen Taster "entschärft" werden - der Timer wird ausgeschaltet.
Nun habe ich folgendes Fehlerbild:
Ab und zu (ich weiß auch nicht warum!) wird der Timer zwar aktiviert, aber auch sofort wieder ausgeschaltet, weil der Arduino neustartet.
Ich habe keine Ahnung, warum das so ist und komme leider mit dem Debugging nicht weiter.
//Arduino Nano Atmega 328P
//Ausgänge definieren
int DO_LED = 13;
int DO_Selbsthaltung = 12;
int DO_Pieper = 6;
int DO_Beleuchtung = 5;
int DO_Sirene = 4;
int DO_Timer = 2;
//Eingänge definieren
int DI_Taster = 8;
int DI_TimerRelais = 7;
//Varbiablen von Eingängen definieren
int TimerRelais = HIGH; //wenn Timersignal anliegt, Active=LOW
int Taster = LOW;
//Variablen definieren
int piepsen = LOW; //für Pieper
int blinken = LOW; //für LED-Beleuchtung blinkend
int flackern = LOW; //für Flackern
static int scharf = LOW; //ist die Bombe scharf oder nicht
static int Ausloesung = LOW; //Hat Bombe ausgelöst?
long t_haltedauer = 1000; //Statische Hilfsvariable, notwendige Dauer für scharfmachen / entschärfen - Standard 10000
long t_fused = 0; //Hilfsvariable, damit Taster nicht direkt wieder scharfstellt/entschärft, wenn länger gehalten wird
long t_defused = -5000; //Hilfsvariable (-5000?), damit Taster nicht direkt wieder scharfstellt/entschärft, wenn länger gehalten wird
long t_ausloesung = 0; //Hilfsvariable, Zeitpunkt wann Auslösung war
void setup() {
pinMode(DO_LED, OUTPUT); //Test-LED
pinMode(DO_Selbsthaltung, OUTPUT);
pinMode(DO_Pieper, OUTPUT);
pinMode(DO_Beleuchtung, OUTPUT);
pinMode(DO_Sirene, OUTPUT);
pinMode(DO_Timer, OUTPUT);
pinMode(DI_Taster, INPUT);
pinMode(DI_TimerRelais, INPUT);
Serial.begin(9600); //Debug-Ausgang
Serial.print("Neustart\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
}
void loop() {
TimerRelais = !digitalRead(DI_TimerRelais); //Variable TimerRelais mit Zustand des DI füllen
Taster = digitalRead(DI_Taster); //Variable Taster mit Zustand des DI füllen
Tasterabfrage(); //Scharfmachen muss durch Taster erfolgen, diese Funktion wird hier eingebunden
Bumm(); //Subfunktion, setzt Variable "Ausloesung"
if (scharf == LOW) { //Grundzustand
digitalWrite(DO_Timer, LOW);
digitalWrite(DO_Sirene, LOW);
digitalWrite(DO_Pieper, LOW);
digitalWrite(DO_Beleuchtung, LOW);
digitalWrite(DO_Beleuchtung, HIGH);
digitalWrite(DO_Selbsthaltung, LOW);
digitalWrite(DO_LED, LOW); //kann später weg
// Serial.println("scharf == LOW");
}
if (scharf == HIGH && Ausloesung == LOW) { //Timer läuft
digitalWrite(DO_Timer, HIGH);
digitalWrite(DO_Beleuchtung, HIGH);
digitalWrite(DO_Selbsthaltung, HIGH);
Piepser();
digitalWrite(DO_LED, HIGH); //kann später weg
// Serial.println("scharf == HIGH && Ausloesung == LOW");
}
if (Ausloesung == HIGH) { //Auslösung, Sirene an, Pieper aus
digitalWrite(DO_Timer, HIGH);
digitalWrite(DO_Sirene, HIGH);
digitalWrite(DO_Selbsthaltung, HIGH);
digitalWrite(DO_Pieper, LOW);
LED_blinken();
flackerLED();
// Serial.println("Ausloesung == HIGH");
}
//TODO: Beim erneuten scharf stellen klackert Timer oder stürzt das Board ab. Keine Ahnung, was da los ist...
} //Ende loop()
void Tasterabfrage() { // Idee von hier https://forum.arduino.cc/t/zeitverzogerung-und-gleichzeitig-weitere-abfragen-mit-arduino-uno/182638/13
static boolean TasterLetzterZustand=LOW;
static long TasterEinschaltzeitpunkt;
if (TasterLetzterZustand==LOW && Taster==HIGH) {
TasterEinschaltzeitpunkt=millis();
Serial.println("Tastendruck Anfang");
}
TasterLetzterZustand = Taster;
if (Taster == HIGH
&& millis() - TasterEinschaltzeitpunkt > t_haltedauer
&& scharf == LOW
&& millis() - t_defused > 5000) //2500 ms, damit durch längeren Tastendruck nicht direkt wieder entschärft wird
{
scharf = HIGH;
t_fused = millis(); //Merker, damit durch längeren Tastendruck nicht direkt wieder entschärft wird
//Debug_scharfmachen(); //später entfernen
}
if (Taster == HIGH
&& millis() - TasterEinschaltzeitpunkt > t_haltedauer
&& scharf == HIGH
&& millis() - t_fused > 5000) //5000 ms, damit durch längeren Tastendruck nicht direkt wieder scharfgestellt wird
{
scharf = LOW;
t_defused = millis(); //Merker, damit durch längeren Tastendruck nicht direkt wieder scharfgestellt wird
//Debug_entschaerfen(); //später entfernen
}
}
void Bumm() { // Liegt Signal des Timers länger als 500 ms an? Wenn ja, dann Variable Ausloesung auf HIGH
static boolean TimerLetzterZustand=LOW;
static unsigned long TimerEinschaltzeitpunkt;
if (TimerLetzterZustand==LOW && TimerRelais==HIGH)
{
TimerEinschaltzeitpunkt=millis();
}
TimerLetzterZustand = TimerRelais;
if (TimerRelais == HIGH
&& millis() - TimerEinschaltzeitpunkt > 500 //Signal muss min 500 ms anstehen
&& TimerEinschaltzeitpunkt > 1000
&& scharf == HIGH )
{
Ausloesung = HIGH;
t_ausloesung = millis(); //Merker, damit nach Auslösung die Scharfstellung wieder aufgehoben wird
}
else if (t_ausloesung > 5000){
Ausloesung = LOW;
scharf = LOW; //Soll Piepen nach Auslösung abschalten
t_ausloesung = 0; //Sonst kein erneutes scharfmachen möglich
}
}
void Piepser() { //sorgt für piepen
static unsigned long previousMillis = 0;
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= 500) //500 ms Intervall
{
// save the last time you blinked the LED
previousMillis = currentMillis;
// if the LED is off turn it on and vice-versa:
if (piepsen == LOW) {
piepsen = HIGH;
} else {
piepsen = LOW;
}
// set the LED with the ledState of the variable:
digitalWrite(DO_Pieper, piepsen);
}
}
void LED_blinken() { //sorgt für blinkende LED
static unsigned long previousMillisLED = 0;
unsigned long currentMillisLED = millis();
if (currentMillisLED - previousMillisLED >= 250) //250 ms Intervall
{
// save the last time you blinked the LED
previousMillisLED = currentMillisLED;
// if the LED is off turn it on and vice-versa:
if (blinken == LOW) {
blinken = HIGH;
} else {
blinken = LOW;
}
// set the LED with the ledState of the variable:
digitalWrite(DO_Beleuchtung, blinken);
}
}
void flackerLED() { //sorgt für flackernde LED auf Board
static unsigned long previousMillisFLACKER = 0;
unsigned long currentMillisFLACKER = millis();
if (currentMillisFLACKER - previousMillisFLACKER >= 100) //100 ms Intervall
{
// save the last time you blinked the LED
previousMillisFLACKER = currentMillisFLACKER;
// if the LED is off turn it on and vice-versa:
if (flackern == LOW) {
flackern = HIGH;
} else {
flackern = LOW;
}
// set the LED with the ledState of the variable:
digitalWrite(DO_LED, flackern);
}
}
void Debug_scharfmachen() {
Serial.print("Zeitstempel: ");
Serial.println(millis());
Serial.println("Scharfmachen");
Serial.print("scharf = ");
Serial.println(scharf);
Serial.print("Ausloesung = ");
Serial.println(Ausloesung);
Serial.print("t_defused = ");
Serial.println(t_defused);
Serial.print("t_fused = ");
Serial.println(t_fused);
Serial.print("t_ausloesung = ");
Serial.println(t_ausloesung);
Serial.println(" ");
}
void Debug_entschaerfen() {
Serial.print("Zeitstempel: ");
Serial.println(millis());
Serial.println("Entschaerfen");
Serial.print("scharf = ");
Serial.println(scharf);
Serial.print("Ausloesung = ");
Serial.println(Ausloesung);
Serial.print("t_defused = ");
Serial.println(t_defused);
Serial.print("t_fused = ");
Serial.println(t_fused);
Serial.print("t_ausloesung = ");
Serial.println(t_ausloesung);
Serial.println(" ");
}
PS: Es gibt noch ein paar Zusatzfunktionen, die ich oben nicht beschrieben habe, da sie wahrscheinlich nichts mit dem Problem zutun haben:
Eine Selbsthaltung - während der Timer läuft, wird der Hauptschalter mit einem Relais überbrückt (Ausgang 12). Es gibt neben der Sirene auch einen Pieper, dieser ist auf 6, extra Beleuchtung auf 5.