bcm2835 Library Precision Delay Problem - GitMasterNikanjam/RaspberryPi_WiKi GitHub Wiki

Problems With The Library

DelayMicroseconds() is a handy function but if you use it a lot you’ll find operation takes much longer than it should. This is because the function allows the linux scheduler to know the process is sleeping and decide to move on to another process.

The DelayMicroseconds() function in the bcm2835 library for Raspberry Pi is used to introduce a delay in the execution of code for a specified number of microseconds. However, there have been reported issues with the accuracy and reliability of this function. Some users have experienced inconsistencies in the actual delay produced by DelayMicroseconds(), especially for very short delays.

One common problem with DelayMicroseconds() is that it relies on busy-waiting, where the CPU is continuously looping and checking the current time to determine when the specified delay has passed. This approach can be imprecise due to factors such as CPU speed variations, system load, and interrupts.

A better alternative for time delay on Raspberry Pi or any other platform is to use operating system-provided functions or libraries specifically designed for precise timing. Here are some alternatives:

1- nanosleep(): This function is part of the POSIX standard and allows you to suspend the execution of a thread for a specified period of time with nanosecond precision. You can use it to introduce delays in your code.

2- usleep(): Similar to nanosleep(), usleep() suspends the execution of a thread but takes the delay time in microseconds. This function provides microsecond precision for time delays.

3- Timer APIs: Depending on your programming language and environment, you might have access to timer APIs that provide more accurate timing mechanisms. For example, in C++, you can use library for precise timing.

4- Hardware Timers: Raspberry Pi also has hardware timers that can be configured to generate accurate delays. This involves a bit more complexity but can provide very precise timing if needed.

5- Threading: In some cases, especially in event-driven or real-time systems, you might consider using threading mechanisms to handle delays asynchronously.

When selecting a method for time delay, consider the required precision, the platform you are working on, and any specific constraints or requirements of your application. Additionally, always test your chosen method to ensure it meets your timing accuracy needs.

here's an example using the usleep() function to introduce a delay of 1 millisecond (1000 microseconds) in a C program on a Raspberry Pi:

#include <stdio.h>
#include <unistd.h> // for usleep()

int main() {
    printf("Delaying for 1 millisecond...\n");
    usleep(1000); // Delay for 1000 microseconds (1 millisecond)
    printf("Delay complete!\n");
    return 0;
}

In this example:

  • We include the necessary header files (stdio.h for standard input/output functions and unistd.h for usleep() function).
  • Inside the main() function, we print a message indicating that we are delaying for 1 millisecond.
  • We then call usleep(1000) to introduce the delay. The argument 1000 specifies 1000 microseconds, which is equivalent to 1 millisecond.
  • After the delay, we print another message indicating that the delay is complete.
  • Finally, we return 0 to indicate successful execution of the program.
    Compile and run this program on your Raspberry Pi, and you should observe a delay of approximately 1 millisecond between the two printed messages.

Here are some libraries and mechanisms you can use for precise timing, hardware timers, and threading in various programming languages and environments:

1- nanosleep()

Library: POSIX standard library
Language: C/C++
Header file: <time.h>
Function: int nanosleep(const struct timespec *req, struct timespec *rem);
Example:

#include <time.h>
int main() {
    struct timespec delay = {0, 1000000}; // 1 millisecond
    nanosleep(&delay, NULL);
    return 0;
}

2- Timer APIs

Library: (C++)
Language: C++
Example:

#include <iostream>
#include <chrono>
#include <thread>

int main() {
    std::chrono::milliseconds duration(1000); // 1 second
    std::this_thread::sleep_for(duration);
    return 0;
}

3- Hardware Timers

Language: C/C++
Depending on your microcontroller or platform, hardware timers may have specific libraries or APIs. For example, on the Raspberry Pi, you might use the WiringPi library to access hardware timers.
Example (using WiringPi on Raspberry Pi):

#include <wiringPi.h>

int main() {
    wiringPiSetup();
    delayMicroseconds(1000); // 1 millisecond delay
    return 0;
}

4- Threading

Language: Various (e.g., C/C++, Python, Java)
Libraries:
C/C++: <pthread.h> (POSIX Threads)
Python: threading module
Java: java.lang.Thread class
Example (C/C++ using POSIX Threads):

#include <pthread.h>
#include <stdio.h>
#include <unistd.h>

void* thread_function(void* arg) {
    usleep(1000000); // 1 second delay
    printf("Thread execution complete.\n");
    return NULL;
}

int main() {
    pthread_t thread;
    pthread_create(&thread, NULL, thread_function, NULL);
    pthread_join(thread, NULL);
    printf("Main thread execution complete.\n");
    return 0;
}
⚠️ **GitHub.com Fallback** ⚠️