Module Question
SCOTTYP
Posts: 32
I was about to begin writing a module for an epson projector that I am putting into a conference center...In total I have 4 of these and was wondering if there is an easier way than adding 4 instances of that module with different names into my program (there has to be). Any nudge in the right direction would help...thanx in advance.
0
Comments
I personally would probably not even make a module. I'd just create an include with an array to handle all the projectors. This method would probabloy use fewer resources and whatnot.
etc...
That's my opinion. I'm sure there are many others here.
That brings up another question....Ive had problems sometimes getting my program to see I have incude files??? Im sure its just me, but how do you decide where to put your #include? Ive been putting underneath my define device but sometimes it works and other times it hasnt, I havent spent a ton of time trying to figure it out or anything but it wluld be nice to get the low down on includes since I havent worked with them much. Thanks Eric for the response.
Why? Thats exactly the scenario modules are designed for. You simply write one block of control code required for communication with the device and then instantiate it for each instance of the physical device. That way everything stays neat and encapsulated and it will allow you to add and remove projectors at will. On the resource front it probably won't cause you issues unless your running a colossal system. There's no point sacrificing code readability and modularity unless you need to. However, in the words of eric: that's my opinion. I'm sure there are many others here.
In relation to includes, they can appear anywhere within a program as they are a compile time directives and not something that is processed in the runtime flow of logic. The only limitation is that the compiler won't analyse all includes prior to attempting to compile the tko so you have to position them so that any variables, constants, functions, devices etc that are declared before they are referenced.
You only need to have one copy of the module file in your project. But generally you then instantiate it (via DEFINE_MODULE) for each occurance of the physical device.
I write a module for every device I control (except IR devices). Granted, sometimes the module may be very basic, but the next time I need to control that type of device I know I can just throw in the module and at least the communication will be all set up.
I always rev my changes so I can make improvements over time and always know what is my latest and greatest.
The biggest headache with modules is when you need to share data with the Master axs. There are multiple ways to handle this discussed many times in this forum.
<code>
switch(t)
{
case 1: // CABLE BOX
{
TO_DENON (1,Denon_Source,3)
TO_Plasma (1,Power_On)
TO_DVR (1,Power_On)
}
case 2: // DVD
{
TO_DENON (1,Denon_Source,1)
TO_Plasma (1,Power_On)
TO_DVD (1,Power_On)
}
}
</code>
or
<code>
switch(t)
{
case 1: // CABLE BOX
{
send_command vdvDenon, "'SOURCE TV/CBL <CR>'"
send_command vdvPlamsa "'SOURCE HDMI <CR>'"
TO_DVR (1,Power_On)
}
case 2: // DVD
{
send_command vdvDenon, "'SOURCE DVD <CR>'"
send_command vdvPlamsa "'SOURCE HDMI <CR>'"
TO_DVD (1,Power_On)
}
}
</code>
I find that it makes my code a lot easier to read, and because of the fact that the commands are basically self explaining, i just less comments in my code, speeding everything up for me
Also I am a real dick sometimes, I don't give the client the unlocked modules sometimes. There is a huge discussion on the forums here about who owns the code, and I know that I will probably insight a riot with this statement, but I am giving the client the working source code, just not everything to modify it. That's within the spirit of intent isn't it?
Yes they can be a pain to write, and sometimes they exhibit issues that you don't find in "straight" code, but the ability to just drop them in over and over again and know that they work, well for me that's a huge time saver. I find that it is also a huge debugging tool, I know that the sections of code in the module work, so if something doesn't work, i don't have to look there, I can start looking in other places.
That's my 2 cents
You could, if you wrote the module to behave that way, but it seems like a lot of trouble to go to. It also makes your code less flexible and reusable - the next project may have six projectors instead of four, or it may have three Sanyos and a Sony.
Having said that, I *have* done what you describe in situations like a chain of video wall cubes on one COM port, where I want to control an individual cube. In a case like that, I write the module to handle the maximum number of devices the equipment supports. Either way, I never have to look at the protocol document again, which is a good thing.
What I generally do is make multiple instances of the module in the "normal" way, and create an array of my virtuals for easy command and feedback handling:
...and in define_device,
..which allows you to do stuff like
This approach allows you to have different kinds and quantities of displays, and to mix and match in the next project, without having to change your module at all. I do my status parsing in the module, and return it to main in the p_stat variable. You could also use send_strings (to the virtual) in the module and parse it out from main (or use channels or levels, whatever you want).
Hope this helps explain why modules are used in this way.
In your module file you probably have something along the lines of: Chances are that your module will be processing string/commands/channel events on vdvVirtualDevice into strings which you are sending to dvRealDevice (and vice versa). vdvVirtualDevice and dvRealDevice are module parameters - variables which are passed into the module when it is instantiated. So the best way to think of this is that if you were to instantiate your module like so: everywhere that vdvVirtualDevice is referred to within your module is replaced with vdvX, and everywhere that dvRealDevice appears it is replaced with dvY. If you were to then instantiate it again with: vdvVirtualDevice becomes vdvA and dvRealDevice becomes dvB in that instance of the module. Each instance then sits then running happily in its own world. That way you only need to write one module for controlling one device. Then each time you instantiate it you are tell it which device you would like it to control.
Paul
I generally write modules to support one device and multiple panels to avoid such issues ... but if I have something like a video wall, I would convert such a module to also support multiple devices in an array as well. Half a dozen or so instances of a single module is OK, but beyond that you start eating up resources more than I am comfortable with.
This is one of the reasons my modules do communications only: it scales better. I have one module instance per controlled device, and that's it. In the example above, I'd have 10 module instances, which is reasonable IMO. I'd handle the 20 panels with a device array in main. My modules don't handle any panels, or know about them in any way; they just receive commands from main, send strings to the device based on those commands, and keep main informed of what the device is doing. "Do one thing and do it well."
How do you give the module the ability to handle an arbitrary number of projectors??? Thats what I wanted to do but got stuck when trying to figure out how to parse out responses from different projectors. I figured the only way was to create a bunch of data events for each potential projector....
I usually use get_last, but there are other methods.
Paul
I know I already thanked you.....but that was a great explanation, I really appreciate you taking your time to help me out.
You don't, exactly. You have to pass it an array with all the projector devices, and route which one gets the commands internally. Since your module can't know in advance how big the array you are passing is going to be, it necessarily must be the biggest size possible to handle whatever your needs may be now or in the future. So, the module may be set up to handle an array 50 records long, but you might only pass it 20 devices ... which might cause difficulties when the empty records are accesses. So, in addition, I pass a parameter value along as well that tells how big the array is (I've found checking the array size isn't always reliable, since when the module initializes, the array may or may not be allocated yet, safer to pass the size explicitly). Then the module uses a lot of FOR loops to iterate through the devices and pass communications.
Not a problem. They can be an interesting thing to get your head around if you haven't had to deal with them before, but it sure does make life easier when you start using them.
I've got to agree with chill on the "Do one thing and do it well" comment. I've got into the habbit of making sure that all my modules for each device type behave in an identical way. After all modules should be 'modular'. That way I can develop modules to a exact spec and forget about them which allows me to piece together systems like lego. During module development I can put all my concentration into efficient data parsing and ensuring I have reliable communication happening in both directions. Then when I'm developing the full system I can just focus on designing something that feels natural to use and tighly integrates all the components so that the user can control racks of potentially complex gear without feeling like they're doing anything more complex than using a toaster.