Go Down

Topic: Programmierfrage: Timeout in While Schleife ?? (Read 1 time) previous topic - next topic

elektron_

Hallo,

ich habe folgenden Code der eigentlich gut funktioniert:

Code: [Select]

  ReadDtmfDigit();
  ISDA=DTA;                                 // 1. Schritt
  while (digitalRead (2));
  while (digitalRead (2) == LOW);
  ReadDtmfDigit();
  ISDB=DTA;                                 // 2. Schritt
  while (digitalRead (2)); 
  while (digitalRead (2) == LOW);
  ReadDtmfDigit();
  ISDC=DTA;                                 // 3. Schritt
  while (digitalRead (2));
  while (digitalRead (2) == LOW);
  ReadDtmfDigit();
  ISDD=DTA;                                 // 4. Schritt
  while (digitalRead (2));


Der Prozessor springt jedes mal wenn Pin2 auf High geht weiter und führt ReadDtmfDigit(); aus. In der Zwischenzeit darf und muß er nichts anderes machen, daher sind die while schlifen hier prinzipiell gut. Aber: Wenn aus irgend einem Grund ein Zyklus (Pin 2 geht auf Low-High) fehlt dann bleibt das Programm in der entsprechenden While Schleife hängen.  :0
Ich bräuchte jetzt den Code für ein Timeout in den While Schleifen. Also wenn er z.B. in einer der obigen Schleifen länger als etwa 1 sec. ist dann soll das Programm zu einer speziellen Stelle springen wo ich auf den Fehler entsprechend reagieren kann...  :)

Danke im Voruas,
Christian
Elektronik funktioniert intern mit Rauch.
Beweis: Wenn der Rauch herauskommt ist es kaputt...

markbee

Meinst Du nicht, das ganze würde besser und sauberer mit Interrupts funktionieren?
XBee blog: http://lookmanowire.blogspot.com/

elektron_

Hallo,

interrupt ginge vermutlich auch, wäre wahrscheinlich sogar eleganter....
Aber ich möchte es aber hier viel lieber ohne Interrupt mit ein bischen Code in den while Schleifen lösen, vor allem weil das hier überhaupt nicht Zeitkritisch ist und ich die Interrupts für andere, kritischere Programmteile aufbewahren möchte....

Christian
Elektronik funktioniert intern mit Rauch.
Beweis: Wenn der Rauch herauskommt ist es kaputt...

blubb113

Ich bin selbst wahrlich keine Experte, aber warum nimmst du nicht einfach die if-Funktion? Dann solltest du mit dem Wechsel auch kein Problem haben.

elektron_

Hallo,

hmm, if ändert meiner Meinung nach nichts am Problem. Ich kann damit auch nur Pin2 abfragen - nur wenn der zu wenig oft High wird dann bleibt es genau so hängen...
Da ist die while schleife, meine ich,  schon nicht so schlecht.
Könnte man nicht z.B. einen Zähler einbauen und bei einem bestimten Zählerstand mit goto herausspringen? Aber ich habe jetzt nicht so die C erfahrung wie das in Code umzusetzen wäre...

Christian
Elektronik funktioniert intern mit Rauch.
Beweis: Wenn der Rauch herauskommt ist es kaputt...

uwefed

Aus der Schleife kommst Du mit break http://arduino.cc/en/Reference/Break
Mit millis() kontrollierst Du ob die Zeit vorbei ist und dann springst Du mit break raus. http://arduino.cc/en/Tutorial/BlinkWithoutDelay
Grüße Uwe

michael_x

#6
Jan 23, 2013, 01:49 pm Last Edit: Jan 23, 2013, 04:10 pm by michael_x Reason: 1
So geht es ohne goto und entspricht eventuell deinen Vorstellungen ;)

Code: [Select]

static boolean error;
...
while (digitalRead (2)
   if (checktimeout()) { error = true; return; }


Am Anfang von loop() kannst du im Timeout-Fall if (error == true) alles neu initialisieren oder was auch immer, wenn erforderlich...

Edit: checktimeout() arbeitet natürlich mit millis(), wie uwe angedeutet hat.

jurs


Ich bräuchte jetzt den Code für ein Timeout in den While Schleifen. Also wenn er z.B. in einer der obigen Schleifen länger als etwa 1 sec. ist dann soll das Programm zu einer speziellen Stelle springen wo ich auf den Fehler entsprechend reagieren kann...  :)


Ich würde das Warten und die Timeouterkennung in eine eigene Funktion auslagern, der Funktionswert gibt an, ob die Funktion ohne Timeout abgearbeitet wurdE:
true ==> abgearbeitet, kein Timeout
false ==> Abbruch wg. Timeout
Und solange kein Timeout auftritt, wird die Sequenz immer weiter abgearbeitet.

Und damit keine ewig tief geschachtelten If-Abfragen auftreten würde ich ausnahmsweise per "goto" ans Ende der auszuführenden Sequenz springen, mit einer Fehlerbehandlungsmöglichkeit kurz vor Ende der Funktion beim Sprunglabel "FEHLERENDE:".

Code: [Select]

boolean waitForStateOrTimeout(byte pin, long timeout) {
// function returns true if no timeout occured
// function returns false in case of a timeout
  long started=millis();
  while ((millis()-started<timeout) && digitalRead(pin));
  if (millis()-started>=timeout) return(false);
  while ((millis()-started<timeout) && digitalRead (pin) == LOW);
  if (millis()-started>=timeout) return(false); else return(true);
}


void myCodeloop() {
  boolean weiter=true;
  ReadDtmfDigit();
  ISDA=DTA;                                 // 1. Schritt
  weiter=waitForStateOrTimeout(2, 1000);
  if (weiter)
  {
    ReadDtmfDigit();
    ISDB=DTA;                                 // 2. Schritt
  }
  else goto FEHLERENDE;
  weiter=waitForStateOrTimeout(2, 1000);
  if (weiter)
  {
    ReadDtmfDigit();
    ISDC=DTA;                                 // 3. Schritt
  }
  else goto FEHLERENDE;
  weiter=waitForStateOrTimeout(2, 1000);
  if (weiter)
  {
    ReadDtmfDigit();
    ISDD=DTA;                                 // 4. Schritt
  }
  else goto FEHLERENDE;
  while (digitalRead (2));
  goto NORMALESENDE;
FEHLERENDE:
  Serial.println("Timeout");
NORMALESENDE: ;
}

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy