Home AMX User Forum NetLinx Studio

Module Question

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.

Comments

  • ericmedleyericmedley Posts: 4,177
    SCOTTYP wrote: »
    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.

    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.
    DEFINE_DEVICE
    dv_proj_1 = 5001:01:0 // proj room one
    dv_proj_2 = 5001:02:0 // proj room two
    dv_proj_3 = 5001:03:0 // proj room three
    dv_proj_4 = 5001:04:0 // proj room four
    
    
    dv_TP_1 = 10001:01:0 // TP room one
    dv_TP_2 = 10002:01:0 // TP room two
    dv_TP_3 = 10003:01:0 // TP room three
    dv_TP_4 = 10004:01:0 // TP room four
    
    DEFINE_VARIABLE
    
    volatile dev dev_projs[]=
    {
    dv_proj_1
    ,dv_proj_2
    ,dv_proj_3
    ,dv_proj_4
    }
    
    volatile dev dev_TPs[]=
    {
    dv_TP_1
    ,dv_TP_2
    ,dv_TP_3
    ,dv_TP_4
    }
    
    DEFINE_EVENT
    
    button_event[dev_TPs,1] // power on
    {
    push:
      {
      local_var integer tp_id
      tp_id=get_last(dev_TPs)
      send_string dev_projs[tp_id],'commence_world_takeover'
      }
    }
    
    

    etc...
    That's my opinion. I'm sure there are many others here.
  • SCOTTYPSCOTTYP Posts: 32
    ....

    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.
  • PhreaKPhreaK Posts: 966
    SCOTTYP wrote: »
    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).

    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.
  • SCOTTYPSCOTTYP Posts: 32
    so is it common practice to include a seperate module file for each physical device? thats what ive been doing but I thought there might be an easier way....
  • PhreaKPhreaK Posts: 966
    SCOTTYP wrote: »
    so is it common practice to include a seperate module file for each physical device? thats what ive been doing but I thought there might be an easier way....

    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.
  • SCOTTYPSCOTTYP Posts: 32
    ahhh...I see. Thanks
  • ColzieColzie Posts: 470
    PhreaK wrote: »
    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.

    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.
  • Personally I have battled with the include vs module delemia, but have now firmly settled on the side of modules. All my modules are referenced by virtual devices, so instead of having "macro" pages with loads of function calls, its a send_command to the virtual device with the action that I want to happen.

    <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
  • SCOTTYPSCOTTYP Posts: 32
    Back to Kim's response....I knew that you can instantiate the seperate instance in the define module but it seems tedious to have to go through and change the names of the devices (a couple of minutes with find and replace), albeit not a whole lot of effort but I guess what I was getting at is.......Is it possible to make one module and bring a dev array of projectors into the module and based on what command you sent the module (send_command vProjArray, 'powerOn_1!') I could then parse out the projector number and feed it into a function.....The only hang up is the parsing. I was hoping there was a global data.text for the projector array or that I could concatenate all the data.text's in the array. I hope that didnt sound too absurd, Ive already started doing it the way I normally do except taking Kim's advice and only adding one instance of the module and just changing the define module modifier. That does make a bit more sense than what I was doing. (changing the name of the module for each instance of the module)
  • chillchill Posts: 186
    SCOTTYP wrote: »
    Back to Kim's response....I knew that you can instantiate the seperate instance in the define module but it seems tedious to have to go through and change the names of the devices (a couple of minutes with find and replace), albeit not a whole lot of effort but I guess what I was getting at is.......Is it possible to make one module and bring a dev array of projectors into the module and based on what command you sent the module (send_command vProjArray, 'powerOn_1!') I could then parse out the projector number and feed it into a function.....The only hang up is the parsing. I was hoping there was a global data.text for the projector array or that I could concatenate all the data.text's in the array. I hope that didnt sound too absurd, Ive already started doing it the way I normally do except taking Kim's advice and only adding one instance of the module and just changing the define module modifier. That does make a bit more sense than what I was doing. (changing the name of the module for each instance of the module)

    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:
    define_module '3m_scp700_series' Em01(proj1,r_proj1,p_stat[1])
    define_module '3m_scp700_series' Em02(proj2,r_proj2,p_stat[2])
    define_module 'sharp_pn655' pn01(lcd1,r_lcd1,p_stat[3])
    define_module 'sharp_pn655' pn02(lcd2,r_lcd2,p_stat[4])
    define_module 'sharp_pn655' pn03(lcd3,r_lcd3,p_stat[5])
    define_module 'sharp_pn655' pn04(lcd4,r_lcd4,p_stat[6])
    

    ...and in define_device,
    volatile dev display[] = {proj1,lcd1,lcd2,proj2,lcd3,lcd4}
    

    ..which allows you to do stuff like
    send_command display[room],'on'
    

    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.
  • SCOTTYPSCOTTYP Posts: 32
    Thats interesting...thanx Chris. Unfortunately I just realized I am still confused about one of the above topics....I said above that I have to find and replace the device names for every projector of that type im using in this project....Well if I do that I still have to import different instances of the module into my project and rename the devices?? So can anybody point me in the right direction on how to implement 4 of the same projector using the same actual module file? I really appreciate all the responses and am sorry in advance for what could appear to be retarded questions.
  • ColzieColzie Posts: 470
    define_module 'CS_Panasonic_Projector' mdl_PROJ1 (dv_PROJ1_232, vdv_PROJ1_MDL, dv_TPs_PROJ1)
    define_module 'CS_Panasonic_Projector' mdl_PROJ2 (dv_PROJ2_232, vdv_PROJ2_MDL, dv_TPs_PROJ2)
    define_module 'CS_Panasonic_Projector' mdl_PROJ3 (dv_PROJ3_232, vdv_PROJ3_MDL, dv_TPs_PROJ3)
    define_module 'CS_Panasonic_Projector' mdl_PROJ4 (dv_PROJ4_232, vdv_PROJ4_MDL, dv_TPs_PROJ4)
    
  • PhreaKPhreaK Posts: 966
    SCOTTYP wrote: »
    Unfortunately I just realized I am still confused about one of the above topics....I said above that I have to find and replace the device names for every projector of that type im using in this project....Well if I do that I still have to import different instances of the module into my project and rename the devices?? So can anybody point me in the right direction on how to implement 4 of the same projector using the same actual module file?

    In your module file you probably have something along the lines of:
    MODULE_NAME='FooBar' (DEV vdvVirtualDevice, dvRealDevice)
    
    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:
    DEFINE_MODULE 'FooBar' mdlFooBar(vdvX, dvY)
    
    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:
    DEFINE_MODULE 'FooBar' mdlFooBar(vdvA, dvB)
    
    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.
  • a_riot42a_riot42 Posts: 1,624
    I have found it easier to write one module that will take an arbitrary number of TPs and projectors. I didn't like having 20 module definitions for all the sat boxes or CD players. If your modules only deal with one device and one TP, then in a project of 20 panels controlling 10 global sources you would need 200 modules running so they can add up quickly on bigger projects.
    Paul
  • DHawthorneDHawthorne Posts: 4,584
    a_riot42 wrote: »
    I have found it easier to write one module that will take an arbitrary number of TPs and projectors. I didn't like having 20 module definitions for all the sat boxes or CD players. If your modules only deal with one device and one TP, then in a project of 20 panels controlling 10 global sources you would need 200 modules running so they can add up quickly on bigger projects.
    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.
  • chillchill Posts: 186
    a_riot42 wrote: »
    I have found it easier to write one module that will take an arbitrary number of TPs and projectors. I didn't like having 20 module definitions for all the sat boxes or CD players. If your modules only deal with one device and one TP, then in a project of 20 panels controlling 10 global sources you would need 200 modules running so they can add up quickly on bigger projects.
    Paul

    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."
  • SCOTTYPSCOTTYP Posts: 32
    Thankyou Kim that makes sense and is exactly what I was getting at...
    a_riot42 wrote: »
    I have found it easier to write one module that will take an arbitrary number of TPs and projectors. I didn't like having 20 module definitions for all the sat boxes or CD players. If your modules only deal with one device and one TP, then in a project of 20 panels controlling 10 global sources you would need 200 modules running so they can add up quickly on bigger projects.
    Paul

    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....
  • a_riot42a_riot42 Posts: 1,624
    SCOTTYP wrote: »
    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
  • SCOTTYPSCOTTYP Posts: 32
    PhreaK wrote: »
    In your module file you probably have something along the lines of:
    MODULE_NAME='FooBar' (DEV vdvVirtualDevice, dvRealDevice)
    
    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:
    DEFINE_MODULE 'FooBar' mdlFooBar(vdvX, dvY)
    
    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:
    DEFINE_MODULE 'FooBar' mdlFooBar(vdvA, dvB)
    
    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.

    I know I already thanked you.....but that was a great explanation, I really appreciate you taking your time to help me out.
  • DHawthorneDHawthorne Posts: 4,584
    SCOTTYP wrote: »
    Thankyou Kim that makes sense and is exactly what I was getting at...



    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....

    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.
  • PhreaKPhreaK Posts: 966
    SCOTTYP wrote: »
    I know I already thanked you.....but that was a great explanation, I really appreciate you taking your time to help me out.

    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.
Sign In or Register to comment.