Home AMX User Forum AMX General Discussion

Feedback

Ok just as a general question. Do most of you put your feedback in main line or do you use a timeline?

If you do it in a timeline where do you start the timeline? In Define_Start or do you do it when the TP comes online?

Comments

  • DHawthorneDHawthorne Posts: 4,584
    I put all my feedback in timelines. Levels and direct channel equivalences only seem to go out when they change, and are OK in mainline, but other statements, like ON, OFF, SEND_COMMAND, etc., wind out streaming continuously in mainline, and can bring your system and your network to it's knees. I put it all in timelines, because I prefer it all to be in one spot when I do any updating. Typically, I use a 1 second period, but if you need zippier response, you can cut it back to 500 ms without too much drain. I am also careful when sending things like variable text changes out only when I know (1) they have changed, or (2) the popup containing them has just been brought up and should be refreshed.

    Since I am rarely dealing with only one panel, but an array of them, I put start my timeline in DEFINE_START. Then, I have a simple flag array that matches the size of the panel array. Online and offline events can set the flags, and the timeline only acts onthe panels that have the flag set on. I generally break this down even further, and have individual timelines for each device requiring feedback, and only setting the appropriate flags on when that device is in use. When done as a module, this is fairly trivial to maintain. I'm a very firm believer in minimizing network traffic at every turn, and this helps greatly. strange things happen when too mcuh traffic is passing to your panels.
  • Chip MoodyChip Moody Posts: 727
    Timelines...
  • Spire_JeffSpire_Jeff Posts: 1,917
    Timelines. I even went as far as writing queue code for send_commands to touchpanels so that commands to the touchpanels don't just start blasting away at the network. I also only send updates to a touchpanel if the touchpanel is viewing a page that is affected by the change.

    Jeff
  • Timelines too
  • Feedback Techniques

    In order of preference and use:

    1. Timelines

    2. Mainline - but under an IF() conditional where the condition is satisfied using a timed WAIT so that the code is only executed on certain passes of Mainline. Certainly the conditional is evaluated each pass of Mainline and is therefore less efficient than a TIMELINE. However, the conditional can be easily set anywhere in code under an event handler for instance to cause the next pass of Mainline to update feedback easily.

    3. Update feedback only when it changes and refresh feedback on panels when they come ONLINE (don't worry about feedback in Timelines or Mainline).

    Note: variable text updates/feedback to panels is only done when the text actually changes and is generally not part of my feedback handling. In other words, if it does not change, don't send it unless a panel goes offline and then comes back online at which point feedback and text is updated on that panel.
  • Timelines every time - usually created in "define_start" and usually with a period of 250mS. Another key realization is that there's no point in updating feedback to buttons on pages that aren't being seen. So if you have a panel with loads of busy pages you could set a variable depending on what page you're on, and then do a switch....case on that variable in your feedback statement so only feedback for the "current" page is evaluated.

    More and more though I try to write code so I don't need to be evaluating feedback at all. For instance if you have a bunch of interlocking presets, I just have every button turn off the feedback for the whole array of buttons, then use get_last to turn the last one pressed back on as well as do whatever the button needs to do. There's no need to be constantly evaluating something where you're in control of the only buttons that affect the feedback.

    I was shocked the other day to do some work where I inheritied a file that had been started by the AMX folks in Costa Mesa. This code had feedback which was in FOR loops in Mainline. And it was throwing errors constantly because of a zero value array index - the error comes up ".....index to large" - I wish, please AMX, could you fix this to say "TOO large". That's what it should say. It bugs me every time I see it.

    **another background fact: when I first moved from the UK to the US in 1992, for the longest time I thought TOO in American was spelt TO. I just never saw it spelt correctly. Then finally I did, and I thought, OK they DO spell it that way, but it seemed an awful lot of people didn't :) Sorry for the rant - I'm just kind of anal about spelling.....
  • JoeJoe Posts: 99
    Example?

    For those of you who do feedback in Timelines, could you give an example? I usually just do feedback for buttons under the DEFINE_PROGRAM section.

    Thanks! This is a great place to learn new progamming techniques.
  • Chip MoodyChip Moody Posts: 727
    Add these to your code:

    DEFINE_CONSTANT

    FeedbackTimeline = 1


    DEFINE_VARIABLE

    VOLATILE LONG FeedbackLoopTime[] = {100}


    DEFINE_START

    TIMELINE_CREATE (FeedbackTimeline,FeedbackLoopTime,1,TIMELINE_ABSOLUTE,TIMELINE_REPEAT)


    DEFINE_EVENT

    TIMELINE_EVENT [FeedbackTimeline]
    {
    // Throw all of your feedback code here
    }


    Adjust the number - in 1000's of a second - for FeedbackLoopTime to adjust how frequently you want your feedback updated. 100 to 200 usually works pretty well, and don't go down to or below 50 - at that point, your master will be running your feedback code and not much else. :)

    You can put TIMELINE_EVENT [FeedbackTimeline] in multiple areas of your code, so you could put the VCR feedback right after the VCR control code, the projector feedback right after the projector code, etc...

    - Chip
  • JoeJoe Posts: 99
    Thanks for the example, Chip! I've been to all 3 programming classes at AMX and they never taught us this. They did, however, teach us how to do feedback in mainline using FOR loops.
  • Chip MoodyChip Moody Posts: 727
    Originally posted by Joe
    Thanks for the example, Chip! I've been to all 3 programming classes at AMX and they never taught us this. They did, however, teach us how to do feedback in mainline using FOR loops.

    Hmmm... I remember picking up on this at a training class at the PA office, but I don't know if it was one of the "regular" ones...

    Feedback with FOR loops? Something like:

    FOR (x=1;x<=10;x++)
    {
    [TP,x] = FeedbackArray[x]
    }

    It takes up more space, but I found in the past that doing each one individually ran a lot faster...

    [TP,1] = FeedbackArray[1]
    [TP,2] = FeedbackArray[2]
    [TP,3] = FeedbackArray[3]
    etc...

    - Chip
  • chillchill Posts: 186
    Re: Feedback
    Originally posted by Frankie
    Ok just as a general question. Do most of you put your feedback in
    main line or do you use a timeline?

    If you do it in a timeline where do you start the timeline? In
    Define_Start or do you do it when the TP comes online?

    For a small job, it probably doesn't matter. But for me now, always in a timeline, ever since that job a few years ago. In my first few Netlinx systems I did feedback in mainline, but when I encountered That Big Job, the mainline feedback concept proved not to be scaleable - it just slowed the system to a crawl, trying to update thousands of buttons in every pass through mainline. After I put my feedback in a timeline, the system appeared considerably more responsive, so I like to say that I speeded thing up by slowing things down.

    By putting feedback in a timeline, the buttons are updated at intervals that you control. You could even have more than one timeline for feedback - a faster one for the more-critical feedback (source selection?) and a slower one for the less critical (projector lamp hours?).

    For feedback that needs to be somewhat realtime, like device selection, I played around with timeline times to find something that was as slow as possible while still seeming realtime-ish. The range of 150 to 200 ms seems about right for that. YMMV.

    For the record, I start the timeline like this:

    <code>
    DEFINE_START
    timeline_create(FBupdate,FBupdateT,1,timeline_relative,timeline_repeat)
    </code>

    Note that you can invoke the timeline_event multiple times in your program. So I have a button_event where the user selects which projector they want to control, followed by

    <code>
    timeline_event[FBupdate]
    {
    [dcDestSel[1]] = (destSel = 1)
    </code>
    ... and so on. Yes, you could certainly put this in a for() loop, as in

    <code>
    timeline_event[FBupdate]
    {
    local_var integer i
    for(i = 1; i <= nDests; n++)
    [dcDestSel] = (destSel = i)
    </code>
    But if it's only 8 or 12 inputs I might not bother.

    Then later on in the program, there is a button_event for the user to select a source, followed by

    <code>
    timeline_event[FBupdate]
    {
    [dcSourceSel[1]] = (switcherStatus = 1)
    [dcSourceSel[2]] = (switcherStatus = 2)
    </code>
    ...and so on.

    Point being twofold: 1) you can name the same timeline_event in multiple places to maintain readabilty ('cause guess who's going to have to figure this out next year, when the client wants an upgrade) and 2) by simply changing the value of (in this case) FBupdateT, you can tune the apparent responsiveness of your program. I find that a *little* bit of lag is good, because it appears that the system has "done something", as opposed to just responded to its own internals (as with an Interlock in Brand C), but you don't want much lag - a barely-perceptible fraction of a second is good. But for anything that matters, like which computer they're seeing right now, I try to use real feedback. That is, "the routing switcher says it's on input 4, and the projector claims to be powered up, unmuted and looking at its VGA input" - that's the best I can do.

    HTH.
Sign In or Register to comment.