Hallo,
meine Countdownkiste ist Dank der tollen Hilfe fertig geworden und wird am 17. zu ihrem ersten Einsatz kommen.
Nun schwebt mir ein zweites Projekt vor. Ich will eine "Buzzersäule" bauen. Kurz, ein 1m langes und 100 mm Duchmesser transparentes Kunststoffrohr mit Multicolor LED Stripes, an dem oben ein sogenannter Grobhandtaster (Buzzerknopf) drauf ist. Die mechanische Hardware habe ich schon so gut wie zusammen.
Das Programm soll folgendermaßen aussehen. Eigentlich wie eine Schachuhr mit nur einem Knopf (Buzzerknopf). Wenn dieser gedrückt wird, läuft eine Zeit in Minuten und Sekunden auf einem Display und z.B. die roten LED´s leuchten. Wird dieser Knopf wieder gedrückt, bleibt die Zeit stehen und eine andere, zweite Zeit fängt an zu zählen und wird auf dem selben oder ein weiteres Display angezeigt. Nun leuchten die gelben LED´s. Wenn eine von beiden Zeiten das Ziel von z.B. eine Stunde erreicht hat, soll eine Tröte los tröten.
Ich hab hier im Forum ein Zeitprogramm gefunden. Doch leider zählen die alle runter. Ich hab ein Programm empfohlen bekommen. Kann man das so modifizieren, das es anstatt runter, hoch zählt? Und die Minuten/Sekundeneingabe kann wegfallen. Dafür ein Reset zum Nullen beider Zeiten. Ich hab hier nur erstmal vobn einen normalen Display auf ein Serialdisplay "umgebaut".
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
/* in der nachfolgenden Zeile wird festgelegt, ob die Schalter
mit PullUp oder PullDown Widerständen beschaltet sind.
INPUT_PULLUP aktiviert die internen PullUp-Widerstände des Atmega
INPUT setzt voraus, dass die Schalter mit externen PullDown-Widerständen beschaltet sind
*/
#define INPUTMODE INPUT_PULLUP // INPUT_PULLUP oder INPUT setzen
const int minuten_switch = 7;
const int sekunden_switch = 6;
const int start_switch = 8;
int timerLaufzeit = 0;
boolean timerGestartet=false;
void eingabe()
{
static boolean oldMinSwitch=false; // Statische Variable für letzten Schalterzustand
static boolean oldSecSwitch=false; // Statische Variable für letzten Schalterzustand
static boolean oldStartSwitch=false; // Statische Variable für letzten Schalterzustand
boolean MinSwitch= digitalRead(minuten_switch); // aktueller Schalterzustand
boolean SecSwitch= digitalRead(sekunden_switch); // aktueller Schalterzustand
boolean StartSwitch= digitalRead(start_switch); // aktueller Schalterzustand
if (INPUTMODE==INPUT_PULLUP) // Vertauschte Schaltlogik bei PullUp
{
MinSwitch=!MinSwitch; // ausgelesenen Zustand vertauschen wg. PullUp
SecSwitch=!SecSwitch; // ausgelesenen Zustand vertauschen wg. PullUp
StartSwitch=!StartSwitch; // ausgelesenen Zustand vertauschen wg. PullUp
}
if (MinSwitch==HIGH && oldMinSwitch==LOW) timerLaufzeit+=60; // Zustandsänderung gedrückt?
oldMinSwitch=MinSwitch; // aktueller Schalterzustand wird zum alten Schalterzustand
if (SecSwitch==HIGH && oldSecSwitch==LOW) timerLaufzeit++; // Zustandsänderung gedrückt?
oldSecSwitch=SecSwitch; // aktueller Schalterzustand wird zum alten Schalterzustand
if (StartSwitch==HIGH && oldStartSwitch==LOW) timerGestartet=true; // Zustandsänderung gedrückt?
oldStartSwitch=StartSwitch; // aktueller Schalterzustand wird zum alten Schalterzustand
}
void verarbeitung()
{
static unsigned long lastMillis=0; // statischer Zähler für letzten Stand des millis() Timers
static unsigned long timedMillis=0;// statischer Zähler für Millisekunden beim Herunterzählen
unsigned long nowMillis=millis(); // aktueller Stand des millis() Timers
if (timerGestartet && timerLaufzeit>0) // Zähler läuft und Restzeit vorhanden
{
timedMillis+= nowMillis-lastMillis; // Millisekunden hochzählen
if (timedMillis>=1000) // Nach jeweils 1000 Millisekunden
{
timedMillis=0; // Millisekundenzähler auf 0 setzen
timerLaufzeit--; // Eine Sekunde Laufzeit abziehen
if (timerLaufzeit==0) timerGestartet=false; // Timer anhalten
}
}
lastMillis=nowMillis; // Zählerstand merken, bei dem diese Funktion zuletzt lief
}
void ausgabe()
{
int minuten=timerLaufzeit/60; // Ganzzahldivision durch 60
int sekunden=timerLaufzeit%60;// Modulo-Divisionsrecht bei geteilt durch 60
lcd.setCursor(0, 1);
if (minuten < 10) lcd.print("0");
lcd.print(minuten);
lcd.print(":");
if (sekunden < 10) lcd.print("0");
lcd.print(sekunden);
}
void setup() {
lcd.begin(16, 2);
pinMode(minuten_switch,INPUTMODE);
pinMode(sekunden_switch ,INPUTMODE);
pinMode(start_switch, INPUTMODE);
lcd.print("TIMER:");
}
void loop()
{
eingabe();
verarbeitung();
ausgabe();
delay(5); // Kleines Delay zum softwaremäßigen Entprellen der mechanischen Schalter
}
Gruß Frank