![](/media/cache/group/ST_logo_2020_blue_V_cmyk.jpg.50x50_q85.jpg)
Test application for the STMicroelectronics X-NUCLEO-LED61A1 LED Control Expansion Board showing several LED control modes, built against mbed OS.
Dependencies: X_NUCLEO_LED61A1
Fork of LedDimming_LED61A1 by
LED Control with the X-NUCLEO-LED61A1 Expansion Board
This application provides an example of usage of the X-NUCLEO-LED61A1 LED Control Expansion Board. It shows how to control a LED stripe load connected to the board through the following control modes:
- Manual PWM Dimming;
- Manual Analog Dimming;
- Sinusoidal PWM Dimming;
- Sinusoidal Analog Dimming;
- Photo-based Analog Dimming.
The button of the MCU board, when available, can be used in the following ways:
- Short Button Press [<0.5s] for Manual Dimming;
- Medium Button Press to Switch Demo;
- Long Button Press [>2s] to Switch Power ON/OFF.
The program starts in mode 1.
Diff: main.cpp
- Revision:
- 2:dbd596540d46
- Parent:
- 1:1c01b873ad45
- Child:
- 3:ed347127fc38
--- a/main.cpp Mon Dec 14 17:43:47 2015 +0000 +++ b/main.cpp Thu Dec 17 18:13:57 2015 +0000 @@ -48,235 +48,235 @@ /* Definitions ---------------------------------------------------------------*/ -#define LOOP_PERIOD_us 1E6 +/* Loop period in micro-seconds. */ +#define LOOP_PERIOD_us 1E6 + +/* Duration of button press in milli-seconds. */ +#define SWITCH_DEMO_BUTTON_PRESS_ms 500 +#define SWITCH_POWER_BUTTON_PRESS_ms 2000 + +/* Dimming Step. */ +#define DIMMING_STEP 0.1f + + +/* Types ---------------------------------------------------------------------*/ + +/* Demos. */ +typedef enum +{ + PWM_DIMMING_STEPS = 0, + ANALOG_DIMMING_STEPS, + PWM_DIMMING_VARY, + ANALOG_DIMMING_VARY, + ANALOG_DIMMING_PHOTO, + LED_DEMO_SIZE +} LED_Demo_t; + +/* Actions. */ +typedef enum +{ + SWITCH_POWER = 0, + SWITCH_DEMO, + SWITCH_STATE, + NO_ACTION +} LED_Action_t; /* Variables -----------------------------------------------------------------*/ -/* LED Control Component. */ -LED6001 *led; - -/* User Button. */ -static InterruptIn button(USER_BUTTON); +/* Main loop's ticker. */ +static Ticker ticker; -/* Interrupt flags. */ -static volatile boolean button_irq_triggered = false; -static volatile boolean xfault_irq_triggered = false; -static volatile boolean timer_irq_triggered = false; - -/* Timer. */ -static Ticker ticker; +/* User Button's interrupt. */ +static InterruptIn button(USER_BUTTON); /* MCU Board's Led which provides the user with a visual feedback on the user button's status (ON = pressed, OFF = released). */ DigitalOut button_pressed_led(LED1); -/* Flags to control the demo. */ -static volatile boolean next_demo_state = false; -static volatile boolean next_demo = false; +/* LED Control Component. */ +LED6001 *led; + +/* Interrupt flags. */ +static volatile bool ticker_irq_triggered; +static volatile bool button_irq_triggered; +static volatile bool xfault_irq_triggered; + +/* Demo State. */ +static volatile LED_Demo_t demo; +static volatile LED_Action_t action; +static volatile bool power_on; + +/* PWM and Analog dimming values. */ +static float pwm_dimming; +static float analog_dimming; + +/* Demos' Names. */ +static char* demos[] = +{ + "Manual PWM Dimming", + "Manual Analog Dimming", + "Cyclic PWM Dimming", + "Cyclic Analog Dimming", + "Photo-based PWM Dimming" +}; /* Functions -----------------------------------------------------------------*/ /** - * @brief State machine initialization - * @param demo - selected demo - * p - reference to pwm dimming level - * a - reference to analog dimming level - * @retval None + * @brief Initilizing the demo. + * @param None. + * @retval None. */ -void SM_Init(LED_DRIVER_Demo* demo, uint8_t* p, uint8_t* a) +void LEDInit(void) { -ChangeDemoState = 0; -NextDemo = 0; -ReInit_LED_Driver = 0; + /* Initializing Interrupt flags. */ + button_irq_triggered = false; + xfault_irq_triggered = false; + ticker_irq_triggered = false; -*p = MAX_BRIGHT_PDIM; -*a = MAX_BRIGHT_ADIM; -*demo = PWM_DIMMING_STEPS; + /* Initializing Demo. */ + power_on = true; + action = SWITCH_DEMO; + demo = (LED_Demo_t) (LED_DEMO_SIZE - 1); + + /* Initializing PWM and Analog dimming to maximum values. */ + pwm_dimming = 1.0f; + analog_dimming = 1.0f; } /** - * @brief Interrupt Request for the timer-related interrupt. - * @param None - * @retval None + * @brief Handling the LED capabilities and executing several demos. + * @param None. + * @retval None. */ -void TimerIRQ(void) +void LEDHandler(void) { - timer_irq_triggered = true; + /* Switching LED power ON/OFF. */ + if (action == SWITCH_POWER) + power_on = !power_on; + + /* Handling the LED when powered ON. */ + if (power_on) + { + /* Switching to the next demo. */ + if (action == SWITCH_DEMO) + { + pwm_dimming = 1.0f; + analog_dimming = 1.0f; + demo = (LED_Demo_t) ((demo + 1) % LED_DEMO_SIZE); + } + + /* Setting the LED depending on the selected demo. */ + switch (demo) + { + /* Changing PWM dimming according to the user button. */ + case PWM_DIMMING_STEPS: + if (action == SWITCH_STATE) + { + pwm_dimming -= DIMMING_STEP; + pwm_dimming = (pwm_dimming <= 0.0f ? 1.0f : pwm_dimming); + } + break; + + /* Changing Analog dimming according to the user button. */ + case ANALOG_DIMMING_STEPS: + if (action == SWITCH_STATE) + { + analog_dimming -= DIMMING_STEP; + analog_dimming = (analog_dimming <= 0.0f ? 1.0f : analog_dimming); + } + break; + + /* Changing PWM dimming continuously. */ + case PWM_DIMMING_VARY: + pwm_dimming -= DIMMING_STEP; + pwm_dimming = (pwm_dimming <= 0.0f ? 1.0f : pwm_dimming); + //wait_ms(50); + action = SWITCH_STATE; + break; + + /* Changing Analog dimming continuously. */ + case ANALOG_DIMMING_VARY: + analog_dimming -= DIMMING_STEP; + analog_dimming = (analog_dimming <= 0.0f ? 1.0f : analog_dimming); + //wait_ms(500); + action = SWITCH_STATE; + break; + + /* Setting Analog dimming according to the photo sensor. */ + case ANALOG_DIMMING_PHOTO: + //analog_dimming = (uint8_t) (led->GetCurrent() * ADC_RANGE / 72 + 8); + analog_dimming = ((1.0f - led->GetCurrent()) * (1.0f - DIMMING_STEP) + DIMMING_STEP); + //wait_ms(100); + action = SWITCH_STATE; + break; + } + } + + /* Writing PWM and Analog dimming values to the LED and printing to the console. */ + if (action != NO_ACTION) + { + if (action == SWITCH_POWER) + if (power_on) + { + /* Initializing PWM and Analog dimming to maximum values. */ + pwm_dimming = 1.0f; + analog_dimming = 1.0f; + + /* Printing to the console. */ + printf("Power ON\r\n"); + } + else + { + /* Powering OFF the LED. */ + led->PowerOFF(); + + /* Printing to the console. */ + printf("Power OFF\r\n"); + } + + if (power_on) + { + /* Writing PWM and Analog dimming values to the LED. */ + led->SetPWMDimming(pwm_dimming); + led->SetAnalogDimming(analog_dimming); + + /* Printing to the console. */ + printf("%-24s PWM/Analog: %.3f %.3f\r\n", demos[demo], pwm_dimming, analog_dimming); + } + + /* Resetting action. */ + action = NO_ACTION; + } +} + +/** + * @brief Interrupt Request for the main loop's ticker related interrupt. + * @param None. + * @retval None. + */ +void TickerIRQ(void) +{ + ticker_irq_triggered = true; +} + +/** + * @brief Interrupt Request for the user button's interrupt. + * @param None. + * @retval None. + */ +void ButtonIRQ(void) +{ + button_irq_triggered = true; button.disable_irq(); } /** -* @brief Handling the LED capabilities and executing several demos. -* @param None -* @retval None -*/ -void LEDHandler(void) -{ - static LED_DRIVER_Demo SM_Demo; - static uint8_t pDim; - static uint8_t aDim; - uint8_t pDim1,pDim2,pDim3; - uint8_t aDim1,aDim2,aDim3; - - /* If LED driver is not to be reinitialized */ - if (!ReInit_LED_Driver) - { - /* Update state machine parameters */ - SM_Update(&SM_Demo,&pDim,&aDim); - - /* Change running demo and transmit serial information */ - if (NextDemo == 1) - { - pDim = MAX_BRIGHT_PDIM; - aDim = MAX_BRIGHT_ADIM; - - if (SM_Demo == PWM_DIMMING_STEPS) - { - SM_Demo = ANALOG_DIMMING_STEPS; - disp.Len = strlen((char*)Msg_Demo2_Line1); - memcpy(disp.Data,Msg_Demo2_Line1,disp.Len); - UART_SendMsg(&disp); - } - else if (SM_Demo == ANALOG_DIMMING_STEPS) - { - SM_Demo = PWM_DIMMING_VARY; - disp.Len = strlen((char*)Msg_Demo3_Line1); - memcpy(disp.Data,Msg_Demo3_Line1,disp.Len); - UART_SendMsg(&disp); - } - else if (SM_Demo == PWM_DIMMING_VARY) - { - SM_Demo = ANALOG_DIMMING_VARY; - disp.Len = strlen((char*)Msg_Demo4_Line1); - memcpy(disp.Data,Msg_Demo4_Line1,disp.Len); - UART_SendMsg(&disp); - } - else if (SM_Demo == ANALOG_DIMMING_VARY) - { - SM_Demo = ANALOG_DIMMING_PHOTO; - disp.Len = strlen((char*)Msg_Demo5_Line1); - memcpy(disp.Data,Msg_Demo5_Line1,disp.Len); - UART_SendMsg(&disp); - } - else if (SM_Demo == ANALOG_DIMMING_PHOTO) - { - SM_Demo = PWM_DIMMING_STEPS; - disp.Len = strlen((char*)Msg_Demo1_Line1); - memcpy(disp.Data,Msg_Demo1_Line1,disp.Len); - UART_SendMsg(&disp); - } - } - - switch (SM_Demo) - { - /* PWM changes with PB action */ - case PWM_DIMMING_STEPS: - aDim = MAX_BRIGHT_ADIM; - if (ChangeDemoState) - { - pDim = pDim - 10; - if (pDim < MIN_BRIGHT_PDIM) - pDim = MAX_BRIGHT_PDIM; - - disp.Len = strlen((char*)Msg_Demo1_Line2); - memcpy(disp.Data,Msg_Demo1_Line2 ,disp.Len); - pDim1 = pDim/100; - if (pDim1 == 1) - { - pDim2 = 0; pDim3 = 0; - disp.Data[disp.Len] = pDim1+0x30; - disp.Data[disp.Len+1] = pDim2+0x30; - disp.Data[disp.Len+2] = pDim3+0x30; - disp.Data[disp.Len+3] = '%'; - disp.Len+=4; - } - else - { - pDim2 = pDim/10; pDim3 = pDim%10; - disp.Data[disp.Len] = pDim2+0x30; - disp.Data[disp.Len+1] = pDim3+0x30; - disp.Data[disp.Len+2] = '%'; - disp.Len+=3; - } - disp.Data[disp.Len] = '\n'; - disp.Data[disp.Len+1] = '\r'; - disp.Len += 2; - UART_SendMsg(&disp); - } - break; - /* Analog dimming changes with PB action */ - case ANALOG_DIMMING_STEPS: - pDim = MAX_BRIGHT_PDIM; - if (ChangeDemoState) - { - aDim = aDim - 5; - if (aDim < MIN_BRIGHT_ADIM) - aDim = MAX_BRIGHT_ADIM; - - disp.Len = strlen((char*)Msg_Demo2_Line2); - memcpy(disp.Data,Msg_Demo2_Line2 ,disp.Len); - aDim1 = aDim/100; - if (aDim1 == 1) - { - aDim2 = 0; aDim3 = 0; - disp.Data[disp.Len] = aDim1+0x30; - disp.Data[disp.Len+1] = aDim2+0x30; - disp.Data[disp.Len+2] = aDim3+0x30; - disp.Data[disp.Len+3] = '%'; - disp.Len+=4; - } - else - { - aDim2 = aDim/10; aDim3 = aDim%10; - disp.Data[disp.Len] = aDim2+0x30; - disp.Data[disp.Len+1] = aDim3+0x30; - disp.Data[disp.Len+2] = '%'; - disp.Len+=3; - } - disp.Data[disp.Len] = '\n'; - disp.Data[disp.Len+1] = '\r'; - disp.Len += 2; - UART_SendMsg(&disp); - } - break; - /* PWM dimming changes continuously */ - case PWM_DIMMING_VARY: - aDim = MAX_BRIGHT_ADIM; - pDim--; - if (pDim < MIN_BRIGHT_PDIM) - pDim = MAX_BRIGHT_PDIM; - HAL_Delay(50); - break; - /* Analog dimming changes continuously */ - case ANALOG_DIMMING_VARY: - pDim = MAX_BRIGHT_PDIM; - aDim-=3; - if (aDim < MIN_BRIGHT_ADIM) - aDim = MAX_BRIGHT_ADIM; - HAL_Delay(500); - break; - /* Analog dimming changes based on photo sensor value */ - case ANALOG_DIMMING_PHOTO: - pDim = MAX_BRIGHT_PDIM; - aDim = (uint8_t)(((BSP_Photo_Sensor_GetVal()>>3)+72)/9); - HAL_Delay(100); - break; - } - - BSP_SetPwmDim(pDim); - BSP_SetAnaDim(aDim); - - ChangeDemoState = 0; - NextDemo = 0; - } -} - -/** - * @brief Interrupt Request for the XFAULT interrupt. - * @param None - * @retval None + * @brief Interrupt Request for the component's XFAULT interrupt. + * @param None. + * @retval None. */ void XFaultIRQ(void) { @@ -285,42 +285,15 @@ } /** - * @brief Interrupt Handler for the XFAULT interrupt. - * @param None - * @retval None - */ -void XFaultHandler(void) -{ - printf("XFAULT Interrupt detected! Re-initializing LED driver...\r\n"); - -BSP_SetPwmDim(ZERO); -BSP_SetAnaDim(ZERO); - -SM_Init(&SM_Demo,&pDim,&aDim); -BSP_SetPwmDim(pDim); -BSP_SetAnaDim(aDim); - - led->EnableXFaultIRQ(); -} - -/** - * @brief Interrupt Request for the user button interrupt. - * @param None - * @retval None - */ -void ButtonIRQ(void) -{ - button_irq_triggered = true; - button.disable_irq(); -} - -/** - * @brief Interrupt Handler for the user button interrupt. - * @param None - * @retval None + * @brief Interrupt Handler for the user button's interrupt. + * @param None. + * @retval None. */ void ButtonHandler(void) { + /* User Button's timer to measure the time the button remains pressed. */ + static Timer button_pressed_timer; + bool button_pressed_flag = (button.read() == 0 ? true : false); if (button_pressed_flag) @@ -334,10 +307,13 @@ button_pressed_timer.stop(); /* Either changing current demo's state or switching to the next demo. */ - if (button_pressed_timer.read_ms() < 1000) - next_demo_state = true; + int time_pressed = button_pressed_timer.read_ms(); + if (time_pressed < SWITCH_DEMO_BUTTON_PRESS_ms) + action = SWITCH_STATE; + else if (time_pressed < SWITCH_POWER_BUTTON_PRESS_ms) + action = SWITCH_DEMO; else - next_demo = true; + action = SWITCH_POWER; button_pressed_timer.reset(); } @@ -345,6 +321,22 @@ button.enable_irq(); } +/** + * @brief Interrupt Handler for the component's XFAULT interrupt. + * @param None. + * @retval None. + */ +void XFaultHandler(void) +{ + /* Printing to the console. */ + printf("XFAULT Interrupt detected! Re-initializing LED driver...\r\n"); + + /* Re-initializing the demo. */ + LEDInit(); + + led->EnableXFaultIRQ(); +} + /* Main ----------------------------------------------------------------------*/ @@ -352,38 +344,32 @@ { /*----- Initialization. -----*/ + /* Printing to the console. */ + printf("LED Control Application Example\r\n\n"); + /* Initializing LED Control Component. */ - led = new LED6001(D4, A3); - - /********** NOT USED, TBC *********/ - LED_DRIVER_InitTypeDef init = - { - LED6001_PDIM_FULL, - LED6001_ADIM_FULL - }; - - if (led->Init(&init) != COMPONENT_OK) + led = new LED6001(D4, A3, D6, D5); + if (led->Init() != COMPONENT_OK) exit(EXIT_FAILURE); /* Attaching interrupt request functions. */ button.fall(ButtonIRQ); button.rise(ButtonIRQ); led->AttachXFaultIRQ(&XFaultIRQ); - ticker.attach_us(TimerIRQ, LOOP_PERIOD_us); + ticker.attach_us(TickerIRQ, LOOP_PERIOD_us); -SM_Init(&SM_Demo,&pDim,&aDim); - - /* Printing to the console. */ - printf("LED Control Application Example\r\n\n"); + /* Initializing the demo. */ + LEDInit(); /*----- LED Control. -----*/ + /* Either performing the component handler, interrupt handlers, or waiting for events. */ while (true) { - if (timer_irq_triggered) + if (ticker_irq_triggered) { - timer_irq_triggered = false; + ticker_irq_triggered = false; LEDHandler(); } else if (button_irq_triggered) {