cancel
Showing results for 
Search instead for 
Did you mean: 

PSoC 4 MCU

GiPo_4761656
New Contributor

Good morning,

my name is Giulio and I am Italian, so I apologize for the English. I have a problem creating a timer to activate a led. I bought the Psoc 4100s plus Kit but I don't know how to use the timer to activate a led after some time that you have placed your finger on the capacitive button. Somebody can help me?

Thank you

0 Likes
1 Solution
MotooTanaka
Esteemed Contributor

Hi,

I modified my program a little.

2sec is 2000 in ms, so I changed ON_DELAY to 2000.

And also to avoid overflow of 32bit integer tick_count,

I stopped counting when the value of tick_count reaches to ON_DELAY.

Now I clear tick_count when button is not pressed.

I hope this does what you wanted.

main.c

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

#include "project.h"

#define LED_ON  0u

#define LED_OFF 1u

#define ON_DELAY 2000

volatile uint32_t tick_count = 0 ;

CY_ISR(tick_callback)

{

    if (tick_count < ON_DELAY) {

        tick_count++ ;

    }

}

int find_empty_slot(void)

{

    int result = -1 ;

    uint32_t i ;

    for (i = 0 ; i < CY_SYS_SYST_NUM_OF_CALLBACKS ; i++ ) {

        if (CySysTickGetCallback(i) == NULL) {

            result = i ;

            break ;

        }

    }

    return(result) ;

}

void init_hardware(void)

{

    int sys_tick_slot = 0 ;

    CyGlobalIntEnable; /* Enable global interrupts. */

   

    sys_tick_slot = find_empty_slot() ;

    if (sys_tick_slot < 0) {

        while(1) { /* halting here with LED blinking */

            LED12_Write(!LED12_Read()) ;

            CyDelay(500) ;

        }

    } else {

        CySysTickStart() ;

        CySysTickSetCallback(sys_tick_slot, tick_callback) ;

    }

   

    CapSense_Start() ;

    CapSense_ScanAllWidgets() ;

}

int main(void)

{

    init_hardware() ;

    for(;;) {

        if (!CapSense_IsBusy()) {

            CapSense_ProcessAllWidgets() ;

            if (CapSense_IsSensorActive(CapSense_BTN1_WDGT_ID, CapSense_BTN1_SNS0_ID)) {

                // button is pressed

            } else {

                tick_count = 0 ; // button is released

            }

            CapSense_ScanAllWidgets() ;

        }

        if (ON_DELAY > tick_count)  {

            LED12_Write(LED_OFF) ;

        } else {

            LED12_Write(LED_ON) ;

        }

    }

}

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

moto

View solution in original post

0 Likes
10 Replies
Kenshow
Esteemed Contributor

Hi Giulio,

Please tell me the details of the timing sequence of LED and capacitance button.

I think it is not so difficult. However, the design changes depending on the timing of the timer and the touch button.

Regards,

Kenshow

0 Likes
Kenshow
Esteemed Contributor

Hi Giulio,

If you can occupy the CPU, you can create a program with the cyDelay (us) function without using Timer.

ex)

 LED_ON

 cyDelay(1000); // wait for 1sec

 LED_OFF

Regards,

Kenshow

0 Likes
GiPo_4761656
New Contributor

thank you for your fast answer

The timing sequence is simple:

timing.jpg

regards,

Giulio

0 Likes
GiPo_4761656
New Contributor

Sorry I forgot a thing.. that if I don't keep the button active for 2 sec, the led don't turn on.

the correct timing sequence

timing.jpg

Sorry for my english

0 Likes
Kenshow
Esteemed Contributor

Hi Giulio,

Thank you for the timing diagram.

In my program case, It seems that the PWM timing should be shifted. I will think about it, so please give me some time.

Regards,

Kenshow

0 Likes
MotooTanaka
Esteemed Contributor

Hi,

I modified my program a little.

2sec is 2000 in ms, so I changed ON_DELAY to 2000.

And also to avoid overflow of 32bit integer tick_count,

I stopped counting when the value of tick_count reaches to ON_DELAY.

Now I clear tick_count when button is not pressed.

I hope this does what you wanted.

main.c

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

#include "project.h"

#define LED_ON  0u

#define LED_OFF 1u

#define ON_DELAY 2000

volatile uint32_t tick_count = 0 ;

CY_ISR(tick_callback)

{

    if (tick_count < ON_DELAY) {

        tick_count++ ;

    }

}

int find_empty_slot(void)

{

    int result = -1 ;

    uint32_t i ;

    for (i = 0 ; i < CY_SYS_SYST_NUM_OF_CALLBACKS ; i++ ) {

        if (CySysTickGetCallback(i) == NULL) {

            result = i ;

            break ;

        }

    }

    return(result) ;

}

void init_hardware(void)

{

    int sys_tick_slot = 0 ;

    CyGlobalIntEnable; /* Enable global interrupts. */

   

    sys_tick_slot = find_empty_slot() ;

    if (sys_tick_slot < 0) {

        while(1) { /* halting here with LED blinking */

            LED12_Write(!LED12_Read()) ;

            CyDelay(500) ;

        }

    } else {

        CySysTickStart() ;

        CySysTickSetCallback(sys_tick_slot, tick_callback) ;

    }

   

    CapSense_Start() ;

    CapSense_ScanAllWidgets() ;

}

int main(void)

{

    init_hardware() ;

    for(;;) {

        if (!CapSense_IsBusy()) {

            CapSense_ProcessAllWidgets() ;

            if (CapSense_IsSensorActive(CapSense_BTN1_WDGT_ID, CapSense_BTN1_SNS0_ID)) {

                // button is pressed

            } else {

                tick_count = 0 ; // button is released

            }

            CapSense_ScanAllWidgets() ;

        }

        if (ON_DELAY > tick_count)  {

            LED12_Write(LED_OFF) ;

        } else {

            LED12_Write(LED_ON) ;

        }

    }

}

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

moto

View solution in original post

0 Likes
Kenshow
Esteemed Contributor

Hi Giulio,

Moto's program is good.

I adjusted the PWM settings, but I couldn't meet the your specifications. A pulse is input when touching, but a delay of 2 seconds has been realized.

1.png

Regards,

Kenshow

0 Likes
NoriakiT_91
Employee

Giulio,

This is my solution using a periodic timer.

GS004858.png

A software counter driven by the periodic interrupt is used to count the delay time.

I have tried to find another solution using a hardware component to create the delay.  But it seems hard to find such solutions using PSoC 4100S Plus.

Regards,

Noriaki

0 Likes
MotooTanaka
Esteemed Contributor

Hi,

As I could not figure out if you want to delay start lighting or delay stop lighting,

I implemented the both.

When you touch the BTN1 and release the finger,

program wait for ON_DELAY (500ms) then turns the LED12 on.

then after OFF_DELAY (1000ms) LED12 off.

If you want to light LED12 immediately, set ON_DELAY to 0

#define ON_DELAY 0

Meantime, since I think the timing of CapSense does not have to bee too exact,

I decided to use SysTick and save PWM/Timer for other purpose.

So my schematic is

001-schematic.JPG

Pins

002-pins.JPG

main.c

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

#include "project.h"

#define LED_ON  0u

#define LED_OFF 1u

#define ON_DELAY 500

#define OFF_DELAY 1000

volatile uint32_t tick_count = 0 ;

CY_ISR(tick_callback)

{

    tick_count++ ;

}

int find_empty_slot(void)

{

    int result = -1 ;

    uint32_t  i ;

    for (i = 0 ; i < CY_SYS_SYST_NUM_OF_CALLBACKS ; i++ ) {

        if (CySysTickGetCallback(i) == NULL) {

            result = i ;

            break ;

        }

    }

    return(result) ;

}

void init_hardware(void)

{

    int sys_tick_slot = 0 ;

    CyGlobalIntEnable; /* Enable global interrupts. */

   

    sys_tick_slot = find_empty_slot() ;

    if (sys_tick_slot < 0) {

        while(1) { /* halting here with LED blinking */

            LED12_Write(!LED12_Read()) ;

            CyDelay(500) ;

        }

    } else {

        CySysTickStart() ;

        CySysTickSetCallback(sys_tick_slot, tick_callback) ;

    }

   

    CapSense_Start() ;

    CapSense_ScanAllWidgets() ;

}

int main(void)

{

    init_hardware() ;

    for(;;) {

        if (!CapSense_IsBusy()) {

            CapSense_ProcessAllWidgets() ;

            if (CapSense_IsSensorActive(CapSense_BTN1_WDGT_ID, CapSense_BTN1_SNS0_ID)) {

                tick_count = 0 ;

            }

            CapSense_ScanAllWidgets() ;

        }

        if ((ON_DELAY < tick_count) && (tick_count <= OFF_DELAY)) {

            LED12_Write(LED_ON) ;

        } else {

            LED12_Write(LED_OFF) ;

        }

    }

}

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

moto

0 Likes
Kenshow
Esteemed Contributor

Hi Giulio,

The PSoC timer can be used as a pulse or interrupt. In other words, in the case of the program posted earlier, it is necessary to control the LED with S/W by the notification from the timer. Fortunately, LED On/Off control can be done on the H/W using PWM. If there is a touch, PWM will do the rest. I tried to make a program with CY8CKIT-149.

1.png

I wanted to use PWM as a one-shot, so I connected the ov output to the stop and stopped it once. When there is a touch, PWM is started and the LED is lit for a periodic time (3 seconds).

2.png

This program is very simple. It starts only PWM at the touch detection.

  1. #include <project.h>
  2. /*******************************************************************************
  3. * Function Name: main
  4. *******************************************************************************/
  5. uint32 sw = 0
  6. int main(void
  7. /* Enable global interrupts. */
  8. CyGlobalIntEnable; 
  9. /* Starts CapSense block */
  10.     CapSense_Start(); 
  11. /* Starts initial scan of widgets */
  12.     CapSense_ScanAllWidgets(); 
  13. for(;;) 
  14.     { 
  15. if(CapSense_NOT_BUSY == CapSense_IsBusy()) 
  16.         { 
  17. /* Process data */
  18.             CapSense_ProcessAllWidgets(); 
  19. /* Turns on LED based on whether widget is active */
  20. if(CapSense_IsWidgetActive(CapSense_BUTTON1_WDGT_ID)){ 
  21. if(sw==0){ 
  22.                     sw=1
  23.                     PWM_1_Start(); 
  24.                 } 
  25.             }else
  26.                 sw=0
  27.             } 
  28.             CapSense_RunTuner(); 
  29. /* Starts scan of widgets */
  30.             CapSense_ScanAllWidgets(); 
  31.         } 
  32.     } 

In this way, PSoC is different from other general-purpose MCUs in that it can be designed for H/W. H/W can be configured more flexibly on devices with UDB (Not on this device).

I hope you can make good use of it.

Regards,

Kenshow

0 Likes