🌐
ESP32 Forum
esp32.com › viewtopic.php
Nanosecond delay - ESP32 Forum
April 12, 2024 - // the clock is set to 125 MHz => 1 tick == 8 ns // init SysTick timer systick_hw->csr = 0x05; // enable systick at 1 cycle resolution (8ns) systick_hw->rvr = 0xffff; // 16 bit // delay 13 ticks or 102 nanoseconds uint16_t ticks = 13; // 13*8 = 102 nanos uint16_t start = systick_hw->cvr; ...
🌐
Reddit
reddit.com › r/esp32 › need to have sub microsecond delay precision
r/esp32 on Reddit: Need to have sub microsecond delay precision
July 29, 2020 -

Hi guys,

I'm trying to implement something that will generate two triggers at regular intervals where the two triggers are separated by a configurable delay. The delay has to be configurable to sub microsecond resolution. Ideally, 500ns or less.

I chose the ESP32 because of its 240MHz clock, but it still seems to be having trouble.

I'm messing around with the following code:

#define cyclespermicro 240
#define microcycles(n) (n*cyclespermicro)

uint32_t startCounter, counter, cpu_cycles;
int cyclediff, totalcycles, corrected;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);

  startCounter = ESP.getCycleCount();
  totalcycles = startCounter + microcycles(2);
  //delayMicroseconds(1);

 while (ESP.getCycleCount() < totalcycles) {
        __asm__ __volatile__ ("nop");
 }
  
  counter = ESP.getCycleCount();
  cpu_cycles = counter - startCounter;
  corrected = cpu_cycles - 262;
  Serial.print("StartCounter: ");
  Serial.print(startCounter);
  Serial.print(" counter: ");
  Serial.print(counter);
  Serial.print(" cpu_cycles: ");
  Serial.print(cpu_cycles);
  Serial.print(" corrected: ");
  Serial.println(corrected);
}

void loop() {

}

The problem is that I get the same number of clock cycles for 1 us as I do for 2 us. I'm guessing this is because the while loop overhead is overwhelming the 1 us delay.

The problem is I need to have the amount of delay configurable and I don't know the best way to do this. Anyone have any ideas how to efficiently create configurable sub-microsecond delays?

EDIT: I am also noticing, when I get rid of the while loop entirely, and just straight up copy in NOP lines, it works as expected for like 3 NOPs, but once I hit 5 NOPS, the overhead jumps to like 500 cycles. What is going on here?

🌐
PlatformIO Community
community.platformio.org › platformio core
How to delay microseconds on ESP32 under a Free RTOS task - PlatformIO Core - PlatformIO Community
September 8, 2022 - I have some code running as a FreeRTOS task on my ESP32. I would like to toggle an output pin in the order of microseconds so use the function delayMicroseconds. However, this crashes my ESP32 every time. Even a simple loop causes it to crash: for ( int i = 0 ; i
🌐
Reddit
reddit.com › r/arduino › sub microsecond delays on esp32
r/arduino on Reddit: Sub microsecond delays on esp32
December 18, 2021 -

Do I have to write instructions in assembly? Im using Arduino IDE and im trying to sample a signal at 44.1khz. I come from a PIC Micro background where I would just use a TMR. Whats the play here in Arduino Land?

🌐
ESP32 Forum
esp32.com › viewtopic.php
Microsecond or fraction of microsecond delay - ESP32 Forum
March 11, 2018 - function delay(period) { start = CCOUNT; while (CCOUNT - start < period) { // do nothing } }[ This would busy wait (waste) the cycles, but it should work. You might also have to disable some of the interrupts if you need absolutely delays no matter what. For example, you may be preempted by FreeRTOS. Free book on ESP32 available here: https://leanpub.com/kolban-ESP32
🌐
ESP32 Forum
esp32.com › viewtopic.php
Wait microsecond - ESP32 Forum
The ROM function ets_delay_us() (defined in rom/ets_sys.h) will allow you to busy-wait for a correct number of microseconds.
🌐
ESP32 Forum
esp32.com › viewtopic.php
esp32 get time with nanoseconds precision - ESP32 Forum
Hi, I am looking for a way to get the time since boot with nanoseconds precision. Currently, the best I can do is esp_timer_get_time() which returns time with microsecond precision. I connected my board to an oscilloscope and found out that it takes around 1.29 us for the esp_timer_get_time() ...
🌐
Instructables
instructables.com › circuits › arduino
6.25 Nanosecond Resolution Timer for Any Microcontroller! - Instructables
September 27, 2017 - 6.25 Nanosecond Resolution Timer for Any Microcontroller!: While designing a solid state replacement for a vacuum-tubes-and-CRT radar display subsystem, I was stuck at getting a suitable system to time the period between the synch pulse and ...
🌐
ESP32 Forum
esp32.com › viewtopic.php
Nanosecond precision packet arrival time for WiFi - ESP32 Forum
Hi everyone, To implement Time-Of-Flight scenarios, I need to know the exact packet arrival time (accurate to ESP32 clock of 240MHz - 4 nanosecond) in the promiscuous mode callback. The current `rx_ctrl->timestamp` field received in the payload is not sufficient as it is precise only to the ...
🌐
ESP32 Forum
esp32.com › viewtopic.php
Reading nanosecond timing on GPIO (Neopixel) - ESP32 Forum
October 8, 2019 - The termination of a frame (24 bits times the number of targeted pixels) is signaled by the pin staying low for >= 6000ns. My intention is to read this signal and modify some color values, then output to my LEDs. The output is not an issue using the RMT device, and I am not concerned about ...
Find elsewhere
🌐
GitHub
github.com › espressif › ESP8266_RTOS_SDK › issues › 914
Nanosecond delay using "nop" (GIT8266O-487) · Issue #914 · espressif/ESP8266_RTOS_SDK
June 10, 2020 - Using "nop" command gives me 0.5us delay when ESP works at 80MHz. It should be much faster. Aswell "for" loop with 1 iteration takes longer then on OPEN RTOS SDK.
Author   espressif
🌐
GitHub
github.com › espressif › arduino-esp32 › issues › 282
micros() & delayMicroseconds() not good enough · Issue #282 · espressif/arduino-esp32
March 23, 2017 - void IRAM_ATTR delayMicroseconds(uint32_t us) { if(us){ uint32_t m = micros(); while( (micros() - m ) < us ){ NOP(); } } }
Author   espressif
🌐
Arduino Forum
forum.arduino.cc › other hardware › leds and multiplexing
Blink with nanosecond resolution delay - LEDs and Multiplexing - Arduino Forum
October 29, 2020 - Arduino example sketch "Blink" allows you to specify "delay()" between state changes in microseconds. Using "delayMicroseconds()", that delay can be specified with microsecond resolution. I did need a multiple MHz blin…
🌐
Espressif
docs.espressif.com › projects › esp-idf › en › latest › esp32 › api-reference › system › esp_timer.html
ESP Timer (High Resolution Timer) - ESP32 - — ESP-IDF Programming Guide latest documentation
The ESP Timer feature allows for creating software timers and invoking their callback functions (dispatching callbacks) on timeout. ESP Timer is useful when user software needs to perform delayed or periodic actions, such as delayed device start/stop or periodic sampling of sensor data.
🌐
ESP32 Forum
esp32.com › viewtopic.php
How to delay microsecond - ESP32 Forum
March 11, 2017 - It might be that the function called "ets_delay_us(value)" is what you could use. Its proto type is defined in <rom/ets_sys.h>. Free book on ESP32 available here: https://leanpub.com/kolban-ESP32
🌐
Espressif
docs.espressif.com › projects › esp-idf › en › stable › esp32s2 › api-reference › system › esp_timer.html
ESP Timer (High Resolution Timer) - ESP32-S2 - — ESP-IDF Programming Guide v6.0.1 documentation
The ESP Timer feature allows for creating software timers and invoking their callback functions (dispatching callbacks) on timeout. ESP Timer is useful when user software needs to perform delayed or periodic actions, such as delayed device start/stop or periodic sampling of sensor data.
Top answer
1 of 7
27

You've changed the requirements by a lot! Measuring something in nanoseconds is hard. Measuring something with a +-100 ns accuracy really isn't. A 10 MHz counter works perfectly fine for that, do 20 MHz if you want to be sure.

Any modern 32 bit microcontroller (read: 2€ investment...) has timer/capture units that can do that for you.

You've went from a problem that requires own hardware design to something that even the cheapest STM32 eval board can do out of the box: That's an excellent illustration of the importance of requirements engineering.

2 of 7
17

Luxury option:

Time to digital converter chip, available from several manufacturers. Accuracy: picoseconds.

AS6500 TDC7200

Easy option:

Microcontroller timer in capture mode to measure pulse width, or time between two pulses. Pretty much any microcontroller will do the job, but accuracy will be at best one clock cycle, so you must choose a microcontroller with suitable clock frequency. And you must also check the timer clock frequency, which is not always the same as the CPU clock frequency. If you want 10ns accuracy that's 100MHz, so there are a lot of options, STM32, LPC, etc. If you want a LCD, just get a module with one on it.

ESP32 is an example of why you should check carefully: the CPU runs at 240 MHz but the timers run at 80MHz.

Next, check the microcontroller datasheet and check if the timer can measure the delay between two pulse edges. If it cannot, then you can use two timers running on the same internal counter to capture the start pulse and the stop pulse counter values, and just substract.

Since you're interested in edges, make sure it can be triggered on the leading edge.

the pulse will be from 0.5V to something higher.

0.5V is too low for a CMOS logic input so you will need a fast comparator to set a suitable threshold, search the category on mouser, digikey etc. It's important to select a comparator with a response time that is low enough. If your minimum pulse width is 100ns, then a <50ns comparator should be adequate. You can also use a highspeed opamp to amplify the signal, but in any case, a CMOS 3V3 logic input will not work directly with a 0.5V signal.

🌐
Rust
docs.rs › esp32-hal › latest › esp32_hal › struct.Delay.html
Delay in esp32_hal - Rust
Delay for the specified number of nanoseconds · source§ · source§ · Returns a copy of the value. Read more · 1.0.0 · source§ · Performs copy-assignment from source. Read more · source§ · source§ · Pauses execution for ms milliseconds · source§ · source§ ·
🌐
ControllersTech®
controllerstech.com › home › arduino › core tutorials › delaymicroseconds() tutorial
Arduino delayMicroseconds() Tutorial: Precise Timing, Pulses & Alternatives
May 29, 2026 - No interrupts are serviced (unless they were already pending). The processor is occupied for the full duration. On a 16 MHz Arduino (UNO, Nano, Mega), one clock cycle is 62.5 nanoseconds.
🌐
Reddit
reddit.com › r/esp32 › esp32 cpu cycles
r/esp32 on Reddit: Esp32 cpu cycles
January 29, 2018 -

hello. first i am a beginner, and sorry for my english.

The esp32 runs at 240mhz (checked) that mean each cpu cycle is 4ns, and in one microseconds we got about 250 cycles right ?

i do a simple code

startCounter = ESP.getCycleCount();

delayMicroseconds(1);

counter = ESP.getCycleCount();

cpu_cycles = (counter - startCounter);

and got this:

startCounter:1210256656 Counter:1210257125 CpuCycles:469

why? 200 cycles overhead?