How fast esp32 can read interrupt pulses

i have a scooter wheel (10 inch) and i want to measure speed of it.

there is built in hall sensor(5v) which is going low/high 30 times for 1 full wheel rotation

so i used 10k/20k voltage devider to make 5v 3.3v and i try to read in esp32

its working ok but my question is . if wheel rotate 25kmh it means it need to make 1 full rotation for 11.5milliseconds which is 30 pulses

is esp32 able to read 30 pulses for 11.5 milliseconds?

const int gpio_pulse_IN_M2 = 2; // Change this to the desired GPIO pin

volatile int M2_pulseCount = 0;
volatile int M2_lastState = LOW;

void setup() {
  Serial.begin(9600);
  pinMode(gpio_pulse_IN_M2, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(gpio_pulse_IN_M2), M2_pulseCounter, CHANGE);
}

void loop() {
  if (Serial.available()) {
    Serial.print("Pulse Count: ");
    Serial.println(pulseCount/30);
  }

  delay(1000); // You can add a delay or perform other tasks in your loop
}

void M2_pulseCounter() {
  int currentState = digitalRead(gpio_pulse_IN_M2);
  if (currentState != lastState) {
    M2_pulseCount++;
    M2_lastState = currentState;
  }
}

That would be 2609 pulses/second. No problem.

yes, unless your code does something silly, such as trying to send a lot of serial characters for each pulse, or inserts any delay() in the process.

This, however, seems strange. On every interrupt, the interrupt pin will of course be the same as the previous time it was triggered, because that's the reason the interrupt code runs. So, you might get a count on the first pass through, but after that, you'll never increase your counter.

Really? The interrupt mode is set to CHANGE.....

1 Like

@arpa123
Checking if the pin changed state is superfluous since the interrupt can only occur if it does change state.

All you need in the ISR is to increment pulse count and 2609 pps is no problem

2 Likes

Check your mathematics. I think you are out by a factor of 10.

11.5ms per revolution is 1000/11.5 = 86.96 rpm
wheel circumference = 10 * 25.4 * Pi = 798mm = 0.798m

distance travelled in 1 second = 86.96 * 0.798 = 69.4m/s

69.4m/s * 3600/1000 ≈ 250km/h

However this mistake only makes it easier to read the pulses as they are at a frequency 1/10th of what you thought.

Yep Missed that detail.

Hmm. If there's a character, Send message. wait a second. Send message. Wait a second. Send message. You never remove the character, so it will always be there, once you've sent one. If you never send a character, there's nothing in the buffer, so false, so no printing.

This is an ESP32, so you've got a 32 bit counter going.
So, what is it you're seeing that made you ask your question?

attachInterrupt(digitalPinToInterrupt(gpio_pulse_IN_M2), M2_pulseCounter, FALLING);

then


void M2_pulseCounter() {
    M2_pulseCount++;
  }

so if i set to falling then 1 full rotation = M2_pulseCount+15

so in this form i get speed of it

my question was if this will be like 30kmh is this ok for esp32 to read pulses coz will be a lot of pulses per second

byte kmh=(((M2_pulseCount - M2_last_pulseCount)*0.05318 )/ ((millis() - ms_last_pulse) / 1000)) * 3.6;

   
  M2_last_pulseCount = M2_pulseCount;
  ms_last_pulse = millis();

Next time I do the same.....

experimented with 2609pulses/second 80uSec wide
ESP32 code using external interrupts on CHANGE

// ESP32 determine pulses/sec and HIGH pulse width in microseconds

#define RXPIN 16

// pulse/sec and average pulse width time
volatile long pulses = 0, average = 0;

// interrupt handler - note pulse width in microseconds
void IRAM_ATTR handleInterrupt2() {
  static long startTime = 0;
  // change to HIGH note pulse start time
  if(digitalRead(RXPIN) == HIGH) {  
    startTime=micros();
    return;
  }
  // change to low calculate pulse width and add tp average
  average += (micros()-startTime);
  pulses++;             // count changes/second
}

// setup intrrupt on change on RXPIN
void setup() {
  Serial.begin(115200);
  pinMode(RXPIN, INPUT_PULLDOWN);
  attachInterrupt(digitalPinToInterrupt(RXPIN), handleInterrupt2, CHANGE);
}

// display pulses/second and calculate pulse width in microseconds
void loop() {
  static long printer = millis();
  // after 10 seconds print pulses/second and average pulse width time
  if (millis() - printer > 10000) {
    Serial.printf("pulses/sec %ld pulse width = %.2fuSec  \n",
                  pulses / 10, ((float)average / pulses));  // print results
    average = pulses = 0;                                   // reset initialse values
    printer = millis();
  }
}

serial monitor output

pulses/sec 2609 pulse width = 80.02uSec  
pulses/sec 2609 pulse width = 80.02uSec  
pulses/sec 2609 pulse width = 80.02uSec  
pulses/sec 2609 pulse width = 80.02uSec  
pulses/sec 2609 pulse width = 80.02uSec  
pulses/sec 2609 pulse width = 80.02uSec  

oscilloscope plot
image

not sure if that was what you were attempting to do

What is a lot, 1000, 2000, 10000, 100000?
Actually it will only be around 313 pulses/second at 30kph. So no problem

testing with 313pulses/second pulse width 500uSec

pulses/sec 313 pulse width = 500.09uSec  
pulses/sec 313 pulse width = 500.07uSec  
pulses/sec 313 pulse width = 500.07uSec  
pulses/sec 313 pulse width = 500.08uSec  
pulses/sec 313 pulse width = 500.07uSec 

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.