Suche Hilfe beim Programmieren eines Countdown mit Bedingung

So Liebe Arduino Gemeinde,

nun habe ich mich durchgerungen Hilfe in Anspruch zu nehmen. Ich habe das Arduino Projektbuch bekommen und schon vieles da umgesetzt. Nun komme ich aber mit einer Idee an meine Genzen.

Ich habe vor ein Waagenelement zu verbauen (habe schon viele im Internet gesehen). Mit einem 2 Zeilendisplay (Später vielleicht auch anderes) welches bei dem Set dabei war.

Nun zu dem Vorhaben. Sobald der Arduino gestartet ist, soll ein Countdown laufen. (ja Countdown bekomme ich hin denke ich)

Dieser soll gestopt werden, sobald das gewünschte Gewicht auf der Waage stehen (Wer nun denkt hey das kommt mir bekannt vor, ja genau das Gallonenrätsel bei Stirb Langsam III). Vielleiht ist ja auch möglich, dass die Waage die Anfrage des Gewichts nur alle 5 Sekunden macht, denn wenn ein Falsch Gwiht auf der Waage steht, soll Zeit abgezogen werden (vielleicht). Ich möchte für einen Kumpel eine Tour organisieren, wo er genau das Rätsel machen muss.

Leider sind da meine Fähigkeiten und Ideen recht eingeschränkt :-(.

Würde mich freuen, wenn mir jemand bei der Umsetzung helfen kann.

Danke

schaddy: Leider sind da meine Fähigkeiten und Ideen recht eingeschränkt :-(.

Da du dich mit dieser Frage hier meldest, können wir das auch nachvollziehen. Aus diesem Grund ist dein Titel sehr schlecht gewählt. Das sehen wir so schon.

Also ändere den Titel in einen, der dei technisches Problem beschreibt. Dann ist der Thread auch besser zu verstehen und auch im Web zu finden.

Da profitieren auch andere von und das ist Sinn des Forums.

HotSystems: Also ändere den Titel in einen, der dei technisches Problem beschreibt.

Danke für den Hinweis, das ist auch das erste Mal, dass ich mit meinen 32 Jahren in einem Forum bin :confused:

Sobald einmal das einigermaßen richtige Ergebnis beim Messen rauskommt, soll der Countdown gestoppt werden (für immer, d.h. bis zum nächsten Reset), ansonsten wird die runterzählende Zeit angezeigt ohne (oder mit?) weiterem Hinweis (gemessener Wert, Abweichung vom Sollwert ?)
Wenn bis Null runtergezählt wurde, ist auch alles zu Ende, bis zum nächsten Reset?

Ich sehe ganz grob 3 Zustände: gewonnen / verloren / countdown läuft noch.

const unsigned int sollmin = 100;
const unsigned int sollmax = 110; 
bool gewonnen;
bool verloren;
unsigned int restzeit = 60 ; // Sekunden bis Ende

void loop() {
   if (verloren) return;
   if (gewonnen) return;

   // Countdown bis waage stimmt;
   int waage = analogRead(A0);
   if ( waage <= sollmax && waage >= sollmin ) gewonnen = true;
   else { 
     restzeit--;
     if (restzeit == 0) verloren = true;
   } 
   anzeige(); // je nach gewonnen/verloren  
   delay (1000); // genau genug zum Sekunden zählen 
}

Kann man natürlich auch anders machen, insbesondere die Anzeige gleich bei der Änderung des Zustands
Oder zeig mal, wo dein Problem genau liegt …

michael_x: Sobald einmal das einigermaßen richtige Ergebnis beim Messen rauskommt, soll der Countdown gestoppt werden (für immer, d.h. bis zum nächsten Reset), ansonsten wird die runterzählende Zeit angezeigt ohne (oder mit?) weiterem Hinweis (gemessener Wert, Abweichung vom Sollwert ?) Wenn bis Null runtergezählt wurde, ist auch alles zu Ende, bis zum nächsten Reset?

Ich sehe ganz grob 3 Zustände: gewonnen / verloren / countdown läuft noch.

Oder zeig mal, wo dein Problem genau liegt ...

Wow, ich bin erst mal für jeden Hinweis dankbar, da ich mich scheinbar sehr überschätzt habe was alleine schon den Countdown angeht ...

Also an sich genau Richtig, solange nicht das ungefähre Ergebnis +- Toleranz erreicht wird, soll der Timer weiter laufen. Am Ende, wenn die Zeit bei "0" ist, soll der Text Verloren erscheinen. Beim Erreichen der Toleranz, "Gewonnen" leider merke ich wie beschränkt meine Denkweise zu sein scheint. Habe gedacht das ist kein riesiges Problem, aber naja Selbstüberschätzung. Ach um die eine Frage noch zu beantworten, ja Sobald er resetet ist, soll er wieder beginnen.

Habe gedacht das ist kein riesiges Problem

Ist es ja auch nicht. Die eigentliche und oben fehlende Aufgabe ist ja nur noch die sinnvolle Anzeige.

Ich gehe mal davon aus, dass das Messen und Anzeigen der Countdown-Sekunden einmal je Sekunde ausreicht und sonst nichts weiter gleichzeitig gemacht werden soll.

michael_x:
Ist es ja auch nicht. Die eigentliche und oben fehlende Aufgabe ist ja nur noch die sinnvolle Anzeige.

Ich gehe mal davon aus, dass das Messen und Anzeigen der Countdown-Sekunden einmal je Sekunde ausreicht und sonst nichts weiter gleichzeitig gemacht werden soll.

Oh naja wenn ich schon nicht mal in der Lage bin einen Countdown zu schreiben naja aber es scheint hier ja Hilfe zu geben über die ich echt sehr dankbar bin.

Ich habe es mir halt so gedacht:
a)- Wenn das Gewicht auf die Waage kommt //wert stimmt nicht//
Countdown zählt weiter
b)- Wenn das Gewicht auf die Waage kommt //wert stimmt Display —> Geschafft
c)- Wenn Countdown bei 0 // Display —> Verloren!

Nun ist ja meine Überlegung, wenn die Waage nachdem das Gewicht 5 Sekunden drauf war, greift sie dann erst das Ergebnis ab, da ja sonst die Möglichkeit besteht, das Gefäß auf die Waage zu stellen und dann Wasser nach und nach reinlaufen zu lassen, bis das Gewicht erreicht ist.

Oder man macht nach einem Versuch der falsch ist gleich Verloren oder 3 Versuche … hmmm Soweit erst mal die Überlegung.

Soweit mein können aber leider zählt er nach oben nicht nach unten

#include <LiquidCrystal.h>

const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

signed short minutes, secondes;
char timeline[16];

void setup() {

 lcd.begin(16, 2);
 lcd.print("Countdown");


}

void loop() {

 lcd.setCursor(0, 1);
 sprintf(timeline,"%0.2d Min %0.2d Sek", minutes, secondes);
 lcd.print(timeline);
 
 delay(1000);
 secondes++;
 
 if (secondes == 60)
 {
   secondes = 0;
   minutes ++;
 }

}

Setze Deinen Code bitte in Codetags (</>-Button oben links im Forumseditor oder [code] davor und [/code] dahinter ohne *).
Dann ist er auch auf mobilen Geräten besser lesbar.
Das kannst Du auch noch nachträglich ändern.

Gruß Tommy

Wenn das Gewicht auf die Waage kommt... da ja sonst die Möglichkeit besteht, das Gefäß auf die Waage zu stellen und dann Wasser nach und nach reinlaufen zu lassen, bis das Gewicht erreicht ist.

Das ist erheblich komplizierter als alles was du bisher als Aufgabenstellung angedeutet hast. Hast also noch einen Zustand (mit Anzeige ?), dass das Gewicht erst wieder neu gemessen wird, wenn die Waage zwischendurch lange genug "frei" war, und einen Zustand, der "Warte auf neues Gewicht ..." oder so heißen könnte. Auch wäre erstmal genau zu ermitteln, wie lange dein Wiegemodul braucht, bis es einen stabilen Wert liefert (und wie sehr der schwanken kann).

Mein Tip: realisiere erstmal eine einfache Variante.

michael_x: Das ist erheblich komplizierter als alles was du bisher als Aufgabenstellung angedeutet hast. Hast also noch einen Zustand (mit Anzeige ?), dass das Gewicht erst wieder neu gemessen wird, wenn die Waage zwischendurch lange genug "frei" war, und einen Zustand, der "Warte auf neues Gewicht ..." oder so heißen könnte. Auch wäre erstmal genau zu ermitteln, wie lange dein Wiegemodul braucht, bis es einen stabilen Wert liefert (und wie sehr der schwanken kann).

Mein Tip: realisiere erstmal eine einfache Variante.

Nun habe ich mir nochmal Gedanken gemacht. Daher würde ich sagen. beim Start direkt Countdown Wenn das Gewicht stimmt oder erreicht ist "Gewonnen" ansonsten nur normal der Countdown

So, mir ist es nun geglückt,
ich habe einen Countdown Timer. Dieser startet Automatisch. Nun muss ich nur mal sehen, wenn ich die Waage bekommen habe, wie ich das einbinde und dann einstellen kann. Vielleicht neee ganz sicher brauche ich dann Hilfe :confused:

#include <LiquidCrystal.h>

 // Goal; 60 second count down timer, when reaches 0 display "Game over"
 // Continue displaying "Game Over" until start button is pressed to reset
 
int hours = 0; // start Stunden bei der Delayzeit eher Minuten
int minutes = 20; //start Minuten bei der Delayzeit eher Sekunden
int seconds = 60; //start Sekunden  bei der Delayzeit eher Millisekunden


 
LiquidCrystal lcd(12, 11, 5, 4, 3, 2); 

 
void setup() {

}
 
void loop() {
 lcd.begin(16, 2);
 lcd.print("Countdown");
 
 
 delay(2000);
 
 while (hours > 0 || minutes > 0 || seconds >= 0) {
 
 lcd.setCursor(4, 2);
 
 (hours < 10) ? lcd.print("0") : NULL;
 lcd.print(hours);
 lcd.print(":");
 (minutes < 10) ? lcd.print("0") : NULL;
 lcd.print(minutes);
 lcd.print(":");
 (seconds < 10) ? lcd.print("0") : NULL;
 lcd.print(seconds);
 lcd.display();
 stepDown();
 delay(10);
 }
}
 
void stepDown() {
 if (seconds > 0) {
 seconds -= 1;
 } else {
 if (minutes > 0) {
 seconds = 59;
 minutes -= 1;
 } else {
 if (hours > 0) {
 seconds = 59;
 minutes = 59;
 hours -= 1;
 } else {
 trigger();
 }
 }
 }
}
 
void trigger() {
 lcd.clear(); 
 lcd.setCursor(0, 1); 
 
 lcd.println("Game-Over");
 delay(50000);
 loop(); 


 }

Ich rate dir dringend davon ab, den ternären Operator auf dieses Weise zu nutzen.

Der Operator zielt auf den Datenfluss.
Du benutzt ihn für den Kontrollfluss.
Das sollte man sich erst gar nicht angewöhnen, meine ich mal so, aus dem Bauch heraus.

Da könnte/wird dich irgendwann die Sequence Point Problematik erwischen.

Auch:

E:\Programme\arduino\portable\sketchbook\sketch_mar30a\sketch_mar30a.ino: In function 'void loop()':
E:\Programme\arduino\portable\sketchbook\sketch_mar30a\sketch_mar30a.ino:31:34: warning: converting to non-pointer type 'unsigned int' from NULL [-Wconversion-null]
   31 |  (hours < 10) ? lcd.print("0") : NULL;
      |                                  ^~~~
E:\Programme\arduino\portable\sketchbook\sketch_mar30a\sketch_mar30a.ino:34:36: warning: converting to non-pointer type 'unsigned int' from NULL [-Wconversion-null]
   34 |  (minutes < 10) ? lcd.print("0") : NULL;
      |                                    ^~~~
E:\Programme\arduino\portable\sketchbook\sketch_mar30a\sketch_mar30a.ino:37:36: warning: converting to non-pointer type 'unsigned int' from NULL [-Wconversion-null]
   37 |  (seconds < 10) ? lcd.print("0") : NULL;
      |

(hours < 10) ? lcd.print(“0”) : NULL;

if(hours < 10) lcd.print("0");

Volle Zustimmung.
Wenn schon, dann wäre
lcd.print(x<10?"0":""); möglich aber sinnlos.

Auf beiden Seiten vom : sollte der gleiche Datentyp stehen.

Selbst das gehört eigentlich verboten (weil je nach Wert von i eine andere Methode print(int) / print(float) dran wäre):

int i = 10;
float x = 23.4;
Serial.print(i>0?i:x);

Liefert “10.00” :slight_smile:
@combie: Vielleicht findest du ja eine Doku, wo drin steht warum das so erlaubt ist. Vorlesen musst du es dann nicht.
Link reicht, von mir aus auch URL. :stuck_out_tongue:

combie:
Da könnte/wird dich irgendwann die Sequence Point Problematik erwischen.

Auch:

E:\Programme\arduino\portable\sketchbook\sketch_mar30a\sketch_mar30a.ino: In function 'void loop()':

E:\Programme\arduino\portable\sketchbook\sketch_mar30a\sketch_mar30a.ino:31:34: warning: converting to non-pointer type ‘unsigned int’ from NULL [-Wconversion-null]
  31 |  (hours < 10) ? lcd.print(“0”) : NULL;
      |                                  ^~~~
E:\Programme\arduino\portable\sketchbook\sketch_mar30a\sketch_mar30a.ino:34:36: warning: converting to non-pointer type ‘unsigned int’ from NULL [-Wconversion-null]
  34 |  (minutes < 10) ? lcd.print(“0”) : NULL;
      |                                    ^~~~
E:\Programme\arduino\portable\sketchbook\sketch_mar30a\sketch_mar30a.ino:37:36: warning: converting to non-pointer type ‘unsigned int’ from NULL [-Wconversion-null]
  37 |  (seconds < 10) ? lcd.print(“0”) : NULL;
      |





~~(hours < 10) ? lcd.print("0") : NULL;~~ 


if(hours < 10) lcd.print(“0”);

Vielen dank, kannst du mir die Problematik versuchen zu erläutern? Das wäre total lieb.

@combie: Vielleicht findest du ja eine Doku, wo drin steht warum das so erlaubt ist.

Hmmm .... Da würde ich das Kapitel zu den impliziten Cast empfehlen. Das gilt für alle Operatoren, warum nicht für diesen? : wird den gleichen Regeln wie + unterliegen.

Da könnte/wird dich irgendwann die Sequence Point Problematik erwischen.

Vielen dank, kannst du mir die Problematik versuchen zu erläutern? Das wäre total lieb.

Sequence Point Order of evaluation - cppreference.com - C++ Reference