From the documentation of this library:

The library use no interupts of the hardware timers and works with the micros() / millis() function.

This library implements timers in software by polling the micros() and millis() functions. It requires the update() method to be called in loop().

So the start of loop() should be:

void loop()
{
    tickerObject.update();

    if(s == true)

I'm trying to use a Ticker.h to sample an analog input consistently at a frequency of 10khz

It is worth a go but this is a software based solution that is prone to jitter depending on how often the event loop can be called.

Answer from Ben T on Stack Overflow
🌐
Everything ESP8266
esp8266.com › viewtopic.php
Enabling micro second timer - Everything ESP8266
Steps: 1) Add #define USE_US_TIMER at the beginning of osapi.h to make the microsecond timer call visible. osapi.h is in the ...\hardware\tools\esp8266\sdk\include directory 2) Add appropriate calls to the Ticker library (attached) 3) Add a call to system_timer_reinit () right at the beginning of the user_init function in core_esp8266_main.cpp.
Discussions

Fractional Microsecond Delay;
Your best bet is to use the chip's hardware timers. I'd start by reading this: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/timer.html Depending on what you're doing, it might also be worth looking into the RMT peripheral. It's designed for generating infrared remote control signals but it can be used to precisely generate custom pulses for other purposes too. It's overkill but it'd get the job done. https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/rmt.html If you're willing to put in the time to learn the lower level ESP32 APIs, they'll seriously pay off in performance and flexibility. You should be able to accomplish microsecond timing without delayXXX() or interrupts using the RMT peripheral. More on reddit.com
🌐 r/esp8266
10
11
October 5, 2021
I want to use microseconds in timer interrupt like in timerone.h for ESP8266
Hello, I've found ticker.h, but this library uses milliseconds, I want to work a little faster. I tried to set the PWM frequency, this works, but I want to count something at every pulse, so an int... More on github.com
🌐 github.com
3
October 12, 2015
How to use Ticker correctly
Hi, using esp8266 i am trying to make a led turn on only for 0.5 seconds every 10 seconds, for that i am using Ticker but it seems that there is some error because the led turns on only a few milliseconds, it is almost imperceptible, could someone tell me how correct this? More on forum.arduino.cc
🌐 forum.arduino.cc
15
0
August 11, 2022
Sub milisecond timer for ESP8266 in Lua - Internet of Things Stack Exchange
I'm trying to make a remotely controlled servo motor controller on ESP8266 which is controlled by a server. The problem I'm facing is how to make an asynchronous timer, like tmr.alarm(), but in More on iot.stackexchange.com
🌐 iot.stackexchange.com
March 28, 2017
🌐
Nanona
sub.nanona.fi › esp8266 › timing-and-ticks.html
Timing and clocking with ESP8266
Invoking os_delay_us() allows us ... slept, when we expect one microsecond sleep. We know that because esp8266's clock rate being 80Mhz, one microsecond is exactly 80 ticks....
🌐
Circuits4You
circuits4you.com › 2018 › 01 › 02 › esp8266-timer-ticker-example
ESP8266 Timer and Ticker Example | Circuits4you.com
July 22, 2018 - Use of timer instead of Ticker gives advantage of precision timing and You can get timer interrupt in micro seconds. /* ESP8266 Timer Example Hardware: NodeMCU Circuits4you.com 2018 LED Blinking using Timer */ #include <ESP8266WiFi.h> #include ...
🌐
GitHub
github.com › sstaub › Ticker
GitHub - sstaub/Ticker: Ticker library for Arduino · GitHub
#include "Ticker.h" void printMessage(); void printCounter(); void printCountdown(); void blink(); void printCountUS(); bool ledState; int counterUS; Ticker timer1(printMessage, 0, 1); // once, immediately Ticker timer2(printCounter, 1000, 0, MILLIS); // internal resolution is milli seconds Ticker timer3(printCountdown, 1000, 5); // 5 times, every second Ticker timer4(blink, 500); // changing led every 500ms Ticker timer5(printCountUS, 100, 0, MICROS_MICROS); // the interval time is 100us and the internal resolution is micro seconds void setup() { pinMode(LED_BUILTIN, OUTPUT); Serial.begin(960
Starred by 209 users
Forked by 36 users
Languages   C++
🌐
Reddit
reddit.com › r/esp8266 › fractional microsecond delay;
r/esp8266 on Reddit: Fractional Microsecond Delay;
October 5, 2021 -

Hey all, possess any of you managed to get fractional microsecond delay on the ESP8266/ESP32? I need to delay about 5.33 microseconds between setting a pin high and then back to low. I understand that delayMicroseconds might‏‏‎‏‏‎‏‏‎‏‏‎­be close, but wanted to see if there might be something with a bit more resolution. Thanks!

🌐
GitHub
github.com › esp8266 › Arduino › issues › 881
I want to use microseconds in timer interrupt like in timerone.h for ESP8266 · Issue #881 · esp8266/Arduino
October 12, 2015 - Hello, I've found ticker.h, but this library uses milliseconds, I want to work a little faster. I tried to set the PWM frequency, this works, but I want to count something at every pulse, so an int...
Author   esp8266
🌐
Mbed
os.mbed.com › docs › mbed-os › v6.16 › porting › microsecond-ticker.html
Microsecond ticker - Porting | Mbed OS 6 Documentation
The generic ticker API uses the ticker_info_t structure to determine each hardware counter's frequency and width. This then requires runtime calculations to convert between the hardware counter and the 64-bit microsecond count used by the generic API.
Find elsewhere
🌐
Engineers Garage
engineersgarage.com › home › micropython: time-related functions, timers & interrupts in esp8266 and esp32
MicroPython: Time-related functions, timers & interrupts in ESP8266 and ESP32
June 2, 2023 - It is equal to the number of ticks, where ticks can be milliseconds, microseconds, or CPU cycles set as the deadline. For example, the following statement returns a deadline of 200 milliseconds.
🌐
Arduino Forum
forum.arduino.cc › projects › programming
How to use Ticker correctly - Programming - Arduino Forum
August 11, 2022 - Hi, using esp8266 i am trying to make a led turn on only for 0.5 seconds every 10 seconds, for that i am using Ticker but it seems that there is some error because the led turns on only a few milliseconds, it is almost i…
🌐
TechTutorialsX
techtutorialsx.com › home › esp32 › esp32: ticker library
ESP32: Ticker library - techtutorialsx
August 7, 2021 - If we go to the Ticker.h file, we can easily see the include for the esp_timer.h at the beginning of the file. Under the hood, the esp_timer.h library is based on hardware timers that can provide microsecond accuracy [1], which can easily be seen in the signature of the function that is used to setup a periodic callback.
🌐
Blogger
lucstechblog.blogspot.com › 2020 › 02 › esp8266-timer-problem.html
lucstechblog: ESP8266 Ticker library problem
Ticker Ticker is a build-in library for the ESP8266 which allows you to have a process run automatically every x seconds or x milliseconds. The use of it is very simple.
Top answer
1 of 2
7

I think you might struggle to get a microsecond delay that is both accurate and non-blocking with the ESP8266.

According to the NodeMCU documentation:

If you look at the app/modules/tmr.c code for this function, then you will see that it executes a low level ets_delay_us(delay). This function isn't part of the NodeMCU code or the SDK; it's actually part of the xtensa-lx106 boot ROM, and is a simple timing loop which polls against the internal CPU clock. It does this with interrupts disabled, because if they are enabled then there is no guarantee that the delay will be as requested.

tmr.delay() is really intended to be used where you need to have more precise timing control on an external hardware I/O (e.g. lifting a GPIO pin high for 20 μSec). It will achieve no functional purpose in pretty much every other usecase, as any other system code-based activity will be blocked from execution; at worst it will break your application and create hard-to-diagnose timeout errors.

It seems that interrupts have to be disabled in this case simply because if an interrupt did occur mid-delay with a short interval (on the order of a few microseconds), the interrupt handler would take up far more time than the whole delay was supposed to be.

Let's say you wanted a timer for 20 microseconds, and an interrupt occurred at about 10 μs. If the handler takes more than 10 μs, you will have already passed the 20 μs delay that you intended.

So, we can rule out tmr.delay() if you do need interrupts working.

I did a bit more digging, and apparently the ESP8266 does support microsecond timers through ets_timer_arm_new() where the last parameter is zero. NodeMCU, however, sets this value to 1 which uses the millisecond precision. This post seems to support that idea:

If you need to get the interval between two gpio interrupt, use the system api system_get_time() to calculate the relative time.(us) If you want to use a os_timer api to arrange a us timer event, use system_timer_reinit at the beginning of user_init and call os_timer_arm_us.

If you're willing to try editing and rebuilding the firmware, it might be worth a shot. Although, there was a feature request for this, which was declined as:

So I tested nanosecond timers, and cannot establish intervals less than 1000us (with compiled and stripped code and in 160MHz CPU mode I got something like 800us). Is this a case to provide new (mostly unusable) functionality?
- djphoenix

Not feasible ATM -> closing.
- marcelstoer

2 of 2
5

I have managed to recompile the NodeMCU firmware with us timer enabled:

  • Install docker build environment of Marcel Stör: https://hub.docker.com/r/marcelstoer/nodemcu-build/

  • change firmware files in your firmware directory (e.g. ./user/nodemcu-firmware)

    1. ./app/user/user_main.c

      void user_init(void)
      {
      

add right here the line: system_timer_reinit();

  1. ./sdk-overrides/osapi.h add above the line #include_next "osapi.h": #define USE_US_TIMER

  2. ./app/modules/tmr.c -> static int tmr_start(lua_State* L){ change: os_timer_arm -> os_timer_arm_us

  3. ./app/modules/tmr.c -> static int tmr_interval(lua_State* L){ change: os_timer_arm -> os_timer_arm_us

  4. ./app/modules/tmr.c: leave os_timer_arm in int luaopen_tmr( lua_State *L ){as is, otherwise you will get a watchdog reset upon start-up

    • recompile firmware, and flash your ESP8266

With CPU running at 160MHz, I have managed to sample ADC with 8.3kHz (timer delay of 125uS). If I go faster, the watchdog kicks in.

Code:

    local mytimer2 = tmr.create()
    local count = 0
    local count2 = 0
    local adc_read = adc.read
    mytimer2:register(125, 1, function (t2) 
        count = count + 1; count2 = count2 + 1
        local adc_v = adc_read(0) 
        if (count2 == 500) then 
            count2 = 0
        end
        if count == 100000 then
            mytimer2:stop()
            print("Time at end: "..tmr.time())
            print("Counter: "..count)
        end
    end)
    print("Time at start: "..tmr.time())
    mytimer2:start()

Output:

Time at start: 1

Time at end: 13

Counter: 100000

100.000 reads in 12 sec.

🌐
Links2004
links2004.github.io › Arduino › dd › de3 › class_ticker.html
ESP8266: Ticker Class Reference
Main Page · Related Pages · Modules · Classes · Class List · Class Index · Class Hierarchy · Class Members · Public Types | Public Member Functions | Protected Member Functions | Protected Attributes | List of all members · Ticker Class Reference
🌐
GitHub
github.com › esp8266 › Arduino › issues › 4632
delayMicroseconds uncorrect, about 50 ticks too much · Issue #4632 · esp8266/Arduino
April 11, 2018 - I measured the following delays in CPU ticks (80 MHz): delayMicroseconds(1) : 130 ticks, 50 ticks too much delayMicroseconds(2) : 202 ticks, 42 ticks too much delayMicroseconds(3) : 286 ticks, 46 ticks too much delayMicroseconds(4) : 370...
Author   esp8266
🌐
Espressif
bbs.espressif.com › viewtopic.php
Precise timing needed (ex. for IR decoding) - ESP8266 Developer Zone
February 13, 2015 - Complete listing of the official ESP8266 related documentation release by ESPRESSIF!