Iam using the RAK11720 and i want to use an external interrupt. But i have a problem that the interrupt is not running asynchronously while the code is running in a while loop as below
attachInterrupt(MainswitchInput, HandleMainSwitch, RISING);
volatile bool interruptOccurred = false; // Define a volatile flag to indicate interrupt occurrence
void HandleMainSwitch()
{
Conf.Mainswitch = !Conf.Mainswitch ; // Invert from low to high and high to low
interruptOccurred = true;
Serial.print("Mainswitch state");
Serial.println(Conf.Mainswitch);
save_at_setting(RWStateMainSwitch);
}
void manageSinglePumpSystem() {
interruptOccurred = false;
while(!Serial.available() > 0 || Conf.Mainswitch == 1){
Serial.println(Conf.Mainswitch);
Pump1_Management();
if(Serial.available() > 0 || Conf.Mainswitch == 0 ){
Serial.println(Conf.Mainswitch);
interruptOccurred = false;
break;
}
}
}
in the manageSinglePumpSystem() function i want to check if there is an interrupt of an external pin and then i want to step out of the while loop. But for some reason the code is running stock in the while loop and the interrupt is not working.
How is Conf.Mainswitch defined? Is it volatile as well?
Conf.Mainswitch is defined as volatile byte.
Is Conf.Mainswitch changed in the Pump1_Management() function?
no its not changed in the Pump1_Management() function. its only changing in te HandleMainSwitch() when an interrupt occurs.
What is Serial.println(Conf.Mainswitch); printing? Is Conf.Mainswitch ever changing?
When an interrupt occurs the Conf.Mainswitch is toggling like this
Conf.Mainswitch = !Conf.Mainswitch ;
Then its printing its value to check which state it is.
Why don’t you use the interruptOccurred flag itself to end the while loop?
I tried this before but the flag is not changing because the interrupt is not executing while its inside the “while” loop → while(!Serial.available() > 0 || Conf.Mainswitch == 1){
but if the interrupt works then i can use the `interruptOccurred to end the while loop.
So the point is, inside the while loop the interrupt is not calling, but outside the while loop the interrupt is working.
With the delay(100) its working! but there is another problem, its not allowed to use delays in the code because the code needs to run constantly… Is there another way to do this?
No, your while loop is blocking everything else without the delay.
Why is a delay of 100ms critical for your application?
From your code it looks like you are taking action when
(a) Conf.Mainswitch is changing
(b) something or nothing (don’t really understand what you are doing there) is available on the serial port
If that happens faster than in 100ms, you need another strategy.
If at some point you need to send data over LoRaWAN or LoRa P2P or BLE, this while loop will interfere with the transmission as well.
Well iam using it for a pump system to read the voltage and ampere values realtime and these are flucturating based on the solar panel. Based on different voltages and amperes i controll the pumps ( on/off ) so its neccesary that i dont have a lot of delay time.
The serial port is checking if a configuration tool is connected. When i connect a configuration tool it needs to stop the while loop, otherwise i cant change parameters.
Is there a way to use millis() instead of delay()?
i tried the following with millis() but the interrupt is only working with a delay().
void manageSinglePumpSystem() {
unsigned long previousMillis = 0;
const long interval = 100; // Interval in milliseconds
// Main loop
while (Conf.Mainswitch == 1) {
unsigned long currentMillis = millis();
// Check if Serial data is available or Mainswitch is turned off
if (Serial.available() > 0 || Conf.Mainswitch == 0) {
Serial.println("System Off");
break;
}
// Check if it's time to manage the pump
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis; // Save the last time we managed the pump
Serial.println("System On");
// Perform pump management
Pump1_Management();
}
}
}
@beegee , Thankyou very much for your help! Is there by the way a brownout interrupt available in the api or something like this? I want to save values to the flash memory if the main voltage crosses a certain voltage. Or is this only possible with creating my own “brownout” interrupt with a ADC measurement to check its voltage?