element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • About Us
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
At The Core Design Challenge
  • Challenges & Projects
  • Design Challenges
  • At The Core Design Challenge
  • More
  • Cancel
At The Core Design Challenge
Blog AtTheCore: Blog #2 - Interfacing LED Bar with ALS
  • Blog
  • Forum
  • Documents
  • Leaderboard
  • Polls
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join At The Core Design Challenge to participate - click to join for free!
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: navadeepganeshu
  • Date Created: 18 Apr 2023 6:54 PM Date Created
  • Views 967 views
  • Likes 7 likes
  • Comments 3 comments
  • infineon
  • element14
  • PSoC 62S4 pioneer kit
  • modustoolbox
  • microcontroller
  • challenge
  • More At The Core Design Challenge
Related
Recommended

AtTheCore: Blog #2 - Interfacing LED Bar with ALS

navadeepganeshu
navadeepganeshu
18 Apr 2023
AtTheCore: Blog #2 - Interfacing LED Bar with ALS

Table of Contents

  • Introduction
  • Running on Cortex M4 Core
  • Code
  • Activating IOs using Device Configurator
  • Interfacing LED Bar and Testing
  • Videos

Introduction

This blog is about interfacing the LED bar with the PSoC CY8CKIT-062S4 board through its vast number of IOs provided in the Arduino shields. It is one of the secondary modules in this project. Overall this involves writing up the logic to control 10 LEDs which will light up according to the Ambient Light Sensor(ALS) value reported by the onboard sensor. The process of obtaining these ALS and Temperature values is discussed in the previous blog and extending that, we'll now see about displaying it to the user.


Running on Cortex M4 Core

This implementation built on top of the code from the previous blog. In this dual-core application, the flow starts from Cortex M0+ (CM0+), enabling the larger Cortex M4 (CM4) core that initializes the IOs and subsystems within the application. We have seen how this whole flow works with both the cores sending UART messages and controlling the LED. Now with this LED bar interfacing, for real-time updates of the bar graph, the program flow is made to follow the loop in CM4 as highlighted. I suppose this can also be done probably in a more efficient way by activating an interrupt in a frequency when new data appears on ALS. Or even doing the process of query every 500ms or so and running through the loop on each core.

image


Code

Contains:

1. 2D array implementation for LED bar indication

2. ALS brightness threshold level definitions

3. Logic to pick the LED series from the matrix based on ALS levels

4. Print the ALS and temperature sensor values over UART

{tabbedtable}Files Code
ledbar.h
/*
 * ledbar.h
 *
 *  Created on: 16-Apr-2023
 *      Author: Navadeep
 */

#ifndef LEDBAR_H_
#define LEDBAR_H_

#define ALS_THRESH_LEVEL1   10
#define ALS_THRESH_LEVEL2   20
#define ALS_THRESH_LEVEL3   30
#define ALS_THRESH_LEVEL4   40
#define ALS_THRESH_LEVEL5   50
#define ALS_THRESH_LEVEL6   60
#define ALS_THRESH_LEVEL7   70
#define ALS_THRESH_LEVEL8   80
#define ALS_THRESH_LEVEL9   90
#define ALS_THRESH_LEVEL10   100

typedef enum
{
    eALSLevel1 = 0,
    eALSLevel2,
    eALSLevel3,
    eALSLevel4,
    eALSLevel5,
    eALSLevel6,
    eALSLevel7,
    eALSLevel8,
    eALSLevel9,
	eALSLevel10,
    eALSLevelMax
}TeALSIndicateLevels;

typedef enum
{
    eLed1 = 0,
    eLed2,
    eLed3,
    eLed4,
	eLed5,
	eLed6,
	eLed7,
	eLed8,
	eLed9,
	eLed10,
    eLedCountMax
}TeALSLed_t;

typedef enum
{
    eLedStateOff = 0,
    eLedStateStatic,
    eLedMaxStates
}TeLedState_t;

#endif /* LEDBAR_H_ */
main.c (CM4)
static int ALSLevel = 0;

/*ALS LED states matrix array*/
static const uint8_t LedState[eALSLevelMax][eLedCountMax] = {
        {eLedStateStatic,      eLedStateOff,      eLedStateOff,     eLedStateOff,   eLedStateOff,         eLedStateOff,      	eLedStateOff,     	 eLedStateOff, 	  eLedStateOff,     	eLedStateOff},
        {eLedStateStatic,     eLedStateStatic,    eLedStateOff,     eLedStateOff,   eLedStateOff,         eLedStateOff,      	eLedStateOff,     	 eLedStateOff, 	  eLedStateOff,     	eLedStateOff},
        {eLedStateStatic,     eLedStateStatic,   eLedStateStatic,   eLedStateOff,   eLedStateOff,         eLedStateOff,      	eLedStateOff,     	 eLedStateOff, 	  eLedStateOff,     	eLedStateOff},
        {eLedStateStatic,     eLedStateStatic,   eLedStateStatic,  eLedStateStatic, eLedStateOff,         eLedStateOff,      	eLedStateOff,     	 eLedStateOff, 	  eLedStateOff,     	eLedStateOff},
        {eLedStateStatic,     eLedStateStatic,   eLedStateStatic,  eLedStateStatic, eLedStateStatic,      eLedStateOff,      	eLedStateOff,    	 eLedStateOff, 	  eLedStateOff,     	eLedStateOff},
        {eLedStateStatic,     eLedStateStatic,   eLedStateStatic,  eLedStateStatic, eLedStateStatic,      eLedStateStatic,      eLedStateOff,     	 eLedStateOff, 	  eLedStateOff,     	eLedStateOff},
        {eLedStateStatic,     eLedStateStatic,   eLedStateStatic,  eLedStateStatic, eLedStateStatic,      eLedStateStatic,      eLedStateStatic,     eLedStateOff, 	  eLedStateOff,     	eLedStateOff},
        {eLedStateStatic,     eLedStateStatic,   eLedStateStatic,  eLedStateStatic, eLedStateStatic,      eLedStateStatic,      eLedStateStatic,     eLedStateStatic, eLedStateOff,     	eLedStateOff},
        {eLedStateStatic,     eLedStateStatic,   eLedStateStatic,  eLedStateStatic, eLedStateStatic,      eLedStateStatic,      eLedStateStatic,     eLedStateStatic, eLedStateStatic,      eLedStateOff},
        {eLedStateStatic,     eLedStateStatic,   eLedStateStatic,  eLedStateStatic, eLedStateStatic,      eLedStateStatic,      eLedStateStatic,     eLedStateStatic, eLedStateStatic,      eLedStateStatic}};

/*core for loop program*/
for (;;)
    {
        if (1);     //or if(cyhal_gpio_read(CYBSP_USER_BTN) == CYBSP_BTN_PRESSED));
        {
        #if ENABLE_SEMA
            /* Attempt to lock the semaphore */
            if (Cy_IPC_Sema_Set(SEMA_NUM, false) == CY_IPC_SEMA_SUCCESS)
        #endif
            {
                /* Print a message to the console and turn Orange LED ON*/
                cyhal_gpio_write(CYBSP_USER_LED2, CYBSP_LED_STATE_ON);
                printf("Message sent from CM4\r\n");	/*UART transmit message*/

                /*Also send sensor data*/
    			/* Wait till printf completes the UART transfer */
    	        while(cyhal_uart_is_tx_active(&cy_retarget_io_uart_obj) == true);

    	        /*Bar LED display logic*/

    	            if(light_intensity < ALS_THRESH_LEVEL1)
    	            {
    	            	ALSLevel = eALSLevel1;
    	            }
    	            else if(light_intensity < ALS_THRESH_LEVEL2)
    	            {
    	            	ALSLevel = eALSLevel2;
    	            }
    	            else if(light_intensity < ALS_THRESH_LEVEL3)
    	            {
    	            	ALSLevel = eALSLevel3;
    	            }
    	            else if(light_intensity < ALS_THRESH_LEVEL4)
    	            {
    	            	ALSLevel = eALSLevel4;
    	            }
    	            else if(light_intensity < ALS_THRESH_LEVEL5)
    	            {
    	            	ALSLevel = eALSLevel5;
    	            }
    	            else if(light_intensity < ALS_THRESH_LEVEL6)
    	            {
    	            	ALSLevel = eALSLevel6;
    	            }
    	            else if(light_intensity < ALS_THRESH_LEVEL7)
    	            {
    	            	ALSLevel = eALSLevel7;
    	            }
    	            else if(light_intensity < ALS_THRESH_LEVEL8)
    	            {
    	            	ALSLevel = eALSLevel8;
    	            }
    	            else if(light_intensity < ALS_THRESH_LEVEL9)
    	            {
    	            	ALSLevel = eALSLevel9;
    	            }
    	            else if(light_intensity == ALS_THRESH_LEVEL10)
    	            {
    	            	ALSLevel = eALSLevel10;
    	            }

    	        /*Update LED status*/
				cyhal_gpio_write(CYBSP_D0 ,LedState[ALSLevel][eLed1]);
				cyhal_gpio_write(CYBSP_D1 ,LedState[ALSLevel][eLed2]);
				cyhal_gpio_write(CYBSP_D2 ,LedState[ALSLevel][eLed3]);
				cyhal_gpio_write(CYBSP_D13 ,LedState[ALSLevel][eLed4]);
				cyhal_gpio_write(CYBSP_D4 ,LedState[ALSLevel][eLed5]);
				cyhal_gpio_write(CYBSP_D5 ,LedState[ALSLevel][eLed6]);
				cyhal_gpio_write(CYBSP_D6 ,LedState[ALSLevel][eLed7]);
				cyhal_gpio_write(CYBSP_D7 ,LedState[ALSLevel][eLed8]);
	            cyhal_gpio_write(CYBSP_D8 ,LedState[ALSLevel][eLed9]);
    	        cyhal_gpio_write(CYBSP_D10 ,LedState[ALSLevel][eLed10]);

				/* Print the temperature and the ambient light value*/
				printf("Temperature: %2.1lfC    Ambient Light: %d%%\r\n", temperature, light_intensity);
				printf("\n");

                cyhal_system_delay_ms(500);
                cyhal_gpio_write(CYBSP_USER_LED2, CYBSP_LED_STATE_OFF);

            #if ENABLE_SEMA
                while (CY_IPC_SEMA_SUCCESS != Cy_IPC_Sema_Clear(SEMA_NUM, false));
            #endif
            }
        }
    }
main.c (CM0+)
                for (;;)
                {
                    /* Check if the button is pressed */
                    if (Cy_GPIO_Read(CYBSP_SW2_PORT, CYBSP_SW2_PIN) == 0)
                    {
                    #if ENABLE_SEMA
                        if (Cy_IPC_Sema_Set(SEMA_NUM, false) == CY_IPC_SEMA_SUCCESS)
                    #endif
                        {
                            /* Print a message to the console and turn Red LED ON */
                            cyhal_gpio_write(CYBSP_USER_LED, CYBSP_LED_STATE_ON);
                            Cy_SCB_UART_PutString(CYBSP_UART_HW, "Message sent from CM0+\r\n");		/*UART transmit message*/

                            cyhal_system_delay_ms(500);
                            cyhal_gpio_write(CYBSP_USER_LED, CYBSP_LED_STATE_OFF);

                        #if ENABLE_SEMA
                            while (CY_IPC_SEMA_SUCCESS != Cy_IPC_Sema_Clear(SEMA_NUM, false));
                        #endif
                        }
                    }
                }


Activating IOs using Device Configurator

Device configurator is one of the interesting, handy and intuitive tools available in ModusToolbox which certainly makes the boring task of initializing peripherals, setting properties and doing that repeatedly for n number of IOs and peripherals we initialize. It is available in the Quick Panel window and will be specific for each project dynamically changing on the chosen project in the Projects Explorer window. The quick panel seems very useful giving options to build, debug and run with the project name shown there itself and it makes you aware what project you're deploying which would be rather confusing to do from the top panel while having multiple projects. I've specifically faced this issue of other/previous projects being taken from build and debug while on a different one operating from the top ribbon panel. 

image

This has most of the configurations handy and I set the peripherals to be initialized and their specifications from the first panel and then going to the Pins tab to select GPIO pins and their functionality feature. For this project, UART to do the sensor data transmission serially and multiple GPIOs for driving the LED bar are needed to be initialized(extras exist to be ignored as I am extending the project from there)

image

10 IOs are initialized with Strong Drive, default 0 state from D0 to D13 pins(arduino header) as some of them were preoccupied with other functions. 

image

All the configurations here got updated immediately and reflected in the project as soon as it is saved with  ctrl+S. We now are all set to go ahead with hefty wiring for the 10-segment LED bar and test out the code.


Interfacing LED Bar and Testing

image

image

Videos

You don't have permission to edit metadata of this video.
Edit media
x
image
Upload Preview
image

You don't have permission to edit metadata of this video.
Edit media
x
image
Upload Preview
image

This being one of the modules running on CM4 with sensor data acquisition, LED interface and display happening from here in CM4, the other CM0+ core involves Capsense buttons and a slider for controlling a 2-channel PWM generated for motor control which we'll discuss in the next blog. Thanks for reading through and would love to know your thoughts. Thank you :)


Also Read:

 AtTheCore: Blog #1 - Intro and what's up with the kit! 

 AtTheCore: Blog #3 - PWM and Capsense on Cortex M0+ 

  • Sign in to reply
  • navadeepganeshu
    navadeepganeshu over 2 years ago

    Continuing over this, there is a very interesting method for doing inter-process communication(IPC). Within the same lock/unlock cage of semaphore, this IPC can be implemented to transfer data between the processes. I am currently trying this feature using Cy_IPC_Drv_SendMsgWord() and Cy_IPC_Drv_ReadMsgWord()

    image

    /*Motor ON full speed if ALS > 60% using IPC pipe*/
    if(light_intensity >= 60)
    {
    myMsg = 0x1; /* MOTOR ON message */
    
        if (CY_IPC_DRV_SUCCESS != Cy_IPC_Drv_SendMsgWord(myIpc, MY_IPC_INTR_MASK, myMsg))
        {
        /* Insert error handling */
        
        }
    }

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • navadeepganeshu
    navadeepganeshu over 2 years ago in reply to shabaz

    Hi shabaz ,

    Thanks! Oh, well yeah. You're quite a lot around RPis ;) I get you on that - it wasn't obvious to me too until I started working on this project. Somehow working on the same thing and seeing the acronyms repeatedly in readme and code made me feel that's a generic acronym and had it mentioned all along the blog,..haha. Sorry about that and I've modified those with full-form in the first few instances of the blog.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • shabaz
    shabaz over 2 years ago

    Very good blog post! But I had difficulty understanding what CM4 was. I wondered if it was a Pi 4 Compute Module. 

    I now know you mean Cortex-M4 but the acronym will get confusing if shortened to CM4, I've not seen it shortened to that before.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube