Have you ever wanted to treat button presses in Arduino similar to other languages, where you get an event callback when the switch is pressed? Look no further, the IO abstraction library can do that with very little fuss. In fact it can also do the same for rotary encoders as well, treating them similar to how scroll bars work in desktop applications. To start we need to get the IoAbstraction library and open the buttonRotartyEncoder example.
In this tutorial for IoAbstraction’s taskManager I explain the differences between traditional loop based programming; which is very common on the Arduino platform and event based programming based on taskManager. Although event based programming looks slightly more complicated at first, as the sketch and surrounding code gets more complex, eventing will scale to that much easier. Eventing task frameworks make ongoing maintenance much easier. Example: Two LEDs blink at different rates.
Along with TaskManagerIO that tries to keep a consistent user level API regardless of the platform, IoAbstraction also has only very small differences across platforms. We support nearly all official (and many unofficial) Arduino devices, most ESP devices and many mbed boards too. Known working devices Processor Platform Tested? Analog Digital Example developer boards AVR Arduino Fully ADC,PWM Pin, Int Uno, AT32x, MEGA 2560, MightyCore SAMD Arduino Fully ADC,PWM,DAC Pin, Int MKR, Nano IoT and Zero nrf52840 Arduino Fully ADC,PWM,DAC Pin, Int Nano 33 BLE devices ESP8266 Arduino Fully ADC,PWM Pin, Int Huzzah, Node MCU ESP32 Arduino Fully ADC,PWM,DAC Pin, Int Wifi32, Huzzah 32 STM32F* mbed Fully ADC,PWM,DAC Pin, Int Discovery, Nucleo etc STM32 Arduino User Report Not tested Pin, Int Blue pill Key:
In summary, task manager supports a wide range of hardware, including nearly every official Arduino board, most ESP boards, many mbed version 5 and 6 boards with or without an RTOS. We mainly test mbed with STM32 and nrf52 hardware. What boards does TaskManagerIO support? Processor Platform Tested? Locking Example developer boards AVR Arduino Fully Atomic Uno, AT32x, MEGA 2560, MightyCore SAMD Arduino Fully Atomic MKR, Nano IoT and Zero nrf52840 Arduino Fully CAS Nano 33 BLE devices ESP8266 Arduino Fully Atomic Huzzah, Node MCU ESP32 Arduino Fully CAS Wifi32, Huzzah 32 STM32F* mbed Fully CAS Discovery, Nucleo etc STM32 Arduino User Report Atomic Blue pill For mbed we support both RTOS and BareMetal versions 5 and 6, and we test on several STM32 boards.
Interrupt handling is generally an advanced topic, but this library provides a very simple way to handle interrupts. There are two ways to handle interrupts in TaskManagerIO, the first is by marshalling, and the second is by writing an event. We recommend that all new code uses the event method to handle interrupts, although we have no plans to deprecate the method below. When you tell the library to handle an interrupt, the library registers the interrupt handler on your behalf, then when the condition is met the internal handler is triggered, it sets a flag to tell the library an interrupt has been raised.
In this guide we assume that you are familiar with the API for scheduling tasks on task manager. Let’s first discuss what we consider an event to be, and what it means to be an interrupt or threaded event. Interrupt or threaded events are subject to external actors (such as threads or interrupts). In this case the event will invariably be triggered by an external event. However, task manager will still ask your event class instance if it is ready to be triggered yet by polling, but in this case you have two choices as listed out below:
In this guide we assume that you are familiar with the API for scheduling tasks on task manager. Let’s first discuss what we consider an event to be, and what it means to be a polled event. By polling we mean no external actors (such as threads or interrupts) are involved. Task manager will ask your event instance frequently if it is ready to be triggered yet, if it is not then task manager will take your instruction on how long to wait, and then call again.
Using TaskManager in your sketches TaskManager is a very simple co-operative coroutines / executor framework that allows work to be scheduled in an internal queue. Instead of writing code using delays, one simply adds jobs to be done at some point in the future. In addition to this, interrupt handling is also supported, such that the interrupt is “marshalled” and handled like a very high priority task to be processed immediately.
Using SwitchInput in your sketches SwitchInput is a button and rotary encoder management library that treats button presses and encoder adjustments as events, similar to web and UI applications. Supporting as many switches and rotary encoders as you need, in a completely event driven way, working along with TaskManagerIO to keep your code clean. Key points: Buttons using either pull down or pull up logic connected directly or via any supported IO expander De-bouncing of events on all buttons and encoders to significantly reduce duplicate callbacks.
Troubleshooting IO issues using LoggingIoAbstraction Within the MockIoAbstraction.h header there is an implementation of BasicIoAbstraction that delegates through a logging layer. If you are having difficulty determining what your code is sending and receiving, this could be useful. Unit testing support within the library This library itself is quite well tested using AUnit, and further it makes unit testing your code easier. There is a MockIoAbstraction that provides very easy support for mocking out an IoAbstraction.