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.

CC2530 + setting joystick press time

Other Parts Discussed in Thread: CC2530

Hello TI,

I am using CC2530 + Smart RF05 board for my development purpose.I am using samplelight app of HA.

I need to trigger an event after pressing joystick for say 5sec. 

I am not able to figure out where to wait while pressing joystick.

Please guide me.

Best Regards

SS.

  • Since Joystick on SmartRF05EB uses ADC reading, you have to start another event to check this ADC reading for pressing joystick. For ADC reading of key pressing, you can refer to halGetJoyKeyInput() in hal_key.c

  • Thanks YiKai for response

    I have to implement is If joystick will be pressed for a long time(say 5 or 10 sec) then only a event occur.

    I am adding code inside zclSampleLight_HandleKeys

    Could you please tell me how to proceed

    Regards

    SS

  • You will receive HAL_KEY_SW_5 in zclSampleLight_HandleKeys() if you press the center of joystick. So, you can start a event to check adc reading from joystick every second. If you keep reading adc value as center pressed for 5 times which means it last more than 5 seconds, you can know user presses center of joystick for 5 seconds.

    Pseudo-codes (please check red lines) are in the followings:

    ...

    int center_hold_cnt=0; //declare global variable for joystick hold checking

    ...

    static void zclSampleLight_HandleKeys( byte shift, byte keys )
    {

    ...

      else if ( keys & HAL_KEY_SW_5 )
      {

        center_hold_cnt=0;
        osal_start_timerEx( zclSampleLight_TaskID, KEYHOLD_EVT, 1000);

        ....
      }
    ...

    }

    ...

    uint16 zclSampleLight_event_loop( uint8 task_id, uint16 events )
    {

      .....

      if ( events & KEYHOLD_EVT )
      {
        uint8 adc;
        adc = HalAdcRead (HAL_KEY_JOY_CHN, HAL_ADC_RESOLUTION_8);
        if ((adc >= 89) && (adc <= 100))
        {
          center_hold_cnt++;
        }
        if (center_hold_cnt>=5)
        {
          //Key hold for 5 seconds
        }
        osal_start_timerEx( zclSampleLight_TaskID, KEYHOLD_EVT, 1000);
        return ( events ^ KEYHOLD_EVT );
      }

     

      // Discard unknown events
      return 0;
    }

  • Hello YikAi 

    I tried as you said but as I press joystick event occurs. It is not waiting for 5 or more then 5 second to occur. Below is the code.

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

    .

    int center_hold_cnt=0; //declare global variable for joystick hold checking.

    static void zclSampleLight_HandleKeys( byte shift, byte keys )
    {

    ...

      else if ( keys & HAL_KEY_SW_5 )
      {

        center_hold_cnt=0;
        osal_start_timerEx( zclSampleLight_TaskID, KEYHOLD_EVT, 1000);

       /* As key pressed for 5 sec below action should be taken */

       uint8 retValue;

      zAddrType_t destAddr;


    uint8 *pIEEEAddr;


    destAddr.addrMode = Addr16Bit;


    destAddr.addr.shortAddr=0x0000;


    pIEEEAddr=NLME_GetExtAddr();


    retValue = (byte)ZDP_MgmtLeaveReq( &destAddr,pIEEEAddr,1,0,1);

     

        ....
      }
    ...

    }

    ...

    uint16 zclSampleLight_event_loop( uint8 task_id, uint16 events )
    {

      .....

      if ( events & KEYHOLD_EVT )
      {
        uint8 adc;
        adc = HalAdcRead (HAL_KEY_JOY_CHN, HAL_ADC_RESOLUTION_8);
        if ((adc >= 89) && (adc <= 100))
        {
          center_hold_cnt++;
        }
        if (center_hold_cnt>=5)
        {
          //Key hold for 5 seconds
        }
        osal_start_timerEx( zclSampleLight_TaskID, KEYHOLD_EVT, 1000);
        return ( events ^ KEYHOLD_EVT );
      }

     

      // Discard unknown events
      return 0;
    }

    Code is not waiting for 5sec joystick hold. As i pressed the joystick action (i.e. device leave the network) occurs. It doesn't even wait for release of joystick.

    Please guide me to solve this issue.

    Best Regards

    SS

  • 1. Revise #define KEYHOLD_EVT  0x0106    //define event for key hold to #define KEYHOLD_EVT  0x0100    //define event for key hold. Event define is a bit flag so you can turn on one bit per define.

    2. You should put mgmt leave request in the following if statement.

        if (center_hold_cnt>=5)
        {
          //Key hold for 5 seconds

       uint8 retValue;

      zAddrType_t destAddr;


    uint8 *pIEEEAddr;


    destAddr.addrMode = Addr16Bit;


    destAddr.addr.shortAddr=0x0000;


    pIEEEAddr=NLME_GetExtAddr();


    retValue = (byte)ZDP_MgmtLeaveReq( &destAddr,pIEEEAddr,1,0,1);

        }

  • Hello Yikai 

    Thanks for the reply

    I have done as you said but after just pressing joystick action occurs still

    if ( events & KEYHOLD_EVT )
    {
    uint8 adc;

    adc = HalAdcRead (HAL_KEY_JOY_CHN, HAL_ADC_RESOLUTION_8);
    if ((adc >= 89) && (adc <= 100))
    {
    center_hold_cnt++;
    }
    if (center_hold_cnt>=5)

    {
    if(zclSampleLight_NwkState == DEV_END_DEVICE)
    {
    uint8 retValue;
    zAddrType_t destAddr;
    uint8 *pIEEEAddr;
    destAddr.addrMode = Addr16Bit;
    destAddr.addr.shortAddr=0x0000;
    pIEEEAddr=NLME_GetExtAddr();
    retValue = (byte)ZDP_MgmtLeaveReq( &destAddr,pIEEEAddr,1,0,1);

    }

    }

    osal_start_timerEx( zclSampleLight_TaskID, KEYHOLD_EVT, 1000);
    return ( events ^ KEYHOLD_EVT );

    }

    After pressing JoyStick once the colored section of the code get executed continuously and hence after a while condition get true and event occurs.

    Please help me to solve this problem.

  • The code are excuted every second because we use "osal_start_timerEx( zclSampleLight_TaskID, KEYHOLD_EVT, 1000);" in the end of event. If the code continepu counts 5 time of correct ADC reading, it means user presses center of joystick for 5 seconds. Doesn't this what you want?

  • Yes I want that.

    But here when I press and release key for a second then also event is occuring.

    Regards

    SS

  • You can add an else like the following red part.

    if ( events & KEYHOLD_EVT )
    {
    uint8 adc;

    adc = HalAdcRead (HAL_KEY_JOY_CHN, HAL_ADC_RESOLUTION_8);
    if ((adc >= 89) && (adc <= 100))
    {
    center_hold_cnt++;
    }
    if (center_hold_cnt>=5)


    if(zclSampleLight_NwkState == DEV_END_DEVICE)
    {
    uint8 retValue;
    zAddrType_t destAddr;
    uint8 *pIEEEAddr;
    destAddr.addrMode = Addr16Bit;
    destAddr.addr.shortAddr=0x0000;
    pIEEEAddr=NLME_GetExtAddr();
    retValue = (byte)ZDP_MgmtLeaveReq( &destAddr,pIEEEAddr,1,0,1); 

    }

    }
    else
       osal_start_timerEx( zclSampleLight_TaskID, KEYHOLD_EVT, 1000);
    return ( events ^ KEYHOLD_EVT );

    }

  • At first i was curious about the  KEYHOLD_EVT define as 0x0100, because i see that keychange  is define as oxc0 ,

    /*********************************************************************
     * Global Generic System Messages
     */

    #define KEY_CHANGE                0xC0    // Key EventsKeyHoldCheckByCompare

    // OSAL System Message IDs/Events Reserved for applications (user applications)
    // 0xE0 ?0xFC

    is that right to define the   KEYHOLD_EVT as 0x0100????

    Secondly  as add those code , when i press the key , it always toggle short press event then toggle long press event

    the code is:

             

    uint16 zclIASZoneVibration_event_loop( uint8 task_id, uint16 events )
    {
      afIncomingMSGPacket_t *MSGpkt;
      (void)task_id;  // Intentionally unreferenced parameter

      if ( events & SYS_EVENT_MSG )
      {
        while ( (MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( zclIASZoneVibration_TaskID )) )
        {
          switch ( MSGpkt->hdr.event )
          {

            case KEY_CHANGE:
              zclIASZoneVibration_HandleKeys( ((keyChange_t *)MSGpkt)->state, ((keyChange_t *)MSGpkt)->keys );
              break;
    #ifdef KeyHoldCheckByCompare          
            case KEYHOLD_EVT:
              zclIASZoneVibration_HandleKeys( ((keyChange_t *)MSGpkt)->state, ((keyChange_t *)MSGpkt)->keys );
              break;
    #endif          
            default:
              break;
          }

          // Release the memory
          osal_msg_deallocate( (uint8 *)MSGpkt );
        }

        // return unprocessed events
        return (events ^ SYS_EVENT_MSG);
      }

     
    #ifdef KeyHoldCheckByCompare
      if ( events & KEYHOLD_EVT )
      {
         if ( HAL_PUSH_BUTTON1())        //P01 === HAL_KEY_SW_6
        {
          KeyPressCnt++;
         
          if(KeyPressCnt >=2)
          {
            HalLedSet ( HAL_LED_4, HAL_LED_MODE_OFF ); 
            HalUARTWrite(0,"SW_6 PRESS HOLD\n", sizeof("SW_6 PRESS HOLD\n"));
          }
          else
            osal_start_timerEx( zclIASZoneVibration_TaskID, KEYHOLD_EVT, 1000);
        }
       
        return ( events ^ KEYHOLD_EVT );
      } 
    #endif
      
      return 0;

    }

    static void zclIASZoneVibration_HandleKeys( byte shift, byte keys )
    {

      if ( keys & HAL_KEY_SW_6 )
      {
    #ifdef KeyHoldCheckByCompare
          KeyPressCnt =0;
         
          HalLedBlink ( HAL_LED_4, 0, 50, 2000 );
          HalUARTWrite(0,"SW_6 PRESS\n", sizeof("SW_6 PRESS\n")); 
          osal_start_timerEx( zclIASZoneVibration_TaskID, KEYHOLD_EVT, 1000);
    #endif

       }
    }

    as the result of press key long time, there is always toggle the short press event, how can i  avoid  this bug:

          

  • Hi  chen

                if i  set this function osal_start_timerEx( zclIASZoneVibration_TaskID, KEYHOLD_EVT, 1000);

    is the event loop judgement , the device will be always working, which is not good for setting sleep mode

  • You can revise the red lines to seperate "SW_6 PRESS" and "SW_6 PRESS HOLD"

    #ifdef KeyHoldCheckByCompare
      if ( events & KEYHOLD_EVT )
      {
         if ( HAL_PUSH_BUTTON1())        //P01 === HAL_KEY_SW_6
        {
          KeyPressCnt++;
         
          if(KeyPressCnt >=2)
          {
            HalLedSet ( HAL_LED_4, HAL_LED_MODE_OFF );
            HalUARTWrite(0,"SW_6 PRESS HOLD\n", sizeof("SW_6 PRESS HOLD\n"));
          }
          else
            osal_start_timerEx( zclIASZoneVibration_TaskID, KEYHOLD_EVT, 1000);
        } else {
          HalUARTWrite(0,"SW_6 PRESS\n", sizeof("SW_6 PRESS\n"));
        }
       
        return ( events ^ KEYHOLD_EVT );
      }
    #endif

    static void zclIASZoneVibration_HandleKeys( byte shift, byte keys )
    {

      if ( keys & HAL_KEY_SW_6 )
      {
    #ifdef KeyHoldCheckByCompare
          KeyPressCnt =0;
         
          HalLedBlink ( HAL_LED_4, 0, 50, 2000 );
          //HalUARTWrite(0,"SW_6 PRESS\n", sizeof("SW_6 PRESS\n"));
          osal_start_timerEx( zclIASZoneVibration_TaskID, KEYHOLD_EVT, 1000);
    #endif

       }
    }

  • The device will not be always working with osal_start_timerEx( zclIASZoneVibration_TaskID, KEYHOLD_EVT, 1000);. It would sleep 1 second and wake up after time is up.

  • oh no!!

    this enddevice is powered by battery ,and it was the IAS_ZONE,

    if the device wake up every 1s , the battery will be loss power soon。

  • In my example, I only start event every second when the button is hold. If you don't hold the button, the device won't be wake up every second.

  • ok i see , you mean if there is not any keypress the device will sleep all the time ,if key press and hold this wake up event will be start  then again and again , when key release,the wake up event will stop , is that right !??

    but there is a problem,when short key press occurs ,it seems need to wait so long  then toggle the short press event 。

  • 1. It is correct that the event would only be created when key is pressed and hold.

    2. You can shorten the delay (from 1000 to 100) of first call to osal_start_timerEx in zclIASZoneVibration_HandleKeys(). Then, you don't have to wait 1 second.

    static void zclIASZoneVibration_HandleKeys( byte shift, byte keys )
    {

      if ( keys & HAL_KEY_SW_6 )
      {
    #ifdef KeyHoldCheckByCompare
          KeyPressCnt =0;
         
          HalLedBlink ( HAL_LED_4, 0, 50, 2000 );
          osal_start_timerEx( zclIASZoneVibration_TaskID, KEYHOLD_EVT, 100);
    #endif

       }
    }

  • hi chen ,i think that is wrong.

    i have change it as you said, but it didn't work.

    so i have try change  the long press event wake up cycle as like this :

      if ( events & KEYHOLD_EVT )
      {
         if ( HAL_PUSH_BUTTON1())//key long press
        {
          KeyPressCnt++;
         
          if(KeyPressCnt >=30)
          {
            HalLedSet ( HAL_LED_4, HAL_LED_MODE_OFF ); 
            HalUARTWrite(0,"SW_6 PRESS HOLD\n", sizeof("SW_6 PRESS HOLD\n"));
          }
          else
            osal_start_timerEx( zclIASZoneVibration_TaskID, KEYHOLD_EVT, 100);
        }
         else // key short press
        {
          HalLedBlink ( HAL_LED_4, 0, 50, 2000 );
          HalUARTWrite(0,"SW_6 PRESS\n", sizeof("SW_6 PRESS\n"));
        }
        return ( events ^ KEYHOLD_EVT );
      }

    and  this method worked

  • Yes, your revision works better.