
Test application for the STMicroelectronics X-NUCLEO-LED61A1 LED Control Expansion Board showing several LED control modes.
Dependencies: X_NUCLEO_LED61A1 mbed
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.
main.cpp
- Committer:
- Davidroid
- Date:
- 2017-07-13
- Revision:
- 16:2497344ba436
- Parent:
- 15:ea1e402ce919
File content as of revision 16:2497344ba436:
/** ****************************************************************************** * @file main.cpp * @author Davide Aliprandi, STMicroelectronics * @version V1.0.0 * @date February 4h, 2016 * @brief mbed test application for the STMicroelectronics X-NUCLEO-LED61A1 * LED Control Expansion Board showing several LED control modes. ****************************************************************************** * @attention * * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. Neither the name of STMicroelectronics nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ /* mbed specific header files. */ #include "mbed.h" /* Component specific header files. */ #include "Led6001.h" /* Definitions ---------------------------------------------------------------*/ /* PI. */ #ifndef M_PI #define M_PI (3.14159265358979323846f) #endif /* Loop period in micro-seconds. */ #define LOOP_PERIOD_us (1E5) /* Sin period in micro-seconds. */ #define PWM_SIN_PERIOD_us (1E7) #define ANALOG_SIN_PERIOD_us (1E7) /* 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.05f) /* Types ---------------------------------------------------------------------*/ /* Demos. */ typedef enum { MANUAL_PWM_DIMMING = 0, MANUAL_ANALOG_DIMMING, AUTOMATIC_PWM_DIMMING, AUTOMATIC_ANALOG_DIMMING, PHOTO_BASED_ANALOG_DIMMING, LED_DEMO_SIZE } LED_Demo_t; /* Actions. */ typedef enum { SWITCH_POWER = 0, SWITCH_DEMO, SWITCH_STATE, NO_ACTION } LED_Action_t; /* Variables -----------------------------------------------------------------*/ /* Main loop's ticker. */ 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); /* LED Control Component. */ Led6001 *led; /* Interrupt flags. */ static volatile bool ticker_irq_triggered = false; static volatile bool button_irq_triggered = false; static volatile bool xfault_irq_triggered = false; /* Demo State. */ static volatile LED_Demo_t demo; static volatile LED_Action_t action; static volatile bool power_on; /* Demos' Names. */ static char* demos[] = { "Manual PWM Dimming", "Manual Analog Dimming", "Sinusoidal PWM Dimming", "Sinusoidal Analog Dimming", "Photo-based Analog Dimming" }; /* Functions -----------------------------------------------------------------*/ /** * @brief Initializing the demo. * @param None. * @retval None. */ void init_demo(void) { power_on = true; action = SWITCH_DEMO; demo = (LED_Demo_t) (LED_DEMO_SIZE - 1); } /** * @brief Handling the LED capabilities and executing several demos. * @param None. * @retval None. */ void led_handler(void) { static int tick = 0; static float pwm_dimming; static float analog_dimming; /* Handling the power switch. */ if (action == SWITCH_POWER) { /* Switching the LED power ON/OFF. */ power_on = !power_on; if (power_on) { /* Initializing PWM and Analog dimming to maximum values. */ pwm_dimming = 1.0f; analog_dimming = 1.0f; } else { /* Printing to the console. */ printf("%-56s\r", "Power OFF"); /* Powering OFF the LED. */ led->power_off(); } } /* Handling the LED dimming when powered ON. */ if (power_on) { /* Switching to the next demo. */ if (action == SWITCH_DEMO) { pwm_dimming = 1.0f; analog_dimming = 1.0f; tick = 0; demo = (LED_Demo_t) ((demo + 1) % LED_DEMO_SIZE); } /* Setting the LED dimming depending on the selected demo. */ switch (demo) { /* Changing PWM dimming according to the user button. */ case MANUAL_PWM_DIMMING: 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 MANUAL_ANALOG_DIMMING: if (action == SWITCH_STATE) { analog_dimming -= DIMMING_STEP; analog_dimming = (analog_dimming < 0.0f ? 1.0f : analog_dimming); } break; /* Changing PWM dimming continuously. */ case AUTOMATIC_PWM_DIMMING: pwm_dimming = 0.5f * sin(2 * M_PI * (tick++ * LOOP_PERIOD_us) / PWM_SIN_PERIOD_us) + 0.5f; tick %= (int) (PWM_SIN_PERIOD_us / LOOP_PERIOD_us); action = SWITCH_STATE; break; /* Changing Analog dimming continuously. */ case AUTOMATIC_ANALOG_DIMMING: analog_dimming = 0.5f * sin(2 * M_PI * (tick++ * LOOP_PERIOD_us) / ANALOG_SIN_PERIOD_us) + 0.5f; tick %= (int) (ANALOG_SIN_PERIOD_us / LOOP_PERIOD_us); action = SWITCH_STATE; break; /* Setting Analog dimming according to the photo sensor. */ case PHOTO_BASED_ANALOG_DIMMING: analog_dimming = 1.0f - led->get_current(); action = SWITCH_STATE; break; } /* Writing PWM and Analog dimming values to the LED. */ if (action != NO_ACTION) { /* Printing to the console. */ printf("%d) %-26s --> Dimming: %0.2f\r", demo + 1, demos[demo], demo == MANUAL_PWM_DIMMING || demo == AUTOMATIC_PWM_DIMMING ? pwm_dimming : analog_dimming); /* Writing PWM and Analog dimming values to the LED. */ led->set_pwm_dimming(pwm_dimming); led->set_analog_dimming(analog_dimming); } } /* Resetting the action. */ action = NO_ACTION; } /** * @brief Interrupt Request for the main loop's ticker related interrupt. * @param None. * @retval None. */ void ticker_irq(void) { ticker_irq_triggered = true; } /** * @brief Interrupt Request for the user button's interrupt. * @param None. * @retval None. */ void button_irq(void) { button_irq_triggered = true; button.disable_irq(); } /** * @brief Interrupt Request for the component's XFAULT interrupt. * @param None. * @retval None. */ void xfault_irq(void) { xfault_irq_triggered = true; led->disable_xfault_irq(); } /** * @brief Interrupt Handler for the user button's interrupt. * @param None. * @retval None. */ void button_handler(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) { button_pressed_led = 1; button_pressed_timer.start(); } else { button_pressed_led = 0; button_pressed_timer.stop(); /* Either changing current demo's state or switching to the next demo. */ 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 { action = SWITCH_POWER; } button_pressed_timer.reset(); } button.enable_irq(); } /** * @brief Interrupt Handler for the component's XFAULT interrupt. * @param None. * @retval None. */ void xfault_handler(void) { /* Printing to the console. */ printf("XFAULT Interrupt detected! Re-initializing LED driver..."); /* Re-starting-up LED Control Component. */ led->start_up(); /* Printing to the console. */ printf("Done.\r\n\n"); /* Re-initializing the demo. */ init_demo(); led->enable_xfault_irq(); } /* Main ----------------------------------------------------------------------*/ int main() { /*----- Initialization. -----*/ /* Printing to the console. */ printf("LED Control Application Example\r\n\n" \ "Demos:\r\n"); int demo = 0; for (demo = 0; demo < LED_DEMO_SIZE; demo++) { printf("%d) %-26s\r\n", demo + 1, demos[demo]); } printf("\r\nActions:\r\n" \ "+ Short Button Press [<%.1fs] --> Manual Dimming\r\n" \ "+ Medium Button Press --> Switch Demo\r\n" \ "+ Long Button Press [>%.1fs] --> Switch Power ON/OFF\r\n\n" \ , SWITCH_DEMO_BUTTON_PRESS_ms / 1000.0f, SWITCH_POWER_BUTTON_PRESS_ms / 1000.0f); /* Initializing LED Control Component. */ led = new Led6001(D4, A3, D6, D5); if (led->init() != COMPONENT_OK) { exit(EXIT_FAILURE); } /* Attaching interrupt request functions. */ button.fall(button_irq); button.rise(button_irq); led->attach_xfault_irq(&xfault_irq); led->enable_xfault_irq(); ticker.attach_us(ticker_irq, LOOP_PERIOD_us); /* Starting-up LED Control Component. */ led->start_up(); /* Initializing the demo. */ init_demo(); /*----- LED Control. -----*/ /* Either performing the component handler, interrupt handlers, or waiting for events. */ while (true) { if (ticker_irq_triggered) { ticker_irq_triggered = false; led_handler(); } else if (button_irq_triggered) { button_irq_triggered = false; button_handler(); } else if (xfault_irq_triggered) { xfault_irq_triggered = false; xfault_handler(); } else { /* It is recommended that SEVONPEND in the System Control Register is NOT set. */ __WFE(); } } }