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();
}
`
horace
April 25, 2024, 9:24am
2
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
Thanks for helping me. This is my signal, it just a square signal with 50% duty cycle.
horace
April 25, 2024, 10:07am
4
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
system
Closed
October 22, 2024, 10:08am
5
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.