Go Down

Topic: [SOLVED] Mijn while loop gedraagd zich als een if then else. (Read 333 times) previous topic - next topic

JevanHa

IDE versie 1.8.2
Ik begrijp iets niet en dus zal ik het wel fout doen. Alleen weet ik niet waarom of hoe dit op te lossen. En daar heb ik dan weer hulp bij nodig.

En ik heb al gezien dat meerdere personen in het verleden hier ook moeite mee hadden.
Alleen ziet mijn probleem er anders uit, denk ik.

Uit de reference guide. While loops
while loops will loop continuously, and infinitely, until the expression inside the parenthesis, () becomes false.

Onderstaande code heb ik meer gezien. er is mij duidelijk wat er verwacht wordt en daarom zonder meer overgenomen.
while (gps.available(gps_port) ) {
        Run_Once(gps.read());
      }

Totdat ik dit in setup() zette en me erover verbaasde dat hij helemaal niet had gedraaid. Tenminste zo ervaarde ik dit. variablen die ik nodig heb bij een andere functie waren helemaal niet gevuld.

Ik heb toen deze GPS_loop() gemaakt en deze wordt nu aangeroepen in de loop() omdat ik nu eenmaal wat meer wilde zien. Na wat Serial.print regels en een teller toegevoegd te hebben kreeg ik het gevoel van dit is geen while loop maar een "if then else".
void GPS_loop() {
      while (gps.available(gps_port) ) {
        Run_Once(gps.read());
      }
      Serial.print("\nStatus gps_port = "); Serial.print(gps.available(gps_port));
      Serial.print(" X="); Serial.print(x);
      x ++;
}
Bij aanvang is (gps.available(gps_port)) een 0 "false", ik zie dan ook een heleboel print regels met daarin de (gps.available(gps_port)) waarde 0. Net als bij een if then wordt de else tak iedere keer uitgevoerd. Tot er wat gebeurt en deze 1 wordt, "true" dan wordt inderdaad de opdracht Run_Once uitgevoerd. Dan gebeurt er ook wat ik verwacht, de variablen die ik nodig heb voor een andere functie zijn gevuld.
Ook het toevoegen dat ik de conditie "true" verwacht,  "while (gps.available(gps_port) == true )" verandert niets aan de zaak dat nog steeds ook de "else" tak wordt uitgevoerd. De while loop verlaat dus ook de functie GPS_loop().
while loops will loop "continuously", and "infinitely". Alleen niet bij mij.

De functie zit in een loop omdat ik dit ook zo uitvoer vanaf void loop().
En de de (gps.available(gps_port) wordt wel iedere seconde true waardoor deze functie wanneer ik 'm maar lang genoeg uitvoer toch gerund wordt.

Waar zit nu mijn gedachte "fout", dat de conditie bij aanvang al "false" is ?

Maar waarom wordt dan Run_once wel uitgevoerd wanneer de conditie "true" wordt ?

Kind regards
Jan
Nederlands Forum   http://arduino.cc/forum/index.php/board,77.0.html

nicoverduin

Dit klopt zowieso niet:

Code: [Select]
while loops will loop "continuously", and "infinitely".

Dit gebeurt alleen als de conditie waar is. Zelfs voor de standaard void loop() gaat dit niet op. die wordt elke keer opnieuw aangeroepen vanuit main.cpp

Verder zou ik ff de hele sketch hier zetten om te zien wat je nu allemaal doet.
Met vriendelijke groet / kindest regards
Nico Verduin
www.verelec.nl
Do not PM me for personal consultancy unless you are willing to pay for it.

MAS3

Hoi JevanHa.

Ik vind je vraag erg lastig te lezen, maar na 'm een aantal malen gelezen te hebben, weet ik wel waar jij je in vergist.
Dat ga ik zometeen uitleggen, en je gelijk laten zien hoe je je vragen beter leesbaar kunt (eigenlijk moet) maken.
Namelijk, zet code tussen [code] [/code] tags.
Daarmee word een stukje code in aan apart kader gezet en is het niet langer een stuk van een lange brei tekst.

Jouw idee dat je een if..then..else hebt gecreëerd, is een kwestie van interpretatie.
Hoewel de IDE niet aan interpreteren doet (in plaats daarvan doet ie aan compileren), doet die het wel correct  en is jouw interpretatie fout.
Als je dit doet:

Code: [Select]
void GPS_loop() {
      while (gps.available(gps_port) ) {
        Run_Once(gps.read());
      }
      Serial.print("\nStatus gps_port = "); Serial.print(gps.available(gps_port));
      Serial.print(" X="); Serial.print(x);
      x ++;
}

Dan doe je niet 1 enkele handeling, maar meerdere.
1 van die handelingen, is een voorwaarde stellen; de while.
De volgende handeling wordt uitgevoerd wanneer er aan die eerdere voorwaarde werd voldaan.
Dat stukje staat tussen de {curly braces}, waarvan de eerste { direct komt na het stellen van de voorwaarde.
Daarna volgt er een stukje dat niet aan een voorwaarde is gebonden.
Dat is het stukje dat iets met de seriële verbinding doet, en x verhoogt.

Je lijkt een aantal zaken door elkaar gehaald te hebben.
Want wat jij een loop noemt, is wat bekend staat als een functie.
Die functie moet je ergens vandaan aanroepen, en dan gaat ie doen wat jij erin hebt gezet.
Jij vertaalt (interpreteert) dat schijnbaar anders, of in ieder geval verwacht je er iets anders van.

Als je de functie hebt aangeroepen, dan word dat wat tussen de daarbij behorende { } staat uitgevoerd.
Jij stelt aan 1 van de daar uit te voeren zaken een voorwaarde, namelijk dat zolang (while) er iets beschikbaar is, een andere functie moet worden aangeroepen.
En daarna wil je dan nog dat er andere dingen (3 regels) worden gedaan, die dus altijd worden uitgevoerd onafhankelijk van een of andere voorwaarde.

Ik hoop dat ik het je voldoende duidelijk heb uitgelegd, en dat je hiermee het probleem dat je ziet kunt oplossen.

[edit]
Als je tijdens setup of in ieder geval voor void loop () iets doet, dan is dat eenmalig.
Je kijkt dus 1 keer of er iets ter beschikking is.
Tijdens loop kijk je de hele tijd of er al iets beschikbaar is.
Dat is het verschil.
Als je eerst wil wachten tot je iets binnen krijgt, dan moet je je voorwaarde !omkeren.
[/edit]
Have a look at "blink without delay".
Did you connect the grounds ?
Je kunt hier ook in het Nederlands terecht: http://arduino.cc/forum/index.php/board,77.0.html

shooter

je sluit de while loop al gelijk dus als er gps available is doe je een read, maar onder de } dat gebeurt altijd, en is dus geen else maar gebeurt ook als de while waar is.

paul deelen
shooter@home.nl
making controls with codesys PLC and arduino

sterretje

Zoals Nico al zei, post de volledige code. En geef ook aan waar we de bibliotheken die je gebruikt kunnen vinden.
If you understand an example, use it.
If you don't understand an example, don't use it.

Electronics engineer by trade, software engineer by profession. Trying to get back into electronics after 15 years absence.

JevanHa

Wat een hoop reacties op mijn vraag en daarvoor wil ik iedereen nu alvast hartelijk danken. Ik moet ook meteen mijn excusses maken over de onduidelijkheid in mijn vraag op het forum. Wanneer ik op de Arduino IDE bij Help -> in de Reference guide -> bij while kijk denk ik te lezen dat bij een while loop je ook in de while loop blijft totdat er aan de voorwaarde is voldaan. Het false worden van de expressie.
Hierbij de aangehaalde zin "while loops will loop continuously, and infinitely, until the expression inside the parenthesis, () becomes false.".
En dat is wat ik niet zie gebeuren in het kleine stukje code bij mijn vraag. De Serial.print regels en de teller die opgehoogd wordt zijn er alleen door mij bijgezet omdat ik aan het zoeken ben waar het nu toch fout gaat, maar horen er zeker niet in. Ik zocht naar de reden waarom het niet werkte in de setup(). Met het op het forum zetten van mijn vraag had ik dat niet moeten doen. Ik kan nu de while ook direct vervangen door een if en dan gebeurt er precies hetzelfde. En dat is wat ik hiermee bedoelde te zeggen. De eerste regel in de reference guide heeft het er ook over dat de door while geteste expressie false wordt. En mijn Serial prints hebben mij aangetoond dat dit dus al "waar" is. Alleen is while, of de compiler wel zo netjes geweest om te begerijpen wat ik wilde doen en voert bij het "waar" worden dan ook het onderstaande statement uit.
Mijn ervaring en kennis zijn nog niet zover dat ik de expressie (gps.available(gps_port) waar ik op wil testen, weet om te bouwen dat hij tijdens deze while default "1" is (ipv "0" wat hij nu is) en bij het "true" worden een "0" wordt, maar dan wordt hij dus "1. Waar ik wel zeker van ben is dat hij iedere seconde "true" wordt. Dat maakt de kans op oneindig in de loop blijven al heel klein.
Ik de Serial.print regels in #define DEBUG. Wel zo netjes en wat duidelijker voor iedereen. Wat ook niet zo fraai is zijn de "switches" in Run_Once en Print_DST functies. Die zijn er door mij ook tijdelijk in gezet. Het was voor mij alleen maar zoeken hoe ik de oorspronkelijke sketch kan opsplitsen in twee afzondelijk van elkaar oproepbare functies. En mijn logische gedachte was om Run_Once in setup() te zetten wat niet werkte.
Eigenlijk zit die er al in maar dan moest je ook de hele sketch laten lopen en dat alleen maar voor een lokale tijd in Zomer en Wintertijd weergave.

Tussen code tags lukt me niet. Meer dan 9000 char. Daarom als attachment.
Kind regards
Jan
Nederlands Forum   http://arduino.cc/forum/index.php/board,77.0.html

sterretje

Gewoon een nieuw antwoord maken en daar je code in plaatsen.

Als je while niet doorlopen wordt betekent dat dat de allereerste keer de conditie false is.
If you understand an example, use it.
If you don't understand an example, don't use it.

Electronics engineer by trade, software engineer by profession. Trying to get back into electronics after 15 years absence.

JevanHa

Ok dus dat is inclusief je ingeklopte tekst. Wel zie ik dat hij meerdere blokken maakt die kennelijk ook met code beginnen. Niets van aantrekken en aan het einde zelf de sluit /code zetten ?
Vwb de eerste keer niet lukken van de while klopt dit. Het zelfs vele meerdere keren. Maar wel binnen de seconde.
Kind regards
Jan
Nederlands Forum   http://arduino.cc/forum/index.php/board,77.0.html

sterretje

Geen idee waar je het over hebt met meerdere blokken

Gewoon ;)

[code]je code hier[/code]
If you understand an example, use it.
If you don't understand an example, don't use it.

Electronics engineer by trade, software engineer by profession. Trying to get back into electronics after 15 years absence.

JevanHa

test
Code: [Select]

#define name    NMEA_timezone.ino
#define version 2017-05-09 23:00
// zie [iurl=https://www.kalender-365.nl/zomertijd_en_wintertijd.html]https://www.kalender-365.nl/zomertijd_en_wintertijd.html[/iurl]
//======================================================================
//  Program: NMEA_timezone.ino
//
//  Description:  This program shows how to offset the GPS dateTime member
//          into your specific timezone.  GPS devices do not know which
//          timezone they are in, so they always report a UTC time.
//          This is the same as GMT.
//
//  Prerequisites:
//     1) NMEA.ino works with your device
//     2) GPS_FIX_TIME is enabled in GPSfix_cfg.h
//     3) NMEAGPS_PARSE_RMC is enabled in NMEAGPS_cfg.h.
//     4) NMEAGPS_INTERRUPT_PROCESSING is not enabled in NMEAGPS_cfg.h
//        You could use any sentence that contains a time field.  
//        Be sure to change the "if" statement in GPSloop from RMC
//        to your selected sentence.
//
//  'Serial' is for debug output to the Serial Monitor window.
//
//======================================================================
//#define DEBUG       // uncomment for DEBUG
// Arduino TX & RX pin number connected to the GPS RX & TX pin
#define RXpin    3     // determined by jumper setting on GPS shield
#define TXpin    4
#include <Arduino.h>
#include <NMEAGPS.h>
#include <NeoSWSerial.h>
  NeoSWSerial gps_port(TXpin, RXpin); // GPS TX_pin connected with Arduino RX_pin & GPS RX_pin connected with Arduino TX_pin
#define DEBUG_PORT Serial
NMEAGPS  gps;    // This parses received characters
gps_fix  fix;
bool dst_printed = false;  // switch
bool run_once    = false;
// Daylight Savings Time rule (calculated once per reset and year!)
NeoGPS::time_t  changeover;
NeoGPS::clock_t springForward, fallBack;
    int x, y, z, teller = 1;
//----------------------------------------------------------------
// Check that the config files are set up properly
#if !defined(GPS_FIX_TIME)
  #error You must define GPS_FIX_TIME in GPSfix_cfg.h!
#endif
#if !defined(NMEAGPS_PARSE_RMC)
  #error You must define NMEAGPS_PARSE_RMC in NMEAGPS_cfg.h!
#endif
#ifdef NMEAGPS_INTERRUPT_PROCESSING
  #error You must *NOT* define NMEAGPS_INTERRUPT_PROCESSING in NMEAGPS_cfg.h!
#endif
//    end of declarations
//----------------------------------------------------------------
void setup()  {
  // Start the normal trace output
  DEBUG_PORT.begin(19200);
  
  while (!DEBUG_PORT)
    ;
  
  // Start the UART for the GPS device
  gps_port.begin( 9600 );
    
  DEBUG_PORT.print( F("\nNMEAtimezone.INO: started\n\n") );
  DEBUG_PORT.print( F("    fix object size: ") );  DEBUG_PORT.println( sizeof(gps.fix()) );
  DEBUG_PORT.print( F("NMEAGPS object size: ") );  DEBUG_PORT.println( sizeof(gps) );
  DEBUG_PORT.flush();
}
//    end of setup
//----------------------------------------------------------------
void loop()  {
  if (!run_once or !dst_printed)
    GPS_loop();
  else for (;;) ;
}
//    end of loop
//----------------------------------------------------------------
/*
 * static void DST_CET() {  // Central Europe set Daylight Saving Time
 *   while (gps.available(gps_port)) {
 *     gps_fix fix = gps.read();
 */
 
void GPS_loop() {
    if (!run_once) {
      while (gps.available(gps_port))
        Run_Once(gps.read());
        
      #if defined DEBUG
      Serial.print("\nStatus gps_port = "); Serial.print(gps.available(gps_port));
      Serial.print(" Teller X="); Serial.print(x);  x ++;
      #endif
    }
    
    if (!dst_printed & run_once)  {
      while (gps.available(gps_port))
        Print_DST(gps.read());  // Print local time (DST)
      #if defined DEBUG
      Serial.print("\nStatus gps_port = "); Serial.print(gps.available(gps_port));
      Serial.print(" Teller Y="); Serial.print(y);  y ++;
      #endif
    }  
}
//    end of GPS_loop
//----------------------------------------------------------------
void Run_Once( const gps_fix & fix ) { // Central Europe set Daylight Saving Time
  if (fix.valid.time && fix.valid.date) { // test if valid date & time
    
    NeoGPS::clock_t seconds = fix.dateTime;
//----------------------------------------------------------------      
    // Daylight Savings Time rule (calculated once per reset and year!)
    if ((springForward == 0) || (changeover.year != fix.dateTime.year)) {
      // CEST - Central Europe Summer Time
      changeover.year    = fix.dateTime.year;
      changeover.month   = 3;   // March
      changeover.date    = 31;  // last Sunday
      changeover.hours   = 2;   // 2:00 midnight
      changeover.minutes = 0;
      changeover.seconds = 0;
      changeover.set_day();
      // Step back to the last Sunday, if day != SUNDAY
      changeover.date -= (changeover.day - NeoGPS::time_t::SUNDAY);
      springForward = (NeoGPS::clock_t) changeover;
      // CET - Central Europe standard Time
      changeover.month   = 10;  // October
      changeover.date    = 31;  // last Sunday
      changeover.hours   = 3;   // to account for the "apparent" DST +1
      changeover.minutes = 0;
      changeover.seconds = 0;
      changeover.set_day();
      // Step back to the 1st Sunday, if day != SUNDAY
      changeover.date -= (changeover.day - NeoGPS::time_t::SUNDAY);
      fallBack = (NeoGPS::clock_t) changeover;
      
      run_once = true;  // succes full run_once
      
    } // end of if ((springForward == 0)
  } // end of if (fix.valid.time
} // end of Run_Once
//----------------------------------------------------------------
static void Print_DST(const gps_fix & fix ) {
  if (fix.valid.time && fix.valid.date) {
    
    NeoGPS::clock_t seconds = fix.dateTime;
    
    // Set these values to the default offset of your timezone from GMT
    static const int32_t zone_hours   = 1L;   // default GMT +1
    static const int32_t zone_minutes = 0L;   // usually zero
    static const NeoGPS::clock_t zone_offset  =
                      zone_hours   * NeoGPS::SECONDS_PER_HOUR +
                      zone_minutes * NeoGPS::SECONDS_PER_MINUTE;
    // add default offset of your timezone from GMT
    seconds += zone_offset;   // add DST offset
    // add summertime offset else (wintertime) use only default time zone offset
    if ((springForward <= seconds) && (seconds < fallBack))
      seconds += NeoGPS::SECONDS_PER_HOUR;
        
    // create date / time from seconds
    NeoGPS::time_t localTime(seconds);
    DEBUG_PORT.print( F("\nLocal time : ") );
    DEBUG_PORT << localTime;    // print Date & Time
    DEBUG_PORT.println();   // print local time (DST)
    dst_printed = true;
    
  } // end of if (fix.valid.time && fix.valid.date)
} // end of Print_DST
//----------------------------------------------------------------
/* EOF */


Kind regards
Jan
Nederlands Forum   http://arduino.cc/forum/index.php/board,77.0.html

JevanHa

oh. is dat alles. Ik gebruikte iedere keer die knop linksboven  </>
Die maakt ook zo'n code vak aan waarin je van alles in kan zetten maar dan niet zoveel.

Weer wat geleerd.
Wat ik wel op mijn scherm mis een knop of zoiets waarin ik in het topic overzicht kan komen.
nu lukt mij dit alleen wanneer ik naar Forum ga, dan helemaal naar beneden bladeren voor Nederlands en die dan openen. Dat moet toch simpel kunnen ?
Kind regards
Jan
Nederlands Forum   http://arduino.cc/forum/index.php/board,77.0.html

sterretje

Je moet een keer je post bookmarken.

Ga naar je draadje (topic), klik je naam.
In de nieuwe pagina die wat informatie over je bevat op 'show posts' klikken. De pagina die je dan krijgt bookmarken.
If you understand an example, use it.
If you don't understand an example, don't use it.

Electronics engineer by trade, software engineer by profession. Trying to get back into electronics after 15 years absence.

JevanHa

Je moet een keer je post bookmarken.

Ga naar je draadje (topic), klik je naam.
In de nieuwe pagina die wat informatie over je bevat op 'show posts' klikken. De pagina die je dan krijgt bookmarken.
Sterretje
Zou je dat Bookmarken willen uitleggen. Ik zie dat nergens staan. Alles wat ik probeer of doe is tijdelijk.
Op zich heb ik hier wel weer van geleerd. Maar dat was eigenlijk niet mijn vraag. Ik zocht een manier om in ene keer naar de index van de Topics te gaan.
Nu ga ik eerst naar de menu regel. Click op forum. Scroll naar beneden voor Nederlands en dan ben ik er eindelijk.
Dat moet toch sneller kunnen alleen zie ik die mogelijkheid (nog) niet.
Kind regards
Jan
Nederlands Forum   http://arduino.cc/forum/index.php/board,77.0.html

JevanHa

Ok dus dat is inclusief je ingeklopte tekst. Wel zie ik dat hij meerdere blokken maakt die kennelijk ook met code beginnen. Niets van aantrekken en aan het einde zelf de sluit /code zetten ?
Vwb de eerste keer niet lukken van de while klopt dit. Het zelfs vele meerdere keren. Maar wel binnen de seconde.
Meerdere code blokken is ook opgelost. Wanneer je (echt) lege regels in je code hebt staan dan wordt  het code block kennelijk gesloten en opent hij een nieuwe.
Nieuwe regel (leeg) met een TAB is al voldoende om dat op te lossen.
Misschien iets om dit bij de uitleg te zeggen dat je dus je regel niet echt "leeg" moet maken.
Kind regards
Jan
Nederlands Forum   http://arduino.cc/forum/index.php/board,77.0.html

sterretje

'Bookmarken' is mijn 'vertaling' van toevoegen aan je favorieten. Ik woon de laatste 17 jaar in een land waar engels de voertaal is on bedrijven en dus is mijn nederlands een beetje verroest ;)
If you understand an example, use it.
If you don't understand an example, don't use it.

Electronics engineer by trade, software engineer by profession. Trying to get back into electronics after 15 years absence.

Go Up