C (9)

Adding Brightness Control to the BLE Lightbulb Example

In the previous post on using a BLE peripheral example, the LED2 could only be controlled in terms of two states, On and Off. With my background of lighting controls, I wasn't satisfied that this could be called a BLE lightbulb project without at least brightness control. Since the example BLE code is already set up to send a byte as the BLE characteristic value, it should be easy to expand the example to brightness control in percentage terms using the byte in the range 0 to 100. The main addition to the previous project is the PWM software module which sets up and controls the internal PWM hardware peripheral on the nRF52832. It is better to use an existing software module which encodes all the knowledge necessary to set up the PWM peripheral rather than just accessing the registers directly which would mean careful study of the datasheet with possible misinterpretation and that gives us an interface layer for future portability. The first location I tried looking for a reference example was SDK\examples\peripheral\led_softblink but it was not suitable for a couple of reasons. led_softblink uses a low power technique for the PWM which involves setting up the PWM timer and…

Continue reading...

Getting a Simple On/Off BLE Peripheral Example To Work

I was getting a little frustrated with the Nordic examples and tutorials all being not quite ready for use. Not as badly frustrated as this guy but there always seemed to be some mismatch between what was required and what I was using, even when I chose the preferred tools. OK, I made a mistake assuming that I should start with the nRF51-DK because that is a smaller, simpler, cheaper chip. Although when you look into pricing, you find that nRF51's are not necessarily cheaper So I got myself onto the nRF52-DK so that I could use the latest SDK 16 and the Segger SES toolchain, which meets all the requirements in the Getting Starting guide. After going through that, I wanted to find a tutorial that was written from outside Nordic Semi so that it could be more objective about the tools. Given that Mohammad Afaneh is presenting these Ellisys BT videos he seems to be an independent (of Nordic) expert, so his post on How to build the simplest nRF52 BLE Peripheral application (Lightbulb use case) seemed to be a good fit with what I wanted to learn and how to learn it. The rest of this post is my attempt to…

Continue reading...

Eliminate Useless Timer Interrupts by Coalescing Timers

While learning about RTOSes, I came across the idea of Timer Coalescing which improves performance by eliminating unnecessary context switches. But there is no reason that this technique cannot be applied to bare metal firmware (without RTOS). To test out how well it works, I implemented it using a STM32F4 discovery board. I wanted to see the improvement factor in a typical use case, so I decided on running 8 software timers on a 1ms timer peripheral. The software timers count down to 0 then reload themselves. From previous experience, typical periods were chosen for these timers of 1000, 200, 125, 50, 18, 27, 40 and 600ms. (If they had a common factor of say 5ms, then it would make more sense to use that as the peripheral timer rate, but it restricts the flexibility for future changes.) TIM6 was chosen because we only need a Basic 16 bit timer in the STM32F4 architecture. It runs off APB1 at 42 MHz (HCLK at 168 MHz). Prescaler was set to 41, Counter Period ARR set to 1999 for 1ms and auto-reload preload set to Disable. TIM6 interrupts were enabled. Once all this is set up in the Device Configuration Tool, all…

Continue reading...

Improving frequency measurement performance by factor of three on STM32 by using DMA

This Youtube video by Controllers Tech shows how to use an STM32 to measure the frequency of an incoming rectangular wave using the input capture functionality of the timers. The code shown the video works but there are a few areas which could be improved, as I will now discuss. Then I make a performance improvement by using DMA instead of interrupts. The code is written using STM's HAL library which means that it does not have to handle the specific STM32's registers, which makes it more portable. However, HAL is still specific to the ARM and STM architecture, so you need to know what features are available in your internal peripherals to be able to write HAL function calls with the appropriate parameters. Initialising Global variables Controllers Tech declares a set of global variables at the top of main.c and initialises them to zero. Since we can rely on the C runtime to clear the RAM, this is unnecessary for globals and can use up code space and boot time. I would remove the initialisations unless it is thought likely that these lines would be moved into a function, making them local automatic variables, in which case they would need to be…

Continue reading...