Home AMX User Forum AMXForums Archive Threads Tips and Tricks

Hold Button Event Issues by using own module

I am trying to do a hold event from a module and i am not able to work. But if i write the code without a module, it works perfectly. What am i doing wrong here. Please see my code examples.

1. Without module
BUTTON_EVENT [dvSFLivingTP,btSerial_Plasma_6]
{
    HOLD[2,REPEAT]:
    {
	SWITCH(get_last(btSerial_Plasma_6))
	{
	    CASE 41:send_string dvSFLivingSerial_Plasma_3,"'LEFT00', $0D,$0A"// INCREASE VOLUME 
	    CASE 42:send_string dvSFLivingSerial_Plasma_3,"'RGHT00', $0D,$0A"// DECREASE VOLUME
	}
    }
    Release:
    {
	SWITCH(get_last(btSerial_Plasma_6))
	{
	    CASE 41:send_string dvSFLivingSerial_Plasma_3,"'LEFT00', $0D,$0A"// INCREASE VOLUME
	    CASE 42:send_string dvSFLivingSerial_Plasma_3,"'RGHT00', $0D,$0A"// DECREASE VOLUME
	}
    }    
}

2. With module
PROGRAM_NAME='iSFLivingAquavisionTV'

#include 'iSFLivingSystemDevices.axi'
#include 'iSFLivingSystemVariables.axi'

DEFINE_VARIABLE


DEFINE_MODULE 'Aquavision TV_Comm' AquavisionTV_Comm (dvSFLivingTP,
			       dvSFLivingSerial_Plasma_3,btSerial_Plasma_6,nAquavisionType)

DEFINE_EVENT			// UI events
BUTTON_EVENT [dvSFLivingTP,btSerial_Plasma_6]
{
    HOLD[2,REPEAT]:
    {
	SWITCH(get_last(btSerial_Plasma_6))
	{
	    CASE 41: DO_PUSH (dvSFLivingTP, 1152)
	    CASE 42:DO_PUSH (dvSFLivingTP, 1151)
	}
    }
    Release:
    {
	SWITCH(get_last(btSerial_Plasma_6))
	{
	    CASE 41:DO_Release (dvSFLivingTP, 1152)
	    CASE 42:DO_Release (dvSFLivingTP, 1151)	    
	}
    }    
}			       

MODULE_NAME='Aquavision TV_Comm'(DEV dvTP_DPS[],DEV dvDevice,integer nCHAN_BTN[],integer nType)

define_start
rebuild_event()
DEFINE_EVENT

DATA_EVENT[dvDevice]
{
  ONLINE:
    {
	send_command dvDevice,"'TSET BAUD 9600,N,8,1 485 disable'"
	if(nType=2)
	    	  send_command dvDevice,"'CHARD-20'"
    }
}

BUTTON_EVENT[dvTP_DPS,nCHAN_BTN]
{
    Hold [2,REPEAT]:
    {
    	if(nType==1)
	{
	    switch(GET_LAST(nCHAN_BTN))
	    {
		CASE 24:send_string dvDevice,"'RGHT00', $0D,$0A"// DECREASE VOLUME
		CASE 25:send_string dvDevice,"'LEFT00', $0D,$0A"// INCREASE VOLUME
	    }
	}else
	{
	    switch(GET_LAST(nCHAN_BTN))
	    {
		CASE 24:send_string dvDevice,"'rght00', $0D,$0A"// DECREASE VOLUME
		CASE 25:send_string dvDevice,"'left00', $0D,$0A"// INCREASE VOLUME
	    }
	}
    }
    RELEASE:
    {
    	if(nType==1)
	{
	    switch(GET_LAST(nCHAN_BTN))
	    {
		CASE 24:send_string dvDevice,"'RGHT00', $0D,$0A"// DECREASE VOLUME
		CASE 25:send_string dvDevice,"'LEFT00', $0D,$0A"// INCREASE VOLUME
	    }
	}else
	{
	    switch(GET_LAST(nCHAN_BTN))
	    {
		CASE 24:send_string dvDevice,"'rght00', $0D,$0A"// DECREASE VOLUME
		CASE 25:send_string dvDevice,"'left00', $0D,$0A"// INCREASE VOLUME
	    }
	}
    }    
}

Comments

  • DHawthorneDHawthorne Posts: 4,584
    I vaguely seem to remember, and I'm not sure, so maybe someone else remembers better ... but I think the issue is using DO_PUSH on a real device that's referenced in the module. Try making it a virtual device within the module and execute your DO_PUSH on that.
  • viningvining Posts: 4,368
    I believe the issue is that do push works like a pulse and releases after .5 seconds so what you need to do is use do_push_timed to maintain the hold otherwise it will release all on its own in .5 seconds.
    DO_PUSH_TIMED
    Similar to DO_PUSH except this one lets you specify the timeout.
    
    DO_PUSH defaults to a 0.5s push on a channel before issuing a DO_RELEASE for you (unless another DO_PUSH is executed for the same channel).
    
    DO_PUSH_TIMED lets you control the length of time that will pass before the automatic DO_RELEASE is generated.
    
    Syntax:
    
    DO_PUSH_TIMED(DEV Device, INTEGER Channel, LONG Timeout)
    
    Parameters:
    
    Device - the device to PUSH.
    
    Channel - the channel to PUSH.
    
    Timeout - the time (in 1/10ths of seconds) that the PUSH shall remain active. If zero is specified as the timeout then the timeout is 0.5s. If DO_PUSH_TIMED_INFINITE is specified as the timeout then the push never times out.
    
    Returns: None
    
    Example:
    
    DO_PUSH_TIMED (dvTouchPanel, 5, 10) // push button 5 for 1.0S
    
    
    You can use do_push_timed_infinite as it mentions above to mimic a release push but I like to create constants of various duration so on something like a volume ramp I might use 50 for 5 second of ramping max at one time in case the cat stands on the real button.

    I probably use do_push timed more than do_push and often use 1 (1/10th second) for my time otherwise if I push a button that uses do_push and immediately release I can"t press and issue another push until the first push times out the default .5 seconds. That is of course unless your force the release with do_release which I always do too.
  • viningvining Posts: 4,368
    after looking at your code a little more it does seem wrong the way the hold is implemented. Usually when I have my code control a module I basically have just a push and release for my TPs which control my module by using do_push_timed in my push handler and my release uses the do_release and I don't use the hold handler at all in my axi or the main code. The hold should be in the module itself and triggered by your do_push_timed outside the module and maintained until you release and issue do_release or the do_push_timed time runs out if you didn't use infinite.

    Example of my axi:
    BUTTON_EVENT[dvUI_SBSArry,0]
         
         {
         PUSH :
    	  {
    	  STACK_VAR INTEGER nBtn;
    	  STACK_VAR INTEGER nSBS_Indx;
    	  STACK_VAR INTEGER nUI_Indx;
    	  STACK_VAR INTEGER i;
    	    
    	  nBtn = BUTTON.INPUT.CHANNEL;
    	  nUI_Indx = GET_LAST(dvUI_SBSArry);
    	  
    	  fnSBS_DeBug("'UI INDX-[ ',itoa(nUI_Indx),' ], SBS-[ ',itoa(nUI_SBSActiveArry[nUI_Indx]),' ], PUSH CHNL-[ ',itoa(nBtn),' ] :DEBUG<',ITOA(__LINE__),'>'");
    	  if(nBtn <= 200)
    	       {
    	       if(nUI_SBSActiveArry[nUI_Indx] && nUI_SBSActiveArry[nUI_Indx] <= NUM_SBS_DEVICES)//not already going on or off page
    		    {
    		    nSBS_Indx = nUI_SBSActiveArry[nUI_Indx];
    		    fnSBS_DeBug("'UI INDX-[ ',itoa(nUI_Indx),' ], SBS-[ ',itoa(nSBS_Indx),' ], PUSH CHNL-[ ',itoa(nBtn),' ] :DEBUG<',ITOA(__LINE__),'>'");
    		    SELECT//could get rid of select/active since they are all the same action.
    			 {
    			 ACTIVE(nBtn == SBS_BTN_LVL_PUSH)://100level bar active
    			      {//push often lags the level event
    			      //ON[vSBS_Arry[nSBS_Indx],SBS_BTN_LVL_PUSH]; //just used in the .axi for level event verification
    			      //DO_PUSH_TIMED(vSBS_Arry[nSBS_Indx],nBtn,DO_PUSH_TIMED_10S_MAX);
    			      }
    			 ACTIVE(nBtn < SBS_BTN_REMOTE_SHUTDWON)://1-198Genral buttons
    			      {
    			      DO_PUSH_TIMED(vSBS_Arry[nSBS_Indx],nBtn,DO_PUSH_TIMED_10S_MAX);
    			      }
    			 ACTIVE(nBtn == SBS_BTN_REMOTE_SHUTDWON)://199 Send when Sever is no longer "on page and not sourced by any zone" shut down server
    			      {
    ....
    
    .....
     RELEASE:
    	  {
    	  STACK_VAR INTEGER nBtn;
    	  STACK_VAR INTEGER nUI_Indx;
    	  STACK_VAR INTEGER nSBS_Indx;
    	    
    	  nBtn = BUTTON.INPUT.CHANNEL;
    	  nUI_Indx = GET_LAST(dvUI_SBSArry);
    	  
    	  nSBS_Indx = nUI_SBSActiveArry[nUI_Indx];
    	 
    	  if(nSBS_Indx <= NUM_SBS_DEVICES)
    	       {
    	       fnSBS_DeBug("'UI INDX-[ ',itoa(nUI_Indx),' ], SBS-[ ',itoa(nSBS_Indx),' ], RELEASE CHNL-[ ',itoa(nBtn),' ] :DEBUG<',ITOA(__LINE__),'>'");
    	       SELECT
    		    {
    		    ACTIVE(nBtn == SBS_BTN_LVL_PUSH)://level bar active
    			 {
    			 OFF[vSBS_Arry[nSBS_Indx],SBS_BTN_LVL_PUSH];//just used in the .axi for level event verification
    			 //DO_RELEASE(vSBS_Arry[nSBS_Indx],nBtn);
    			 }
    		    ACTIVE(nBtn < SBS_BTN_OFFPAGE):// || nBtn > SBS_BTN_ONPAGE_MAX)://all command buttons
    			 {
    			 DO_RELEASE(vSBS_Arry[nSBS_Indx],nBtn);
    			 }
    		    }
    

    Example of my axs (module)
    BUTTON_EVENT	[vSBS,0]
         
         {
         PUSH :
    	  {
    	  STACK_VAR INTEGER nBtn;
    	       
    	  nBtn = BUTTON.INPUT.CHANNEL;
    	  //fnDevMod_DeBug("'PUSH_CHNL-[',itoa(nBtn),'], SBS LVL-[',itoa(sSBS.sBrowseState.nLevel),'] :DEBUG<',ITOA(__LINE__),'>'",2);
    	  if(sSBS.sPlayer.nIP_ConState > IP_CLIENT_PENDING || nBtn == SBS_BTN_ONPAGE || nBtn == SBS_BTN_OFFPAGE)
    	       {
    	      // if(![vSBS,SBS_BTN_PROGRESS_BUSY])
    //		    {
    	       STACK_VAR INTEGER nLVL;
    	             
    	       nLVL = sSBS.sBrowseState.nLevel;
    	       if(nLVL)
    		    {
    		    STACK_VAR INTEGER nRemote;
    		    LOCAL_VAR INTEGER nWarning_OK;
    			 //nIsPlugin = sLevel[nLVL].nType >= SBS_infoApps;
    			 nRemote = sSBS.sNowPlaying.nRemote;
    		   //_1_//fnDevMod_DeBug("'PUSH_CHNL-[',itoa(nBtn),'], LVL-[',itoa(sSBS.sBrowseState.nLevel),'] :DEBUG<',ITOA(__LINE__),'>'",2);
    		    CANCEL_WAIT 'AUTO_CLOSE_SELECT';
    		    
    		    SELECT
    			 {
    			 ACTIVE(nBtn == SBS_BTN_PLY_PAUSE)://1 PLAY OR PAUSE, added double tap for stop
    			      {
    			      //moved to release
    			      }
    			 ACTIVE(nBtn == SBS_BTN_SKP_FWD || nBtn == SBS_BTN_SKP_BACK)://skip foward , skip back
    			      {
    			      STACK_VAR INTEGER nDoIt;
    			      
    			      SWITCH(nBTN)
    				   {
    				   CASE SBS_BTN_SKP_FWD:
    					{
    				
    .......
    .......
    
     HOLD[5,REPEAT]:
    	  {
    	  if(sSBS.sPlayer.nIP_ConState > IP_CLIENT_PENDING)
    	       {
    	       STACK_VAR INTEGER nBtn;
    		 
    	       nBtn = BUTTON.INPUT.CHANNEL;
    	      //_1_//fnDevMod_DeBug("'HOLD_CHNL-[',itoa(nBtn_Holding),'] :DEBUG<',ITOA(__LINE__),'>'",2);
    	       SELECT
    		    {
    		    ACTIVE(nBtn == SBS_BTN_SCN_FWD || nBtn == SBS_BTN_SCN_BACK):
    			 {
    			 nBtn_Held = 0;
    			 if(sSBS.sStatus.nMode == SBS_PlayMode_Play)
    			      {
    			      SELECT
    				   {
    				   ACTIVE(nBtn == SBS_BTN_SCN_FWD):
    					{
    
    .....
    .....
    RELEASE:
    	  {
    	  if(sSBS.sPlayer.nIP_ConState > IP_CLIENT_PENDING)// || nBtn == UI_BTN_ONPAGE)
    	       {
    	       STACK_VAR INTEGER nBtn;
    		 
    	       nBtn = BUTTON.INPUT.CHANNEL;
    	       SELECT
    		    {
    		    ACTIVE(nBtn == SBS_BTN_PLY_PAUSE)://1 PLAY OR PAUSE, added double tap for stop
    			 {
    			 if(nBtn_Held == SBS_BTN_PLY_PAUSE)
    			      {
    			      fnBtn_DoCommand(SBS_PlayMode_Stop);
    
  • GregGGregG Posts: 251
    My usual way to do things inside a module is with channel events or commands.

    So, main code:
    Button_Event[dvTP,1]
    { Push: To[vdvModule,101] }
    

    And inside the module:
    Channel_Event[vdvModule,101]
    {
      On:
      {
        // Do ramping start code
      }
      Off:
      {
        // Do ramping stop code
      }
    }
    
  • viningvining Posts: 4,368
    Yeah channel_events with work just as well and then instead of using a hold, repeat to issue repetitive commands you just create a timeline that does the same and just start and stop it.

    I think I gravitated towards the button_event method simply because it can work exactly the same as if you had it in the main code if done correctly and I don't need to use timelines. Of course I don't think I ever thought of using a "to" with a push to work the channel ON/OFF, or even tried to see if that would work on a button event in a module instead of using do_push. In fact I really haven't used "to" for anything since my early days of programming and I have no idea why. Maybe it was "to" easy and I just felt the need to over complicate things. :)
  • ajish.rajuajish.raju Posts: 185
    Thanks Guys for the posts. I modified as per Vining's advice and it works perfectly now.
Sign In or Register to comment.