Hoe spring ik uit een Functie

algemene C code
Berichten: 45
Geregistreerd: 08 Jan 2020, 17:23

Hoe spring ik uit een Functie

Berichtdoor RonalT » 05 Mrt 2022, 12:30

Mijn programma om het aantal omwentelingen van een molen te tellen (Molenteller) werkt naar tevredenheid.
Toch zit ik op dit moment met een puntje wat mijn aandacht vraagt.

In een Functie controleer ik of er de juiste gegevens maar de EEprom zijn geschreven. Dit doe ik door simpel de gegevens terug te lezen en te vergelijken met de gegevens in een variabele.

Even simpel, elke 10 minuten schrijf ik het getal uit de variabele "aantal omwentelingen van het spoorwiel" (revolutionsSpurwheel) naar de Eeprom, adres 88 en lees adres 88 weer uit. Ik vergelijk deze twee en als ze gelijk zijn dan is alles ok.
Zijn ze niet gelijk aan elkaar dan stopt het programma en verzoekt opnieuw te starten. (dit was gemakkelijk bij het testen, maar in de praktijk niet) Ik raak dan de gegevens van max 10 minuten kwijt.

Daarom wil ik deze routine aanpassen door bij een schrijf/lees fout opnieuw te proberen om de gegevens te schrijven. Niet direct, maar na 30 seconden. Als ik het direct probeer en er is echt iets fout blijft hij in deze routine hangen, daardoor stopt het tellen omdat hij het te druk heeft met de 'schrijven en lezen' functie.

Dus nu wil ik direct uit de functie terug naar de LOOP springen als de schrijf/lees fout zich voor doet.


cpp code
void bijwerkEEprom()                                                                // Functie "gegevens naar EEprom schrijven".
{
if ((revolutionsSpurwheel) != (EEPROM.readFloat(addresOmwenteling))) // | als: het geschreven aantal omw afwijkt van het gelezen aantal omw.
{ // |
Serial.print ("opgeslagen aantal omwentelingen : "); // || dan: print de tekst naar de seriële monitor.
Serial.print (revolutionsSpurwheel); // || dan: print de waarde naar de seriële monitor.
Serial.print (" - "); // || dan: print de tekst naar de seriële monitor.
Serial.println (EEPROM.readFloat(addresOmwenteling)); // || dan: print de waarde naar de seriële monitor.
// de updatetijd wordt verlaagd naar 30 seconden, dit werkt
// maar dan wil ik uit deze functie springen naar de LOOP en dat lukt me niet
}
Serial.println ("Schrijf- /leesactie goed verlopen"); // | geen schrijf- of leesprobleem

Serial.println(""); // lege regel en ga een regel omlaag.
Serial.println(""); // lege regel en ga een regel omlaag.
} // Einde van Functie "bijwerkEEprom".


Met een BREAK kan ik wel uit de For loop springen, maar dan wordt regel 12 op het scherm geprint en dat wil ik nu juist niet. Want het 'schrijven / lezen' ging niet goed.

Mijn vraag is: wat forceert op regel 10 dat ie terug springt naar de LOOP?

Advertisement

Berichten: 68
Geregistreerd: 04 Sep 2021, 08:31

Re: Hoe spring ik uit een Functie

Berichtdoor RobGood » 05 Mrt 2022, 18:35

return;

Gebruikers-avatar
Berichten: 631
Geregistreerd: 15 Nov 2015, 11:54

Re: Hoe spring ik uit een Functie

Berichtdoor Gij Kieken » 05 Mrt 2022, 20:38

Ja <return> is daar een goede oplossing voor.
Zo bijvoorbeeld
Je kunt zelf kiezen wat goed of fout is (return 0 is fout, return 1 is goed)
Merk op dat ik void heb verandert naar byte.
Code: Alles selecteren

uint8_t bijwerkEEprom()                                                // Functie "gegevens naar EEprom schrijven".
{
  uint8_t result;
  if ((revolutionsSpurwheel) != (EEPROM.readFloat(addresOmwenteling))) // | als: het geschreven aantal omw afwijkt van het gelezen aantal omw.
    {                                                                  // |
    Serial.print ("opgeslagen aantal omwentelingen : ");               // || dan: print de tekst naar de seriële monitor.
    Serial.print (revolutionsSpurwheel);                               // || dan: print de waarde naar de seriële monitor.
    Serial.print (" - ");                                              // || dan: print de tekst naar de seriële monitor.
    Serial.println (EEPROM.readFloat(addresOmwenteling));              // || dan: print de waarde naar de seriële monitor.
    result = 0;
    return result;
                                                                       // de updatetijd wordt verlaagd naar 30 seconden, dit werkt
                                                                       // maar dan wil ik uit deze functie springen naar de LOOP en dat lukt me niet   
    }   else {                                                                       
    Serial.println ("Schrijf- /leesactie goed verlopen");              // | geen schrijf- of leesprobleem
    result = 1;
    Serial.println("");                                                // lege regel en ga een regel omlaag. 
    Serial.println("");                                                // lege regel en ga een regel omlaag.
    return result; 
  }
}

Berichten: 45
Geregistreerd: 08 Jan 2020, 17:23

Re: Hoe spring ik uit een Functie

Berichtdoor RonalT » 06 Mrt 2022, 00:44

Maar dan komt bij mij de vraag op waarom je VOID naar UINT8_T veranderd heb?
Met VOID duidt men een functie aan, kan dat met uint8_t ook...

Gebruikers-avatar
Berichten: 631
Geregistreerd: 15 Nov 2015, 11:54

Re: Hoe spring ik uit een Functie

Berichtdoor Gij Kieken » 06 Mrt 2022, 10:32

Met void geef je niets terug.
Met uint8_t (dit is hetzelfde of byte ,oftewel een getal van 8 bits 0 tot 255) geef je een getal terug aan de aanroepende functie.
Zo geef ik een 0 terug als het fout is en 1 als het goed.
Het is dan aan jouw om in de void loop() functie met die info iets te doen.
Wens je dat niet ,blijf dan bij void bijwerkEEprom() en zet dan enkel in de if constructie een <return>.
Jouw functie springt dan op die plaats terug naar je loop zonder iets mee te geven.

In plaats van een byte terug te geven kan je ook een bool gebruiken (true / false),maar beiden zijn 8-bits .

Gebruikers-avatar
Berichten: 631
Geregistreerd: 15 Nov 2015, 11:54

Re: Hoe spring ik uit een Functie

Berichtdoor Gij Kieken » 06 Mrt 2022, 10:55

Bijgevoegd een klein voorbeeldje van <return> toegepast in de <void loop>



Code: Alles selecteren
void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  delay(1000);
Serial.println("We zitten bovenaan in de void loop() functie");
  delay(1000);
Serial.println("We zitten een regel verder in de void loop() functie");
  delay(1000);
 Serial.println("We zitten weer een regel verder in de void loop() functie");
 delay(1000);
 return;
 Serial.println("hier geraken we nooit in de void loop() functie");
}

Berichten: 45
Geregistreerd: 08 Jan 2020, 17:23

Re: Hoe spring ik uit een Functie

Berichtdoor RonalT » 06 Mrt 2022, 14:04

Bedankt. Ik zal eens kijken of ik hier verder mee kom.

En iets terug geven is niet nodig. Dit is de functie BIJWERKEEPROM waarin gegevens naar de EEprom worden geschreven en gecontroleerd of dat goed is gegaan. Als het goed is gegaan wordt na 10 minuten opnieuw naar de EEprom geschreven.
Als het fout gaat wordt in de functie zelf de tijd verlaagd naar 30 seconden en wordt er een nieuwe poging gedaan. Gaat dit weer mis dan wordt de tijd 1 minuut om een nieuwe poging te doen.

Voor deze constructie heb ik gekozen omdat de omwentelingenteller elke 3 tot 12 seconden een omwenteling moet tellen. Als het schrijven en lezen mis gaat en het wordt dan steeds herhaald worden er telpulsen gemist.
Als er eens 1 telpuls wordt gemist is dat max 6 per uur. Waarschijnlijk wordt er weinig gemist.... want ter controle hebben we de oude mechanische teller nog en die lopen redelijk gelijk. (beter dan ik verwacht had)

Om het tellen zo goed mogelijk te laten verlopen is de VOID LOOP zo weinig mogelijk belast. Er worden enkel zaken gecontroleerd en alles wordt in functies afgewerkt. De LOOP wordt meestal in 3-5 millis doorlopen.
Hieronder de LOOP als voorbeeld.


cpp code
void loop()                                                              // the loop routine is running all the time.  
{
(buttonAState) = digitalRead(reedSchakA); // controleer of reed schakelaar A is geactiveerd.
if (buttonAState != buttonAStateOld) // controleren of de schakelaar bediend wordt.
{
if (buttonAState == LOW) // controleer of buttonAState is laag.
{
rotationTimeA = millis(); // zet variabele rotationTimeA op huidige tijd.
wiekSnelheid(); // spring naar functie "wiekSnelheid bepalen".
totaalOmw(); // spring naar functie "totaal aantal omwentelingen per jaar".
revolutionsSpurwheel = revolutionsSpurwheel + 1; // verhoog variabele revolutionsSpurwheel met 1.
}
}
buttonAStateOld = buttonAState; // oude buttonAState is gelijk aan buttonAState.

if (millis() - rotationTimeA == 8000) // als de huidgie tijd min rotationTimeA is gelijk aan 8000 miliseconden.
{
stilGevlucht(); // spring naar functie "gevlucht staat stil".
}

if (millis() - bijwerkTijd > 600000) // als de huidige tijd min bijwerkTijd is groter dan 600000 miliseconden (dat is 10 minuten)
{
bijwerk(); // spring naar functie "bijwerk" om de EEPROM bij te werken.
}

(buttonResetState) = digitalRead(reedSchakReset); // controleer of reed schakelaar RESET is geactiveerd.
if (buttonResetState != buttonResetStateOld) // controleren of de schakelaar bediend wordt.
{
if (buttonResetState == LOW) // als de reset schakelaar laag is wordt "weetZekerDisplay" uitgevoerd.
{
weetZekerDisplay(); // jump to functie "weetZekerDisplay.
rotationTimeA = millis(); // zet variabele rotationTimeA op huidige tijd.
}
}
buttonResetStateOld = buttonResetState; // oud = nieuw.
} // End of "loop".

Terug naar C code

Wie is er online?

Gebruikers in dit forum: Geen geregistreerde gebruikers en 14 gasten