TP Button Feedback Statements?
Tworhythms
Junior Member
I have often wondered what others are doing for button feedback statements on TPs. Some disagree with putting them in mainline (Define Program Block)
i.e.
Define Program
[dvTP,38]=[dvRELAY,1] //Simple statement for illustration purposes
What are you doing? This is just a curiosity thing
i.e.
Define Program
[dvTP,38]=[dvRELAY,1] //Simple statement for illustration purposes
What are you doing? This is just a curiosity thing
Comments
-
Tworhythms wrote: »I have often wondered what others are doing for button feedback statements on TPs. Some disagree with putting them in mainline (Define Program Block)
i.e.
Define Program
[dvTP,38]=[dvRELAY,1] //Simple statement for illustration purposes
What are you doing? This is just a curiosity thing
I generally associate my button feedback with a state change from a device or from a module. When the state changes, the feedback goes with it and I also note the state change in a variable for refreshing feedback on UI online events. This method is best when using dev arrays for multiple TPs. I don't combine panels, so I would need a feedback statement for each button and each panel if using define program.
It always seemed lame to put feedback in define program, but the Programmer III teacher does it that way! It's probably OK fo single panel systems. -
TurnipTruck wrote: »I generally associate my button feedback with a state change from a device or from a module. When the state changes, the feedback goes with it and I also note the state change in a variable for refreshing feedback on UI online events. This method is best when using dev arrays for multiple TPs. I don't combine panels, so I would need a feedback statement for each button and each panel if using define program.
It always seemed lame to put feedback in define program, but the Programmer III teacher does it that way! It's probably OK fo single panel systems.
I used to to feedback in mainline, but things get pretty bogged down in a big system where you're trying to update thousands of buttons on every pass through mainline. For several years now I've been updating button feedback in a timeline that runs every 150 to 200 ms. This works very well; it's fast enough to appear instantaneous to the human eye, but slow enough to take a load off the processor. And yes, my feedback is real - the source select button doesn't light up until the switcher and display both claim to be on the appropriate input. -
TurnipTruck wrote: »I generally associate my button feedback with a state change from a device or from a module. When the state changes, the feedback goes with it and I also note the state change in a variable for refreshing feedback on UI online events. This method is best when using dev arrays for multiple TPs. I don't combine panels, so I would need a feedback statement for each button and each panel if using define program.
This is not necessary with button channels, the master already does this kind of tracking internally (except if it's a virtual device). Try it - turn on notifications, and put your feedback statement in mainline. You will see it only changes when the value you are comparing with changes. It is not necessary with levels either, only with feedback that relies on SEND_COMMANDs.
That said, I always make a function or CALL for my feedback. If it's a small system and the feedback generates little traffic, I'll call it in mainline; if that generates too much master load, I'll put it in a timeline. Since it's already modularized into a function, the change is trivial. For modules, I'll go a step further and only call the feedback routine when something happens that might change the feedback, like a button press, incoming string, or a page change. I would use that method universally, but when you have a half dozen modules changing things outside the scope of the parent program, it can get messy, so I leave that to modules that are doing one thing alone. -
DHawthorne wrote: »Try it - turn on notifications, and put your feedback statement in mainline. You will see it only changes when the value you are comparing with changes. It is not necessary with levels either, only with feedback that relies on SEND_COMMANDs.
I've seen that and was quite suprised. No one at AMX has been able to explain exactly how that works.
I've found that discrete feedback statements can be quite clumsy for multiple panels in dev arrays. I have not found a way to be able to say:
[tparray,1]=feedback_flag
Each TP must be be stated seperately. -
Could just loop through the DEV array rather than doing it discretely - but by saying that, I know I'll start a debate on what is more efficient.
Here's my source feedback statement for my code:FOR (nLOOP=1;nLOOP<=LENGTH_ARRAY(dv_TP);nLOOP++) { // Source feedback FOR(nLOOP1 = 1;nLOOP1<=LENGTH_ARRAY(nSOURCE_BTNS);nLOOP1++) // Loop btns [dv_TP[nLOOP],nSOURCE_BTNS[nLOOP1]]=(nPOP_FB[nLOOP]==nLOOP1)// Turn on according to pop up feedback var } -
I use a FOR loop like jjames describes, except that I have found that you can't reliably use LENGTH_ARRAY for an array passed to a module, so I generally set up a constant for array dimensions that I can use for capping the FOR loop as well.
-
Feedback idea update
For all you code heads out there, I did some reasearch into this topic recently and might be able to shed some new light on the topic.Could just loop through the DEV array rather than doing it discretely - but by saying that, I know I'll start a debate on what is more efficient.
Here's my source feedback statement for my code:FOR (nLOOP=1;nLOOP<=LENGTH_ARRAY(dv_TP);nLOOP++) { // Source feedback FOR(nLOOP1 = 1;nLOOP1<=LENGTH_ARRAY(nSOURCE_BTNS);nLOOP1++) // Loop btns [dv_TP[nLOOP],nSOURCE_BTNS[nLOOP1]]=(nPOP_FB[nLOOP]==nLOOP1)// Turn on according to pop up feedback var }
Depending on the size of the compiled program, you can except the Define_Program section to loop anywhere from between 100 to +300 times per second. So at a minimum you can expect at least 100 loops per second no matter what is going on with the event queue.
Those of you like myself who prefer to put your feedback statements in Define_Program can use this to your advantage. In Jay's example above we can make the program run more efficiently by letting the Define_Program section become your first "for loop."
Revised concept below:Define_Program [color=green]// The variable nTP_Loop represents a counter for the number of touch panels in the program[/color] nTP_Loop++ [color=green]// Increment the nTP_Loop counter[/color] [color=green]// Check to make sure nTP_Loop counter is in the proper range[/color] IF(nTP_Loop<1 or nTP_Loop>LENGTH_ARRAY(dv_TP)) nTP_Loop=1 [color=green]// Source feedback - The variable nBTN_Loop represents a counter for the number of sources buttons.[/color] FOR(nBTN_Loop = 1;nBTN_Loop<=LENGTH_ARRAY(nSOURCE_BTNS);nBTN_Loop++) [color=green]// Turn on according to pop up feedback var[/color] [dv_TP[nTP_Loop],nSOURCE_BTNS[nBTN_Loop]] = (nPOP_FB[nTP_Loop]==nBTN_Loop)
-
Are there any proponents for feedback in define event? Am I all alone in the room?
-
I like it!
Hmm - interesting concept. I like it! It surely doess seem that it'd be more efficient - one less loop that runs through DEFINE_PROGRAM is good with me!B_Clements wrote: »Those of you like myself who prefer to put your feedback statements in Define_Program can use this to your advantage. In Jay's example above we can make the program run more efficiently by letting the Define_Program section become your first "for loop."
I know I've run into some major problems before with having too many loops in DEFINE_PROGRAM, especially with lighting feedback. Restructuring my feedback portion somewhat fixed the problems I was experiencing to the point where the system wasn't too "laggy".
If you're talking about not having loops for feedback - yes, I'll use that as well in some portions for feedback. If I'm just doing a handful of buttons that need specific feedback (AM, FM, WX, repeat, random, etc.) I won't use a loop.TurnipTruck wrote:Are there any proponents for feedback in define event? Am I all alone in the room?
There are times when I feel it's more appropriate to use "discrete" feedback rather than "looped" feedback, but more often I use the latter. There's no "wrong" way to do things if it's working, just more "efficient" or "easier" ways. But whatever works for you, then that's all that should matter. The fun of being a "code head", is that we're always trying to think of ways to improve on something that already works.
-
Let me first admit I haven't tried this, so I could be missing something obvious
Instead of a timeline set to run every .2 seconds, why not use a wait?define_program wait 2 { [dvTP,1]=var1 [dvTP,2]=var2 [dvTP,3]=var3 [dvTP,4]=var4 [dvTP,5]=var5 }
The wait wont recreate again until the first one is done, so it seems to me that this would severely decrease load in the define_program section of the code.
Forgive me if I'm missing something obvious, I don't really remember all of how waits work, but this seems like so much less work than a timeline that I'd like to know why a timeline is considered better
J -
Feedback
I've used all of them and I agree that it depends on the system size. Currently, I am using a combination of feedback in the button events as well as mainline. I also code source state and room state feedback in mainline not based off from the switchers and other components and here's why. In residential, I have found that when a switcher doesn't switch properly, you won't see your source material on screen. That's one perceived error for the client. If the touch panel isn't lighting up the button when the client pushes it too, that's two perceived errors. Actual quote from a client, "Hey! I pushed the button and the screen didn't change and the button won't push! Why is everything broken?" I know that this is a nebulous thing but it seems to work well so far. It's opposed to, "I pushed the button but the screen won't change!"
In events, I will use a statement like TO[BUTTON.INPUT] for feedback on channels for simple receivers like cable or satellite. In commercial, I can imagine a different approach would be needed. I've also used waits in mainline to slow down the feedback sometimes when there are a lot of strings going back and forth with a lot of parsing. The theory is if I'm using a good amount of loops in parsing data, I really want to feeback only when neccessary. Seems to be that when a large amount of data is being parse and a lot of feedback needs to be updated, the system will take a larger performance hit. Seems to be anyways...
I really liked the way Brian does his feedback and it seems really elegant so thx Brian! -
TurnipTruck wrote: »Are there any proponents for feedback in define event? Am I all alone in the room?
I do that inside modules where I can narrow down exactly what events will require a feedback change. It's not always feasible in a busy main program, where all you might have to work with is a variable change, and that is your only way of knowing something needs updating. Sometimes that is even the case in a device module, but it is more rare there. So, yes, I am a proponent of that, but I find it can't be used sometimes. -
BCalderwood wrote: »I also code source state and room state feedback in mainline not based off from the switchers and other components and here's why. In residential, I have found that when a switcher doesn't switch properly, you won't see your source material on screen. That's one perceived error for the client. If the touch panel isn't lighting up the button when the client pushes it too, that's two perceived errors. Actual quote from a client, "Hey! I pushed the button and the screen didn't change and the button won't push! Why is everything broken?" I know that this is a nebulous thing but it seems to work well so far. It's opposed to, "I pushed the button but the screen won't change!"
I ran into this situation as well and it was determined (by my boss and the client) that the button should light up when pushed, so that the client knows they pushed it. In this case I added a text box that contains the current video/audio source and this updates based on switcher/avr feedback. -
...and this is exactly why I create arrays for text that is to be sent to a panel button with the feedback rather than just using send_command on its own - if the G4 touch panel goes offline and you have sent some text to a button via send_command, when it returns online, it will not have that text in it any more.TonyAngelo wrote: »I ran into this situation as well and it was determined (by my boss and the client) that the button should light up when pushed, so that the client knows they pushed it. In this case I added a text box that contains the current video/audio source and this updates based on switcher/avr feedback.
So, an online_event sends the the current value of cSourceSel to a button for example. Mainline looks after my button feedback.
JJames and B_Clements' revised FOR loop system is very interesting - thanks for posting it guys -
I also put feedback in many places and when I put it in DEFINE_PROGRAM I almost always put it behind a wait to keep it from running 100-300 x per second. So if it were me I would use Jays original version with a wait.
DEFINE_PROGRAM WAIT 5 { FOR (nLOOP=1;nLOOP<=LENGTH_ARRAY(dv_TP);nLOOP++) { // Source feedback FOR(nLOOP1 = 1;nLOOP1<=LENGTH_ARRAY(nSOURCE_BTNS);nLOOP1++) // Loop btns [dv_TP[nLOOP],nSOURCE_BTNS[nLOOP1]]=(nPOP_FB[nLOOP]==nLOOP1)// Turn on according to pop up feedback var } }
With a wait the processor checks the wait queue every 100ms to see if the wait time is up and checks the queue on every pass of the mainliine to see if the wait is in the queue or not which does use up processor power but it still much better then running the loop on every pass of the mainline unless you have alot of waits in the queue that the processor has to search through.
The wait time depends on what type of feedback we're talking about but a wait of 2 or 5 is usually appropriate for what I do. -
I am in the non define_program boat. I tend to think of the program as a state machine. So certain states lead to other states, which lead to other states etc. in a predictable pattern. So every button is associated with a particular state, so that if that state is triggered (button pressed) then there is a feedback state that would go along with it. All feedback is done in functions that represent the current state and the button events only change state, they do not really do any processing.
Paul -
B_Clements wrote: »Those of you like myself who prefer to put your feedback statements in Define_Program can use this to your advantage. In Jay's example above we can make the program run more efficiently by letting the Define_Program section become your first "for loop."
That's a great idea, Brian.
I'm in the Define_Program camp, although the majority of my systems have only of couple of TP's.
--D -
Wasting processing power?I also put feedback in many places and when I put it in DEFINE_PROGRAM I almost always put it behind a wait to keep it from running 100-300 x per second. So if it were me I would use Jays original version with a wait.
DEFINE_PROGRAM WAIT 5 { FOR (nLOOP=1;nLOOP<=LENGTH_ARRAY(dv_TP);nLOOP++) { // Source feedback FOR(nLOOP1 = 1;nLOOP1<=LENGTH_ARRAY(nSOURCE_BTNS);nLOOP1++) // Loop btns [dv_TP[nLOOP],nSOURCE_BTNS[nLOOP1]]=(nPOP_FB[nLOOP]==nLOOP1)// Turn on according to pop up feedback var } }
With a wait the processor checks the wait queue every 100ms to see if the wait time is up and checks the queue on every pass of the mainliine to see if the wait is in the queue or not which does use up processor power but it still much better then running the loop on every pass of the mainline unless you have alot of waits in the queue that the processor has to search through.
The wait time depends on what type of feedback we're talking about but a wait of 2 or 5 is usually appropriate for what I do.
Vining, this is not a slam so please don't take it that way. I don't believe that is possible to "waste" processing power just like it not possible to save electricity. It is going to be there whether you use it or not. Efficiency is the key.
Simple feedback evaluations are not very processor intensive as compared to calling a function or sending the feedback (via ethernet packet) to the panel. Once again, evaluating feedback and sending feedback are two entirely different things. It just so happens that the firmware can automatically determine whether feedback needs to be updated to the panel every pass through the Define_Program section. Sending text to panels that come online is a different story.
Executing for-loops in Define_Program are a bit more processor intensive than single line feedback for every button. The trade-off with loops is much better scalabilty with a small reduction in efficiency. The real processor hog is input/output processing, with ethernet based events being first, followed closely by RS232 data events.
One could argue that a 0.05 to 0.1 second repeating Timeline_Event for processing feedback might be the best approach. I have not done any benchmarking to determine which is better/faster, but this would require the double for-loop approach in Jay's example. -
Thanks DaveThat's a great idea, Brian.
I'm in the Define_Program camp, although the majority of my systems have only of couple of TP's.
--D
Thinking about this further, the stopping point would be 30-40 touch panels. -
B_Clements wrote: »Simple feedback evaluations are not very processor intensive as compared to calling a function or sending the feedback (via ethernet packet) to the panel.
This is what I usually do:DEFINE_FUNCTION fnFeedback(INTEGER nArgBtn, INTEGER nArgArray[], INTEGER nArgPanel) { OFF[vdvTP[nArgPanel],nArgArray] // turn off btns IF(nArgBtn) { ON[vdvTP[nArgPanel],nArgArray[nArgBtn]] // turn on btn } }
Are you saying that a FOR loop in Define_program would be more efficient? -
Which is one reason why I'm a proponent to the looping - it's expandable. You can start it out with three touch panels, and a year down the road add fifteen touch panels and the feedback portion doesn't have to change.B_Clements wrote: »Thinking about this further, the stopping point would be 30-40 touch panels.
Though, in your experience Brian - would you have 30-40 touch panels running off of a single processor? I'm not saying it isn't possible, but keeping with the tone of efficiency - would you sooner move to a M2M layout then? -
You can tryTonyAngelo wrote: »This is what I usually do:
DEFINE_FUNCTION fnFeedback(INTEGER nArgBtn, INTEGER nArgArray[], INTEGER nArgPanel) { OFF[vdvTP[nArgPanel],nArgArray] // turn off btns IF(nArgBtn) { ON[vdvTP[nArgPanel],nArgArray[nArgBtn]] // turn on btn } }
Are you saying that a FOR loop in Define_program would be more efficient?
Unless the program is very large, you may not notice a speed difference. -
Master to Master applicationWhich is one reason why I'm a proponent to the looping - it's expandable. You can start it out with three touch panels, and a year down the road add fifteen touch panels and the feedback portion doesn't have to change.
Though, in your experience Brian - would you have 30-40 touch panels running off of a single processor? I'm not saying it isn't possible, but keeping with the tone of efficiency - would you sooner move to a M2M layout then?
Running that number of panels is not a problem at all. Off loading data processing for sub-systems would be the ideal M2M solution. For example, use separate NI-700 processors for lights, HVAC, media server, etc; all of which have the potential for a lot of data I/O. As we covered in previous threads, only update panels that are on the page needing the updates to reduce button and text feedback messages. -
Makes sense! Thanks.B_Clements wrote: »Running that number of panels is not a problem at all. Off loading data processing for sub-systems would be the ideal M2M solution.
-
B_Clements wrote:
No offense taken. In the scale of the jobs I'm doing I not really concerned about memory usage or bogging down the processor but ideally I like to plan every job as if it's a mega system so that the day I get to do a mega system I'll have a clue of what to do and I won't have to start a new from scratch. It just seems that running the loop every pass all be it for a different TP each pass seems over kill for simple feedback even if for the most part it's just evaluating the need for feedback updates and not necassarily do any updating.Vining, this is not a slam so please don't take it that way. I don't believe that is possible to "waste" processing power just like it not possible to save electricity. -
B_Clements wrote: »As we covered in previous threads, only update panels that are on the page needing the updates to reduce button and text feedback messages.
I agree completely. R4's are in need of this even with the queing module. Request modules are an example of devices that chat a lot to a touch panel so I usually only send text feedback when that page showing said feedback is displayed. Some of my touch panel navigation buttons will pulse a variable where the feedback in mainline is conditional on the variable, expecially with text feedback. *sometimes* I don't mind if a structure is constantly updating looking for changes but a touch panel doesn't need to. In my earlier days, I've crippled the master in just sending text all of the time. So, not only does it help to put feedback statements in the event section opposed to mainline, it also helps to control the feedback, especially text IMHO. In fact, you told me that on the phone once Brian and ever since then, I've implemented it. So... Thx again!
What I haven't figured out yet (and a topic for another thread), is how to get text off from a touch panel without setting up variable states or structures for comparision if text feedback needs to be updated. But I digress. -
Text feedback?BCalderwood wrote: »I In fact, you told me that on the phone once Brian and ever since then, I've implemented it. So... Thx again!
What I haven't figured out yet (and a topic for another thread), is how to get text off from a touch panel without setting up variable states or structures for comparision if text feedback needs to be updated. But I digress.
Brad, thanks for the kind words.
And by all means, go ahead and start a new thread so we all can discuss how we manage text feedback. I'm game.
Once again, thank you all for your continued contributions to the AMX forums. -
BCalderwood wrote: »What I haven't figured out yet (and a topic for another thread), is how to get text off from a touch panel without setting up variable states or structures for comparision if text feedback needs to be updated. But I digress.
What do you mean by get text off from a touch panel? You mean how to request from a touch panel what the text on a button is? Why would you need to, you sent it there correct? Maybe I misunderstand.
Paul -
Sorry I didn't jump in earlier, I have been away. Great ideas, everyone! I am a Define_Program with a FOR loop kind of guy (scalability in mind). I have worked on quite a few larger jobs using this method (6 master, 23 TPs, 18 zones of audio/video kind of system) and have always wondered if there was a more efficient way of handling these statements. My statements have worked with good results but it is the common "Coder Head" mentality to make it better
Thx for the input! I always learn something new everyday I read your posts! Some people pick up the Financial Times and others read forums
Categories
- All Categories
- 2.5K AMX General Discussion
- 922 AMX Technical Discussion
- 514 AMX Hardware
- 502 AMX Control Products
- 3 AMX Video Distribution Products
- 9 AMX Networked AV (SVSI) Products
- AMX Workspace & Collaboration Products
- 3.4K AMX Software
- 151 AMX Resource Management Suite Software
- 386 AMX Design Tools
- 2.4K NetLinx Studio
- 135 Duet/Cafe Duet
- 248 NetLinx Modules & Duet Modules
- 57 AMX RPM Forum
- 228 MODPEDIA - The Public Repository of Modules for Everyone
- 943 AMX Specialty Forums
- 2.6K AMXForums Archive
- 2.6K AMXForums Archive Threads
- 1.5K AMX Hardware
- 432 AMX Applications and Solutions
- 249 Residential Forum
- 182 Tips and Tricks
- 146 AMX Website/Forums

