This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Count how long button is pressed on CC2530

Other Parts Discussed in Thread: CC2530

Hello,

I have a question about how to program a CC2530  to count how long a button is pressed and if the button is pressed for 5 seconds, it will turn on LED2. Otherwise if it's less than 5 seconds, it will turn on LED1. How would I program this with a new project in IAR 8051? I would appreciate any helpful replies.

  • You have to create a event to keep reading button status to see if the button is pressed for a period.
  • Could you share what I would do to create this even for P0.2 or HAL_KEY_SW_2. I've been looking at this page and it hasn't worked for me: e2e.ti.com/.../384426.
  • Have you been able to get HAL_KEY_SW_2 event when you trigger high/low change on P0.2?
  • When I presss SW2 every 2 or 3 times, then the LED will turn on and off with the code below. I was aiming so that I would hold the button for 5 seconds and not for every 2 or 3 times. I tried the code from the site, but I might've messed up. Did I do something wrong?

    #define KEYHOLD_EVT 0x0100 //define event for key hold
    int KeyPressCnt=0;
    int h = 0;

    static void zclSampleLight_HandleKeys( byte shift, byte keys )
    {
    //if(h == 1){
    if ( keys & HAL_KEY_SW_2)
    {
    KeyPressCnt=0;
    osal_start_timerEx( zclSampleLight_TaskID, KEYHOLD_EVT, 1000);

    if (KeyPressCnt>=5){
    giLightScreenMode = LIGHT_MAINMODE;

    // toggle local light immediately
    zclSampleLight_OnOff = zclSampleLight_OnOff ? LIGHT_OFF : LIGHT_ON;
    #ifdef ZCL_LEVEL_CTRL
    zclSampleLight_LevelCurrentLevel = zclSampleLight_OnOff ? zclSampleLight_LevelOnLevel : ATTR_LEVEL_MIN_LEVEL;
    #endif
    }
    }
  • Do you implement KEYHOLD_EVT in zclSampleLight_event_loop?
  • No. What code should I type up in that function?
  • I did this from the site, but it doesn't seem to know when I press the button.

    #define KEYHOLD_EVT 0x0100 //define event for key hold

    int KeyPressCnt=0;

    uint16 zclSampleLight_event_loop( uint8 task_id, uint16 events )
    {
    if ( events & KEYHOLD_EVT )
    {
    if ( HAL_KEY_SW_2) //=== HAL_KEY_SW_2
    {
    KeyPressCnt++;
    if (KeyPressCnt>=5){
    giLightScreenMode = LIGHT_MAINMODE;

    // toggle local light immediately
    zclSampleLight_OnOff = zclSampleLight_OnOff ? LIGHT_OFF : LIGHT_ON;
    #ifdef ZCL_LEVEL_CTRL
    zclSampleLight_LevelCurrentLevel = zclSampleLight_OnOff ? zclSampleLight_LevelOnLevel : ATTR_LEVEL_MIN_LEVEL;
    #endif
    }
    else
    osal_start_timerEx( zclSampleLight_TaskID, KEYHOLD_EVT, 100);
    }
    return ( events ^ KEYHOLD_EVT );
    }
  • I have told you that you cannot use  "if ( HAL_KEY_SW_2)". If you use P0.2 as SW2, you should use "if (P0.2==0)" or "if (P0.2==1)" which depends on P0.2 is active low or active high.

    if ( events & KEYHOLD_EVT )
    {
    if ( HAL_KEY_SW_2)  //I have told you that you cannot use  "if ( HAL_KEY_SW_2)". If you use P0.2 as SW2, you should use "if (P0.2==0)" or "if (P0.2==1)"
    {
    KeyPressCnt++;
    if (KeyPressCnt>=5){
    giLightScreenMode = LIGHT_MAINMODE;

    // toggle local light immediately
    zclSampleLight_OnOff = zclSampleLight_OnOff ? LIGHT_OFF : LIGHT_ON;
    #ifdef ZCL_LEVEL_CTRL
    zclSampleLight_LevelCurrentLevel = zclSampleLight_OnOff ? zclSampleLight_LevelOnLevel : ATTR_LEVEL_MIN_LEVEL;
    #endif
    }
    else
    osal_start_timerEx( zclSampleLight_TaskID, KEYHOLD_EVT, 100);
    }
    return ( events ^ KEYHOLD_EVT );
    }

  • Thanks. The code works, but now I'm trying to get where when I just press and release P0.2, it turns on the LED, but if I press and hold P0.2 for 5 seconds, it resets the CC2530. Below is the code I tried, but I can't get it to work. When I press and release P0.2, the CC2530 does nothing. If I hold longer for 1-2 seonds, it turns on the LED. Why can't I just tap the button and instantly release it?

    if (KeyPressCnt>5){
    extern void ZDApp_ResetTimerStart( uint16 delay );
    zgWriteStartupOptions(ZG_STARTUP_SET, (ZCD_STARTOPT_DEFAULT_NETWORK_STATE | ZCD_STARTOPT_DEFAULT_CONFIG_STATE) );
    ZDApp_ResetTimerStart(2000);
    }
    else if(KeyPressCnt<=5){
    giLightScreenMode = LIGHT_MAINMODE;

    // toggle local light immediately
    zclSampleLight_OnOff = zclSampleLight_OnOff ? LIGHT_OFF : LIGHT_ON;
    #ifdef ZCL_LEVEL_CTRL
    zclSampleLight_LevelCurrentLevel = zclSampleLight_OnOff ? zclSampleLight_LevelOnLevel : ATTR_LEVEL_MIN_LEVEL;
    #endif
    }

  • Where do you put these code?
  • I fixed it, but how do I make it so that the CC2530 knows it's being held for 5 seconds? Because when I press the and hold P0.2, the LED turns on and then after 5 secs, it resets. "I'm saying I don't want the LED to turn on when I'm trying to reset the CC2530."

    P.S. 

    The LED on stuff is HandleKey and Reset stuff is in Event Loop.

  • The LED is controlled by you, isn't it? Why can't you disable it?
  • Right now the below code says that the LED is going to turn on when my goal is to reset and not turn on the LED in the process. Can I move the code in bold to somewhere else?

    static void zclSampleLight_HandleKeys( byte shift, byte keys )
    {
    if ( P0_2==1 && P0_1==0)
    {
    KeyPressCnt=0;
    osal_start_timerEx( zclSampleLight_TaskID, KEYHOLD_EVT, 1000);

    giLightScreenMode = LIGHT_MAINMODE;

    // toggle local light immediately
    zclSampleLight_OnOff = zclSampleLight_OnOff ? LIGHT_OFF : LIGHT_ON;
    #ifdef ZCL_LEVEL_CTRL
    zclSampleLight_LevelCurrentLevel = zclSampleLight_OnOff ? zclSampleLight_LevelOnLevel : ATTR_LEVEL_MIN_LEVEL;
    #endif
    }

  • Yes, I see no problem to remove those codes to elsewhere.