Home AMX User Forum NetLinx Studio

queue programming

I am wondering what you guys think about wiring a call statement for a particular device (RS232 communication) with CHAR string[1024] which will contain all the commands from the Master to the device. Then have mainline run to check whether there is anything in the CHAR string before sending out the command. One thing I have noticed about this type of programming is that when a customer has pressed the command a number of times it sends all that command in the queue and eventually sends the string to the device. I am trying to see how I can improve this method.

Comments

  • DHawthorneDHawthorne Posts: 4,584
    I usually queue RS-232 commands in my own buffer, and I've found that to prevent overruns like you mention, you pretty much have to diddle with the timing you send the commands for every device. I typically set an unused channel on the RS-232 device to act as a busy flag, then wait short time (set with a constant) before turning the flag off. The next item in queue won't be sent unless the busy flag is off. Depending on the nature of your device and its responsiveness, you may need to adjust the amount of time that flag takes to reset, and in many cases you can reset it in code when you get a response from the device. Some devices (typically projectors) require a wait as long as 15 seconds between commands, and some devices will take them as fast as you can send them.

    Once you have the flag in place, you can decide to queue up further commands or just discard them; you could even test the command itself in your code with a SWITCH or SELECT tree to determine what you want to do with it. For devices with long delays, it's usually best to discard them, or you will have things going on long after the button presses stop. I've even seen some devices that require differing length delays between commands depending on what the last received command was (in which case you make the WAIT time a variable, and change it accordingly).

    I've sidestepped a lot of such issues by giving certain buttons (volume, channel up & down) a HOLD handler with the REPEAT flag. By adjusting the HOLD time and busy flag delay, you can optimize those kinds of commands without it being possible for the queue to get too deep. - as long as they are holding the button and not aggressively pouncing on it :). In these cases you have to take the ime to optimize the delays for the fastest response, then educate your end user so they know beating on the button won't make anything happen any faster.

    Now what I want to know is the secret of getting the customer to understand that pressing harder on a hardware button won't make it go any faster... :D
  • kennyannkennyann Posts: 113
    Dear DHawthorne:

    Thank you for the suggestion. I will try that.

    I understand how you feel when the customers decide to continuously press the button or press the button harder - as if it is magically doing to do something different. I guess it all comes down to us explaning to the cusomters how should it work. It also shows that the customers are frustrated with the system.
  • Spire_JeffSpire_Jeff Posts: 1,917
    This is actually sort of on my to do list this weekend. I'll let you know what I find out. I am looking at using a timeline function to balance commands being sent, but hopefully this weekend I can figure out how well that approach works. The thing that makes me think of timeline is the ability to adjust the timing on the fly couple with the fact that data transfer times are something that can be calculated. I still haven't decided if I will adjust the timing cycle to change according to the messages being sent by counting characters or by using an average message size to determining timing... hopefully this will all work out this weekend.

    Jeff
  • I use pretty much the same method as DHawthorne, i create a variable that says something like "device_busy" , then have some code like;

    define_call 'serial_comm'
    {
    cancel_wait_untill 'wait_name' // making sure only the last command is sent
    wait_untill (!(device_busy)) 'wait_name'
    {// tabs don't work here i see
    send_string dvRS232,"serial_command"
    on [device_busy]
    }
    }

    Then you need some code in the string: section of a data_event where you clear the device_busy flag based upon echoing of the commands. (or use a predefined wait time), this could look like :
    data_event[dvRS232]
    {
    string:
    {
    serial_buffer = "serial_buffer,data.text"
    if (find_string(serial_buffer,"$0D",1))
    off [device_busy]
    }
    }
    Don't forget to periodically set the device_busy flag to off in your mainline or you could end up with no communication at all.
    AND , power on and power off strings should be kept out of this loop as they could end up never reaching the device (because of the cancel_wait_untill)
  • alexanboalexanbo Posts: 282
    I've taken to using timelines to dictate how often commands get sent out to serial devices. I usually write a module for any 232 device in my system. There's a constant that tells the module how often to send out string, the port is also initialized at that time.

    This allows me to have a lot of control over when stuff gets sent out. It also allows you to flush the buffer if need be. For some devices that stop responding to commands as their powering up I throw a wait flag into the buffer that tells the timeline to stop sending commands for a certain period and also gives feedback that it is in a paused state.
  • I agree. Timelines are by far the better way to go when timing the 232 commands going out to a device. The best reason for using them over a named WAIT is that they are independent within modules. That is, the timeline numbers used within a module are unique from timelines used in other modules, main, or even other instances of the same module. Named waits are not. This makes using multiple instances of a module that uses a named wait for timing pretty useless. The other thing thats nice about using timelines is that one timeline can be used with different delay times based upon the command sent to a device without having to code it statically. This send interval can even be passed in by the user of the module. This is useful when one module is being used with different models of equipment which might use different baud rates and response times such as Autopatch.
  • frthomasfrthomas Posts: 176
    Originally posted by LCubed@snet.net
    The best reason for using them over a named WAIT is that they are independent within modules. That is, the timeline numbers used within a module are unique from timelines used in other modules, main, or even other instances of the same module. Named waits are not.
    The other thing thats nice about using timelines is that one timeline can be used with different delay times based upon the command sent to a device without having to code it statically.

    It's not that I prefer WAITs, but the above is simply not true in my experience.

    WAIT names have the same scope as global variables, that is, they ARE independant between modules. I tried it to make sure!. BTW that is the only logical choice for AMX otherwise the whole module concept goes to waste.

    Also you can specify a VARIABLE for the wait time but it has to be a global variable (which you can initialize dynamically).

    My two cents

    Fred
  • WAIT names have the same scope as global variables, that is, they ARE independant between modules. I tried it to make sure!.

    I tried it too, and I stand corrected. I was told they were not independent from AMX Tech Support years ago, and I never bothered to verify this since I was just a happy to use Timelines. I appologize for the mis-information.

    BTW that is the only logical choice for AMX otherwise the whole module concept goes to waste.

    I'm not sure why you say that. Timelines are STILL a very flexible means of controlling your events, more so than waits. I never use WAITs of any kind in my modules and I prefer it that way. Timelines are (IMO) easier to maintain and manipulate.
  • frthomasfrthomas Posts: 176
    Originally posted by LCubed@snet.net
    BTW that is the only logical choice for AMX otherwise the whole module concept goes to waste.

    I'm not sure why you say that. Timelines are STILL a very flexible means of controlling your events, more so than waits. I never use WAITs of any kind in my modules and I prefer it that way. Timelines are (IMO) easier to maintain and manipulate.

    Just that having a single scope for WAITs (as you thought it was) makes it impossible to distribute safely a compiled module, since there is a risk a named wait in the caller's code has the same name as one in the module.
    The full benefit of modules can only be reaped if, and only if, namespaces are completely separate. When designing module, AMX engineers probably thought the same, hence it was a priori not logical to have a common namespace for wait.

    It was not a comment on the use of timelines, which have their positive side, I agree fully!

    Fred
Sign In or Register to comment.