- Add a MATLAB System block to your Simulink model.
- Set its System object class to PulseCounter.
- Set its sample time to 0.005 (5 ms).
- The output will be the number of pulses counted in the last 5 ms.
How to count flowmeter pulses at 1 kHz on ESP32 in Simulink without forcing solver step to 0.5 ms (want solver ≥5 ms for stable serial comm)?
13 views (last 30 days)
Show older comments
I am working with two ESP32 boards in Simulink.
- Board A (pump control) runs in External Mode with a base step of 5 ms and receives data via Serial Receive.
- Board B (flowmeter) must detect pulses up to 1 kHz. If I set the Digital Input block to 0.5 ms sample time (Respecting Shanon rule), Simulink forces the solver fixed-step size to 0.0005 s, which breaks serial comm with Board A (TX-RX connection).
Whats working:
I know that when both solver fixed-step size of both simulink are the same, the serial communcation is fine.
My goal is:
- Keep accurate pulse counting (1 kHz max → need ≥2 kHz detection).
- Keep solver fixed-step ≥5 ms for stable serial communication and External Mode.
I know hardware counters (PCNT, interrupts) or a MATLAB System block could be used to count pulses asynchronously and then read the count every 5 ms. But I don’t know the cleanest Simulink approach: which blocks or library should I use to implement a pulse counter on ESP32?
Any example or workflow to achieve this would be really helpful.
0 Comments
Answers (1)
Aditya
on 24 Sep 2025 at 6:05
Hi Salah,
The cleanest approach in Simulink is to use a MATLAB System block that interfaces with custom C code. This C code sets up the ESP32’s hardware pulse counter, counts incoming pulses, and provides a function to read and reset the count. The MATLAB System block calls these C functions at each Simulink step (e.g., every 5 ms), giving you the number of pulses detected in that interval. This allows you to maintain a 5 ms solver step for external mode and serial communication, while still detecting pulses up to 1 kHz or more.
To implement this, you first write the C code to initialize and access the pulse counter. Then, you create a MATLAB System block that calls these C functions using coder.ceval. Finally, you add this block to your Simulink model and set its sample time to 0.005 (5 ms). This workflow is robust, efficient, and integrates seamlessly with Simulink and the ESP32 Support Package.
1. C Code for ESP32 Pulse Counter (PCNT)
Save as my_pulse_counter.c and my_pulse_counter.h:
// my_pulse_counter.h
#ifndef MY_PULSE_COUNTER_H
#define MY_PULSE_COUNTER_H
void init_pcnt(void);
int read_and_reset_pulse_count(void);
#endif
// my_pulse_counter.c
#include "my_pulse_counter.h"
#include "driver/pcnt.h"
#define PCNT_INPUT_IO 4 // Change to your GPIO pin number
void init_pcnt(void) {
pcnt_config_t pcnt_config = {
.pulse_gpio_num = PCNT_INPUT_IO,
.ctrl_gpio_num = PCNT_PIN_NOT_USED,
.channel = PCNT_CHANNEL_0,
.unit = PCNT_UNIT_0,
.pos_mode = PCNT_COUNT_INC,
.neg_mode = PCNT_COUNT_DIS,
.lctrl_mode = PCNT_MODE_KEEP,
.hctrl_mode = PCNT_MODE_KEEP,
.counter_h_lim = 10000,
.counter_l_lim = 0,
};
pcnt_unit_config(&pcnt_config);
pcnt_counter_pause(PCNT_UNIT_0);
pcnt_counter_clear(PCNT_UNIT_0);
pcnt_counter_resume(PCNT_UNIT_0);
}
int read_and_reset_pulse_count(void) {
int16_t count = 0;
pcnt_get_counter_value(PCNT_UNIT_0, &count);
pcnt_counter_clear(PCNT_UNIT_0);
return count;
}
2. MATLAB System Block Implementation
Place this in a new file, e.g., PulseCounter.m:
classdef PulseCounter < matlab.System & coder.ExternalDependency
%#codegen
methods (Static)
function name = getDescriptiveName()
name = 'PulseCounter';
end
function b = isSupportedContext(context)
b = context.isCodeGenTarget('rtw');
end
function updateBuildInfo(buildInfo, context)
buildInfo.addSourceFiles('my_pulse_counter.c');
buildInfo.addIncludePaths(pwd); % or the path to your header
end
end
methods (Access = protected)
function setupImpl(obj)
coder.cinclude('my_pulse_counter.h');
coder.ceval('init_pcnt');
end
function count = stepImpl(obj)
coder.cinclude('my_pulse_counter.h');
count = int16(coder.ceval('read_and_reset_pulse_count'));
end
end
end
3. Simulink Integration
0 Comments
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!