TP Button Feedback Statements?
Tworhythms Posts: 51
I have often wondered what others are doing for button feedback statements on TPs. Some disagree with putting them in mainline (Define Program Block)
[dvTP,38]=[dvRELAY,1] //Simple statement for illustration purposes
What are you doing? This is just a curiosity thing
[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.
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.
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.
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:
Each TP must be be stated seperately.
Here's my source feedback statement for my code:
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.
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:
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!
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.
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.
Instead of a timeline set to run every .2 seconds, why not use a wait?
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
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!
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.
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
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.
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.
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.
Thinking about this further, the stopping point would be 30-40 touch panels.
This is what I usually do:
Are you saying that a FOR loop in Define_program would be more efficient?
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?
Unless the program is very large, you may not notice a speed difference.
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.
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.
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.
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.