probleem stack overflow met unsigned long?

Arduino specifieke Software
Berichten: 88
Geregistreerd: 16 Jul 2015, 21:02

probleem stack overflow met unsigned long?

Berichtdoor wim2584 » 25 Jul 2020, 22:36

Hallo,

ik heb een pompbewaking gemaakt (voor een grondwaterpomp, met een anti-pendel in-en uitschakelvertraging, verder meet hij de temperatuur van de pomp, als deze niet binnen gestelde tijd genoeg is gedaald (door koude grondwater), naar alarm fase (bescherming pomp), verder een aan/uit op de druk van het water, en een timer om om de tuin x tijd te besproeien)

nu werkt alles goed, alleen als ik voor de temperatuur bewaking een tijd kies meer als 32 sec krijg ik foutmelding:

ino:164:52: warning: integer overflow in expression [-Woverflow]

if (millis() - timer1 > (inschakel_delay * 1000)) { // timer inschak
el

Vraag wat heb ik fout gedaan?

Code: Alles selecteren
// wim FSM machine voor pomp beveiliging en timer 24-04-2020 V2.6 timers reset toegevoegd in "idle", en een uitschaklevertraging toegevoegd

// tijden van de timers
#define inschakel_delay  60        // inschakel delay in sec   
#define uitschakel_delay  10        // inschakel delay in sec
#define bewaking_Temp_delay 20    // bewakings delay in sec
#define sproeitijd 180             // sproeitijd min
#define minimale_temperatuur  30  // temperatuur in °c

//librarie
#include <OneWire.h>
#include <DallasTemperature.h>

// PIN definitions
#define pomp_aan 3        // uitgang pomp aan
#define temp_timerpin 4   // indicatie "dat de temperatuur timer loopt"
#define aan_schakelaar 5  // druk schakelaar aan
#define uit_schakelaar 6  // druk schakelaar uit en reset na alarm
#define Timer_aan_schakelaar 10      // sproeitijd schakelaar
#define pompdruk_laag 7   // ingang drukschakelaar
#define alarm 8           // uitgang led, "aangeven dan de temperatuur boven setpoint is nadat de timer is afgelopen"
#define standby 9         // uitgang led "schakeling standby, wacht op druk laag signaal"
#define sproei_uit 13
int ledstate = LOW;

//voor de temepratuurvoeler
float temp = 0.0;                       // variabele om temperatuur in op te slaan (float is getal met komma)
int oneWireBus = 12;                    // 1-wire pin
OneWire oneWire(oneWireBus);            // 1-wire instantie op de oneWireBus pin
DallasTemperature sensors(&oneWire);    // geef de instantie van de oneWire bus door aan de DallasTemperature


// FSM states                                              // de diverse state van de FSM
#define idle_state 0
#define inschakelvertraging_state 10
#define bewakingvertraging_state 20
#define aan_state 30
#define alarm_state 40

// variables
int fsm_state = 0;

//  timers
unsigned long long timer0;
unsigned long timer1;
unsigned long long timer2;
unsigned long timer3;
unsigned long previousMillis = 0;

// start programma

void setup() {

  // beschrijvng van de in en outputs

  pinMode(aan_schakelaar , INPUT_PULLUP);
  pinMode(uit_schakelaar , INPUT_PULLUP);
  pinMode(Timer_aan_schakelaar , INPUT_PULLUP);
  pinMode(pompdruk_laag , INPUT_PULLUP);
  pinMode(temp_timerpin, OUTPUT);
  pinMode(pomp_aan, OUTPUT);
  pinMode(alarm, OUTPUT);
  pinMode(standby, OUTPUT);
  pinMode(sproei_uit, OUTPUT);
  timer0 = 0;
  timer1 = 0;
  timer2 = 0;
  timer3 = 0;


  // voor temperatuur voeler "ds18b20"  one wire

  Serial.begin(9600);                                                              // stel de seriële monitor in
  sensors.begin();                                                                  // begin met het uitlezen van de sensor

}                                                                                         // einde set up

void loop() {                                                                         //start programma loop

  unsigned long currentMillis = millis();                                     // set timer ledje sproeitimer
  delay(20);
  if (digitalRead(sproei_uit) == HIGH)  {

    Serial.println("sproeitimer loopt ");

    if (currentMillis - previousMillis >= 500) {

      previousMillis = currentMillis;

      if (ledstate == LOW) {
        ledstate = HIGH;
      } else {                                                                  //voor ledje te laten knipperen als sproeier timer aan
        ledstate = LOW;
      }

      digitalWrite(standby, ledstate);
    }

    if (timer0 != 0) {                                                      // timer voor sproeien
      if (millis() - timer0 > (sproeitijd * 60000)) {

        digitalWrite(sproei_uit, LOW);

        fsm_state = idle_state;                                         // ga naar FSM IDLE als sproeitijd over is
      }
    }
  }


  // FSM states
  switch (fsm_state) {


case idle_state:     // idle_state, wacht op aan aktie

      timer0 = millis();                                     
      Serial.println("idle ");                                                   // toon status FSM
      digitalWrite(sproei_uit, LOW);                                      // sproeitimer uit
      digitalWrite(alarm, LOW);                                            // zet alarm led uit
      digitalWrite(pomp_aan, LOW);                                      // Pomp uit
      digitalWrite(temp_timerpin, LOW);                               // indicatie temp timer niet loopt
      digitalWrite(standby, LOW);                                        // indicatie schakeling niet standby

   
      timer1 = 0;                                                                          // reset timer 1
      timer2 = 0;                                                                           // reset timer 2
      timer2 = 0;                                                                         // reset timer 3
     
      delay(20);
      if (digitalRead(aan_schakelaar) == LOW)                              // kijk of aan schakelaar is ingedrukt
      {
        digitalWrite(standby, HIGH);
        digitalWrite(sproei_uit, LOW);
        fsm_state = inschakelvertraging_state;
      }
      delay(20);
      if (digitalRead(Timer_aan_schakelaar) == LOW)  {
        timer0 = millis();                                                            // set sproeitimer
        digitalWrite(sproei_uit, HIGH);                                         // set "vlag" voor knipperled , en schakel over naar FSM inschakel

        fsm_state = inschakelvertraging_state;
      }

      delay(20);
     
      break;

case inschakelvertraging_state:

      Serial.println("inschakelvertraging");
      digitalWrite(temp_timerpin, LOW);

      if (digitalRead(pompdruk_laag) == HIGH) {
        timer1 = 0;
       
      }

      if (digitalRead(pompdruk_laag) == LOW) {
        Serial.println("inschakel delay pomp active ");
        timer3 = 0;
        if (timer1 != 0) {
          if (millis() - timer1 > (inschakel_delay * 1000)) {                    // timer inschakel
            digitalWrite(pomp_aan, HIGH);                                           // start de POMP
            fsm_state = bewakingvertraging_state;                              // ga naar state bewakingvertraging
          }
        } else {
          timer1 = millis();
        }
      } else {

        if (digitalRead (pomp_aan) == HIGH) {
          Serial.println("uitschakel delay pomp active");
         
          if (timer3 != 0) {
            if (millis() - timer3 > (uitschakel_delay * 1000)) {            // timer inschakel
              digitalWrite(pomp_aan, LOW);
               timer1 = 0;                                                               // reset timer 1
               timer2 = 0;                                                               // reset timer 2
               timer3 = 0;                                                               // reset timer 3
               fsm_state = inschakelvertraging_state;
            }
          } else {
            timer3 = millis();
          }
        }
      }
      if (digitalRead(uit_schakelaar) == LOW) {

        fsm_state = idle_state;                                                         // ga naar state idle
      }
      delay(20);

      break;

 case bewakingvertraging_state:

      Serial.println("bewakingvertraging_state");

      if (digitalRead(pomp_aan) == HIGH) {
        if (timer2 != 0) {                                                                  // timer voor temperatuur bewaking
          if (millis() - timer2 > (bewaking_Temp_delay *  1000)) {

            digitalWrite(temp_timerpin, HIGH);
            fsm_state = aan_state;                                                   // ga naar state aan
          }
        } else {
          timer2 = millis();
        }
      }
      if (digitalRead(pompdruk_laag) == HIGH) {
        fsm_state = inschakelvertraging_state;                              // ga naar state inschakelvertraging
      }
      if (digitalRead(uit_schakelaar) == LOW) {

        fsm_state = idle_state;
      }

      delay(20);

      break;

    case aan_state:

      Serial.println("aan ");


      sensors.requestTemperatures();                                         // lees de temperatuur sensor uit
      temp = sensors.getTempCByIndex(0);                               // haal temperatuur in Celcius op van eerste sensor
      Serial.println(temp);                                                       // print gemeten temperatuur


      if (temp > (minimale_temperatuur))  {                              // controleer of temperatuur warmer is dan .. graden

        fsm_state = alarm_state;                                              // ga naar Alarm, als temperatuur te hoog is
      }
      if (digitalRead(pompdruk_laag) == HIGH) {
        fsm_state = inschakelvertraging_state;
      }
      if (digitalRead(uit_schakelaar) == LOW)
      {
        fsm_state = idle_state;
      }

      delay(20);


      break;

    case alarm_state:

      Serial.println("alarm ");
      digitalWrite(pomp_aan, LOW);
      digitalWrite(temp_timerpin, LOW);
      digitalWrite(alarm, HIGH);
      digitalWrite(sproei_uit, LOW);
      digitalWrite(standby, LOW);

      if (digitalRead(uit_schakelaar) == LOW)                          // kijk of aan schakelaar is ingedrukt
      {
        fsm_state = idle_state;
      }
      delay(100);
  }
}

Advertisement

Gebruikers-avatar
Berichten: 2655
Geregistreerd: 06 Aug 2016, 01:03

Re: probleem stack overflow met unsigned long?

Berichtdoor Koepel » 26 Jul 2020, 01:41

Welk Arduino board gebruik je ?
De compiler gebruikt default een integer.
Bijvoorbeeld bij een Arduino Uno is een integer een signed 16-bit, van -32768 tot +32767.

De compiler vertelt wat je verkeerd doet: "integer overflow in expression".
De compiler is bezig om een getal te maken voor de uiteindelijke binaire code, maar die expressie komt uit op een getal dat te hoog is voor een integer, dat noemt de compiler een 'overflow'.
De compiler had ook kunnen zeggen: "Het getal past niet in een integer".

De compiler doet wat jij de compiler verteld. Je kunt 'UL' achter een getal zetten om aan te geven dat het een 'unsigned long' getal is. Dan gaat de compiler een berekening ook met 'unsigned long' doen.
Code: Alles selecteren
unsigned long inschakel_delay = 60UL;
...
if (millis() - timer1 > (inschakel_delay * 1000UL)) {


Wat wil je doen met een 64-bit "unsigned long long" ?
Was 50 dagen niet genoeg voor een timer ?

Je zou dit:
Code: Alles selecteren
// FSM states                                              // de diverse state van de FSM
#define idle_state 0
#define inschakelvertraging_state 10
#define bewakingvertraging_state 20
#define aan_state 30
#define alarm_state 40

// variables
int fsm_state = 0;
kunnen vervangen door dit:
Code: Alles selecteren
enum
{
  idle_state,
  inschakelvertraging_state,
  bewakingvertraging_state,
  aan_state,
  alarm_state,
} fsm_state = idle_state;


Een sketch met een FSM en millis() is een hele mooie combinatie. Waarom heb je dan zoveel delay() in je sketch ?

Je gebruikt "timer0" en ook de andere timers met een waarde nul als een boolean flag en ook als waarde van millis(). Dat zijn twee totaal verschillende dingen met dezelfde variabele.
Code: Alles selecteren
if (timer0 != 0) {
  if (millis() - timer0 > (sproeitijd * 60000)) {
    digitalWrite(sproei_uit, LOW);
    fsm_state = idle_state;
  }
}
Dit zie ik meer, maar ik ben er erg op tegen om doelbewust foute code te schrijven. Eerlijk gezegd begrijp ik niet eens waarom iemand zoiets zou doen. Stel dat sommige steden gebruik gaan maken van een horizontaal stoplicht met vier lichten: paars, paars, paars en blauw. Als alle lichten uit zijn, dan mag je doorrijden, behalve als de lichten uit zijn door een stroomstoring. Dan kunnen ze als commentaar geven: "meestal gaat het goed". Maar dat is natuurlijk geen argument.

Berichten: 88
Geregistreerd: 16 Jul 2015, 21:02

Re: probleem stack overflow met unsigned long?

Berichtdoor wim2584 » 26 Jul 2020, 11:20

Hallo Koepel,

ja dat eea niet goed geprogrammeerd is weet ik, ben meer hardware man... software bllijft lastig voor mij, (heb hier ook nooit les in gehad:))

maar bedankt voor je hulp, ik had zelf ook UL achter de 1000 gezet, maar bleef foutmelding houden, nadat ik ook "unsigned long inschakel_delay = 60UL;" is de fout weg.

de "long long" is nog een fout erin geslopen bij de diverse versies...

de mix van timers ook een beetje, door diverse try and error pogingen , om een werkende versie te krijgen, ik was al blij dat het werkte!.......

de delay's staan erin een iets rustiger verloop te krijgen, aangezienhet aan een waterpomp zit met drukschakelaar en lucht buffer, is alles nogal dynamisch, en kwam het gauw is een oscillate (pomp aan/uit/aan/ enz) , deze delays hielpen, maar uiteindelijke oplossing is de uitschakel en inschakel delay timer.

in ieder geval Bedankt!, en als ik een keer weer tijd heb... zal ik de timers beter proberen proberen te programmeren.. maar eerlijk gezegd blijf ik het timer verhaal in arduino lastig vinden, maar door diverse uitleg (is verschillende onderwerpen) van jou kant hier op het forum , toch het een en ander beetje begrepen, maar als je dat bezig bent , komen er fouten en dingen die niet werken, en probeer je andere dingen......

Groet Wim

Terug naar Arduino software

Wie is er online?

Gebruikers in dit forum: Geen geregistreerde gebruikers en 23 gasten