Home AMX User Forum AMX Technical Discussion

Stacking/Queuing IR and Serial commands

Is there a recommended method (AMX recommended?) for delivering commands to your controlled devices?

I currently aim to queue all IR & serial commands per device, so no matter how many times, and how quickly, the user hits every button on their touch panel, all commands are delivered to the necessary devices in a controlled and timely manner.

As an example, my standard practice is to develop a module for each device in my system. Within this module, when a command (mainly just serial or ir) is to be sent to the device, this command is first appended to an array (this array holds all commands required to be sent to the device). A timeline within the module that is constantly repeating, will then send out each command stored in the afore-mentioned array (and remove it from the array), controlling the time between each command is delivered.
I then add in other timing processes dependant upon the device, as well as everything else needed within the module.

I ask because I have worked with various programmers who have either recommended it, or thought it a waste of time and code.

Is this a common practice?

Thanks for any info

Mark

Comments

  • DHawthorneDHawthorne Posts: 4,584
    For IR, there is a built-in command. SEND_COMMAND dvIR_Port, "'SP', #"; where # is the IR channel. This will queue it up if there are any other IR commands pending. Replacing the SP with CP will clear the queue first, then send the channel. Writing any of your won routines for IR is just a waste of time and effort; AMX has it built into the hardware.

    As for serial, I always buffer my commands and queue them up, even for the most simple protocols. Many devices barf if you send things too fast; many have warm up periods where they won't accept commands. Others will send a response that you have to wait for before sending the next command. All of this is easily adjusted for when you have a queue. You can write a routine for this just once, and adapt it for every project that needs it. I've been using much the same code block for this since Axcent3 days:
    DEFINE_CALL 'Send Commands'
    {
        STACK_VAR CHAR sCmd[50] ;
    	
        IF(FIND_STRING(sCommandQue, "13", 1))
        {
    	IF(!bDataPending)
    	{
    	    sCmd = REMOVE_STRING(sCommandQue, "13", 1) ;
                DEBUG("'Sending - ', sCmd") ;
    	    SEND_STRING dvDev, "sCmd " ;
    	    bDataPending = TRUE ;
    	    WAIT 5 'Data Pending' 
    	        bDataPending = FALSE ;   
    	}
        }
        ELSE IF(LENGTH_STRING(sCommandQue) > 1000)
        {
    	DEBUG ("'Command queue overrun, clearing queue.'") ;
    	CLEAR_BUFFER sCommandQue ;
        }
    }
    

    When using, the above, I'll put a line in my code that parses the output of the port that sets bDataPending to false again and cancels the WAIT. So the delay time in the WAIT is a maximum time period, not absolute. If you need to hold up processing for any reason, just set it to TRUE, and back to FALSE when you are ready again. To cancel pending commands, clear the queue buffer. The DEBUG function referenced above is just a little function that identifies the module the code is in and sends the parameter string to the terminal screen if a flag is set - very handy for troubleshooting serial devices. I put the call to this routine right in DEFINE_PROGRAM; it has it's own internal pacing and won't do anything if the buffer is empty.

    But that's just an example. There are probably dozens of ways to do it that work just as well. Once you settle on something, you can re-use it to your heart's content.
  • Thanks loads Dave.

    I was not aware of the IR command that handles all the buffering, that should save me a lot of code/time.

    Glad to hear that I'm heading along a recommended form of controlling devices. And thanks for the code example. Very handy.

    Mark
  • champchamp Posts: 261
    Does anyone know the buffer limit of "SP" commands.

    I was once told not to rely on it for buffering more than 3 commands so I still stack my "SP" and "XCH" commands just in case.

    I also stack up serial commands but just had a thought...

    If you set the "CHARDM" (character delay in milliseconds) to a high number (say 50), that should work to buffer serial data as long as you don't overflow the serial buffer, which is 2048 bytes for an NXI (see tech note 156 for full buffer size details of all amx devices)
  • DHawthorneDHawthorne Posts: 4,584
    CHARD and CHARDM only slow the output. They don't do any buffering function. The idea is not to slow things down, but to control the flow without losing anything.

    I don't recall ever seeing any information on how many IR commands the SP function can stack - but three doesn't seem reasonable. Even the CH and XCH functions can manage 4-5. I'm sure it's more than that - but then again, how many do you really need, considering they start firing right away and are typically less than a second in pulse length anyway? Either way, I've never concerned myself with it, and I use SP extensively without ever having lost a pulse.
  • champchamp Posts: 261
    The first AMX program I ever did was with an Axcent2 and IRS-4 controlling lots of TV's for sports betting. I soon found that they only have two phisical emitters shared over four IR ports, so I had to create a stack and I've never gone back.
    After a while I started using 'SP' and 'XCH' commands (they are great), but haven't checked just how reliable the AMX IR buffers are since Axcent 2 days.

    ...A bit off topic

    When controllng some DVD recorders I've had to send up to 16 pulses to do an erase all.

    I've also had to put TV's into teletext sub channels for sports betting which can take up to 12 pulses.

    I've also had to stack up to 4 devices off the one IR port before (I didn't choose to).

    Doing all of these things really would stretch the friendship with the port buffers and I have never tried it.
Sign In or Register to comment.