probleem stack overflow met unsigned long?
3 berichten
• Pagina 1 van 1
probleem stack overflow met unsigned long?
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 inschakel
Vraag wat heb ik fout gedaan?
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 inschakel
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
Re: probleem stack overflow met unsigned long?
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.
Wat wil je doen met een 64-bit "unsigned long long" ?
Was 50 dagen niet genoeg voor een timer ?
Je zou dit:
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.
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;
- 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;
}
}
Re: probleem stack overflow met unsigned long?
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
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
3 berichten
• Pagina 1 van 1
Wie is er online?
Gebruikers in dit forum: Geen geregistreerde gebruikers en 23 gasten