Sida 1 av 1

C (arduino), while funkar ej, if och goto funkar.

Postat: 15 juli 2014, 21:13:46
av Elias
Hej!

Kort funktions beskrivning:
3 st analoga sensorer s0, s1 & s2.
När s1 är "trigg" lägre än s0 & s2 skall en buzzer pipa, när s1 åker upp till samma nivå som s0 & s2 skall det sluta pipa. Finns även en knapp "b1" som går att använda.

Försöker lösa det men en while loop, funkar inte. en if satts och en goto funkar. Varför?


Kan egentligen inte C är mer en assembler kille men ful kör lite i arduino miljö, hoppas nån kan förklara för mig varför förljande INTE funkar m.a.p. s0,s1 & s2, knappen b1 fungerar som den skall.

Problemet:
Den går in i while loopen men aldrig ut om den är triggad av s1.
Jag har provat att skicka ut s0,s1,s2 på serie monitorn och dom ligger i nivå med varandra när den ligger och vägrar hoppa ur




funkar INTE:

Kod: Markera allt

while ((s1+trigg<s0) &&(s1+trigg<s2) || (digitalRead(b1) == LOW )){

  int s0 = analogRead(A0);
delay(10);
   s0 = analogRead(A0);


  int s1 = analogRead(A1);
delay(10);
   s1 = analogRead(A1);


  int s2 = analogRead(A2);
delay(10);
   s2 = analogRead(A2);//read all analoge values from laser sensors, two reading to get stable results. First reading switches to correct channel, second takes valid reading

 Serial.println(s0);
 Serial.println(s1);
 Serial.println(s2);
 Serial.println("BEEPAAAAA!2 ");
}

MEN följande fungerar, den går in och ur som den skall.
(varför lipar jag då, jag har ju ett sätt att lösa det?
Jag har googlat och fått för mig att goto INTE är best practice i C och så vill jag veta för jag kan inte med min okunniga ögon se varför while loopen inte skulle funka!)


Funkar:

Kod: Markera allt


label:

  int s0 = analogRead(A0);
delay(10);
   s0 = analogRead(A0);


  int s1 = analogRead(A1);
delay(10);
   s1 = analogRead(A1);


  int s2 = analogRead(A2);
delay(10);
   s2 = analogRead(A2);

 Serial.println("BEEPAAAAA!2 ");
if ((s1+trigg<s0) &&(s1+trigg<s2) || (digitalRead(b1) == LOW )) goto label;


Re: C (arduino), while funkar ej, if och goto funkar.

Postat: 15 juli 2014, 21:33:11
av bit96

Kod: Markera allt

while ((s1+trigg<s0) &&(s1+trigg<s2) || (digitalRead(b1) == LOW )){
Kolla upp prioriteterna!
== har högre prio än && och ||
Använd många parenteser, fler än du tror du behöver. :)

Kod: Markera allt

while ( ( (s1+trigg<s0) &&(s1+trigg<s2) || (digitalRead(b1)  ) == LOW )){
Jag orkar inte läsa all din kod och jag kan inte Arduino, men detta uttryck ser inte korrekt ut.

Alternativt:

Kod: Markera allt

while ( ( (s1+trigg<s0) &&(s1+trigg<s2) ) || (digitalRead(b1)  == LOW )){

Re: C (arduino), while funkar ej, if och goto funkar.

Postat: 15 juli 2014, 21:39:23
av Klas-Kenny
Jag ser ett potentiellt problem.

Inuti loopen så deklarerar du s0, s1 och s2 igen (int s0....), vilket du antagligen redan gjort utanför loopen, annars skulle den inte fungera.
Det som händer då är att du får NYA variabler med samma namn, inom just det blocket.

Det är något lite lurigt i C. Du kan skapa många variabler med samma namn, bara de deklareras inom olika block.

Så det som händer är att dina nyinlästa värden lägger sig i de nya variablerna, medan loopen kollar på de gamla variablerna. :)
Du får ju inte glömma att variabelnamnen bara är minnesadresser sedan när programmet väl kompilerats.

Re: C (arduino), while funkar ej, if och goto funkar.

Postat: 15 juli 2014, 21:50:15
av Elias
Tack, där var problemet.
Tog bort "int" inuti loopen och nu hoppar den ur som den skall!

Re: C (arduino), while funkar ej, if och goto funkar.

Postat: 15 juli 2014, 22:49:58
av TomasL
Ska inte en C-kompilator ge ett felmeddelande, eller i alla fall en varning.

Re: C (arduino), while funkar ej, if och goto funkar.

Postat: 15 juli 2014, 23:29:23
av nifelheim
GCC varnar, man måste bara läsa varningarna :-)

Jag testade

warning: 's2' may be used uninitialized in this function

Till och med snålandet med parenteser :

warning: suggest parentheses around && within ||

Re: C (arduino), while funkar ej, if och goto funkar.

Postat: 15 juli 2014, 23:46:53
av kodar-holger
Fast det räcker inte med att ta bort dina re-deklarationer. (int inne i loopen).

I while-fallet testar man på innehållet i s0,s1,s2 innan du kör innehållet i loopen. Alltså är variablerna inte initierade när du kommer dit om det inte görs tidigare i koden.

I goto-fallet testar du innehållet efter du läst vilket är mer rätt.

Men goto är mycket sällan en bra konstruktion. I C finns också en sällan använd do...while som förmodligen vore bättre att använda än goto.