ESP32 больше не может вводить прерывание после появления прерывания во время функции delayMicrosecond
У меня странная проблема с моим проектом ESP32. Я использую ADPS-9960 для управления жестами, который запускает внешнее прерывание. В самом обработчике прерываний я задаю только переменную, которая вызывает выполнение функции в цикле. Когда я запускаю прерывание во время функции задержки, прерывание перестает работать. Это означает, что цикл все еще выполняется, но процедура прерывания больше не выполняется.
#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");
}
}
@FriendlyGuest, 👍1
Обсуждение0
Смотрите также:
- Постоянная частота дискретизации АЦП на ESP8266 или ESP32
- Как избежать электромагнитных помех на входе ESP32
- Присоедините функцию Arduino ISR к члену класса
- Внешние прерывания Esp32 иногда отсутствуют
- Как реализовать детектор brown out arduino ESP32?
- Чтение внутренних критических разделов из ISR
- Анимация светодиодной ленты с ESP32 не работает при использовании WiFi
- RFM95 digital io для управления отключением звука на PAM8403, чтобы избавиться от шипения во время приема
isr_flag
должен быть объявлен как "изменчивый". Пожалуйста, сделайте это и повторите попытку, @chrislЭй, @chrisl, спасибо за ваш ответ. Я изменил его на " volatile int isr_flag = 0;", но, к сожалению, проблема все еще присутствует., @FriendlyGuest
Почему вы используете " delayMicroseconds()
для задержки 5 секунд. Я думаю, что тип параметра-это только " unsinged int
. Согласно документации Arduino, максимальное значение составляет 16383us. Пожалуйста, используйте "задержка ()" для таких длительных задержек. В более старых версиях " delayMicroseconds()` также отключал прерывания. Так что это может быть вашей проблемой, @chrislЯ использовал " dealyMicroseconds ()", потому что я неправильно понял документацию " attachInterrupt ()". К сожалению, использование
delay()
не решило проблему, если во время функции задержки появляется прерывание, я все еще не могу ввести прерывание после этого. Проблему очень трудно локализовать, так как, похоже, нет хорошего способа отладки в среде IDE Arduino., @FriendlyGuestНе могли бы вы, пожалуйста, проверить, когда именно выполняется ISR (особенно после первого вызова " задержка ()"), подключив светодиод и переключив его в ISR (но не в операторе if, а только в ISR)?, @chrisl
@крис Еще раз спасибо за ответ. Когда я делаю жест во время задержки, ISR, похоже, не выполняется, так как индикатор не переключается. Я посмотрел в справочном примере и заметил кое-что странное. Они объявляют 2 как контакт прерывания, но затем используют 0 в attachInterrupt/detachInterrupt, это должно быть ошибкой, верно? [link](https://github.com/sparkfun/APDS-9960_RGB_and_Gesture_Sensor/blob/master/Libraries/Arduino/APDS-9960_RGB_and_Gesture_Sensor_Arduino_Library/examples/GestureTest/GestureTest.ino), @FriendlyGuest
Мхх, теперь я больше не вижу причин, по которым ISR не должен срабатывать снова после 5 секунд и движения сервопривода. Вы уверены, что проблема в задержке? Может быть, удалите его и повторите попытку. В настоящее время я немного копаюсь в темноте, @chrisl
Да, я почти уверен, что это должно что-то сделать с задержкой, потому что, когда я использую жест, который вызывает выполнение блока else в " handleGesture ()", кажется, проблем нет. Дальше я попробую использовать простую кнопку для внешнего прерывания и посмотрю, не изменится ли что-нибудь. Спасибо за вашу поддержку до сих пор!, @FriendlyGuest