This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

BLE ANT App Timer

Hi all,

I have a firmware in which I want to use BLE and ANT communication (with Softdevice S310) to send and receive commands from other Nordic devices or smartphones. I also have 64 RGB LEDs WS2812 which have a specific communication protocol and I want to update the color of the LEDs at a given frequency. I plan to do that by instantiating an App Timer as described here.

It is important that the communication to the LEDs is not interrupted by any events or interrupts.

So I have BLE & ANT events as well as a timer handler.

What is the best way to handle this? It is important that the communication to the LEDs is not interrupted and that I can still communicate through BLE and ANT from time to time.

One possibility would be to setup a radio notification with ble_radio_notification_init(NRF_APP_PRIORITY_HIGH, NRF_RADIO_NOTIFICATION_DISTANCE_2680US,myradio_callback_handler); to know when the radio is active. Then I could set a flag each time I enter my Timeout handler to request for an update of the LEDs color. In the main loop, I could just check these two conditions to be active at the same time and then update the LEDs.

Is there a better way to do this? Would a Scheduler or a TImeslot API be more appropriate?

Best regards

  • Hello.

    In the WS2812 data sheet, we can see that the shortest pulse we must send is 0.35 uS. The lowest time we can count with the app_timer is 32 uS, because it uses the 32khz RTC timer.

    You can find a library for using ws2812 with the nRF51 on this github page. This implementation bit-bangs the protocol using assembly. This is the most common way of interfacing to the ws2812 (afaik). They also included a note about using the lib with a softdevice. As you suggested, it uses the radio notification API.

    Sending data to one led will take about 32 uS. Since it is so fast, it is ok to just do a blocking implementation (bit banging). Just do it right after the radio events are finished.

    The timeslot API could also be used, but you would not be guaranteed a slot 100% periodically.

    -Anders

  • Thanks for the answer, Anders. Yes I have seen this code for the WS2812 and I am using it already. My concern is that I need to update the colors of the LEDs more often than just at the single moment where the radio events are finished. I was then thinking of updating the LEDs in the main loop based on the status of a flag set in the radio callback as defined here:

    void myradio_callback_handler(bool radio_active)
    {
    	if (radio_active) // radio going active
    	{
    		bNeoShow = false;
    	}
    	else if (radio_active == false) //radio inactive
        {
    		bNeoShow = true;
        }
    }
    
  • With BLE only, one can schedule things between connection events using the app_timer. With ANT trown into the mix, things will be a bit more complex. What you can try is the following: Create an app_timer which updates the led at the frequency you want (probably 20+ Hz?). In the timer event handler, check if it is "safe" to update the leds. You can check this by checking if the radio is being used soon with the radio event notifications. In this way, you will lose some led updates here and there, but it might be few enough that you won't notice.

  • I have 64 LEDs to update. That makes 64 * 32us = 2048us Is that ok to update the LEDs in the timer event handler itself? I thought that it was good practice to have few instructions executed in a short amount of time in the event handlers in general...

  • It depends on wether or not is would stop other more important things from executing. If you do not have important stuff in main() or in other interrupt handler, it should be fine. But yes, it is a good rule of thumb to keep interrupt handlers short :)

Related