Using Channels for Feedback
mpullin
Posts: 949
Read on only if you want to know about a bizarre programming experience I'm having right now.
I keep remembering that someone on the forum said never to test for something based on the status of a button. Something odd is happening around the office to make me believe that advice is more valuable than I thought. Consider this code, for a mute toggle button:
The channel state is determined by this:
Now... this code had worked perfectly for about a month. This weekend we had some power outages, but nothing fatal to anything on our network. When I came in monday, I noticed that the Mute button, when pressed, would flicker but would not change the volume. At first I blamed the ADA Bus but I realized that the ADA Bus was working fine because other buttons on the system that communicated with the ADA Bus were working. In fact, all of the devices in my system seemed okay.
Running some tests, I found that the Mute button would throw 'MUTE=0:1' every time I pressed it. I used NS to set channel 18 of the touchpanel to ON, and I pushed the button again. Still 'MUTE=0:1'. The code had not changed at all, the devices in the system were all fine, I rebooted the master and the panels a couple times, this problem persisted. It's like all of a sudden my system decided to call me on this unhealthy programming practice.
That wasn't the only piece of code in the system that was messing up either.
Again, the buttons would sort of flicker when pressed, the channels would not stay on as intended. I plan to fix this by inserting variables for each button of which I want to keep track the state. But if this code is wrong, why did it work for so long and after so many reboots? The whole thing seems very.. odd to me.
EDIT:
I keep remembering that someone on the forum said never to test for something based on the status of a button. Something odd is happening around the office to make me believe that advice is more valuable than I thought. Consider this code, for a mute toggle button:
BUTTON_EVENT[TouchPanels,18]{ // muting PUSH:{ if ([BUTTON.INPUT.DEVICE,BUTTON.INPUT.CHANNEL]) send_command vdv_ADA_Suite7, "'MUTE=0:1'" else send_command vdv_ADA_Suite7, "'MUTE=1:1'" } }
The channel state is determined by this:
DATA_EVENT[vdv_ADA_Suite7]{ // ada suite7 feedback COMMAND: { SELECT{ ACTIVE (data.text == 'MUTE=1:1'): { ON[TouchPanels[1],18] ON[TouchPanels[2],18] } ACTIVE (data.text == 'MUTE=0:1' OR LEFT_STRING(data.text,3) == 'VOL'): { OFF[TouchPanels[1],18] OFF[TouchPanels[2],18] } } } }
Now... this code had worked perfectly for about a month. This weekend we had some power outages, but nothing fatal to anything on our network. When I came in monday, I noticed that the Mute button, when pressed, would flicker but would not change the volume. At first I blamed the ADA Bus but I realized that the ADA Bus was working fine because other buttons on the system that communicated with the ADA Bus were working. In fact, all of the devices in my system seemed okay.
Running some tests, I found that the Mute button would throw 'MUTE=0:1' every time I pressed it. I used NS to set channel 18 of the touchpanel to ON, and I pushed the button again. Still 'MUTE=0:1'. The code had not changed at all, the devices in the system were all fine, I rebooted the master and the panels a couple times, this problem persisted. It's like all of a sudden my system decided to call me on this unhealthy programming practice.
That wasn't the only piece of code in the system that was messing up either.
BUTTON_EVENT[TouchPanels,TP_ADA_Inputs]{ // ADA inputs PUSH:{ if ([BUTTON.INPUT.DEVICE,BUTTON.INPUT.CHANNEL] == 1) TOTAL_OFF[BUTTON.INPUT.DEVICE,TP_ADA_Inputs] else{ ON[BUTTON.INPUT.DEVICE,BUTTON.INPUT.CHANNEL] if ( ([BUTTON.INPUT.DEVICE,61] OR [BUTTON.INPUT.DEVICE,62]) OR [BUTTON.INPUT.DEVICE,63]){ // if an output is selected CALL 'ADA_Zone_Change' (BUTTON.INPUT.DEVICE) } } SEND_COMMAND vdv_ADA_TUNER_ARRAY[BUTTON.INPUT.CHANNEL-64], 'TUNE?' } }
Again, the buttons would sort of flicker when pressed, the channels would not stay on as intended. I plan to fix this by inserting variables for each button of which I want to keep track the state. But if this code is wrong, why did it work for so long and after so many reboots? The whole thing seems very.. odd to me.
EDIT:
Chip Moody wrote:A very wizened programmer (or two or three) at AMX told me back when I was first starting to program that I shouldn't use channels on a touch panel on the right side of a boolean equation like you would with other devices, like a com port, or a variable. (I.E., asign to the channels, but don't use them as reference)
I don't remember the explanation if there was one, but it's just been one of those "you just shouldn't do it" type things that's stuck with me for most of the past decade...
0
Comments
Strange thing,
I never use channels like that. Most of the time i use a channel on the device port or virtual device. I remember a issue long ago. It was on a axcent 2. I made a var and forget to reset it when the system reboots. Normally you do something like Var=0 in DEFINE_START. In this case i forget that and at one time there was a power failure and the system reboots. The var was used to read a buffer of a vcr. It was set (var=1) as long as the buffer was reading. The power failure came at the moment that the var was set. A reboot doesn't changed is so it stays 1 and the buffer was never read again. The only way to solve this was to download the software again so every var was reset. I did that and everything worked fine (i put of course the var in the DEFINE_START section and reset it as the system was rebooting).
So my advice DOWNLOAD the software again and check if things are working fine.
Good luck
I suspect your problem is the OFF statement on the buttons. Replace it with a TOTAL_OFF. Your OFF statement only shuts the input channel off, not the feedback channel. I always thought the BUTTON.INPUT.CHANNEL value reflected the input channel just by the way it's named, but there may be circumstances where it reflects the feedback channel instead. As far as I'm concerned, the whole area is a bit murky, which is why I use variables.
Of course, this does not explain why it was fine for a while, then suddenly stopped working. Different version of Studio?
But yeah, don't trust those TP buttons.
- Chip
I think the thread is worth to go to Tips & Tricks section, is not it?
I suppose I should amend my earlier statement about using variables. I use them for system and general tracking; if it's device specific, it makes far more sense to use a channel or level on that device, or a virtual connected to it.
[TP,1] = [Mixer,Mic1Mute]
[TP,2] = [Mixer,Mic2Mute]
...etc
[TP,21] = [Mixer,ATCOffHook]
[TP,22] = [Mixer,ATCSendMute]
Where the [Mixer,xxxxx] channels get turned on/off during the parsing of the mixer's string DATA_EVENTs.
And yes, you can use channels on a virtual device, but the ones on the physical device aren't doing anything, and the fact that it's a physical device over a non-existent one appeals to my anal-retentiveness.
- Chip
I built a DEV array like this: DEV BOOLEAN[] = {5001:1:0,5001:2:0}
and I went though each instance where I'm setting a channel in order to read it later, and I replaced BUTTON.INPUT.DEVICE with BOOLEAN[GET_LAST(TouchPanels)]. It worked like a charm!
The only thing was, I some rapid flicker when I changed outputs on the ADA. I realized however that I had a mutually exclusive set defined for the TouchPanel buttons but not for the BOOLEAN channels :-p
Greetings all.
I would like to weigh in on this subject becasue it has brought on much thought during many years of programming and an eventual technique for storing conditions.
Part 1) Typical Use of Variables
I typically use variables for state management when the value goes beyond a simple On or Off (zero or one.) For example, if I am tracking which source is selected I might use the variable nSource. If you notice, I pretty much use button arrays exclusively to take advantage of the Get_Last object which is the index of the array nSource_Btns. This provides easy scalability in the number of source select buttons without changing the Button_Event defintion or button feedback code.
You can debate whether feedback should go into a Timeline or Define_Program. Define_Program works great until a program becomes very large.
I typically use channels for state management when the value is a simple On or Off (zero or one.) For example, if I am tracking power status. This was discussed previously, but I will illustrate with an example.
Suppose you have 5 touch panels controlling 5 different plasmas.
It is never a good idea to use a channel in a touch panel for state evalutions because the panel can go offline. I either use a physical device in the NIxxx or a virtual.
Keep in mind, if you use a virtual device you must set the upper channel limit if you use channels above 255. Use the command Set_Virtual_Channel_Count (vdvDEV,x) in the Define_Start section where x represent the upper channel limit up 4000.
Hi there I work with ships which dont have real ground we find often on reboot things go wierd what we thought (and untill the event) worked fine now doesent
in many cases it appears that the PS can cause more issues than you would think possible
before to change all you belive to be correct have you looked at the ps?