WiFi interfering with my own Interrupt function.
Posted: Thu Jun 15, 2023 3:47 pm
What am I doing wrong?
I want to use a ESP32 to receive signals from 433Mhz, take that message and place on a MQTT topic.
My code below works until I add WiFi.
The circuit is simple. I have a ESP32 WROOM and connected to GPIO35 is a QAM_RX 433Mhz receiver
My code basically sets up an function to trigger on an Interrupt of when the state changes on GPIO35.
In that function I record the time (millis) and then when the state changes and calls the Interrupt I record the time and take the difference. I then record the duration of my and its state in an array of struct called PULSE.
Of course the function first looks for a preample before recording and likewise a postample to stop.
Simple enough.
Compile the code and press a button a 433 device I have and bingo my code display the recorded message in the PULSE buffer.
My problem comes when I add the WiFi library. The extra code is enabled by the #define. At the moment I simply initate the library and connect to my MyWifi, nothing else.
At this point my code stops working. Sometimes my code detects the preample but never a full message.
I tried running my code on Core0 so the WiFi could have core1, but that didn't work.
What am I missing?
I read in the forums of people having trouble with WiFi interfering with Timers, but my interrupt is being triggered by state change on GPIO35.
I know from previous tests (without WiFi enabled) my received single was giving me 132 elements in my PULSE buffer. So I tried adding a counter to see how many times my function was being triggered when the WiFi was enabled. If answer was variable and never once did I get 132.
Any ideas?
I want to use a ESP32 to receive signals from 433Mhz, take that message and place on a MQTT topic.
My code below works until I add WiFi.
The circuit is simple. I have a ESP32 WROOM and connected to GPIO35 is a QAM_RX 433Mhz receiver
My code basically sets up an function to trigger on an Interrupt of when the state changes on GPIO35.
In that function I record the time (millis) and then when the state changes and calls the Interrupt I record the time and take the difference. I then record the duration of my and its state in an array of struct called PULSE.
Of course the function first looks for a preample before recording and likewise a postample to stop.
Simple enough.
Compile the code and press a button a 433 device I have and bingo my code display the recorded message in the PULSE buffer.
My problem comes when I add the WiFi library. The extra code is enabled by the #define. At the moment I simply initate the library and connect to my MyWifi, nothing else.
At this point my code stops working. Sometimes my code detects the preample but never a full message.
I tried running my code on Core0 so the WiFi could have core1, but that didn't work.
What am I missing?
I read in the forums of people having trouble with WiFi interfering with Timers, but my interrupt is being triggered by state change on GPIO35.
I know from previous tests (without WiFi enabled) my received single was giving me 132 elements in my PULSE buffer. So I tried adding a counter to see how many times my function was being triggered when the WiFi was enabled. If answer was variable and never once did I get 132.
Any ideas?
Code: Select all
#define BASEPROTOCOL433_RX_PREAMPLE_THRESOLD_MIN 8000
#define BASEPROTOCOL433_RX_PREAMPLE_THRESOLD_MAX 25000
#define RAWBITBUFFERSIZE 150
// Declare states that we can be in
#define BASEPROTOCOL433_RX_LISTENMODE 0x00 // Listening for a message to start on the RX
#define BASEPROTOCOL433_RX_RECEIVEMODE 0x01 // Currently receiving a message over RX
#define BASEPROTOCOL433_RX_MESSAGERECEIVED 0x02 // Received a complete message
#define BASEPROTOCOL433_SETUP 0xF0
// Struct which is used to store received pulses in a buffer
typedef struct {
bool state; // state 0 or 1 (Boolean)
unsigned int duration; // duration of the state in ms
} PULSE;
//#define USE_WIFI
#ifdef USE_WIFI
const char* wifi_ssid = "MyWiFi";
const char* wifi_password = "0101010101";
const char* wifi_hostname = "ESP32";
#include <WiFi.h>
#endif
#include <Arduino.h>
TaskHandle_t Task1;
volatile PULSE rawBitBuffer[RAWBITBUFFERSIZE];
volatile unsigned int rawBitBufferPosition = 0;
volatile byte baseProtocolState = BASEPROTOCOL433_SETUP;
volatile unsigned long lastRedTime = 0;
void IRAM_ATTR qam_rx4_isr() {
static unsigned int prevTime = 0; // lastTime
unsigned int newTime = micros(); // now
// Calculate the duration of the current signal state
unsigned int duration = newTime - prevTime;
bool state = digitalRead(35);
// If we find the preample (4.5ms < x < 12.5ms) trigger baseProtocolState to receiving mode
if ((duration > BASEPROTOCOL433_RX_PREAMPLE_THRESOLD_MIN) && (duration < BASEPROTOCOL433_RX_PREAMPLE_THRESOLD_MAX) ) {
if (baseProtocolState == BASEPROTOCOL433_RX_RECEIVEMODE) {
baseProtocolState = BASEPROTOCOL433_RX_MESSAGERECEIVED;
detachInterrupt(35);
} else {
baseProtocolState = BASEPROTOCOL433_RX_RECEIVEMODE;
}
}
if (baseProtocolState == BASEPROTOCOL433_RX_RECEIVEMODE) {
// Store the duration of the received pulse
rawBitBuffer[rawBitBufferPosition].state = !state;
rawBitBuffer[rawBitBufferPosition].duration = duration;
rawBitBufferPosition++;
}
// Check for a buffer overflow
if (rawBitBufferPosition == (RAWBITBUFFERSIZE - 1)) {
baseProtocolState =BASEPROTOCOL433_RX_LISTENMODE;
rawBitBufferPosition = 0;
}
prevTime = newTime;
}
void loop2(void * parameter) {
// loop2 runs on Core0
int x;
while(true) {
if (baseProtocolState == BASEPROTOCOL433_SETUP) {
attachInterrupt(digitalPinToInterrupt(35), qam_rx4_isr, CHANGE);
baseProtocolState = BASEPROTOCOL433_RX_LISTENMODE;
}
if (baseProtocolState == BASEPROTOCOL433_RX_MESSAGERECEIVED) {
for (x = 0; x <= rawBitBufferPosition; x++) {
Serial.print("x = ");
Serial.print(x);
Serial.print(", S = ");
Serial.print(rawBitBuffer[x].state);
Serial.print(", D = ");
Serial.println(rawBitBuffer[x].duration);
}
Serial.print("loop2() - core# ");
Serial.println(xPortGetCoreID());
baseProtocolState = BASEPROTOCOL433_RX_LISTENMODE;
attachInterrupt(digitalPinToInterrupt(35), qam_rx4_isr, CHANGE);
}
}
}
void setup() {
Serial.begin(115200);
rawBitBufferPosition = 0;
baseProtocolState = BASEPROTOCOL433_SETUP;
// Run my main code on Core0
xTaskCreatePinnedToCore(loop2, "qam_rx_task", 20000, NULL, 1, NULL, 0);
#ifdef USE_WIFI
Serial.println("calling setup_wifi()");
WiFi.disconnect(true);
delay(1000);
// Set the WiFi into Station Mode
WiFi.mode(WIFI_STA);
// Set the hostname
WiFi.setHostname(wifi_hostname);
// Start the WiFi
WiFi.begin(wifi_ssid, wifi_password);
// Wait for WiFi to connect
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(WiFi.status());
}
#endif
Serial.println("Setup() done");
}
void loop() {
// This loop should be on core1 and isn't doing anything apart from display the core its running on.
// Should be core1
unsigned long now = millis();
if (now - lastRedTime > 2000) {
Serial.print("loop() - core# ");
Serial.println(xPortGetCoreID());
lastRedTime = now;
}
}