COMM Module Virtual Devices Help
staticattic
Posts: 200
I created my own COMM module for our NEC 52 inch LCD screens. I grew tired of having to look up all of the hex strings, so I made my own COMM module, dumped them all in there and let the COMM module do all of the work. It works great if I send one command at a time via a timeline in my main program. I found in the NEC manual, command strings must not be sent any faster than .6 seconds between each one. In order to get rid of the timelines in the main program and to make the COMM module do all of the work, I need to be able to rack and stack the commands and send them out one at a time with a .6 second wait between each one. I created 2 virtual monitors, and since right now the monitors work in unison with each other, I also created a VOLATILE DEV DISPLAYS[] = {vdvMonitor1, vdvMonitor2} for them.
When someone comes in and powers up the room, part of the power sequence involves the monitors:
SEND COMMAND DISPLAYS, " 'POWER=ON', 13,10"
SEND COMMAND DISPLAYS, " 'INPUT=VGA',13,10"
SEND COMMAND DISPLAYS. " 'AUDIO=2',13,10"
SEND COMMAND DISPLAYS, " 'VOLUME=89',13,10"
If I do a WAIT or create a timeline to stagger the commands, it works fine. If I blast them, I get mixed results. Inside the COMM module, I created a data event:
In a simple form like that, and with the main program pausing between commands, I simply parse cCommand and send the proper hex string to the real display. It was when I started trying to get the COMM module to rack and stack the commands I started running into problems.
Inside the COMM module, I created another virtual device and did this:
In order for that to work, I created a buffer for vdvPARSER and my thoughts were if the buffer were big enough, I could parse that info, one command at a time and send them .6 seconds apart from each other. Again, it worked fine with the main program waiting between sending commands to the virtual monitors.
This is what I have:
I was thinking with the WHILE loop, the module would continue processing the parser buff, one command at a time, until the buffer was empty. Something like:
Inside the COMM module, I am having problems with where to put the WAIT. It seems no matter where I put it, all I have successfully done is locked up the program or caused it to stop after rx-ing the first command. What am I missing? Is there a better way I should be doing this?
When someone comes in and powers up the room, part of the power sequence involves the monitors:
SEND COMMAND DISPLAYS, " 'POWER=ON', 13,10"
SEND COMMAND DISPLAYS, " 'INPUT=VGA',13,10"
SEND COMMAND DISPLAYS. " 'AUDIO=2',13,10"
SEND COMMAND DISPLAYS, " 'VOLUME=89',13,10"
If I do a WAIT or create a timeline to stagger the commands, it works fine. If I blast them, I get mixed results. Inside the COMM module, I created a data event:
DATA EVENT[vdvDisplay] { COMMAND: { cCommand = (DATA.TEXT) } }
In a simple form like that, and with the main program pausing between commands, I simply parse cCommand and send the proper hex string to the real display. It was when I started trying to get the COMM module to rack and stack the commands I started running into problems.
Inside the COMM module, I created another virtual device and did this:
DATA EVENT[vdvDisplay] { COMMAND: { cCommand = (DATA.TEXT) SEND_STRING vdvPARSER, "cCommand" } }
In order for that to work, I created a buffer for vdvPARSER and my thoughts were if the buffer were big enough, I could parse that info, one command at a time and send them .6 seconds apart from each other. Again, it worked fine with the main program waiting between sending commands to the virtual monitors.
This is what I have:
DATA_EVENT [vdvPARSER] { STRING: { WHILE (FIND_STRING(cPARSER_BUFF, "13,10",1) { do something } } }
I was thinking with the WHILE loop, the module would continue processing the parser buff, one command at a time, until the buffer was empty. Something like:
cMSG = REMOVE_STRING(cPARSER_BUFF, "13,10",1)
Inside the COMM module, I am having problems with where to put the WAIT. It seems no matter where I put it, all I have successfully done is locked up the program or caused it to stop after rx-ing the first command. What am I missing? Is there a better way I should be doing this?
0
Comments
Thanks for the push in the right direction. I'll re-do it and let you know what happens. Basically, all I need to do is veify I have a proper command, and take action. So if the commands all come in at once, like:
POWER=ON,13,10AUDIO=2,13,10VOLUME=89,13,10
I want it to first parse the POWER command. Wait .6 seconds, then check to see if more data needs to be parsed. If there is something else there, then do it again and continue until there are no more commands. The thought of using Mainline totally slipped my mind. I'll give it a shot. Thanks again.
The job of the comm module now is, to pick up the commands, and then to create the control strings for the physical device, queueing them, checking for the dependencies of device's state and the serial handling. The amount of commands the module can buffer for sending, depends on the size of the module internal transmit queue.
For example, if a projector needs power on, waiting 20 seconds to get powered, and then to switch it to VGA input, the main program simply sends the commands 'POWER=1' and 'INPUT=VGA'. Everything else is managed inside the module.
Other example may be a matrix control module. If you have to set 20 routes by one push, the main program simply sends the 20 commands in a row into the module. The module will receive 20 single events, translate them to the real protocol,manage to queue them, and handle the sending based on the serial handling, serial feedbacks etc.
OK, this is what I did. First, I got rid of the "13,10" after each command. Since I am writing the COMM module and making my own protocol, I made the delimiter an exclamation point, shorter and easier to code. Inside the COMM module I created 2 functions. One puts the commands in a que and the other grabs a command once a second. The one that grabs the commands parses them and determines the appropriate hex string to send to the real device. I don't care about feedback from the real device, but I suppose I should incorporate that eventually. In the meantime, here's a Cliff's Notes version of what I have. Any pointers would be greatly appreciated. Thanks again for the replies and push in the right direction.
Main Program:
And the COMM Module:
Future improvements to the Jedi powers of this module will incorporate feedback from the devices to verify a proper commands was RX'd and a check that verifies the command is complete before sending it out to the real device.
Hi Jeff,
Another idea for your module would be to include a priority insertion that would place a command in the front of the que instead of the end. I found it handy when the data to be sent out in a que (checking a bunch of status), got in the way of the user change (to kill audio feedback). Depending on the device you're dealing with a couple of seconds delay may be more then you want.
Just an idea.
ROO
First, if you are looking for speed and ease of parsing, consider switching to using a virtual device as the interface to the comm module:
in Comm Module:
in Main code:
This eliminates the needs for string processing all together between the main program and the comm module (unless you have something that doesn't work well as being channel events or level events.
Second, consider using an indexed queue. Check out this http://amxforums.com/showthread.php?t=5372&highlight=queue link. I eventually posted some sample code of the queue. Ignore the dev component of the queue as it is not needed in most normal circumstances.
Jeff