Hardware timer is a common and important feature of microcontrollers. It is also one of the features that are considered by the Engineers while selecting a microcontroller for a particular application. While making the selection, the Engineer mainly tends to check the number of hardware timers supported by the microcontroller and what is the timing resolution it can provide. Generally, most of the microcontrollers have support for 16 and 32-bit timers, but the number of timers supported is specific to each controller. For example, the ESP8266EX and ESP8266MOD have just one 32-bit hardware timer while the TICC3200 has four 32-bit timers. One of the reasons why TICC3200 is more expensive than the ESP8266 🙂
A few reasons why I would use a hardware timer are as follows:
- I want to generate interrupts at very tight or short timing intervals. This again depends on your microcontrollers clock frequency and timer’s resolution.
- I want the timing to be highly precise because I am working on a timing critical application. So, If you don’t want to compromise with timing variations or miss on an external event, then go for a hardware timer.
- I don’t like using the polling mechanism because it adds to the processing overhead. Then, I would definitely get rid of the polling mechanism by using a timer.
The usage of the hardware timers differs from one microcontroller to another. But the principle working of these timers are same in all microcontrollers i.e. they have a counter that will either count up or down. The number of count steps and the clock frequency will determine the timing. To know more about how the timers work, please click here.
In this article, I will be demonstrating how to use the hardware timer on the ESP8266. The demonstration will lead to some in-depth understanding of how to test, debug and validate your code by performing some timing analysis. When you write a code to use a hardware timer to generate interrupts at regular intervals of time, It is always important that the Engineer should check if his/her code is meeting the timing requirements and is consistent. Making this as a practice will avoid any future complications.
1. Environment Setup – ESP8266 Hardware Timer
The image shows the environment setup to test the hardware and code. I am using the Saleae Logic Analyzer to test the code. I have programmed the NodeMCU such that, the timer will trigger an interrupt every 150 or 250us i.e. The program will execute an ISR every 150 or 250us. The ISR will toggle a GPIO everytime the interrupt occurs.
If you do not have a DSO or USB Logic Analyzer, it would be quite difficult to perform any timing analysis or test your code, especially when evaluating a new controller. However, if you believe that you have programmed it right, then it should work as expected.
Interrupts that need to occur for timing range of 50ms or greater can be rawly tested using an LED e.g. toggling a LED every time the interrupt occurs. You cannot use this LED test method for testing interrupts that would occur for very tight timing intervals such as for less than 50ms.
And for interrupts occurring at microseconds, don’t even think about using the LED method for testing. Because the LED will be toggling at such a fast rate that a normal human eye will not be able to capture it. This is when equipment/devices such as DSO’s and Logic Analyzers play an important role. Ok, enough of the talk and let’s see the code 🙂
2. ESP8266 Hardware Timer – Code
The official ESP8266 SDK provides a bunch of API’s that makes it very easy to use the hardware timer. Thanks to the open source community developers for making most of the API’s to be available in the OpenSDK.To learn more about the hardware timer API’s used in my example project and understand their usage, please refer the ESP8266 API Reference Document.
You can check out and download the example code/project from my Github repository here or clone it by running the below command.
git clone https://github.com/deeplyembeddedWP/ESP8266_HardwareTimer_Interrupt.git
Before looking into the code, I would also recommend you to check out my post on how I use the Arduino GPIO API’s with the OpenSDK here. I ported the ESP8266 GPIO control functions from the Arduino core libraries to the OpenSDK. As I had got annoyed with the usage of the GPIO API’s provided in the Espressif SDK.
The project will consist of a file named “user_hw_timer.c” which consists of definitions of all the hardware timer API’s. I found this source file in Espressif forum shared by one of the Espressif folks. The project consists of another file named “user_timer_interrupt.c” which I have written. This source file shows the examples of how we can use the hardware timer to generate interrupts using the hardware timer API’s.
I have written the code such that, you can generate interrupt either for at 150us or 250us. This can be controlled by commenting or uncommenting the MACRO shown below in the “user_timer_interrupt.c” source file.
/* Arm timer to trigger every 150us */
Also, take note that I have programmed the hardware timer to generate Non-Maskable Interrupts(NMI). NMI makes sure that no other interrupts or routines can interrupt this ISR. It will always give the highest priority to this ISR.
The above video shows how to build and flash the firmware onto the ESP8266. It also shows the Saleae Logic Analyzer in action i.e. capturing the GPIO toggling at every 150us that happens within the ISR.
3. Timing Analysis and Validation of the Code
In this section, we will check and validate if the code is actually doing what it is supposed to do. I will be performing a timing analysis using the USB Logic Analyzer. Let’s start by programming the ESP8266 to generate interrupts at every 150us.
In the above image, Channel 3 shows the GPIO_4 toggling at a rate of 150us. I have used the markers A1 and A2 to measure the timing. The time difference i.e.Δt, measured by the markers is 0.15ms. This can be seen as |A1-A2|=0.15ms in the right side corner of the image under “Annotations“.
Similarly, this time we program the ESP8266 to generate interrupts at every 250us. And again, Channel 3 shows the GPIO_4 toggling at a rate of 250us. The time difference i.e.Δt , measured by the markers this time is 0.25ms i.e. |A1-A2|=0.25ms.
Hence, from the above analysis, we can conclude that the timing is consistent and the code is doing what it is supposed to do. I hope you enjoyed reading this post and it gave you insights on how to work with timer interrupts on microcontrollers. In my next post, I will be coming up with something interesting, till then happy learning and Adios 😉