Determination of Wheel Acceleration / Deceleration for use in Integrated Stability Control Systems

I used this algorithm for my project to Detect wheel acceleration for ABS. My question is, when I increase the value of time_gap_threshold to a higher value, why is the acceleration I measure small (corresponding to my time_gap being large), but when I decrease the value of time_gap_threshold, the acceleration I measure increases (corresponding to my time_gap being large). with my time_gap large). I'm confused because I think the value of time_gap_threshold doesn't have much effect on the measured acceleration value but is only used to reset two variables, time_gap and a_current. Can someone explain to me why? Thank you.

#include  <Arduino.h>
#include <WiFi.h>
#include <math.h>
#include <stdlib.h>

#define _Speed_senPin     32
#define _Base_Freq        40000    
#define _Working_Freq     5        
#define _Communi_Freq     1        
#define _Sys_CLK          80000000 
#define _BaseTimer_CLK    1000000  
#define _BaseTimer_PRE    (_Sys_CLK / _BaseTimer_CLK)
#define _Pi               3.14
#define _Speed_senPin     32
#define So_xung1vong      50  
#define D_banhxe          0.56  
#define kmh_ms            3.6
#define doi_don_vi        2500000/9
#define f_to_v            _Pi * D_banhxe * kmh_ms / So_xung1vong
#define SPEED_THRESHOLD   0.5
#define time_gap_thresold 10
#define sample_time       0.005 // giây


hw_timer_t*     BaseTimer = NULL;
portMUX_TYPE    BaseTimerMux = portMUX_INITIALIZER_UNLOCKED;
volatile uint32_t count = 0;
volatile uint32_t buffer[3];
volatile bool f_read = false;


void IRAM_ATTR Fred_mes() 
{ 
  portENTER_CRITICAL_ISR(&BaseTimerMux);
  buffer[count] = timerRead(BaseTimer); 
  count++; 
  if(count >= 3)
  {
    count = 0;
    f_read = true;
  }
  portEXIT_CRITICAL_ISR(&BaseTimerMux);
}

float current_speed = 0, last_speed = 0 , tan_so = 0;
float time_gap = 0 , a_current = 0;

void setup() 
{
  Serial.begin(115200);
  pinMode(_Speed_senPin, INPUT);
  attachInterrupt(digitalPinToInterrupt(_Speed_senPin), Fred_mes, CHANGE);
  BaseTimer = timerBegin(0, _BaseTimer_PRE, true);
  timerStart(BaseTimer); 
}


void loop()
{
  if(f_read)
  {
    tan_so  = 1000000 / ((buffer[2] - buffer[0]));
    current_speed = tan_so*f_to_v;
    portENTER_CRITICAL_ISR(&BaseTimerMux);
    f_read = false; 
    portEXIT_CRITICAL_ISR(&BaseTimerMux);
  }
  if(abs(current_speed - last_speed) <= SPEED_THRESHOLD)
  {
    time_gap = time_gap + sample_time; 
    // Serial.print("toc do hien tai ");
    // Serial.print(current_speed);
    // Serial.print("\t");
    // Serial.print("tai thoi gian ");
    // Serial.print(time_gap);
    // Serial.println();
    //delayMicroseconds(1000);
  }
  else
  {
    a_current = ((current_speed - last_speed) / (time_gap*3.6));
    Serial.print(last_speed);
    Serial.print("\t");
    Serial.print(current_speed);
    Serial.print("\t");
    Serial.print(time_gap);
    Serial.print("\t");
    Serial.println(a_current);
    last_speed = current_speed;
    time_gap = 0;
  }
  if(time_gap >= time_gap_thresold)
  {
    time_gap = 0;
    a_current = 0;
  }
    // Serial.print(time_gap);
    // Serial.println();
}



`

have you an oscilloscope plot of the signals you are measuring?
what is the time range you are looking at?

looks like you are using an ESP32 this may give you some ideas

// ESP32 determine time between two pulses rising edge

#define RXPIN 16
#define RXPIN2 17

volatile int pin = 0;
volatile long timer = 0, start;
volatile long average = 0;
volatile long counter=0;

// interrupt handler - if rising edge start timer
void IRAM_ATTR handleInterrupt() {
  if (digitalRead(RXPIN) == HIGH)
    start = micros();
}

// interrupt handler - if rising edge calculate timer for loop() to display
void IRAM_ATTR handleInterrupt2() {
  if (digitalRead(RXPIN2) == HIGH) {
    timer = micros() - start;   // time between rising edges
    average+=timer;
    counter++;
  }
}

void setup() {
  Serial.begin(115200);
  pinMode(RXPIN, INPUT_PULLDOWN);
  pinMode(RXPIN2, INPUT_PULLDOWN);
  attachInterrupt(digitalPinToInterrupt(RXPIN), handleInterrupt, CHANGE);
  attachInterrupt(digitalPinToInterrupt(RXPIN2), handleInterrupt2, CHANGE);
}

// calculat pulse widtch in microseconds
void loop() {
  static long printer = millis(), second = millis();
  // every second print time
  if (millis() - second > 1000) {
    second = millis();
    Serial.printf("counter %ld timer %ld\n", counter, timer);

  }
  // after 10 seconds print average pulse time
  if (millis() - printer > 10000) {
    Serial.printf("*** average %f  *****\n", (float)average / counter);  // print average pulse width
    counter = average = 0;                                   // reset initialse values
    printer = millis();
  }
}

results

serial monitor output two 100microsecond period square waves 90degrees phase difference

*** average 25.089582  *****
counter 8378 timer 25
counter 28398 timer 25
counter 48418 timer 26
counter 68438 timer 25
counter 88458 timer 26
counter 108478 timer 27
counter 128498 timer 24
counter 148518 timer 24
counter 168538 timer 24
counter 188558 timer 24
*** average 25.125244  *****
counter 8558 timer 24
counter 28578 timer 24
counter 48597 timer 24
counter 68617 timer 25
counter 88637 timer 26
counter 108657 timer 25
counter 128677 timer 25
counter 148697 timer 24
counter 168717 timer 27
counter 188737 timer 24
*** average 25.109776  *****

phase  difference 60degrees
counter 101539 timer 33
counter 121559 timer 34
counter 141579 timer 33
counter 161599 timer 35
counter 181619 timer 34
*** average 33.377483  *****
counter 1618 timer 36
counter 21638 timer 34
counter 41658 timer 32
counter 61678 timer 33
counter 81698 timer 32
counter 101718 timer 32
counter 121737 timer 33
counter 141757 timer 33
counter 161777 timer 32
counter 181797 timer 33
*** average 33.243462  *****
counter 1799 timer 33

oscilloscope plot signals 90degrees phase difference
image

Thanks for helping me. This is my signal, it just a square signal with 50% duty cycle.

looks like the square wave period is in the milliseconds region
have a look at

// ESP32 square wave determine pulses/sec and pulse width in microseconds

// samples averaged over 10 seconds therefore lowest frequency to measure is 0.1Hz - if less pulses = 0

#define RXPIN 16

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

// interrupt handler - note pulse width in microseconds
void IRAM_ATTR handleInterrupt2() {
  static unsigned long lastTimer = 0;
  unsigned long timer = micros();
  // add pulse width time in microseconds to average and increment pulse counter
  if (lastTimer) average += (timer - lastTimer);
  lastTimer = timer;    // note current time
  pulses++;             // count changes/second
}

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

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

results

square wave 50KHz
frequency 50000Hz pulse width = 10.00uSec  
frequency 50000Hz pulse width = 10.00uSec  
frequency 50001Hz pulse width = 10.00uSec  

square wave 100KHz
frequency 99401Hz pulse width = 5.03uSec  
frequency 99395Hz pulse width = 5.03uSec  
frequency 99397Hz pulse width = 5.03uSec


frequency 0.1Hz pulse width = 5000230.00uSec  
frequency 1.0Hz pulse width = 500019.00uSec  
frequency 10.0Hz pulse width = 50001.87uSec  
frequency 100.0Hz pulse width = 5000.19uSec  
frequency 1000.0Hz pulse width = 500.02uSec  
1 Like

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