Home AMX User Forum AMX Control Products

Volume Slider constantly changing without touching?

I just implemented my first active slider (I don't think I'll do this at a job other than my own home), and it works great when I select a section of the slider. A problem has come in where I dragged the slider up, and now it is constantly adjusting itself up and down regardless of what I try and do. I am watching my variable go up and down in debug mode. How do I get it to stop?!?! I don't recall adding any drag programming.

Comments

  • vegastechvegastech Posts: 369
    This is what I started with:

    LEVEL_EVENT[dvJVCLT37X898Tp,2]
    {
    nTVVOL=LEVEL.VALUE
    SEND_COMMAND vdvJVCLT37X898, "'PASSTHRU-!',$82,$80,'VL',itoa(nTVVOL*50/255),$0A"
    SEND_LEVEL dvJVCLT37X898Tp,2,nTVVOL

    }

    I am doing a *50/255 because the TV has discrete volume from 1-50. This way I get the proper % on my bargraph.
  • PhreaKPhreaK Posts: 966
    There shouldn't be any need to be sending the level back to to the panel on its own level event. If you are getting feedback from the device and are wanting the panel to be updated if the level is changed by the device then you may want to look at the DEFINE_CONNECT_LEVEL or COMBINE_LEVEL commands.

    Also, in regards to displaying a percentage you can use the '$P' escape sequence in the button text and it will calculate the percentage on the panel. You can then just set your min and max values to relate to the values that the device supports. This will remove unnessecary overhead from providing a control granularity higher than the parameter granularity.
  • viningvining Posts: 4,368
    I don't like using the same bar graph for display and active touch. I found it always acted weird doing it that way, jumpy and jittery and in a couple cases I think it was possesed. I create one active touch bar graph with level channel 1 and another for display only on level 2 (or what ever 2 channels you want). The one for displaying my level is visible and my active touch bar graph is transparent but directly on top on the visible one. This way they don't interfere with each other.

    You could also change the bargraph range low to 1 and range high to 50 so you don't need to do any math.

    There are also different bargraph settings to allow drag or not. If you're going to use a bargraph to send volume level use should use the drag since it acts as a safety net preventing accidential ramping to full volume if the top of the bargraph is mistakenly tapped. It also provide a limit by stopping after the amount a range is reached. I personally like up and down buttons for ramping with a couple presets for volume control and leave the bargraphs for things like lights or camera PTZ.
  • Use your bargraph with two 'Level Control' buttons with Level codes the same as you bargraph, and set the bargraph to 'display only'. This will give you more control over your range time settings, but will only work for Level codes on Level PORT 1.

    And yes, remove the SEND_LEVEL from the Level Event; what you've done is create a feedback loop. If you get strings back from the device (unless of course it is IR) when the level changes without any input from the panel, parse the level value out of the string and send it back to the panel in a DATA_EVENT. Make sure to differentiate the responses from when the Level changes YOU send the unit, from when the Level changes are External (if there is a difference in the responses), otherwise you will be back to square one with your dancing bargraphs.

    Example (arbitrary values used, no real protocol):

    String to Unit: " SETLEVEL 60, $0d "
    String from Unit " ACK-LEVELSET 60, $0d, $0a "
    When sent from the AMX

    String from Unit " LEVELSET60, $0d, $0a "
    When changed on the Unit itself, e.g. thru a remote.


    If there's a serial command to increment the level by say 1.0dB or 1%, that may be easier than sending a direct value. When a Level changes on a panel and you send that level to the unit, you could be sending a whole barrage of commands to the unit and its getting confused. E.g. going from 20 to 40 on the Bargraph might actually send at least 20 strings all at the same time to the Unit.
  • I now have a functioning sliding bargraph for volume. Thank you! The resetting of the mins and maxs worked great. I have created my volume presets, and they do indeed hold separate values that I am able to recall. I am, however, having two issues.

    1. The presets work, but as I try to watch the array variable change/update in the watch bar, it is always set to 0, never changes. (I'm not sure how the presets are working.)

    2. What button type do I need to use on my panel in order for the preset buttons to show the percentage once it is saved? I have it set to a general type button, and added $P for the text, but it doesn't work.

    [code]
    DEFINE_VARIABLE

    NON_VOLATILE INTEGER nTVVOL
    PERSISTENT INTEGER nVolPre[3]

    BUTTON_EVENT[dvJVCLT37X898Tp,405] //vol preset 1
    BUTTON_EVENT[dvJVCLT37X898Tp,406] //vol preset 2
    BUTTON_EVENT[dvJVCLT37X898Tp,407] //vol preset 3
    {
    HOLD[20]: //If Button is Held for 2 seconds
    {
    nVolPre[BUTTON.INPUT.CHANNEL-404] = nTVVOL
    SEND_COMMAND dvJVCLT37X898Tp,'ADBEEP' //double beeps panel
    }

    RELEASE:
    {
    //SEND_COMMAND vdvJVCLT37X898, "'PASSTHRU-!',$82,$80,'VL',itoa(nVolPre[1]),$0A"
    SEND_LEVEL dvJVCLT37X898Tp, 2, nVolPre[BUTTON.INPUT.CHANNEL-404] //This sends the level to the touchpanel, which in turn sends the command to the tv to adjust volume. See the level event below for more info.
    }


    }

    LEVEL_EVENT[dvJVCLT37X898Tp,2]
    {
    nTVVOL=LEVEL.VALUE
    SEND_COMMAND vdvJVCLT37X898, "'PASSTHRU-!',$82,$80,'VL',itoa(nTVVOL),$0A"


    }
    [\code]
  • PhreaKPhreaK Posts: 966
    vegastech wrote: »
    What button type do I need to use on my panel in order for the preset buttons to show the percentage once it is saved? I have it set to a general type button, and added $P for the text, but it doesn't work.

    The '$P' escape sequence will only work on the volume control (or other button assigned that level code). To show the levels on your preset buttons you will need to use the '^TXT' command. All the info you need about it is in AMX PI.
  • Glad your volume controls are working. And by the way, the ending bbcode tag to make your code more readable is [/code] not [\code]

    --John
  • Haha yeah I figured that was the case after I posted. ;) I guess I had a 50/50 chance of getting it right...
  • Thank you everyone for helping me out with this very small portion of my project. I have now done something that even my Cr**tron programmer doesn't do - shows actual %s for volume presets instead of just Pre 1, Pre 2, Pre 3. I have included my code below for review. It all works as expected, but if anyone has any suggestions about how I can condense it, please let me know. Thanks.
    BUTTON_EVENT[dvJVCLT37X898Tp,405] //vol preset 1
    BUTTON_EVENT[dvJVCLT37X898Tp,406] //vol preset 2
    BUTTON_EVENT[dvJVCLT37X898Tp,407] //vol preset 3
    {
    	HOLD[20]:    //If Button is Held for 2 seconds
    	{
    		nVolPre[BUTTON.INPUT.CHANNEL-404] = nTVVOL
    		SEND_COMMAND dvJVCLT37X898Tp,'ADBEEP' //double beeps panel
    		SWITCH(BUTTON.INPUT.CHANNEL-404)
    		{
    			CASE 1:
    			{
    				SEND_COMMAND dvJVCLT37X898Tp,"'^TXT-10,0,',ITOA(nVolPre[1]*2),'%'"
    			}
    			CASE 2:
    			{
    				SEND_COMMAND dvJVCLT37X898Tp,"'^TXT-11,0,',ITOA(nVolPre[2]*2),'%'"
    			}
    			CASE 3:
    			{
    				SEND_COMMAND dvJVCLT37X898Tp,"'^TXT-12,0,',ITOA(nVolPre[3]*2),'%'"
    			}
    		}
    		
    	}
    	
    	RELEASE:
    	{
    		//SEND_COMMAND vdvJVCLT37X898, "'PASSTHRU-!',$82,$80,'VL',itoa(nVolPre[1]),$0A"
    		SEND_LEVEL dvJVCLT37X898Tp, 2, nVolPre[BUTTON.INPUT.CHANNEL-404]  
    	}
    	
    	
    }
    
    LEVEL_EVENT[dvJVCLT37X898Tp,2]
    {
    	nTVVOL=LEVEL.VALUE
    	SEND_COMMAND vdvJVCLT37X898, "'PASSTHRU-!',$82,$80,'VL',itoa(nTVVOL),$0A"
    	
    	
    }
    
  • viningvining Posts: 4,368
    BUTTON.INPUT.CHANNEL is a global value and can subsequently change due to a button push from any TP for any device. It isn't the current button for just this device it's the current button for any device in the system. You would be better off defining a global variable for this device and set the hold channel in the PUSH: handler, then reference that global variable in your HOLD: handler instead of BIC.

    There's more you could do but at least this will keep the last button pushed for this device as your hold button and not the last button pushed system wide which could be any device from another TP.

    2 seconds is a short amount of time for the hold to execute but it is possible that in that time someone else will push a button on another TP for any number of devices and your BIC value will then be something you don't want.
  • vegastech wrote: »
    Thank you everyone for helping me out with this very small portion of my project. I have now done something that even my Cr**tron programmer doesn't do - shows actual %s for volume presets instead of just Pre 1, Pre 2, Pre 3. I have included my code below for review. It all works as expected, but if anyone has any suggestions about how I can condense it, please let me know. Thanks.
    BUTTON_EVENT[dvJVCLT37X898Tp,405] //vol preset 1
    BUTTON_EVENT[dvJVCLT37X898Tp,406] //vol preset 2
    BUTTON_EVENT[dvJVCLT37X898Tp,407] //vol preset 3
    {
    	HOLD[20]:    //If Button is Held for 2 seconds
    	{
    		nVolPre[BUTTON.INPUT.CHANNEL-404] = nTVVOL
    		SEND_COMMAND dvJVCLT37X898Tp,'ADBEEP' //double beeps panel
    		SWITCH(BUTTON.INPUT.CHANNEL-404)
    		{
    			CASE 1:
    			{
    				SEND_COMMAND dvJVCLT37X898Tp,"'^TXT-10,0,',ITOA(nVolPre[1]*2),'%'"
    			}
    			CASE 2:
    			{
    				SEND_COMMAND dvJVCLT37X898Tp,"'^TXT-11,0,',ITOA(nVolPre[2]*2),'%'"
    			}
    			CASE 3:
    			{
    				SEND_COMMAND dvJVCLT37X898Tp,"'^TXT-12,0,',ITOA(nVolPre[3]*2),'%'"
    			}
    		}
    		
    	}
    	
    	RELEASE:
    	{
    		//SEND_COMMAND vdvJVCLT37X898, "'PASSTHRU-!',$82,$80,'VL',itoa(nVolPre[1]),$0A"
    		SEND_LEVEL dvJVCLT37X898Tp, 2, nVolPre[BUTTON.INPUT.CHANNEL-404]  
    	}
    	
    	
    }
    
    LEVEL_EVENT[dvJVCLT37X898Tp,2]
    {
    	nTVVOL=LEVEL.VALUE
    	SEND_COMMAND vdvJVCLT37X898, "'PASSTHRU-!',$82,$80,'VL',itoa(nTVVOL),$0A"
    	
    	
    }
    
    integer nPresetButtons[] = {405,406,407}
    
    BUTTON_EVENT[dvJVCLT37X898Tp,nPresetButtons] //vol presets
    {
    	HOLD[20]:    //If Button is Held for 2 seconds
    	{
                    Curr_preset = get_last(nPresetButtons)
    		nVolPre[Curr_preset] = nTVVOL
    		SEND_COMMAND dvJVCLT37X898Tp,'ADBEEP' //double beeps panel
                    SEND_COMMAND dvJVCLT37X898Tp,"'^TXT-',itoa(Curr_preset+9),',0,',ITOA(nVolPre[Curr_preset]*2),'%'"
    	}
    	
    	RELEASE:
    	{
    		Curr_preset = get_last(nPresetButtons)
    		SEND_LEVEL dvJVCLT37X898Tp, 2, nVolPre[Curr_preset]  
    	}
    	
    	
    }
    
    LEVEL_EVENT[dvJVCLT37X898Tp,2]
    {
    	nTVVOL=LEVEL.VALUE
    	SEND_COMMAND vdvJVCLT37X898, "'PASSTHRU-!',$82,$80,'VL',itoa(nTVVOL),$0A"
    }
    

    Here an option for condensing. Use a button array and use more of the indexing power.
  • viningvining Posts: 4,368
    Using GET_LAST in a hold event has the same potential of producing an erroneous result as does using BIC in a hold. Again you should use the PUSH handler to set your hold channel variable to ensure that the correct channel is used when the hold executes. Otherwise if anyone uses any TP for any device after you pushed but before that hold executes your GET_LAST will return a matching index position of the last "last" button pushed.
  • Regarding the get_last portion: Is there a way to differentiate between multiple instances of the get_lasts Index, in this case, Curr_Preset? I was thinking on a more global scale, like setting presets for each room in the house. Would I, perhaps, simply rename the index to something more room-appropriate?
  • vining wrote: »
    Using GET_LAST in a hold event has the same potential of producing an erroneous result as does using BIC in a hold. Again you should use the PUSH handler to set your hold channel variable to ensure that the correct channel is used when the hold executes. Otherwise if anyone uses any TP for any device after you pushed but before that hold executes your GET_LAST will return a matching index position of the last "last" button pushed.



    yes, you will notice that any STACK_or LOCAL_VARs you try to put into a HOLD will not 'colour' correctly. It'll work (kinda) but isn't the Best Practice.
  • vegastech wrote: »
    Regarding the get_last portion: Is there a way to differentiate between multiple instances of the get_lasts Index, in this case, Curr_Preset? I was thinking on a more global scale, like setting presets for each room in the house. Would I, perhaps, simply rename the index to something more room-appropriate?

    DEFINE_VARIABLE
    
    INTEGER nPRESETS  [number of rooms] [number of presets]  =  {
                   { presetvalue, presetvalue, presetvalue, presetvalue.......}, //ROOM 1
                   { presetvalue, presetvalue, presetvalue, presetvalue.......}, //ROOM 2
                   { presetvalue, presetvalue, presetvalue, presetvalue.......}, //ROOM 3
                                      ....
                                     }
    
    
    

    then when you want to address a value in the array use nPRESETS [room number] [preset value index]


    You could set up constants for the room numbers to make is easier to read.




    Or you could use a structure...over to you eric!




    I'll post a fuller example later
Sign In or Register to comment.