Met deze code verwacht bij het starten van het programma dat de vlag Monitor_print false is en er dus geen actie op de monitor te zien is.
Dat is ook wat er gebeurd.
Vervolgens trek ik pin 2 laag waarna ik verwacht dat de vlag true wordt en dus in de loop er continue naar de monitor geschreven wordt maar tot mijn verbazing stopt het schrijven zodra pin 2 weer hoog is. Toch schrijf ik nergens Monitor_print weer false.........
Ik snap er niets van en hoop dat iemand me uitleg kan geven.
/* Testprogramma om een vlag te zetten
*/
// Library's --------------------------------------------
// Constanten ---------------------------------------------
int LEDpin = 13;
// Objecten -----------------------------------------------
// Globale variabelen -------------------------------------
volatile bool Monitor_print = false;
volatile int state = LOW;
// Programma ----------------------------------------------
void setup() {
Serial.begin(9600); // communicatie snelheid serial monitor
pinMode(LEDpin, OUTPUT);
pinMode (2,INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(2), blink, LOW);
}
void loop() {
digitalWrite(LEDpin, state);
if (Monitor_print == true)
Serial.println("Gedrukt");
}
void blink() {
state = !state;
Monitor_print = true;
}
// Einde Programma en compile directive ==================
#if !defined(ARDUINO_AVR_UNO )|| defined(ARDUINO_AVR_NANU_EVERY)
#error "Oeps! 'Uno'is niet geselekteerd als board."
#elif defined(__AVR_ATmega2560__)
#error "Oeps! 'Mega'is geselekteerd als board."
#endif
/*#if defined(ESP32)
#if defined(ESP8266)
#if defined(ARDUINO_RASPBERRY_PI_PICO
#if !defined(ARDUINO_AVR_UNO)
D:\Programfiles(x86)\Arduino1.8.15\examples\01 basics\bareminimum
*/
De onderbreking is niet op een flank (FALLING), maar op LAAG. Dus zolang je LAAG bent, wordt de onderbreking zo snel herhaald dat de loop() geen tijd heeft om uit te voeren.
zet achter die pull up even een delay dan heeft de arduino ook tijd om de pin naar HIGH te trekken en het laag trekken gaat zo snel langzaam dat jouw blink wel tig keer gedaan wordt.
/* Testprogramma om een vlag te zetten
* Bij gebruik van een interrupt met als trigger LOW, gaat de onderbreking
* zo snel dat de loop geen tijd heeft om uitgevoerd te worden.
* verander de LOW in FALLING en het programma doet wat wordt verwacht.
*
*/
// Library's --------------------------------------------
// Constanten ---------------------------------------------
int LEDpin = 13;
// Objecten -----------------------------------------------
// Globale variabelen -------------------------------------
volatile bool Monitor_print = false;
volatile int state = LOW;
unsigned long VorigeMillis = millis();
// Programma ----------------------------------------------
void setup() {
Serial.begin(9600); // communicatie snelheid serial monitor
pinMode(LEDpin, OUTPUT);
pinMode (2, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(2), blink, LOW);
}
void loop() {
digitalWrite(LEDpin, state);
if (Monitor_print == true)
Serial.println("Probeer FALLING en LOW");
/* Zie uitleg J-M-L in post 6 en Sterretje in post 12
if (millis() >= VorigeMillis + 5000)
{ Monitor_print = false;
VorigeMillis = millis();
}
*/
if (millis() - VorigeMillis >= 5000)
{ Monitor_print = false;
VorigeMillis = millis();
}
}
void blink() {
state = !state;
Monitor_print = true;
}
// Einde Programma en compile directive ==================
#if !defined(ARDUINO_AVR_UNO )|| defined(ARDUINO_AVR_NANU_EVERY)
#error "Oeps! 'Uno'is niet geselekteerd als board."
#elif defined(__AVR_ATmega2560__)
#error "Oeps! 'Mega'is geselekteerd als board."
#endif
/*#if defined(ESP32)
#if defined(ESP8266)
#if defined(ARDUINO_RASPBERRY_PI_PICO
#if !defined(ARDUINO_AVR_UNO)
D:\Programfiles(x86)\Arduino1.8.15\examples\01 basics\bareminimum
*/
Ook dat werkt niet want als millis() na zo'n 50 dagen weer naar nul gaat staat er feitelijk:
als iets meer dan 0 minus een giga getal groter of gelijk is aan 5000.....
de uitkomst van de som is dan negatief en dus nooit groter dan of gelijk aan 5000
Wanneer men werkt met unsigned long, wordt het getal nooit negatief.
Vertrouw me, dit is hoe je het moet doen. Altijd aftrekken, nooit optellen, en je zult geen problemen hebben wanneer millis overloopt vanwege de manier waarop ondertekende modulo-aritmetica werkt.
Onderstaand programma is een demonstratie waar je geen 49 dagen hoeft te wachten maar slechts iets meer dan een minuut. We gebruiker hier geen uint32_t (unsigned long) om de tijden op te slaan maar een uint16_t (unsigned int) en daarom gaat het ruw weg 65000 keer sneller.
Hoi Ster,
Dank voor je progje. Dit maakt het antwoord van J-M-L een heel stuk duidelijker.
Er is iets in de output wat me verbaasde. Zoals ik al had verwacht is de berekening in timestamp 13.770 negatief dus in mijn beleving had de if niet uitgevoerd mogen worden. (464 minus 65000) maar is de output toch 1000 .....
De rekenregels van een computer zijn blijkbaar toch iets anders dan de logica van mensen. Dat is iets waar ik bijzonder goed rekening mee moet houden blijkbaar.
Het komt erop neer dat we niet gewend zijn om wiskundige bewerkingen uit te voeren in gehele getallen zonder een teken met een modulo.
Maar er zijn momenten waarop het eigenlijk heel natuurlijk aanvoelt: bijvoorbeeld, als ik je vraag hoeveel uren er tussen maandag 23.00 uur en de volgende dag om 1.00 uur zijn, dan doe je mentaal 1 uur - 23 uur en zeg je niet tegen jezelf "-22 uur geleden", maar eerder "2 uur geleden"...
Eigenlijk voer je dan wiskunde uit in gehele getallen zonder een teken met een modulo 24 :)