-
Notifications
You must be signed in to change notification settings - Fork 7.7k
Fixing frequency measurements with PCNT when using open collector configuration #8368
-
Writing this in case it might ever help someone else. Using an ESP32-WROOM-32UE.
I am using the FreqCountESP library, which lets you use the PCNT module to count pulses on a pin. I had been testing it with a signal generator connected directly to IO4, no problems at all! Very precise and exact, to within 1 Hz which is what I needed. However, I then connected the signal as in the following schematic:
Which is what I was going to ultimately use to sample an RPM signal. To my surprise, frequency measurements became very inexact and noisy. For example, I'd set a 500 Hz test signal on the base of the transistor, and IO4 would read anything between 500 and 510 Hz. If I disabled the usage of the PCNT module and simply used interruptions to measure the frequency, it would work OK again.
After some reading, I came across some posts mentioning that the glitch filter could help. I configured it by setting pcnt_set_filter_value(PCNT_UNIT, 1); and enabled it with pcnt_filter_enable(PCNT_UNIT);, and this solved the issue!
Still don't know why, I can't see any glitches with my oscilloscope, signal looks perfectly clean:
SDS00013
If anyone has any ideas as to why this solved it, I'd appreciate it!
Beta Was this translation helpful? Give feedback.
All reactions
Replies: 2 comments 10 replies
-
Conceptually, I see no issues with your circuit. It does introduce the following changes:
- Signal goes from 5V->3V
- Signal is inverted
- The 1k pullup will cause a rounded rising edge
I suspect your issue is the slower rising edge. You can see this on your scope measurements: Rise=486ns vs Fall= 82ns.
You can fix this with the following methods:
- Use two transistors in push/pull configuration to get sharp edges
- Use an op-amp instead of a transistor (watch out for 5V->3V level shift)
- Use hysteresis or a slower sampling rate on the software side. I'm guessing the glitch filter does this.
Beta Was this translation helpful? Give feedback.
All reactions
-
❤️ 1
-
pcnt_filter_enable(PCNT_UNIT);
Please note that anybody might not be a programming guru. Where does it need to be added those two operators, in setup, in library?
By the way, this library seems interfere with WiFi library and the MC falls into endless restarts.
Beta Was this translation helpful? Give feedback.
All reactions
-
I have tried to use different libraries for stability increasing. For input debounce eliminating it's commented out the first used "Throttles". For porting try to Rasperry Pi PicoW has been using EEPROM instead of ESP32 specific "Preferences", which does not do because of Websockets falling. The code allows virtual dashboard connection by Virtuino IOT cross-platform application.
Beta Was this translation helpful? Give feedback.
All reactions
-
Given the length of your code it is a little bit difficult to find the culprit. My suggestion would be to make a simpler version of your code with only the core functionality, and check if the resets still occur when you add the FreqCountESP library functionality. Also, check the version of the Arduino core for ESP32 that you are using. I am using 2.0.14.
Beta Was this translation helpful? Give feedback.
All reactions
-
I have removed everything not related to the library's performance and got the following compilation errors (by the way an hour ago, ESP core on Arduino was updated).
In file included from c:\Users\woodl\Documents\Arduino\libraries\FreqCountESP\src/FreqCountESP.h:12, from C:\Users\woodl\AppData\Local\Temp\.arduinoIDE-unsaved2024312-7968-1fdbssb.fc0gi\sketch_apr12a\sketch_apr12a.ino:4: C:\Users\woodl\AppData\Local\Arduino15\packages\esp32\tools\esp32-arduino-libs\idf-release_v5.1-3662303f31/esp32/include/driver/deprecated/driver/pcnt.h:15:2: warning: #warning "legacy pcnt driver is deprecated, please migrate to use driver/pulse_cnt.h" [-Wcpp] 15 | #warning "legacy pcnt driver is deprecated, please migrate to use driver/pulse_cnt.h" | ^~~~~~~ In file included from c:\Users\woodl\Documents\Arduino\libraries\FreqCountESP\src\FreqCountESP.h:12, from c:\Users\woodl\Documents\Arduino\libraries\FreqCountESP\src\FreqCountESP.cpp:1: C:\Users\woodl\AppData\Local\Arduino15\packages\esp32\tools\esp32-arduino-libs\idf-release_v5.1-3662303f31/esp32/include/driver/deprecated/driver/pcnt.h:15:2: warning: #warning "legacy pcnt driver is deprecated, please migrate to use driver/pulse_cnt.h" [-Wcpp] 15 | #warning "legacy pcnt driver is deprecated, please migrate to use driver/pulse_cnt.h" | ^~~~~~~ c:\Users\woodl\Documents\Arduino\libraries\FreqCountESP\src\FreqCountESP.cpp: In function 'void onHLim(void*)': c:\Users\woodl\Documents\Arduino\libraries\FreqCountESP\src\FreqCountESP.cpp:25:39: warning: compound assignment with 'volatile'-qualified left operand is deprecated [-Wvolatile] 25 | *(volatile uint32_t *)backupCounter += PCNT_HIGH_LIMIT; | ^ c:\Users\woodl\Documents\Arduino\libraries\FreqCountESP\src\FreqCountESP.cpp: At global scope: c:\Users\woodl\Documents\Arduino\libraries\FreqCountESP\src\FreqCountESP.cpp:52:24: warning: ignoring attribute 'section (".iram1.3")' because it conflicts with previous 'section (".iram1.1")' [-Wattributes] 52 | void IRAM_ATTR onTimer() | ^ c:\Users\woodl\Documents\Arduino\libraries\FreqCountESP\src\FreqCountESP.h:16:16: note: previous declaration here 16 | void IRAM_ATTR onTimer(); | ^~~~~~~ c:\Users\woodl\Documents\Arduino\libraries\FreqCountESP\src\FreqCountESP.cpp:90:23: warning: ignoring attribute 'section (".iram1.4")' because it conflicts with previous 'section (".iram1.0")' [-Wattributes] 90 | void IRAM_ATTR onRise() | ^ c:\Users\woodl\Documents\Arduino\libraries\FreqCountESP\src\FreqCountESP.h:15:16: note: previous declaration here 15 | void IRAM_ATTR onRise(); | ^~~~~~ c:\Users\woodl\Documents\Arduino\libraries\FreqCountESP\src\FreqCountESP.cpp: In function 'void onRise()': c:\Users\woodl\Documents\Arduino\libraries\FreqCountESP\src\FreqCountESP.cpp:93:18: warning: '++' expression of 'volatile'-qualified type is deprecated [-Wvolatile] 93 | _FreqCountESP::sCount++; | ~~~~~~~~~~~~~~~^~~~~~ c:\Users\woodl\Documents\Arduino\libraries\FreqCountESP\src\FreqCountESP.cpp: In member function 'void _FreqCountESP::_begin(uint8_t, uint8_t)': c:\Users\woodl\Documents\Arduino\libraries\FreqCountESP\src\FreqCountESP.cpp:125:5: error: 'timerAlarmEnable' was not declared in this scope; did you mean 'timerAlarm'? 125 | timerAlarmEnable(mTimer); | ^~~~~~~~~~~~~~~~ | timerAlarm c:\Users\woodl\Documents\Arduino\libraries\FreqCountESP\src\FreqCountESP.cpp: In member function 'void _FreqCountESP::begin(uint8_t, uint16_t, uint8_t, uint8_t)': c:\Users\woodl\Documents\Arduino\libraries\FreqCountESP\src\FreqCountESP.cpp:134:22: error: too many arguments to function 'hw_timer_t* timerBegin(uint32_t)' 134 | mTimer = timerBegin(hwTimerId, 80, true); | ~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~ In file included from C:\Users\woodl\AppData\Local\Arduino15\packages\esp32\hardware\esp323円.0.0-rc1\cores\esp32/esp32-hal.h:84, from C:\Users\woodl\AppData\Local\Arduino15\packages\esp32\hardware\esp323円.0.0-rc1\cores\esp32/Arduino.h:36, from c:\Users\woodl\Documents\Arduino\libraries\FreqCountESP\src\FreqCountESP.h:4: C:\Users\woodl\AppData\Local\Arduino15\packages\esp32\hardware\esp323円.0.0-rc1\cores\esp32/esp32-hal-timer.h:35:14: note: declared here 35 | hw_timer_t * timerBegin(uint32_t frequency); | ^~~~~~~~~~ c:\Users\woodl\Documents\Arduino\libraries\FreqCountESP\src\FreqCountESP.cpp:135:23: error: too many arguments to function 'void timerAttachInterrupt(hw_timer_t*, void (*)())' 135 | timerAttachInterrupt(mTimer, &onTimer, true); | ~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~ C:\Users\woodl\AppData\Local\Arduino15\packages\esp32\hardware\esp323円.0.0-rc1\cores\esp32/esp32-hal-timer.h:50:6: note: declared here 50 | void timerAttachInterrupt(hw_timer_t * timer, void (*userFunc)(void)); | ^~~~~~~~~~~~~~~~~~~~ c:\Users\woodl\Documents\Arduino\libraries\FreqCountESP\src\FreqCountESP.cpp:136:3: error: 'timerAlarmWrite' was not declared in this scope; did you mean 'timerWrite'? 136 | timerAlarmWrite(mTimer, timerMs * 1000, true); | ^~~~~~~~~~~~~~~ | timerWrite c:\Users\woodl\Documents\Arduino\libraries\FreqCountESP\src\FreqCountESP.cpp: In member function 'void _FreqCountESP::end()': c:\Users\woodl\Documents\Arduino\libraries\FreqCountESP\src\FreqCountESP.cpp:172:5: error: 'timerAlarmDisable' was not declared in this scope 172 | timerAlarmDisable(mTimer); | ^~~~~~~~~~~~~~~~~
Beta Was this translation helpful? Give feedback.
All reactions
-
I have installed overnight build 2.0.15
Beta Was this translation helpful? Give feedback.
All reactions
-
Seems Espressif guys did an instant revolution. https://github.com/espressif/arduino-esp32/issues/9169?ysclid=lux27g5kxy803967698
Beta Was this translation helpful? Give feedback.