Polling vs.Interrupts

Programming bare-metal microcontrollers without any kind of RTOS or scheduler mainly leads to the architectural decision: Polling or Interrupts.
This section will give a short overview of how both design patterns work.


Polling is a simple approach to get a first prototype running. Most programs look like this:

void main() {

The program starts with an initialization. After this, everything will be handled in a while loop, where the inputs will be polled cyclically – in this case every 100 milliseconds plus the execution time the program. Waiting for x milliseconds does not need to be realized in a blocking delay function, it also can be done by using sleep modes and a timer interrupt. But the main idea of polling is cyclic reacting on events.
For applications where events/inputs only rarely occur, this is not a good design choice, as the sensors are read frequently. This will lead to higher power consumption.


Using interrupts is the second approach, where the system reacts on interrupts, which can occur asynchronously. Thus, the system does not need to cyclically poll the inputs. The normal execution of the program will be interrupted and it jumps to the Interrupt Service Routine (ISR), which then will be executed. Typically, the execution of the ISR should be as fast as possible, as other interrupts could occur while executing the ISR. Therefore, bool flags are commonly used, which serve as memory. A simple implementation look like this:

int main() {
	while(true) {
		if(bool_flag1 == true) {
			bool_flag1 = false;
		if(bool_flag2 == true) {
			bool_flag2 = false;
		// sleep_mode();

ISR_1 {
	bool_flag1 = true;

ISR_2 {
	bool_flag2 = true;

Each ISR uses one specific boolean flag, which stores wherever an interrupt has occurred. This pattern is often combined with a sleep mode, so that the microcontroller’s CPU is only active after an interrupt. This pattern is often used for low power applications, which are powered by batteries.