I'm not entirely sure what is going wrong here.
Hardware
ESP32 Microcontroller. Attached to 8 neopixels, and a button with pull-up resistors going through a schmitt trigger (for learning).
Software/libraries
I'm using FastLED and the ESP32 Wifi libraries.
My code is below.
What I expected to happen.
I have multiple 'color presets' I want to cycle through when I push the button. I want debouncing on the button. When I push the button, it should change the presets ONCE.
What actually happens
If I do NOT enable WiFi. Meaning I comment out the 'setup_wifi()' line in setup(). Then everything works correctly. I push the button once and hold it down, I get ONE change to the next preset light cycle. This uses my 100msec debounce in the ISR routine.
But, if I uncomment setup_wifi() to turn it on. And then press and hold the button, it continuously cycles through each of my preset light configurations. Without stopping and without really much of a delay..
Then, if I leave wifi enabled. But I change the 100msec delay to like ~225 or above (maybe 250? and above). And then I push and hold the button, it goes back to working. One press and hold gets ONE change of lights. And then I release and press again and it works.
Thoughts
If I have to, I could leave it at a debounce of 250. But I tend to push fast, and would really like a debounce of 100 or even less (I was hoping a schmitt trigger would let me get to like 50-75, but that's a story for a different topic).
But at the very least I'd like to understand what is happening here. Because my code seems to work okay on its own. Just not with the WiFi enabled.
I'm assuming WiFi does something with the interrupts or some other sort of conflict causing my interrupts to be called oddly. But I honestly have no real idea.
So can someone explain to me what is happening? And is there a fix to allow wifi to be enabled, have a short debounce of <=100, and only cycle one preset light at a time?
Code
This code reproduces the problem on my setup. The long (*) sections point to where I change things to make it work/not work.
#include <FastLED.h>
#include <WiFi.h>
// WIFI
char ssid[] = "##";
const char* password = "##";
// Static IP Stuff
IPAddress local_IP(##);
IPAddress gateway(10, 23, 24, 1);
IPAddress subnet(255, 255, 255, 0);
IPAddress primaryDNS(8, 8, 8, 8);
IPAddress secondaryDNS(8, 8, 4, 4);
// The definitions to control the actual LEDs through the FastLED library
#define LED_PIN 23
#define NUM_LEDS 8
#define BRIGHTNESS 15 // Up to 255
#define LED_TYPE WS2812B
#define COLOR_ORDER GRB
CRGB leds[NUM_LEDS];
// Set up some pallete variables to be used later
CRGBPalette16 currentPalette;
TBlendType currentBlending;
// Set up the buttons(as struct) for controlling the lights
struct Button {
const uint8_t PIN; // Pin the button is attached to
uint32_t station; // station we are 'at'. 0 = white, 1 = rainbow, etc
bool pressed; // last pressed value (true/false)
};
Button btn01 = {39, 0, false};
/*
* Intterrupt for button push
*/
void IRAM_ATTR btnISR() {
static unsigned long last_interrupt_time = 0;
unsigned long interrupt_time = millis();
// ************************************************
// If I make this 100 changed to 250, i have no issue
// ***************************************************
if (interrupt_time - last_interrupt_time > 100)
{
// Do stuff here
btn01.pressed = true;
btn01.station += 1;
if (btn01.station >= 4) {
btn01.station = 0;
}
}
last_interrupt_time = interrupt_time;
}
/*
* setup_wifi()
*/
void setup_wifi() {
// This calls the config to load in the static stuff
if (!WiFi.config(local_IP, gateway, subnet, primaryDNS, secondaryDNS)) {
Serial.println("STA Failed to configure");
}
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi Connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
} // end setup_wifi
/*
* fillLEDsFromPalette()
*/
void fillLEDsFromPalette( uint8_t colorIndex ) {
uint8_t brightness = 35;
for (int i = 0; i < NUM_LEDS; i++) {
leds[i] = ColorFromPalette( currentPalette, colorIndex, brightness, currentBlending );
colorIndex += 3;
}
}
void setup() {
Serial.begin(115200);
// *********************************************
// Or If I comment out this, and don't initialize wifi, everything works as expected
// **********************************************
//setup_wifi();
pinMode(btn01.PIN, INPUT);
attachInterrupt(digitalPinToInterrupt(btn01.PIN), btnISR, RISING);
delay( 1500 ); // power-up safety delay
FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS);
FastLED.setBrightness( BRIGHTNESS );
currentBlending = LINEARBLEND;
} // end setup()
void loop() {
static uint8_t startIndex = 0;
startIndex = startIndex + 1;
if (btn01.station == 0 and btn01.pressed) {
Serial.println("White");
for( int i = 0; i < NUM_LEDS; i++) {
leds[i] = CRGB::White;
}
btn01.pressed = false;
}
if (btn01.station == 1 and btn01.pressed) {
Serial.println("Red");
for( int i = 0; i < NUM_LEDS; i++) {
leds[i] = CRGB::Red;
}
btn01.pressed = false;
}
if (btn01.station == 2 and btn01.pressed) {
Serial.println("Green");
for( int i = 0; i < NUM_LEDS; i++) {
leds[i] = CRGB::Green;
}
btn01.pressed = false;
}
if (btn01.station == 3) {
Serial.println("Rainbow");
currentPalette = RainbowColors_p;
fillLEDsFromPalette( startIndex );
btn01.pressed = false;
}
FastLED.show();
FastLED.delay(50);
} // end void loop()