Home AMX User Forum AMX General Discussion

reading the status of pushed channel by DO_PUSH (new)

Hello

Is is possible to read the status of a virtual channel if it was pushed or not

I used DO_PUSH(myVirtualDev,1) to do the push
and it seems that IF([myVirtualDev,1]) does not return the correct status of the channel

I can save all the pushed channels inside an array, but what if I have lot of channels to work with or even dynamic channels ?

any idea ?

Comments

  • HedbergHedberg Posts: 671
    If you want the feedback status of a channel to change, you have to make it change in some way, don't you? You have to turn it on and off, just like a button on a physical panel. Simply pushing a button will not change it's feedback state.

    For example, if you have a physical panel with a button on it [dvPhysicalPanel,1] and someone presses that button on a panel, the feedback status (what you check when you check [dvPhysicalPanel,1] ) doesn't change unless you turn it on or off or use a to[] or whatever.

    this may be very simple to accomplish. In the button event you might just change the status in the push: handler:
    [myVirtualDev,1] = ![myVirtualDev,1]
    
  • viningvining Posts: 4,368
    Do_Push pulses the channel so it's only on for a 1/2 second. When your if statement runs you're probably off again. You could use on and off for your devchan or you could use use do_push_timed with the infinite constant but you'd have to do a do_release at some point in order to push again.
  • moty66moty66 Posts: 31
    Hedberg wrote: »
    If you want the feedback status of a channel to change, you have to make it change in some way, don't you? You have to turn it on and off, just like a button on a physical panel. Simply pushing a button will not change it's feedback state.
    [myVirtualDev,1] = ![myVirtualDev,1]
    

    I don't want to use the feedback
    Becasue when the DO_PUSH_TIMED() function release the push the feedback will not be updated
  • moty66moty66 Posts: 31
    vining wrote: »
    Do_Push pulses the channel so it's only on for a 1/2 second. When your if statement runs you're probably off again. You could use on and off for your devchan or you could use use do_push_timed with the infinite constant but you'd have to do a do_release at some point in order to push again.

    Good, I used do_push_timed with very infinite push constant

    but How can I read later if this channel is pushed or not ?
    How can I use on off ?? and can I read them later ??
    On(myDev,myChan) ?

    thanks
  • viningvining Posts: 4,368
    moty66 wrote: »
    Good, I used do_push_timed with very infinite push constant

    but How can I read later if this channel is pushed or not ?
    How can I use on off ?? and can I read them later ??
    On(myDev,myChan) ?

    thanks
    ON[dev,chan]
    OFF[dev,chan]

    IF([dev,chan]) should work when using the on/off but maybe not when using do_push. I rarely check channel states myself so I'm somewhat ignorant on their usage but it might be do_push affects input channels and on/off affects feedback channels. Since I don't really use these I never gave it much thought but there has been discussions about feedback vs input channels that you may be able to find. Maybe I should have read them.
  • moty66moty66 Posts: 31
    vining wrote: »
    ON[dev,chan]
    OFF[dev,chan]

    IF([dev,chan]) should work when using the on/off but maybe not when using do_push. I rarely check channel states myself so I'm somewhat ignorant on their usage but it might be do_push affects input channels and on/off affects feedback channels. Since I don't really use these I never gave it much thought but there has been discussions about feedback vs input channels that you may be able to find. Maybe I should have read them.

    Thanks again
    Yes, I guess that ON/OFF works for the feedback, I will do some test and I will leave a message when I am done

    Regards
  • HedbergHedberg Posts: 671
    We are talking about two different things. One is whether the button is being pushed or not and the other is the status of the button, that is, the feedback state. When you push a button (either on a physical panel or with a do_push(), you are not turning the channel on and off. If you push a button, or an IO, or a virtual with do_push(), you will not see a change of state on the button's channel, you cannot trigger a channel event. If you test a channel, eg if([dev.channel]), you won't see a button press.

    So, when you evaluate a button, you are not checking to see if it is currently pushed, you are not checking to see if it has been pushed, you are checking to see what the state of it's feedback is, and you control that in the code in any manner you desire -- typically in response to a button press or in response to a channel feedback state, or an IO state or a string received from a device or whatever.
  • moty66moty66 Posts: 31
    Hedberg wrote: »
    We are talking about two different things. .
    Yes, I understand what you are saying
    but ...

    From the Netlinx Language Reference
    This keyword causes an input change from OFF to ON to occur on a specified
    device-channel without the device-channel being activated by external means.
    To prevent the program from stalling mainline too long, there is a 0.5 second
    timeout on DO_PUSH. DO_PUSH defaults to a 0.5 second push on a channel
    before issuing a DO_RELEASE for you (unless another DO_PUSH is executed for
    the same channel). NetLinx will forcibly exit the DO_PUSH after 0.5 seconds,
    regardless of the operation it is executing. If the channel is already ON, no
    event is generated.

    Note: The timeout feature is used to prevent un-released pushes and out of
    control ramping.
    DO_PUSH(DEVICE, CHANNEL)

    As you see, AMX says that IF the channel is allready ON, no event is generated ! I really don't understand how can they check if a Channel is ON / OFF.

    I didn't describe will my issue, i try now

    I am translating a protocol from RS232 -> Virulent device Channel Events
    The protocol sends to me the address from 0x00 to 0xFF I call it RS_ADDRESS, and a Time out: RS_TIMEOUT, and Action RS_ACTION (01-ON/10-OFF/11-CHANGE_STATE)
    I have no problems with ON OFF and I do it in this way

    FOR ON: DO_PUSH_TIMED(vDEV,RS_ADDRESS,(RS_TIMEOUT /10)
    FOR OFF: DO_RELEASE(vDEV,RS_ADDRESS)

    But my problem is the TOGGLE (change state), so what I need is to check if the channel is already ON then I call the DO_RELEASE function otherwise I call the DO_PUSH / DO_PUSH_TIMES

    Thank you guys for the help
  • HedbergHedberg Posts: 671
    The section of the manual which you quote is describing the _INPUT_ which is not what you are looking at when you evaluate a [device,channel]. There are two binary values associated with each of the channels, an _INPUT_, which is what the quoted text is referring to, and an _OUTPUT_ (or feedback), which you must control through code. The difference is the difference between a button push (which can trigger a button event) and an output channel status change, which can trigger a channel event. They are not at all the same, though the same device,channel syntax may be used for each.

    To understand this better, look at the following code:
    DEFINE_DEVICE
    dvser1 = 5001:1:0 
    
    DEFINE_VARIABLE
    integer nTestdvSer1Chan1
    
    DEFINE_EVENT
    
    
    button_event[dvSer1,1]
    {
    	push:
    	{
    		nTestdvSer1Chan1 = [dvSer1,1]
    		send_string 0, "10,13,'dvSer1,1 pushed: nTestdvSer1Chan1 = ', itoa(nTestdvSer1Chan1)"
    	}
    	release:
    		nTestdvSer1Chan1 = [dvSer1,1]
    		send_string 0, "10,13,'dvSer1,1 released: nTestdvSer1Chan1 = ', itoa(nTestdvSer1Chan1)"
    	}
    }
    
    

    Monitor your diagnostics and debug watching nTestdvSer1Chan1 and use diagnostics/emulate a device to "push" and hold 5001:1:0 and then release it. Do you see how [dvser1,1] never changes?

    Now try the following code instead:
    DEFINE_DEVICE
    dvser1 = 5001:1:0 
    
    DEFINE_VARIABLE
    integer nTestdvSer1Chan1
    
    DEFINE_EVENT
    
    button_event[dvSer1,1]
    {
    	push:
    	{
    		on [dvSer1,1]
    		nTestdvSer1Chan1 = [dvSer1,1]
    		send_string 0, "10,13,'dvSer1,1 pushed: nTestdvSer1Chan1 = ', itoa(nTestdvSer1Chan1)"
    	}
    	release:
    	{
    		off [dvSer1,1]
    		nTestdvSer1Chan1 = [dvSer1,1]
    		send_string 0, "10,13,'dvSer1,1 released: nTestdvSer1Chan1 = ', itoa(nTestdvSer1Chan1)"
    	}
    }
    
    button_event[dvSer1,2]
    {
    	push:
    	{
    		do_push(dvSer1,1)
    	}
    }
    

    You can trigger the button event of interest either directly or with the do_push and the behavior is as expected. If you want to monitor the status of an input (i.e. whether a button push is engaged), you need to turn something on in the push handler and turn it off in the release handler. That is, you need to control the feedback, which you can monitor in code, and not try to monitor the input, which you can't.

    Alternatively, since you are dealing with virtual devices and not physical touch panels, instead of do_push(), you can just manipulate the channels and use channel events instead of button events. That is, instead of do_push() and do_release(), just turn the channel on and off with the desired timing. Depending on how your device is behaving, this may not be practical without using a timeline because I don't think you can use a wait with a variable delay.

    added: of course, rather than turning the channel on and off you can use to[devchan]
  • moty66moty66 Posts: 31
    Thanks for your time and this detailed answer, it was so helpful and I understood the differences now
    Hedberg wrote: »
    Alternatively, since you are dealing with virtual devices and not physical touch panels, instead of do_push(), you can just manipulate the channels and use channel events instead of button events. That is, instead of do_push() and do_release(), just turn the channel on and off with the desired timing. Depending on how your device is behaving, this may not be practical without using a timeline because I don't think you can use a wait with a variable delay.
    added: of course, rather than turning the channel on and off you can use to[devchan]

    Good idea, but using on is not the same as using do_push, because if u turn on a devicechan it will not be off after the time out ! so this is not suitable for what I need

    I will do some tests and I will be back with my results

    Regards
    M.
  • mushmush Posts: 287
    Just to add some more clarification, each channel actually has three states, each of which are separately managed by AMX. These are;
    1. Input - These are pushes. If the button is being pushed then the input is on.
    2. Output - This is controlled by the programmer e.g. ON[5001:8:0, 1] would turn the output on (relay 1 on a NI-3100).
    3. Feedback - This is what the AMX master thinks the channel is. Generally if you turn a channel on then it's feedback will be on. Under certain circumstances the channel will be off but the feedback will be on i.e. if you have a relay in a mutually exclusive group and you pulse it, the channel will say it's off but feedback will say it's on.
  • mushmush Posts: 287
    moty66 wrote: »
    FOR ON: DO_PUSH_TIMED(vDEV,RS_ADDRESS,(RS_TIMEOUT /10)

    For on you could do this;
    ON[vDEV,RS_ADDRESS]
    WAIT RS_TIMEOUT/10 OFF[vDEV,RS_ADDRESS]

    For off;
    OFF[vDEV,RS_ADDRESS]

    For toggle;
    [vDEV,RS_ADDRESS] = ![vDEV,RS_ADDRESS]

    Then your if([vDEV,RS_ADDRESS]) would produce an accurate result.
  • moty66moty66 Posts: 31
    this is what I do for now

    but I don't use ON / OFF
    I still use DO_PUSH and DO_RELEASE
    at the same time I update the feedback
    cancel_wait ('mywait')
    DO_PUSH_TIMES(dev,chan,timeOut)
    [dev,chan] = 1
    
    wait timeOut 'mywait' {
     [dev,chan] = 0
    }
    
    
    I don't have the original code now, so maybe there are some errors in my code
  • viningvining Posts: 4,368
    Why are you using dp_push in the first place? Are you using it to control a module? I'm a big fan of do_push since it allows you to easily do hold events in modules where as a channel event requires you to create timelines that start in the on handler and are killed in the off handler.

    I don't know what you're actually trying to accomplish or if the module is open but I would probably set the devchan feedback in the module and in the push do ON[dev,chan] and then in the release do the OFF[dev,chan].
  • moty66moty66 Posts: 31
    Hardware Map
    ============
    
    							[AMX NI-700]<---(eth)--->[Lutron]
    [KEYPAD]<---(batibus)--->[Batibus-Rs232]<---(rs232)---->[AMX NI-700]<---(IR)--->[Home video]
    						       	[AMX NI-700]<---(rs)--->[Other devices]			
    
    -------------------------------------------------------------------------------------------
    
    The module
    ==========
    When a key is pressed the [Batbus-Rs232] sends to AMX the string of the action, the string holds:
    * Src address  
    * Dst address (will be used as channel)
    * Action ( on / off / toggle)
    * Timeout (0, x>0 secs, -1 infinit)
    
    Then I forward the action to a SWITCH:
    
    switch (action)
    {
    	case on : 
    	{ 	
    		do_push_timed(vDev, channel, timeout)	
    		break
    	}
    	case off: 
    	{	
    		release(vDev,channel)	
    		break	
    	}
    	case toggle: 	
    	{	
    		if(isChannelPushed(channel))
    			release(vDev,channel)
    		else
    			do_push_timed(vDev,channel,timout)
    		break
    	}
    }
    
    
    DEFINE_FUNCTION integer isChannelPushed(integer channel)
    {
    	// not working because we have to set the feedbaack in the switch 
    	// but will not work if we have a timeout 
    	return [vDev,channel]
    }
    
    -------------------------------------------------------------------------------------------
    The program
    ===========
    
    
    DEFINE_EVENT [vDev,0]
    {
    	PUSHED: 
    	{
    		//do stuff
    	}
    	//..etc
    }
    
    -------------------------------------------------------------------------------------------
    
    Problems
    ========
    
    * Can't check if a channel is pushed or not
    * Can't use the feedback, because it will not be updated after the timeout
    * Can't use the wait, because I may receive the same message before the timeout
    * Can't use cancel_timeout because  I may receive a message from different address
    
    
    -------------------------------------------------------------------------------------------
    INFO
    ====
    [] 	= device
    () 	= protocol
    <--> 	= direction
    
    
Sign In or Register to comment.