I have a strange problem with my ESP32 project. I use an ADPS-9960 for gesture control which triggers an external interrupt. In the interrupt handler itself I only set a variable that causes the execution of a function in the loop. When I trigger an interrupt during the delay function the interrupt stops working. This means the loop is still running, but the interrupt routine doesn't get executed anymore.
#include <Arduino.h>
#include <Wire.h>
#include <SparkFun_APDS9960.h>
#include <ESP32Servo.h>
// Pins
#define APDS9960_INT 25 // Needs to be an interrupt pin
#define SERVO 4
// Constants
// Global Variables
SparkFun_APDS9960 apds = SparkFun_APDS9960();
int isr_flag = 0;
void IRAM_ATTR interruptRoutine();
int detectorPin = 19;
Servo myservo;
void setup()
{
// Set interrupt pin as input
pinMode(APDS9960_INT, INPUT_PULLUP);
// Initialize Serial port
Serial.begin(9600);
Serial.println();
Serial.println(F("--------------------------------"));
Serial.println(F("SparkFun APDS-9960 - GestureTest"));
Serial.println(F("--------------------------------"));
// Initialize interrupt service routine
attachInterrupt(digitalPinToInterrupt(APDS9960_INT), interruptRoutine, FALLING);
// Initialize APDS-9960 (configure I2C and initial values)
if ( apds.init() )
{
Serial.println(F("APDS-9960 initialization complete"));
}
else
{
Serial.println(F("Something went wrong during APDS-9960 init!"));
}
apds.setGestureGain(GGAIN_1X); // ohne diese Zeile geht es nicht zuverlässig
// Start running the APDS-9960 gesture sensor engine
if ( apds.enableGestureSensor(true) )
{
Serial.println(F("Gesture sensor is now running"));
}
else
{
Serial.println(F("Something went wrong during gesture sensor init!"));
}
myservo.attach(SERVO);
myservo.write(20);
pinMode(detectorPin, INPUT);
}
void loop()
{
if( isr_flag == 1 )
{
detachInterrupt(digitalPinToInterrupt(APDS9960_INT));
handleGesture();
isr_flag = 0;
attachInterrupt(digitalPinToInterrupt(APDS9960_INT), interruptRoutine, FALLING);
}
if(digitalRead(detectorPin))
Serial.println("ON");
else
Serial.println("OFF");
}
void IRAM_ATTR interruptRoutine()
{
if(isr_flag == 0)
isr_flag = 1;
}
void handleGesture()
{
if ( apds.isGestureAvailable() )
{
if( apds.readGesture() == DIR_FAR )
{
Serial.println("FAR");
myservo.write(165);
delayMicroseconds (5000000);
myservo.write(20);
}
else
Serial.println("FALSE");
}
}
isr_flag
needs to be declared asvolatile
. Please do this and try againvolatile int isr_flag = 0;
but unfortunaltely the problem is still present.delayMicroseconds()
for delaying 5s. I think the parameter type is onlyunsinged int
. According to the Arduino documentation the max is 16383us. Please usedelay()
for such long delays. In older versionsdelayMicroseconds()
also disabled interrupts. So that might be your problemdealyMicroseconds()
because I missunderstood the documentation of àttachInterrupt()` . Unfortunately usingdelay()
didn't solve the problem, if an interrupt appears during the delay function I am still not able to enter the interrupt after this. The problem is very hard to localize as there seems no good way to debug in the Arduino IDE.delay()
call), by connecting a LED and toggling it in the ISR (but not in the if statement, just in the ISR)?