Skip to content

multiple tickers stop working #1378

Closed
Closed
@andrewjfox

Description

@andrewjfox

Hi, I've read about previous issues with tickers being resolved, however I'm having trouble and want to confirm if ticker functions are all ok. I'm using nRF51422 based board and nRF51-DK platform on mbed to generate FOTA files.

Code has BLE running. Problem occurs after several seconds when connected, or after 10's seconds when not connected.

Following is class used to drive RGB leds with single ticker for each led (there are 2 leds

#include "mbed.h"

class RGBColour
{
public:
    RGBColour(int r=0, int g=0, int b=0) {
        red = r;
        green = g;
        blue = b;
        brightness = 100;
    }    

    bool isOn(void) {
        if(!brightness) return false;
        if(!red && !green && !blue) return false;
        return true;
    }    

    int red;        // 0 - 100 %
    int green;
    int blue;
    int brightness; // 0 - 100 %
};



class RGBControl {
public:
#ifdef TARGET_DK
    const static int LED_ON    = 0;
    const static int LED_OFF   = 1;
#else
    const static int LED_ON    = 1;
    const static int LED_OFF   = 0;
#endif

    // 20ms PWM period with ? count resolution on RGB values
    // any faster and interrupts can't service in time
    const static float PWM_PERIOD = 0.025;
    const static int COUNTS_PER_PERIOD = 10;
    const static float SEC_PER_COUNT = (PWM_PERIOD / (float)COUNTS_PER_PERIOD);

    RGBControl(PinName red, PinName green, PinName blue) : _red(red), _green(green), _blue(blue) {  
        rgb(RGBColour(0,0,0)); 
    }

    /** @param RGB values
    */        
    void rgb(RGBColour c) {        
        _ticker.detach();
        _red = LED_OFF;
        _green = LED_OFF;
        _blue = LED_OFF;

        if(c.isOn()) {
            _tickerCompare[0] = (((c.red * c.brightness) / 100) * COUNTS_PER_PERIOD) / 100;
            _tickerCompare[1] = (((c.green * c.brightness) / 100) * COUNTS_PER_PERIOD) / 100;
            _tickerCompare[2] = (((c.blue * c.brightness) / 100) * COUNTS_PER_PERIOD) / 100;

            _tickerCount = COUNTS_PER_PERIOD;
            _ticker.attach(this, &RGBControl::tickerCallback, SEC_PER_COUNT);
        }    
    }

private:
    DigitalOut _red;
    DigitalOut _green;
    DigitalOut _blue;
    Ticker _ticker;
    int _tickerCount;
    int _tickerCompare[3];

    void tickerCallback(void)
    {
        if(++_tickerCount >= COUNTS_PER_PERIOD) { 
            _tickerCount=0;

            if(_tickerCompare[0]) _red = LED_ON;
            if(_tickerCompare[1]) _green = LED_ON;
            if(_tickerCompare[2]) _blue = LED_ON;
        }    

        if(_tickerCount == _tickerCompare[0]) _red = LED_OFF;
        if(_tickerCount == _tickerCompare[1]) _green = LED_OFF;
        if(_tickerCount == _tickerCompare[2]) _blue = LED_OFF;
    }  
};

if I drive a single LED, all good, if I drive 2 leds simultaneously, both of the tickers stop after several seconds.

RGBControl led1(LED1_RED,LED1_GREEN,LED1_BLUE);
RGBControl led2(LED2_RED,LED2_GREEN,LED2_BLUE);
...
while(1)
{
...
if(triggerEvent) {
    // call this every second, increments through colour table
    led1.rgb(colour[currentColour]);
    if(++currentColour >= COLOUR_MAX) currentColour = COLOUR_BLACK;
    led2.rgb(colour[currentColour]);

    triggerEvent = false;
}
...
}

Is there an issue with my code, or is it possibly an unresolved ticker issue?

Andrew

Some additional background:

  • my code has 1/2 doz other tickers and timers in main loop for various functions, but are all quite slow and haven't noticed any issues until led class started freezing
  • BLE functions keep working in background even when led class freezes
  • other gpio functions, that read inputs using InterruptIn and have timers for debouncing, also stop working when leds freeze

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions