[SOLVED] My function for microseconds delay doesn't work properly

filo_gr
Posts: 110
Joined: Wed Jul 28, 2021 12:25 pm
Location: Italy

[SOLVED] My function for microseconds delay doesn't work properly

Postby filo_gr » Thu Sep 09, 2021 6:57 am

Hello community,

I made a function that should be able to create a delay for a certain number of microseconds, here the code.

Code: delay_us.cpp Select all


void delay_us(uint64_t number_of_us){
// Initializing the variable with the time BEFORE the count.
uint64_t microseconds = esp_timer_get_time();
// Starting the count, it exits when it is greater than number_of_us.
while(number_of_us <= (esp_timer_get_time() - microseconds));
}
As you can see I measure the time between two instants using esp_timer_get_time() (this funcion returns an uint64_t with the number of microseconds starting from the power up).
I encountered the following problem when using it: if I use a value such as delay_us(20), it doesn't work!
Driving a pin (from high to low and vice versa) with a period of 40us I see, using an oscilloscope, that the time is not respected.
The period time is more or less 7us, very far from 40us (it is 3us low and 3us high!!!!).
That's not all! If I put delay_us(1000) the result doesn't change...

What am I doing wrong?
Last edited by filo_gr on Wed Sep 15, 2021 7:25 am, edited 1 time in total.
Filippo


filo_gr
Posts: 110
Joined: Wed Jul 28, 2021 12:25 pm
Location: Italy

Re: My function for microseconds delay doesn't work properly

Postby filo_gr » Thu Sep 09, 2021 7:47 am

Thank you @WiFive, however I also found my mistake (I think and I ask for a confirm).
Firstly, I didn't included esp_timer.h, I think the compiler didn't recognize esp_timer_get_time() and that's why it wasn't working (but no errors during compiling). Am I right?
Then, I tried your esp_rom_delay_us but it gives a possible problem (and here the second question): it stops the processor for a certain time, giving the impossibility of performing other tasks. It's true?
Filippo

filo_gr
Posts: 110
Joined: Wed Jul 28, 2021 12:25 pm
Location: Italy

Re: My function for microseconds delay doesn't work properly

Postby filo_gr » Thu Sep 09, 2021 9:40 am

I want to give a complete explanation of what I did.
1) Using esp_timer_get_time() I need to write an #include "esp_timer.h". The lines of code resulting from this choice are:

Code: Untitled.cpp Select all


void delay_us(uint64_t number_of_us){
uint64_t microseconds = (uint64_t)esp_timer_get_time();
if(number_of_us){
uint64_t total = (microseconds + number_of_us);
if(microseconds > total){
while((uint64_t)esp_timer_get_time() > total);
}
while((uint64_t)esp_timer_get_time() < total);
}
}
It works, however with a small value of number_of_us it could be imprecise.

2) On the other hand I can use esp_rom_delay_us and so I need #include "esp_rom_sys.h".

Code: Untitled.cpp Select all


void delay_us(uint64_t number_of_us){
esp_rom_delay_us((uint32_t)number_of_us);
}
Here the microprocessor waits util the time is passed.

What of these approaches is the best?
Filippo

User avatar
mbratch
Posts: 317
Joined: Fri Jun 11, 2021 1:51 pm

Re: My function for microseconds delay doesn't work properly

Postby mbratch » Thu Sep 09, 2021 5:20 pm

When using unsigned values, if you do the math in the right place, the overflow takes care of itself. So I think your first option could look like this:

Code: Select all

void delay_us(uint64_t number_of_us) {
    uint64_t microseconds = (uint64_t)esp_timer_get_time();
    if (number_of_us) {
        while ((uint64_t)esp_timer_get_time() - microseconds < number_of_us) ;
    }
}
At first glance, this appears to be incorrect if `esp_timer_get_time()` overflows back to 0 before the difference reaches `number_of_us`. But this is not the case. The "unsigned math" works in your favor. :)

Actually, in your first post, you just about had it right. You just had the inequality reversed.
Last edited by mbratch on Thu Sep 09, 2021 9:25 pm, edited 2 times in total.

igrr
Espressif staff
Espressif staff
Posts: 2077
Joined: Tue Dec 01, 2015 8:37 am

Re: My function for microseconds delay doesn't work properly

Postby igrr » Thu Sep 09, 2021 5:23 pm

if `esp_timer_get_time()` overflows back to 0
Luckily, this shouldn't happen in a long long time :D

User avatar
mbratch
Posts: 317
Joined: Fri Jun 11, 2021 1:51 pm

Re: My function for microseconds delay doesn't work properly

Postby mbratch » Thu Sep 09, 2021 6:52 pm

if `esp_timer_get_time()` overflows back to 0
Luckily, this shouldn't happen in a long long time :D
Haha yep

chegewara
Posts: 2505
Joined: Wed Jun 14, 2017 9:00 pm

Re: My function for microseconds delay doesn't work properly

Postby chegewara » Thu Sep 09, 2021 9:48 pm

Easier to use:

Code: Select all

ets_delay_us(); == esp_rom_delay_us();
no problem with header file.

filo_gr
Posts: 110
Joined: Wed Jul 28, 2021 12:25 pm
Location: Italy

Re: My function for microseconds delay doesn't work properly

Postby filo_gr » Fri Sep 10, 2021 6:15 am

Thank you for your replies!
@mbratch, with your message, now I understand why my first piece of code wasn't working, the condition was wrong! :lol:
Hence if I use the esp_rom_delay_us (instead of the while loop and esp_timer_get_time) it should not give any kind of problem.
Filippo

Who is online

Users browsing this forum: ChatGPT-User and 1 guest