1

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");
  }
}
8
  • isr_flag needs to be declared as volatile. Please do this and try again
    – chrisl
    May 13, 2021 at 10:38
  • Hey @chrisl thanks for your reply. I changed it to volatile int isr_flag = 0; but unfortunaltely the problem is still present. May 13, 2021 at 12:29
  • Why are you using delayMicroseconds() for delaying 5s. I think the parameter type is only unsinged int. According to the Arduino documentation the max is 16383us. Please use delay() for such long delays. In older versions delayMicroseconds() also disabled interrupts. So that might be your problem
    – chrisl
    May 13, 2021 at 13:59
  • I used dealyMicroseconds() because I missunderstood the documentation of àttachInterrupt()` . Unfortunately using delay() 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. May 13, 2021 at 15:56
  • Can you please check, when exactly the ISR is executed (especially after the first delay() call), by connecting a LED and toggling it in the ISR (but not in the if statement, just in the ISR)?
    – chrisl
    May 13, 2021 at 16:18

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.