With interrupts declared, when calling ledcWriteTone() to activate a buzzer, some internal conflict arises that causes the interrupt to be triggered continuously.
I have 5 SPDT physical switches (to function as DIP switches) connected to 5 pins in an ESP32. If all pins are HIGH, all is good. One pin (any pin) can change to LOW and all is good (including the "click" sound generated by the buzzer). But once a second pin changes to LOW, its ISR is triggered continuously. When disabling the call to ledcWriteTone(), any combination of pins cans change and all is good.
I tried several tones, durations and channels for the buzzer's ledcAttachPin() (the ESP32 has 16 channels for this function) and even tried declaring the ISR without the "IRAM_ATTR" qualifier (to force it into flash vs RAM). No luck.
I'm using the Arduino-ESP32 core ver 2.0.4. I found some references of conflict between PWM (especially w/stepper motors) and interrupts but all for older versions of the core (pre 2.0).
The (awesome) sequence to create the 5 ISR's using parameters was provided by @killzone_kid here: (Are you basically looking to pass an argument to the interrupt routine?)
Any leads, thoughts or previous experiences?
Thanks!
//---declarations for interrupts
typedef struct {
const uint8_t PIN;
bool changed;
bool value;
} fSwitch;
// SPDT switches connected to pins 27,33,15,32,14 (all adjacent in the Adafruit ESP32 Feather V2)
fSwitch FS[5] = {{27,0,0},{33,0,0},{15,0,0},{32,0,0},{14,0,0}};
volatile bool sFlag = false;
void IRAM_ATTR chkFS(void *arg) {
fSwitch *fs = static_cast<fSwitch *>(arg);
fs->changed = true;
fs->value = digitalRead(fs->PIN);
sFlag = true;
}
//---declarations for Buzzer
int buzzPin = 12;
int buzzChan = 0;
long buzzTimer = 0;
void setup() {
Serial.begin(115200);
Serial.println("Start");
for (byte i=0; i<5; i++) {
pinMode(FS[i].PIN,INPUT);
FS[i].value = digitalRead(FS[i].PIN); // initial state of each switch
Serial.println("Initial State FS" + String(i) + "=" + String(FS[i].value));
attachInterruptArg(FS[i].PIN,chkFS,&FS[i],CHANGE);
}
ledcAttachPin(buzzPin, buzzChan);
}
void loop() {
if (sFlag) { // if any PIN has changed
ledcWriteTone(buzzChan,300);
buzzTimer = millis();
sFlag = false;
for (byte i=0; i<5; i++)
if (FS[i].changed) { // determine which PIN changed
Serial.println("Changed State FS" + String(i) + "=" + String(FS[i].value));
FS[i].changed = false;
}
}
if (millis() - buzzTimer > 40) ledcWriteTone(buzzChan,0);
}


