Frage zu einer Subroutine

Ich möchte aus "normalen" einfachen Konfigration:

  1. Vorgeplänkel

  2. void setup()

  3. void loop()

  4. void irgendwas1()

  5. void irgendwas2(),

in dem bei Aufruf von void irgenws(1 oder 2 ) dieser Teil ja aufgerufen wird und danach zum eigentlichen loop zurückgekehrt wird, folendes machen /erreichen.

ich nehme void irgenwas3() hinzu.

hier soll nun eine abfrage von eingegebenen signalen erfolgen.
Diese kommen per IR-Fernbedienung ( das klappt schon soweit )

ABER
ich möchte das hier weitergelaufen wird also immer wieder zu void irgendwas3() zurückgekehrt wird.

( Der Grund ist, ich möchte hier per IR Werte schrittweise erhöhen oder verringern, bis mir das Ergebnis genehm ist)

ERST, wenn per Fernbedienung ein bestimmter Wert eingegeben wird, soll zum normalen loop zurückgekehrt werden.

Dazu 2 Fragen:

  1. geht das
  2. Wenn ja, was muss ich dafür reinschreiben?

Ich weiß, dass das mit GOTO ganz einfach zu lösen ist, anstelle von VOID, aber VOID ist mir an der Stelle einfach angenehmer, bzw ich wills einfach gern so machen.

GOTO ist ziemlich einfach, aber eben auch ziemlich bah.

(deleted)

Danke für den Tip. Er war schwergewichtig genug, um das fette Brett vor meinem Kopf weghauen:-))

ziemlich komplex, das Ganze, aber ich habs im ersten Step hinbekommen.
Im setup > x=0 ( x steht hier nur symblisch)

Wenn X == 0 läuft der komplette loop als

void loop()

IR stand by für Eingabe.

if (Eingabewert == Wunschwert)
{ x=1;
IR resume; // ( muss genau hier her )
}

if x == 1 void irgenwas3()

if x == 0
renne los bis fertig
fang neu an.

In irgendwas3 gibt es dann wieder einen Vergleichswert, der x zu 0 werden läßt.
Andere Werte verändern up/down meine Werte.

klappt bis dahin prima, die veränderten Werte muss ich jetzt noch per I2C in ein Modul schreiben.
Das sollte aber hinzukriegen sein.

WOZU DAS GANZE

Es geht um mein bestehendes Projekt Wetterstation, in der ein RTC3231 drin ist.
Dieses Modul ist nicht so unproblematisch wie man annehmen dürfte.

Also die Unterroutine dient dazu Stunde, Minute und Sekunde einzustellen, um die Uhr nachjustieren zu können, ohne dieses Umständliche Prozedere beim Neustart mit der Einstellzeile.
Da muss jedesmal der Rechner dran, das ist nervig.

Warum ist das nötig?
Nun, das Modul, wenn man den stecker direkt an der Station zieht, zählt ja per Knopfzelle brav die Zeit weiter.

ABER
Wehe der strom fällt aus, oder man ziht vom Netzteil statt den 12V Stecker mal den Netzstecker.
die fetten Kondensatoren lassen die Spannung langsam abfallen, und DAS... kann das Uhrmodul mal gleich gar nicht ab.
Das Ding schaltet dann nämlich ganz unbrav nicht mehr auf weiterzählen, und wenn man 5 Minuten später den stecker wieder reinsteckt, dann fehlen hier mal glatt 5 Minuten.

Das ging mir auf den Sack.
Sobald es laufen sollte, erweitere ich das noch um Tag Wochentag, Monat und Jahr. ( :-)) sehr wichtig, wenn am 31.12. der Saft weg geht, und erst am 1.1. des Folgejahres wiederkommt:-)).
Das ist ja nur noch Fleißarbeit dann.

Wenn ich das Ganze fertig habe, stelle ich es unter Projekte wieder ein

Allen, die mir mir jetzt den Tip geben wollen, dass man die Uhrzeit und das Datum und den tag auch aus dem Netz per WLAN fischen kann sei vorab gesagt, dafür bin ich nicht schlau genug, das würde ich never ever zum Laufen bringen.
Dito gilt für DCF.

Ach ja, ich habe übrigens die Wetterstation noch um zwei Servoausgänge erweitert.
Damit läßt sich nun mit 2 präzisen Servos auch eine parallel laufende, analoge Anzeige von Temperatur und Druck machen.
Braucht niemand, hat aber Spaß gemacht, das zum Laufen zu bringen.

Zum einen: dein 'void irgendwas()' nennt sich in C++ eine Funktion. Das 'void' davor bedeutet nur, dass diese Funktion keinen Wert zurückgibt. Das kann auch durchaus anders sein, d.h. z.b dass diese Funktion einen Wert zurückgibt, der anzeigt ob der richtige Wert empfangen wurde oder nicht.

Dein Ansatz zur Lösung ist falsch. 'loop()' sollte niemals angehalten/blockiert werden. Das heist, Du rufst im loop immer und ständig deine IR-Empfangs-Funktion auf. Und nur wenn sie zurückgibt, das der gewünschte Wert empfangen wurde, tuts Du im loop was.
Das ist im Prinzip das, was auch Peter vorgeschlagen hat.

Am besten zeigst Du mal deinen Sketch, damit man sich besser vorstellen kann was Du vorhast.

Edit: auch nach deiner Antwort habe ich immer noch nicht so ganz verstanden, was da abläuft, und was Du vorhast.

skyfox60:
Es geht um mein bestehendes Projekt Wetterstation, in der ein RTC3231 drin ist.
Dieses Modul ist nicht so unproblematisch wie man annehmen dürfte.

Nun, das Modul, wenn man den stecker direkt an der Station zieht, zählt ja per Knopfzelle brav die Zeit weiter.

ABER
Wehe der strom fällt aus, oder man ziht vom Netzteil statt den 12V Stecker mal den Netzstecker.
die fetten Kondensatoren lassen die Spannung langsam abfallen, und DAS... kann das Uhrmodul mal gleich gar nicht ab.
Das Ding schaltet dann nämlich ganz unbrav nicht mehr auf weiterzählen, und wenn man 5 Minuten später den stecker wieder reinsteckt, dann fehlen hier mal glatt 5 Minuten.

Dann ist was faul.
Das Phänomen kenne ich nur wenn die CR-Bat langsam ans Ende ihrer Lebenszeit kommt.
Ersetz mal gegen eine frische Zelle.

(deleted)

skyfox60:
IR resume; // ( muss genau hier her )

Auch das stimmt nicht. Das gehört mit in die Empfangsfunktion, wo es auch logisch hingehört.

Ganz ruhig bleiben, Freunde,

ich weiß, ihr meint es alle gut.

Also, hier mal der wichtigste Teile im Programm und dazu ein paar Erklärungen, die vielleicht verständlich machen, warum ich den Loop an der Stelle sogar ganz bewusst unterbreche.

void loop(){
    if (irrecv.decode(&results)) {
    Serial.print(results.value); Serial.print("  "); Serial.println(lastCode);

    if (results.value == 4294967295) {

      results.value = lastCode;
    }
    if (results.value == 16769565) { // Adjust date and time
      stellen =1;}
      irrecv.resume();
   }
         
     
    if (stellen==1){
    DTset();
    }
  if (stellen == 0){ 
  zeigeZeit(); // show time()

Ich fange mal unten an:

letzte Zeile zeigeZeit()

das war der Anfang meines loops, und das funktionierte.
Es wurden Datum Zeit Sommer- oder Winterzeit angezeigt ( Zeile 1
Druck ++ in 2. Zeile usw usw.

WENN ich das if stellen==0 NUR dann zeigeZeit() NICHT mache,
dann tut er das bei jedem Loop.
Das führte dazu, das meine "Zeit-Einstell-Seite" flimmernderweise ständig von der normalen Anzeige überschrieben wurde.
Soviel zum Thema man darf den Loop nie unterbrechen.
Hey, wenn ich Druck Temperatur und den ganzen Kram nicht anzeigen will, dann brauch ich ihn auch nicht messen, der Loop kann somit unterbrochen werden. Das geflimmer kann man sich nicht anschauen.

Statt dessen wird DTset() angezeigt, und solange stellen == 1 ist, auch ständig.
Hier kann ich in ruhe die Werte ändern, und jede Änderung direkt ins Uhrmodul schreiben.
bis im DTset() der "Rücksprungwert empfangen wird, der mir einfach stellen = 0 macht, und der loop läuft wie vorher.

@MicroBahner:
das irrecv.resume(); oben sitzt an der Stelle aber mal ganz genau richtig.
schon hinter die nächste } gesetzt funktioniert der ganze Rutsch nämlich schon nicht mehr.

So, wie es jetzt ist funktioniert das bisher prächtig.
es kommt nun nur noch die blöde Fleißarbeit
IR Werte mit if abragen und dann Wert ändern, Wert schreiben ins Modul.

Hier die bisherige Zeit-Einstellseite, die nur aus der halben Maske und dem "Rausprung besteht bisher.
Schaut man sich dort das lcd.print an, weiß man auch, warum der normale Loop da mal besser nicht zwischenfunkt.

void DTset(){             
     lcd.setCursor(0,0);
       lcd.print("  Uhrzeit stellen   "  );
       lcd.setCursor(0,1);
       
       lcd.print("St:");
       if (stunde < 10) { 
          lcd.print("0");
        }
       lcd.print(stunde); 
             
       lcd.print(" Min:"); 
       if (minute < 10) { 
          lcd.print("0");
        }
        lcd.print(minute);
               
        lcd.print(" Sek:");
        if (sekunde < 10) { 
          lcd.print("0");
        }
       lcd.print(sekunde);    

       if (results.value == 16754775)  
    {
      
      stellen = 0;
    }

skyfox60:
Ganz ruhig bleiben....

Soll das eine Drohung sein, oder was soll das ?

das irrecv.resume(); oben sitzt an der Stelle aber mal ganz genau richtig.
schon hinter die nächste } gesetzt funktioniert der ganze Rutsch nämlich schon nicht mehr.
.....

Dann hast du noch einen anderen Fehler eingebaut.

irrecv.resume();

Gehört außerhalb der if-Abfrage, damit diese Anweisung auch auf andere Abfragen reagieren kann.

Da du hier aber nur Fragmente postest, können wir deine anderen Fehler nicht sehen.

skyfox60:
Ich möchte ....

Du möchtest endliche Automaten bauen.
Ob dir das klar ist, oder auch nicht, aber genau das möchtest du.

In deinem Fragment kann ich nicht erkennen, wo Du den loop unterbrichst.

Hallo Franz Peter,

da muss ich dir Recht geben. es ist insoweit keine Unterbrechung.
Lediglich wird über den Status der Variablen "stellen" ein Teil ( nämlich der ab zeigeZeit(), nicht mehr ausgeführt, weil immer direkt DTset() angesprungen wird. Erst bei entsprechendem Signal von der IR wird wieder der "normale Loop abgearbeitet.

Bis hierhin funktioniert das so wie es soll.
Man könnte so sogar zwei kleine Programmabläufe unabhängig voneinander laufen lassen, und mittels Fernbedienung zwischen diesen "Programmen" hin und her schalten, ohne jeweils zuerst den anderen Sketch laden zu müssen. dies, soweit setup und entsprechende Pinbelegungen und Timernutzungen nicht dagegen sprechen. Aber prinzipiell würde das gehen .-)).

Für die Interessierten der bisherige noch unfertige Sketch im Anhang.

Neuer ZIP-komprimierter Ordner.zip (5.51 KB)

So, Fleißarbeit erledigt.
Uhr läßt sich jetzt mittels der Fernbedienung einstellen.

Einstellbar sind:
Tag
Monat
Jahr
Stunde
Minute
Sekunde
Wochentag
Sommer- bzw Winterzeit

Die Kommentare wurden angepasst.
Wie gehabt, die Anzeige in deutsch, die Kommentare in englisch inclusive der Übersetzungen der angezeigten deutschen Texte, damit sich das für den geneigten internationalen Leser leicht "umstricken lässt.

Weitere Änderung gegenüber der in "zeigt her eure Projekte" aufgeführten Version:

Display jetzt über I2C angebunden

Zwei Servoausgänge hinzugefügt, mit denen sich Temperatur und Druck in weiten Bereichen auch analog anzeigen lassen. Ich weiß, braucht man nicht, aber für Spielkinder ist sowas ja vielleicht fein.
IR-Fernbedienung adaptiert zur Einstellung der Daten. Das war sonst recht umständlich.

Wetterstation-UhrzeitRTC3231-mit IR-Einstellbar.zip (6.43 KB)

Kleines Video.zip (1.75 MB)