Home AMX User Forum NetLinx Studio

FIFO buffer for controlling RS232 devices?

Anybody has implemented kind of flow control or a timed FIFO buffer approach for controlling a serial device? Instead of sending to the device directly, just call a function with the command as a parameter and the function will keep track of all arriving commands to be send and que them and send with a predefined pause in between so that the controlled device would not miss a thing.

Comments

  • bobbob Posts: 296
    Probably the Netlinx Studio subforum would have been a more appropriate place for this, any admin out there and can move? Thanks!
  • ericmedleyericmedley Posts: 4,177
    bob wrote: »
    Anybody has implemented kind of flow control or a timed FIFO buffer approach for controlling a serial device? Instead of sending to the device directly, just call a function with the command as a parameter and the function will keep track of all arriving commands to be send and que them and send with a predefined pause in between so that the controlled device would not miss a thing.

    I typically will do a queue for all rs232 stuff.. they're not that hard to build and manage and just generally seem to keep things moving more smoothly. It has a built-in collision insurance that makes programming over large systems less quirky.

    My method is to make a larger buffer for holding the message. (usually 5 to 10-ish commands) Then keep an array of wait times for devices that require different wait times depending upon the command (projectors, older Plasmas, etc...) or just a standard wait time for devices that don't really care much.

    Then just watch for length in the buffer and do something about it when you find something.
  • bobbob Posts: 296
    Something like calling a function instead of sending a string. This function then manipulates the outgoing buffer (one for each serial device) and then there is another routine (or best a DATA_EVENT) that reads the buffer, sends the command strings in a timed matter and deletes them from the buffer.
  • ericmedleyericmedley Posts: 4,177
    bob wrote: »
    Something like calling a function instead of sending a string. This function then manipulates the outgoing buffer (one for each serial device) and then there is another routine (or best a DATA_EVENT) that reads the buffer, sends the command strings in a timed matter and deletes them from the buffer.



    the data_event from the main program works something like this (using simplified code)
    define_variable
    virt_buff[200]
    real_buff[200]
    
    
    define_event
    DATA_EVENT[vdv_Device]
    {
    command:
      {
      virt_buff=" virt_buff,data.text,'my_delimiter'"
      } 
    }
    
    DATA_EVENT[dv_Device]
    {
    string:
      {
      real_buff=" real_buff,data.text,'my_delimiter'"
      } 
    }
    
    

    Then you could, for example, put something down in define_program to watch for strings

    define_program
    
    if(length_string(virt_buff) and !virt_flag)
    {
    virt_flag=1
    process_virt_buff(virt_buff)
    }
    
    if(length_string(real_buff) and !real_flag)
    {
    real_flag=1
    process_real_buff(real_buff)
    }
    
    

    Then in the function
    define_function process_virt_buff(buff[200])
    {
    
    stack_var command[20]
    command=remove_string(buff,'my_delimiter',1)
    // then take out the delimter howeve you like or just test for the command
    // do something based on the command
    WAIT wait_for_This_Device // maybe 10 ticks  - whatever
      {
      if(length_string(buff)<5) // some amount that is less than a command length long
        {
        virt_buff='' // clear out buffer.  it's just left over garbage.
        }
      virt_flag=0 // reset the flag.  If more stuff in buffer, it will process again.
      }
    }
    
    

    this is, of coure, overly simplified. You'd need to do some checking for bad commands/string and deal with that. You'd probably also need to track device status and whatnot. It is important to watch the flag that starts and stops the whole mess as bad commands, buffer overruns or whatever can get it stuck. Sometimes that kind of thing can be a real bear to figure out once you've written a whole bunch of code.

    I actually use a timeline for this kind of thing because I can really tweak the delay times much better and can squeeze them down so the whole thing runs more quickly and efficiently.

    There's lots of ways to do this and I'm sure someone else can give you clever ideas to make it happen.
  • bobbob Posts: 296
    Eric, thanks! The timeline approach will be also interesting, you are right.
  • PhreaKPhreaK Posts: 966
    Spire_Jeff did some benchmarking of different queueing methods not to long ago. There some interesting discussion on FIFO methods and implimentation in that thread.
  • bobbob Posts: 296
    Thanks guys, again!
Sign In or Register to comment.