Using Multiple Tp with Multiple Iports

I would like to use multiple tp's (4) with multiple iports (4) and have the ability to access any iport from any tp using the netlinx jar module. I have a theory but would love to have some guidance from someone who has ran into this problem.

my question lies in the define start section will the code below work or

DEFINE_MODULE 'Sonance_iPort_Comm_dr1_0_0' DuetCode(vdvIport_1, dvIW_22_1)
DEFINE_MODULE 'Sonance_iPort_Comm_dr1_0_0' DuetCode(vdvIport_2, dvIW_22_2)
DEFINE_MODULE 'Sonance_iPort_Comm_dr1_0_0' DuetCode(vdvIport_3, dvIW_22_3)
DEFINE_MODULE 'Sonance_iPort_Comm_dr1_0_0' DuetCode(vdvIport_4, dvIW_22_4)

DEFINE_MODULE 'Sonance_iPort_UI' TP1(vdvIport_1, dvTP1, nCHAN_BTN, nTXT_BTN, nLVL_BTN)
DEFINE_MODULE 'Sonance_iPort_UI' TP2(vdvIport_2, dvTP2, nCHAN_BTN, nTXT_BTN, nLVL_BTN)
DEFINE_MODULE 'Sonance_iPort_UI' TP3(vdvIport_3, dvTP3, nCHAN_BTN, nTXT_BTN, nLVL_BTN)
DEFINE_MODULE 'Sonance_iPort_UI' TP4(vdvIport_4, dvTP4, nCHAN_BTN, nTXT_BTN, nLVL_BTN)

should i change the define ui module to something like this

Define_Module 'Sonance_iPort_UI' TP1(vdvIport_1,dvTP1_Iport_1,dvTP2_Iport_1,dvTP3_Iport_1,dvTP4_Iport_1,dvTP4, nCHAN_BTN, nTXT_BTN, nLVL_BTN)
and so for tp 2-4.

any help would be appreciated
thanks
Greg

Comments

  • viningvining X Member Posts: 4,354
    Unfortunately no! Your module declaration parameters must match what the module header expects. If the second paremeter is looking for a dev you need to send it a dev not a dev array, in your case dev, dev, dev, dev. Likewise if your 3rd parameter is meant to be the an integer array for Btns you have to send it an integer array for the buttons. You just can't modify what you send to the module since it expects a parameter to parameter match and won't compile if you add parameters the module doesn't expect or delete parameters that the module needs.

    You could change the module header for the UI mod which should be open to allow an array of devs (not individuals as you've shown) but then you need to re-write the majority of the code to track which iPort the TP is supposed to control to determine which virtual to send commands to and which virtual's feedback to send to which TP.

    It can be done but it's alot of work. It might be easier to create a seperate TP port/pages for each iPort then using the arrays of TPs will be easier to manage.

    I personally use a non duet "modified" module for the iPort that does allow for any TP to control any iPort using a single TP port/page approach that does the instance tracking for control & feedback. I tend to shy away from Duet modules and locked modules in general since I've had limited experience and success with them. If I can't personally fix it I don't want to use it.
  • ericmedleyericmedley Senior Member - 4000+ posts Posts: 4,166
    I'm not at my computer to check this but I do this on almost every project I've done. I'm not sure the problem is but it's obviously doable. I know I make UI layouts on different TP ports to get the gig done. So for example: iPort 1's buttons/text fields/levels might be on port 11, iPort 2's bla bla will be on port 12 and so forth. But, I have multiple TPs controlling multiple iPorts.

    I know my post is not entirely helpful. I'll try to look at what I did so I can speak more intelligently. But, it is doable and I do it all the time.
  • Spire_JeffSpire_Jeff Formerly Caffeinated Programmer Posts: 1,917
    My personal recommendation is to use the NetLinx module from AMX for the comms. Unless the Duet has been completely overhauled, the AMX module just plain works and it works well. I did modify the UI portion of the NetLinx module to support multiple panels within my code and it wasn't very difficult. I added a flag to indicate if a touch panel is active on the iPort and the module only responds to button pushes if the touch panel is active. When the touch panel is activated, the module sends the feedback data and will continue to update while the touch panel is active. I run one instance of the UI for each iPort.

    Jeff
  • ericmedleyericmedley Senior Member - 4000+ posts Posts: 4,166
    Spire_Jeff wrote: »
    My personal recommendation is to use the NetLinx module from AMX for the comms. Unless the Duet has been completely overhauled, the AMX module just plain works and it works well. I did modify the UI portion of the NetLinx module to support multiple panels within my code and it wasn't very difficult. I added a flag to indicate if a touch panel is active on the iPort and the module only responds to button pushes if the touch panel is active. When the touch panel is activated, the module sends the feedback data and will continue to update while the touch panel is active. I run one instance of the UI for each iPort.

    Jeff

    To amplify Jeff's statement. I do use the Netlinx version myself too. I never had any luck with the Duet version. It's a process hog too.
  • jjamesjjames AMX Sustaining Engineer Posts: 2,900
    Yup! Use the NetLinx module!

    Here's my definition for 20+ panels controlling 3 different iPorts
    DEFINE_MODULE 				'iPort_UI' 							IPORT_UI1
    (vdvIPOD_HRT_L, dv_TP_IPOD_L, TP_BUTTONS, TP_FIELDS, iPORT_TP_LEVELS, TP_UI_LIST)
    
    DEFINE_MODULE 				'iPort_UI' 							IPORT_UI2
    (vdvIPOD_HRT_R, dv_TP_IPOD_R, TP_BUTTONS, TP_FIELDS, iPORT_TP_LEVELS, TP_UI_LIST)
    
    DEFINE_MODULE 				'iPort_UI' 							IPORT_UI3
    (vdvIPOD_MBR, 	dv_TP_IPOD_M, TP_BUTTONS, TP_FIELDS, iPORT_TP_LEVELS, TP_UI_LIST)
    
    DEFINE_MODULE 				'iPort COMM' 						IPORT_MODULE1
    (vdvIPOD_HRT_L,dvIPOD_HRT_LF)
    
    DEFINE_MODULE 				'iPort COMM' 						IPORT_MODULE2
    (vdvIPOD_HRT_R,dvIPOD_HRT_RT)
    
    DEFINE_MODULE 				'iPort COMM' 						IPORT_MODULE3
    (vdvIPOD_MBR, 	dvIPOD_MBR)
    

    I was going to modify the UI module - but never got around to it. Good luck!
  • GfullGfull Junior Member Posts: 19
    thanks guys i'll definitley try the netlinx module then
  • a_riot42a_riot42 AMX Wizard Posts: 1,619
    vining wrote: »
    You could change the module header for the UI mod which should be open to allow an array of devs (not individuals as you've shown) but then you need to re-write the majority of the code to track which iPort the TP is supposed to control to determine which virtual to send commands to and which virtual's feedback to send to which TP.

    I am looking at a project with 12 iPods and many UIs and need to modify the UI module so that I don't use 12 ports. Given that the UI module does touch panel feedback in various places including define_program, it looks like I will need a few for loops. 12 for loops running, updating 20 touch panels at every iPod's elapsed second is going to hog the processor big time I would think. The kaleidescape module does something similar and its feedback can slow down, so I am wondering if there is a better method. Ultimately all these strings have to be sent to all these wireless devices so there may not be much that can be done other than throwing hardware at it. I've tried dynamically populating the dvTP array for feedback but that requires a rebuild_event call which is also expensive. Has anyone come up with any clever tricks to deal with this?
    Paul
  • viningvining X Member Posts: 4,354
    a_riot42 wrote: »
    I am looking at a project with 12 iPods and many UIs and need to modify the UI module so that I don't use 12 ports. Given that the UI module does touch panel feedback in various places including define_program, it looks like I will need a few for loops. 12 for loops running, updating 20 touch panels at every iPod's elapsed second is going to hog the processor big time I would think. The kaleidescape module does something similar and its feedback can slow down, so I am wondering if there is a better method. Ultimately all these strings have to be sent to all these wireless devices so there may not be much that can be done other than throwing hardware at it. I've tried dynamically populating the dvTP array for feedback but that requires a rebuild_event call which is also expensive. Has anyone come up with any clever tricks to deal with this?
    Paul
    I created an array of virtuals and devs and each comm module get its own virtual & dev, my virtuals return FB to a single .axi which defines these modules and handles all iPort button puhes. I also create tracking arrays so any TP that goes to a specific iPort which in my code would be buttons 201-212, if I were doing 12 iPorts, then that TP index would be assigned nBtn - 200 or 1-12. I reset the TPs index value to 0 on button push 200 (device page exit) or any offline/online event since I revert back to the main page when UI's come online. The iPort index assigned also matches my virtual array so when I receive FB from the com mods (channel, data, etc) using GET_LAST on the virtual array tells me which module, then a single for loop that runs through my TP tracking array which at any given time will be mostly 0's just sends to the TPs that are on that GET_LAST index.

    Just gotta do allot of re-writting.
  • a_riot42a_riot42 AMX Wizard Posts: 1,619
    vining wrote: »
    Just gotta do allot of re-writting.

    Yes with a locked comm module there isn't much choice I guess. I'll have to redo the buttons and feedback it looks like similar to what you have done. I am just worried about burdening the processor. Have you had any issue with this when using multiple iPorts?
    Paul
  • viningvining X Member Posts: 4,354
    a_riot42 wrote: »
    Yes with a locked comm module there isn't much choice I guess. I'll have to redo the buttons and feedback it looks like similar to what you have done. I am just worried about burdening the processor. Have you had any issue with this when using multiple iPorts?
    Paul
    the most I ever used were 6 iPorts and that system had maybe 8 TPs. Since the for loop only runs when there's FB from the module and the first thing I do in each for loop is see what TPs are active on that particular iPort page it steps through pretty fast. Usually only 1 TP is on any given iPort at a time so the loop just looks for a match.

    I also use an overall flag so values are just stored and no loops are run in there's not at least 1 TP on an iPort page.
  • a_riot42a_riot42 AMX Wizard Posts: 1,619
    vining wrote: »
    I also use an overall flag so values are just stored and no loops are run in there's not at least 1 TP on an iPort page.

    So if an iPod is playing but its not a source for any UI, no for loops run?
    Paul
  • viningvining X Member Posts: 4,354
    a_riot42 wrote: »
    So if an iPod is playing but its not a source for any UI, no for loops run?
    Paul

    Yeah, if iPods are playing but no UI is on an iPort page there's no FB that needs to be sent so no loops run. FB is just stored in a structure so when a UI does return to the iPort page it can be updated with the data stored in the index of the structure that matches the virtual device/iPort.
  • a_riot42a_riot42 AMX Wizard Posts: 1,619
    vining wrote: »
    Yeah, if iPods are playing but no UI is on an iPort page there's no FB that needs to be sent so no loops run. FB is just stored in a structure so when a UI does return to the iPort page it can be updated with the data stored in the index of the structure that matches the virtual device/iPort.

    I was thinking about setting it up so that if iPods are running and no UI is currently controlling it, that the PROCESS_RESPONSE function wouldn't get called. That function is 600 lines long, and I don't want it called in 12 modules every second if no one is controlling it. Still have to figure out a good way to do that though.
    Paul
  • viningvining X Member Posts: 4,354
    a_riot42 wrote: »
    I was thinking about setting it up so that if iPods are running and no UI is currently controlling it, that the PROCESS_RESPONSE function wouldn't get called. That function is 600 lines long, and I don't want it called in 12 modules every second if no one is controlling it. Still have to figure out a good way to do that though.
    Paul
    I obviously use 1 com mod per iPort but I only have 1 UI mod per sei. All com mods report back to a data, channel or level event handler in a single include file using a virtual dev array for the handler type needed. Get_last tells me which virtual/iPort index is sending the response and I process it, if a UI is on page I store the values and update the UIs that are on that iPort index and if no UI's are on page I simply store the data. If the virtual receives elapsed time info I would ignore it if no UI's are on page but store all the other data being returned so they can be updated when they go back to the iPort page. I would zero the UI's elapsed time VT or level on page exit or when it returns to the page since if playing it will automatically update in 1 second or less and if it's not playing it should be 0 anyway.
  • DHawthorneDHawthorne Junior Member Posts: 4,584
    The current iPort module already supports multiple panels, so you would only need to include separate modules for each actual device. I'm not 100% sure on this, but I do recall someone either from iPort or AMX telling me that the Duet version is *not* as recent as the NetLinx module. They weren't, at least at the time, updating the Duet.
  • a_riot42a_riot42 AMX Wizard Posts: 1,619
    DHawthorne wrote: »
    The current iPort module already supports multiple panels, so you would only need to include separate modules for each actual device. I'm not 100% sure on this, but I do recall someone either from iPort or AMX telling me that the Duet version is *not* as recent as the NetLinx module. They weren't, at least at the time, updating the Duet.

    It supports multiple panels, but the UI module is written to use its own port. 5 iPods means 5 ports, which seemed silly to me. So I modified it to use one port like I normally do, and buttons/feedback is ignored if the UI isn't currently controlling the device. It seems to have also made feedback more snappy too. As soon as the iPod is pulled from the iPort feedback is virtually instant, and same when its docked, so that a nice benefit I wasn't considering.
    Paul
  • DHawthorneDHawthorne Junior Member Posts: 4,584
    a_riot42 wrote: »
    It supports multiple panels, but the UI module is written to use its own port. 5 iPods means 5 ports, which seemed silly to me. So I modified it to use one port like I normally do, and buttons/feedback is ignored if the UI isn't currently controlling the device. It seems to have also made feedback more snappy too. As soon as the iPod is pulled from the iPort feedback is virtually instant, and same when its docked, so that a nice benefit I wasn't considering.
    Paul

    It's probably done to conserve memory. Since you can't allocate memory on the fly in NetLinx, your state variables (all your meta data, browing info) have to be big enough to hold all the possible feedback on all the possible panels and all the possible devices, which can use a lot of memory up real fast. And in case you are thinking that's not likely to be a problem, I ran across it only minutes ago where a project loaded on a test controller failed because it ran out of memory. The target controller is more than big enough, but my bench unit, a mere 900, is not. I can just comment out some modules and still test ... but if they were all together, that wouldn't be an option.

    So the question becomes, does it use more resources to load another instance, or just combine all the variable allocation into one? In the end, more instances are going to use more memory, but if you only need one or two, but the module is explicitly set up for 5 devices and 20 panels, you're hosed if you aren't the source originator and can't just change the dims and recompile.
  • a_riot42a_riot42 AMX Wizard Posts: 1,619
    DHawthorne wrote: »
    So the question becomes, does it use more resources to load another instance, or just combine all the variable allocation into one? In the end, more instances are going to use more memory, but if you only need one or two, but the module is explicitly set up for 5 devices and 20 panels, you're hosed if you aren't the source originator and can't just change the dims and recompile.


    Display Memory
    Volatile Free : 14169096/67108864 (largest free block in bytes/max physical)
    NonVolatile Free: 1010616/1047536 (bytes free/max physical)
    Disk Free :114843648/128299008 (bytes of free space/max physical)
    Duet Memory Free : 6288520 (bytes)
    Partition 1 - 6288520 (bytes)
    Total Collections - 2
    Average Time Between Collections - 19418ms
    Partition 2 - <UNKNOWN>

    I've got 12 instances of the Netlinx iPort comm and UI module, plus a dozen or so other modules, and it looks like there is memory left so it shouldn't be an issue.

    I have a feeling that the memory gained by using fewer ports is more than what is taken up by more modules using the same port, but I could be wrong.
    Paul
    Paul
  • viningvining X Member Posts: 4,354
    a_riot42 wrote: »
    I have a feeling that the memory gained by using fewer ports is more than what is taken up by more modules using the same port, but I could be wrong.
    Paul
    Why more modules using the same port? The only instances needed are for the com modules which care less about TP ports. The UI side can use just 1 UI mod or .axi using 1 port for all the TPs and all receive status from all the iPort com mods. That why god made arrays and structures. :) Maybe if Netlinx used a multi thread processor you'de need instances of the UI but it ain't, so you don't.
  • a_riot42a_riot42 AMX Wizard Posts: 1,619
    vining wrote: »
    Why more modules using the same port? The only instances needed are for the com modules which care less about TP ports. The UI side can use just 1 UI mod or .axi using 1 port for all the TPs and all receive status from all the iPort com mods. That why god made arrays and structures. :) Maybe if Netlinx used a multi thread processor you'de need instances of the UI but it ain't, so you don't.

    Maybe I am confused, but the way the UI/comm module are written, any TP in the array passed to it will trigger events and get feedback from the comm if they use the same port. For instance, the UI module has this code in define_program:

    [dvTP, dvTP_BUTTONS[4]] = (nONLINE == 1) // Online Status button

    So every TP in the array will have its online status button turned on, even if only one of the iPods is docked. This is the module declaration using one port for all iPods:


    define_module
    'iPort_UI' mdlIpodUI
    (vdvIpod, dvIpodUIs, iIportTPChannels, iIportTPVTChannels, iIportTPLevels, TP_UI_LIST, nR4_DMS_PORT1, nR4_DMS_PORT2)

    define_module
    'iPort COMM' mdlIpodComm
    (vdvIpod, dvIpod)

    As soon as vdvIpod comes online, all the TPs in dvIpodUIs will have their status turned on. However, one TP might be controlling another iPod which isn't currently online so the feedback is incorrect. So I have to do this:

    define_module
    'iPort_UI' mdlKitchenIpodUI
    (vdvKitchenIpod, dvIpodUIs, iIportTPChannels, iIportTPVTChannels, iIportTPLevels, TP_UI_LIST, nR4_DMS_PORT1, nR4_DMS_PORT2)

    define_module
    'iPort COMM' mdlKitchenIpodComm
    (vdvKitchenIpod, dvKitchenIpod)

    define_module
    'iPort_UI' mdlDenIpodUI
    (vdvDenIpod, dvIpodUIs, iIportTPChannels, iIportTPVTChannels, iIportTPLevels, TP_UI_LIST, nR4_DMS_PORT1, nR4_DMS_PORT2)

    define_module
    'iPort COMM' mdlDenIpodComm
    (vdvDenIpod, dvDenIpod)

    Perhaps I am misunderstanding what you are saying.
    Paul
  • viningvining X Member Posts: 4,354
    You have to do some serious re-writting to use just 1 UI file but at least the UI mod is open so it's doable without having to start from scratch.
  • a_riot42a_riot42 AMX Wizard Posts: 1,619
    vining wrote: »
    You have to do some serious re-writting to use just 1 UI file but at least the UI mod is open so it's doable without having to start from scratch.

    I might end up doing that, but for now this method seems to work. This way I can use the least amount of memory too. Not much with one iPort, more with more iPorts. I wish Jon had kept the UI code separate from the parsing code though to make it easier to integrate but it didn't take as much work as I thought it would.
    Paul
Sign In or Register to comment.