'huge variations using two concurrent ISR in ESP32
I've tried to use a pair of proximity sensors for measuring two identical motor speed I used the esp32, with double ISR and counting the duration between puless however, the plot shows when motor speeds are low the calculation nearly each other and converge but when motor speed increases the calculation for both motors have huge variations and diverge since high speed means a high number of interrupt triggers and HW triggers can happen both without any priority
this is my code
#include "driver/gpio.h"
//PULSE INPUT 0
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
int RPM_0_RESET = 0;
//portMUX_TYPE synch = portMUX_INITIALIZER_UNLOCKED;
#define PULSE_IN_0_PIN 15 //25-G1
volatile double pulseTime_0, lastTime_0;
volatile double pulse_freq_0;
void ICACHE_RAM_ATTR isr_pulse_0() {
//used to measure time between pulses.
//portENTER_CRITICAL(&synch);
lastTime_0 = pulseTime_0;
pulseTime_0 = micros();
pulse_freq_0 = (pulseTime_0 - lastTime_0);
//portEXIT_CRITICAL(&synch);
}
int RPM_1_RESET = 0;
//portMUX_TYPE synch = portMUX_INITIALIZER_UNLOCKED;
#define PULSE_IN_1_PIN 25 //25-G1
volatile double pulseTime_1, lastTime_1;
volatile double pulse_freq_1;
void ICACHE_RAM_ATTR isr_pulse_1() {
//used to measure time between pulses.
//portENTER_CRITICAL(&synch);
lastTime_1 = pulseTime_1;
pulseTime_1 = micros();
pulse_freq_1 = (pulseTime_1 - lastTime_1);
//portEXIT_CRITICAL(&synch);
}
//SEQUENCER
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
#define telem_time_interval 200 //Time in ms
unsigned long telem_time = 0;
void setup() {
delay(2000);
//Serial
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Serial.begin(115200);
//PULSE INPUT 0 - RPM FEEDBACK
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
pinMode(PULSE_IN_0_PIN, INPUT);
//attachInterrupt(PULSE_IN_0_PIN, isr_pulse_0, FALLING);
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
pinMode(PULSE_IN_1_PIN, INPUT);
}
void loop() {
if (millis() > telem_time + telem_time_interval)
{
detachInterrupt(PULSE_IN_0_PIN);
detachInterrupt(PULSE_IN_1_PIN);
Serial.print(6000000/pulse_freq_0);
Serial.print(",");
Serial.println(6000000/pulse_freq_1);
telem_time = millis();
attachInterrupt(PULSE_IN_0_PIN, isr_pulse_0, RISING);
attachInterrupt(PULSE_IN_1_PIN, isr_pulse_1, RISING);
}
}
also, I've tried to use a semaphore to sync between interrupts however, its shows that one of the interrupts has very high variation
#include "driver/gpio.h"
//PULSE INPUT 0
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
#if CONFIG_FREERTOS_UNICORE
static const BaseType_t app_cpu = 0;
#else
static const BaseType_t app_cpu = 1;
#endif
int RPM_0_RESET = 0;
//portMUX_TYPE synch = portMUX_INITIALIZER_UNLOCKED;
#define PULSE_IN_0_PIN 15 //25-G1
volatile double pulseTime_0, lastTime_0;
volatile double pulse_freq_0;
#define telem_time_interval 200 //Time in ms
unsigned long telem_time = 0;
static SemaphoreHandle_t bin_sem = NULL;
int RPM_1_RESET = 0;
//portMUX_TYPE synch = portMUX_INITIALIZER_UNLOCKED;
#define PULSE_IN_1_PIN 25 //25-G1
volatile double pulseTime_1, lastTime_1;
volatile double pulse_freq_1;
void calculator(void *parameters){
while(1)
{
//Serial.println("wait for ");
xSemaphoreTake(bin_sem, portMAX_DELAY);
if (millis() > telem_time + telem_time_interval)
{
Serial.print(6000000/pulse_freq_0);
Serial.print(",");
Serial.println(6000000/pulse_freq_1);
telem_time = millis();
}
xSemaphoreGive(bin_sem);
}
}
void ICACHE_RAM_ATTR isr_pulse_0() {
//used to measure time between pulses.
//portENTER_CRITICAL(&synch);
lastTime_0 = pulseTime_0;
pulseTime_0 = micros();
pulse_freq_0 = (pulseTime_0 - lastTime_0);
xSemaphoreGiveFromISR(bin_sem,0);
//portYIELD_FROM_ISR();
// if (task_woken)
//portEXIT_CRITICAL(&synch);
}
void ICACHE_RAM_ATTR isr_pulse_1() {
//used to measure time between pulses.
//portENTER_CRITICAL(&synch);
lastTime_1 = pulseTime_1;
pulseTime_1 = micros();
pulse_freq_1 = (pulseTime_1 - lastTime_1);
xSemaphoreGiveFromISR(bin_sem, 0);
//
//portEXIT_CRITICAL(&synch);
}
//SEQUENCER
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
void setup() {
delay(2000);
//Serial
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Serial.begin(115200);
//PULSE INPUT 0 - RPM FEEDBACK
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
pinMode(PULSE_IN_0_PIN, INPUT);
//attachInterrupt(PULSE_IN_0_PIN, isr_pulse_0, FALLING);
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
pinMode(PULSE_IN_1_PIN, INPUT);
bin_sem = xSemaphoreCreateBinary();
// xSemaphoreGiveFromISR(bin_sem,0);
attachInterrupt(digitalPinToInterrupt(PULSE_IN_0_PIN), isr_pulse_0, FALLING);
attachInterrupt(digitalPinToInterrupt(PULSE_IN_1_PIN), isr_pulse_1, FALLING);
Serial.println(" Fan tacho detection sucessfully initialized.");
xTaskCreatePinnedToCore(calculator,
"Print values",
1024,
NULL,
2,
NULL,
app_cpu);
}
void loop() {
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
