10 Replies Latest reply on Feb 3, 2020 5:44 PM by MoTa_728816

    To dim LED

    UlMo_4589691

      Hello,

      now I have a touch sensor and a LED. The touch sensor enables the LED. Now I want to preset the brightness of the LED. How can I do this?

        • 1. Re: To dim LED
          BragadeeshV_41

          Hi UlMo_4589691,

           

          If you wish to adjust the brightness of the LED (fixed brightness), you can increase/ decrease the current flowing through the LED. This can be done by varying the resistor connected in series to the LED. Increasing the resistance will dim the LED.

           

          If you wish to dynamically control the brightness of the LED, you can connect it to a PWM block and change the duty cycle of the PWM to increase/ decrease brightness. If ON time is increased , brightness increases.

           

          Regards,

          Bragadeesh 

          • 2. Re: To dim LED
            JoMe_264151

            Many of the PSoC devicws have a PrISM component which is specialized for dimming LEDs dynamically.

            Have a look into the datasheet.

             

            Bob

            • 3. Re: To dim LED
              UlMo_4589691

              No there is no such PrlSM on my PSoC 4000 Kit

              • 4. Re: To dim LED
                UlMo_4589691

                Hi Bragadeesh,

                I want to use the second option and have made the code below. There a touch button shall switch on the LED and its brightness I want to set up PWM.

                 

                Before I have tested: With no PWM and not connect the LED to the PWM (no "HW connection"), the touch button switches the LED on to full brightness.

                 

                Now programming the device the Leds flashes shortly and the touch is not working anymore. Do you know, what is wrong?

                 

                #include "project.h"

                 

                //leds

                #define LED_ON                        (0u) //Für Oledanschluss OFF=0u --> on=1u

                #define LED_OFF                        (1u)

                 

                int main(void)

                {

                    CyGlobalIntEnable; /* Enable global interrupts. Immer notwendig */

                 

                    CapSense_1_Start();

                   

                    PWM_Start();

                    PWM_SetMode(PWM_MODE_PWM_DT);

                    PWM_SetPWMDeadTime(255);

                   

                    //How can I controll

                   

                    for(;;)

                    {

                    //CHECK IF CAPSENSE IS NOT BUSY -- Touch funktioniert dann besser

                    if(!CapSense_1_IsBusy())

                        {

                        CapSense_1_ScanAllWidgets();

                        CapSense_1_ProcessAllWidgets();

                        ledGreen_Write(CapSense_1_IsWidgetActive(CapSense_1_BUTTON0_WDGT_ID) ? LED_ON : LED_OFF );

                        }

                    }

                }

                • 5. Re: To dim LED
                  MoTa_728816

                  Hi,

                   

                  I tried with CY8CKIT-044.

                  My Program starts with LED off,

                  when you touch the button,

                  (1) LED lights with 1/4 brightness

                  (2) LED lights with full brightness

                  (3) LED turns off

                  (1) ...

                   

                  schematic

                  001-schematic.JPG

                  main.c

                  ====================

                  #include "project.h"

                   

                  #define PWM_PERIOD 1000

                  #define LED_OFF  0

                  #define LED_1_4  250

                  #define LED_HALF 500

                  #define LED_3_4  750

                  #define LED_FULL 1000

                   

                  int main(void)

                  {

                      int led_level = LED_OFF ;

                    

                      CyGlobalIntEnable; /* Enable global interrupts. */

                   

                      CapSense_1_Start() ;

                   

                      PWM_WritePeriod(PWM_PERIOD) ;

                      PWM_WriteCompare(led_level) ;

                      PWM_Start() ;

                   

                      for(;;)

                      {

                          if (!CapSense_1_IsBusy()) {

                              CapSense_1_ProcessAllWidgets() ;

                            

                              if (CapSense_1_IsSensorActive(CapSense_1_BUTTON0_WDGT_ID, CapSense_1_BUTTON0_SNS0_ID)) {

                                  switch(led_level) {

                                  case LED_OFF:  led_level = LED_1_4  ; break ;

                                  case LED_1_4:  led_level = LED_FULL ; break ;

                                  case LED_FULL: led_level = LED_OFF  ; break ;

                                  default:      led_level = LED_OFF  ; break ;

                                  }

                                  // PWM_Stop() ;

                                  PWM_WriteCompare(led_level) ;

                                  // PWM_Enable() ;

                                  CyDelay(500) ; /* cheap debouncing */

                              }        

                              CapSense_1_ScanAllWidgets() ;  

                          }

                      }

                  }

                  ====================

                   

                  moto

                  1 of 1 people found this helpful
                  • 6. Re: To dim LED
                    MoTa_728816

                    Hi,

                     

                    Although I'm afraid that this may be somewhat supererogatory,

                    I modified my program to only ON <-> OFF function.

                     

                    Meantime as I played with my CY8CKIT-044, about 10~100 for compare out of 1000  period cycle seemed to be "dim".

                    This number may vary in each system(s).

                     

                    main.c

                    ===============

                    #include "project.h"

                     

                    #define PWM_PERIOD 1000 /* 65535 (0xFFFF) was too much for this purpose */

                    #define LED_OFF       0

                    #define LED_DIM      10 /* could be anywhere from 1 to 1000 */

                     

                    int main(void)

                    {

                        int led_level = LED_OFF ;

                       

                        CyGlobalIntEnable; /* Enable global interrupts. */

                     

                        CapSense_1_Start() ;

                     

                        PWM_WritePeriod(PWM_PERIOD) ;

                        PWM_WriteCompare(led_level) ;

                        PWM_Start() ;

                     

                        for(;;) {

                             if (!CapSense_1_IsBusy()) {

                                CapSense_1_ProcessAllWidgets() ;

                               

                                if (CapSense_1_IsSensorActive(CapSense_1_BUTTON0_WDGT_ID, CapSense_1_BUTTON0_SNS0_ID)) {

                                    if (led_level == LED_OFF) {

                                        led_level = LED_DIM ;

                                    } else {

                                        led_level = LED_OFF ;

                                    }

                                    PWM_WriteCompare(led_level) ;

                                    CyDelay(500) ; /* cheap debouncing */

                                }      

                               

                                CapSense_1_ScanAllWidgets() ;   

                            }

                        }

                    }

                    ===============

                     

                    moto

                    2 of 2 people found this helpful
                    • 7. Re: To dim LED
                      UlMo_4589691

                      Hi

                      your answer is very helpfull. I think that LED_DIM -input for PWM_WriteCompare) shall be between 0 and 65535 for getting 0 to 100 %.

                      • 8. Re: To dim LED
                        MoTa_728816

                        Hi,

                         

                        There are some more things to consider.

                         

                        (1) The "period" of the counter defines the frequency. (frequency = 1/period)

                         

                        (2) As a 16bit counter, the TCPWM can count 0 to 65535 (= 65536 cycles)

                         

                        (3) If you count up to 65535 with 2MHz clock, it takes 32.768ms => 30.5175 Hz

                         

                        (4) The "compare" value could be 0 to the period+1, although we can assign up to 65535 anyway.

                            But 0 to period+1 will be mapped to 0% to 100%

                         

                        (5) In my sample, I set the period to "1000", so meaningful compare value is 0 to 1001.

                           (Oops, I notice that I should have set it to 999, so that 0 to 1000 was meaningful, but it's a detail)

                         

                        (6) On the other hand, to avoid seeing the LED flickering,

                            usually, we'd like to make the frequency more than 50 or 60Hz,

                            so that about "10000" or less will be good for the period.

                         

                        (7) And I chose 1000.  (So compare value should be 0 to 1001, which is 0% to 100%)

                         

                        moto

                        • 9. Re: To dim LED
                          UlMo_4589691

                          Hi,

                          now I have measured the output frequency by the help of an oscilloscope. Changing the PWM_PERIOD or even cancel (//PWM_WritePeriod(PWM_PERIOD)  has no impact on the final frequency of 61 Hz.

                          To work with PWM_PERIOD, do I have change the settings direct in the ''Configure PWM"?

                           

                          Please find below a screenshot of the ''Configure PWM" and my main.

                           

                           

                          #include "project.h"

                           

                          //#define PWM_PERIOD 1 //16 bit clock/period = frequency

                          #define LED_OFF 0          //16 bit for writeCompare   

                          #define LED_1_4  64*256

                          #define LED_HALF 128*256

                          #define LED_3_4  192*256

                          #define LED_FULL (256*256)-1

                           

                           

                          int main(void){

                           

                              int led_level = LED_OFF ;

                           

                              CyGlobalIntEnable; /* Enable global interrupts. */

                           

                              CapSense_1_Start() ;

                           

                              //PWM_WritePeriod(PWM_PERIOD) ;   ---------has no impact on frequency

                              PWM_Start() ;

                              PWM_WriteCompare(led_level) ;

                           

                              for(;;) {

                                  if ( ! CapSense_1_IsBusy()) {

                                      CapSense_1_ProcessAllWidgets() ;

                                     

                                      if (CapSense_1_IsSensorActive(CapSense_1_BUTTON0_WDGT_ID, CapSense_1_BUTTON0_SNS0_ID)) {

                                          switch(led_level) {

                                              case LED_OFF:  led_level = LED_1_4  ; break ;

                                              case LED_1_4:  led_level = LED_HALF ; break ;

                                              case LED_HALF:  led_level = LED_3_4 ; break ;

                                              case LED_3_4:  led_level = LED_FULL ; break ;

                                              case LED_FULL: led_level = LED_OFF  ; break ;

                                          default:      led_level = LED_OFF  ; break ;

                                          }

                                          PWM_WriteCompare(led_level) ;

                                       

                                          CyDelay(500) ; /* cheap debouncing */

                                      }       

                                      CapSense_1_ScanAllWidgets() ; 

                                  }

                              }

                          }

                          • 10. Re: To dim LED
                            MoTa_728816

                            Hi,

                             

                            It was my mistake, before setting period PWM_Start() or PWM_Init() must have been called.

                            Note: PWM_Init() is called at the first time PWM_Start() is called

                            003-pwm_start.JPG

                            And in the PWM_Init(), period is overwritten to the value set in the GUI.

                             

                            So I should have written

                            =================

                            PWM_Start() ;

                            PWM_Stop() ; /* before changing the period, PWM must be stopped */

                            PWM_WritePeriod(PWM_PERIOD) ;

                            PWM_WriteCompare(led_level) ;

                            PWM_Start() ;

                            =================

                             

                            To test if PWM_WritePeriod() really works,

                            I made following test program.

                             

                            schematic

                            001-schematic.JPG

                            pins

                            002-pins.JPG

                            main.c

                            Note: To handle UART interactions I cheated by using my tty_utility

                            tty_utils a utility sample for CLI type program

                            ================

                            #include "project.h"

                            #include "stdio.h"

                            #include "tty_utils.h"

                             

                            #define PWM_PERIOD 1000 /* 65535 (0xFFFF) was too much for this purpose */

                            #define LED_OFF       0

                            #define LED_DIM      10 /* could be anywhere from 1 to 1000 */

                             

                            uint16_t led_period = PWM_PERIOD ;

                            uint16_t led_level = LED_DIM ; /* set default to ON */

                             

                            void config_pwm(uint16_t period, uint16_t compare) ;

                             

                            typedef void (*func_ptr_type)(char *str) ;

                             

                            void do_help(char *str) ;

                            void do_period(char *str) ;

                            void do_compare(char *str) ;

                            void do_pwm(char *str) ;

                            void do_status(char *str) ;

                             

                            typedef struct _cmd_func_st {

                                char *cmd ;

                                func_ptr_type func ;

                                char *description ;

                            } cmd_func_type ;

                             

                            cmd_func_type cmd_list[] = {

                                { "help",    do_help,    "Print Help Message" },

                                { "period",  do_period,  "Set PWM Period value, period 1000" },

                                { "compare", do_compare, "Set PWM Compare value, compare 10" },

                                { "pwm",     do_pwm,     "Set PWM Config period and compare, pwm 1000 10" },

                                { "status",  do_status,  "Show current setting" },

                                { 0, 0, 0 }

                            } ;

                             

                            void do_help(char *str)

                            {

                                (void) str ;

                                int i = 0 ;

                               

                                print("=== command ===\n\r") ;

                                for (i = 0 ; cmd_list[i].cmd ; i++ ) {

                                    snprintf(str, STR_BUF_LEN, "%10s : ", cmd_list[i].cmd) ;

                                    print(str) ;

                                    print(cmd_list[i].description) ;

                                    print("\n\r") ;

                                }

                            }

                             

                            void do_period(char *str)

                            {

                                sscanf(str, "%*s %hd", &led_period) ;

                                config_pwm(led_period, led_level) ;

                            }

                             

                            void do_compare(char *str)

                            {

                                sscanf(str, "%*s %hd", &led_level) ;

                                config_pwm(led_period, led_level) ;

                            }

                             

                            void do_pwm(char *str)

                            {

                                sscanf(str, "%*s %hd %hd", &led_period, &led_level) ;

                                config_pwm(led_period, led_level) ;   

                            }

                             

                            void do_status(char *str)

                            {

                                uint16_t period, compare ;

                                period = PWM_ReadPeriod() ;

                                compare = PWM_ReadCompare() ;

                                print("=== PWM Status ===\n\r") ;

                                snprintf(str, STR_BUF_LEN, "Period: %hd\r\n", period) ;

                                print(str) ;

                                snprintf(str, STR_BUF_LEN, "Compare: %hd\r\n", compare) ;

                                print(str) ;

                            }

                             

                            void init_hardware(void)

                            {

                                CyGlobalIntEnable; /* Enable global interrupts. */

                             

                                CapSense_1_Start() ;

                               

                                UART_Start() ;

                                tty_init() ;

                                splash("CapSense and LED PWM Test") ;

                               

                                PWM_Start() ;

                            }

                             

                            void config_pwm(uint16_t period, uint16_t compare)

                            {

                                PWM_Stop() ;

                                PWM_WritePeriod(period) ;

                                PWM_WriteCompare(compare) ;

                                PWM_Start() ;

                            }

                             

                            func_ptr_type get_func(char *cmd)

                            {

                                int i ;

                                for (i = 0 ; cmd_list[i].cmd ; i++ ) {

                                    if (strcmp(cmd, cmd_list[i].cmd) == 0) {

                                        break ;

                                    }

                                }

                                return( cmd_list[i].func ) ;

                            }

                             

                            void do_command(char *str)

                            {

                                char command[STR_BUF_LEN+1] ;

                                func_ptr_type func ;

                                sscanf(str, "%s", command) ;

                                func = get_func(command) ;

                                if (func) {

                                    func(str) ;

                                } else {

                                    do_help(str) ;

                                }

                            }

                             

                            int main(void)

                            {  

                                init_hardware() ;

                               

                                config_pwm(led_period, led_level) ;

                             

                                prompt() ;

                               

                                for(;;) {

                                    if (get_line()) {

                                        do_command(str) ;

                                        prompt() ;

                                    }

                                    if (!CapSense_1_IsBusy()) {

                                        CapSense_1_ProcessAllWidgets() ;

                                       

                                        if (CapSense_1_IsSensorActive(CapSense_1_BUTTON0_WDGT_ID, CapSense_1_BUTTON0_SNS0_ID)) {

                                            if (led_level == LED_OFF) {

                                                led_level = LED_DIM ;

                                            } else {

                                                led_level = LED_OFF ;

                                            }

                                            PWM_WriteCompare(led_level) ;

                                            CyDelay(500) ; /* cheap debouncing */

                                        }      

                                       

                                        CapSense_1_ScanAllWidgets() ;   

                                    }

                                }

                            }

                            ================

                             

                            Tera Term log

                            001-tera_term_log.JPG

                             

                            When the program started, as Period = 1000, Compare = 10 and the PWM Clock = 2MHz

                            About 2KHz pulse(s) are generated

                            TEK0000.jpg

                             

                            When I entered "pwm 2000 1000" to the prompt (>)

                            Now frequency is 2KHz and as compre value is 1000 the duty is 50%

                            TEK0001.jpg

                             

                            When I entered "pwm 3000 1000"

                            The frequency was about 668Hz and duty is about 30%

                            TEK0002.jpg

                             

                            When I entered "pwm 1500 1000", frequency was about 1.336 kHz

                            and duty is about 67%.

                            TEK0003.jpg

                             

                            So the bad news is that I had a bug in my previous program,

                            and the good news is PWM_WritePeriod() does its work ;-)

                             

                            moto