Home AMX User Forum AMX General Discussion

dynamic device passed to module

I have 3 display modules where I am trying to choose one of them to use in the main program. All 3 modules are loaded in the program. Each module has a virtual device passed into it rather than the actual serial port. I am trying to reassign the device Id passed into the module after the NI has booted. What I am finding is that since the Define_Start has already run that by simply re-assigning the device id from vdvDisplay1(33100:1:0) = dvDisplay(5001:1:0) after boot up that the module is not going to get the update.

I have used Define_Combine but it has a drawback, you cannot see what is being sent and received over the actual serial port. The virtual simply echos what you sent. Not what I'm going for.

The only way I think I can get this to work is value to a persistent variable and do an IF/Else when the modules are being instantiated on startup. So after the uer selects the display type it would then force a reboot.

Is there another way?

Comments

  • ericmedleyericmedley Posts: 4,177
    jgreer9514 wrote: »
    I have 3 display modules where I am trying to choose one of them to use in the main program. All 3 modules are loaded in the program. Each module has a virtual device passed into it rather than the actual serial port. I am trying to reassign the device Id passed into the module after the NI has booted. What I am finding is that since the Define_Start has already run that by simply re-assigning the device id from vdvDisplay1(33100:1:0) = dvDisplay(5001:1:0) after boot up that the module is not going to get the update.

    I have used Define_Combine but it has a drawback, you cannot see what is being sent and received over the actual serial port. The virtual simply echos what you sent. Not what I'm going for.

    The only way I think I can get this to work is value to a persistent variable and do an IF/Else when the modules are being instantiated on startup. So after the uer selects the display type it would then force a reboot.

    Is there another way?

    Hmm..

    Please post the code. That might help to diagnose the problem.
  • Are the modules AMX's or yours? If they are AMX's just send a SEND_COMMAND vdvDEVICE,'REINIT'. It should rerun the startup code to setup the device. As far as the real device, just use a DEV variable and assign whatever device you want to it.

    dvDisplay = dvProjector1
    SEND_COMMAND vdvDEVICE,'REINIT'.

    If it is your module? Program it to use the REINIT command. Just put all of the code that is in the online event and place it in the data_event command handle. So if find_string(data.text,'REINIT',1) run the code that was in the online event.
  • AuserAuser Posts: 506
    jgreer9514 wrote: »
    What I am finding is that since the Define_Start has already run that by simply re-assigning the device id from vdvDisplay1(33100:1:0) = dvDisplay(5001:1:0) after boot up that the module is not going to get the update.

    See the second post in this thread: http://www.amxforums.com/showthread.php?t=6123

    I use this same method to choose between modules. Where two rooms are almost identical except for different displays for example, it often makes sense to load identical code to the master and determine which module/s to make active at runtime based on a config file/IP address/data from a GPS attached to the master/whatever. Generally, the memory/performance penalties associated with this scenario do not pose a problem.

    The way I do it is as follows:

    * Set dev variables passed to the modules to 0:0:0 in define_variable section
    * Assign real devs to them at runtime if the module is to be made active
    * Have a timeline in the module which triggers a rebuild_event() and any necessary online event code when the value of the dev variables change. The rebuild_event() statement is critical to force the module to see events which occur on the devices passed into the module as parameters after changing their value.

    Won't work with AMX modules obviously, as I doubt they support this form of dynamic assignment for the module vdev. You may be able to assign a real vdev to them and just update the physical device at runtime and do a send_command 'REINIT', but I don't use AMX modules on the whole and haven't tried it...
  • Responses

    All modules I have coded, each has an Initilization virtual command to resetup the port settings.
    I guess my question is once a module is instantiated is it possible for the Data event section to retrigured when assigning a new device?

    Here is an example of what I'm trying to do.

    DEFINE_DEVICE

    dvDisplay = 5001:1:0
    vdvDisplay1 = 33100:1:0
    vdvDisplay2 = 33101:1:0
    vdvDisplay3 = 33102:1:0

    DEFINE_START

    DEFINE_MODULE 'NEC LCD' NEC (vdvDisplay1, dvTP_NecArray, vdvNecInterface)

    DEFINE_MODULE 'LG' LG2 (vdvDisplay2, dvTP_LgArray, vdvLgInterface)

    DEFINE_MODULE 'Philips' PHILIPS (vdvDisplay3, dvTP_PhilipsArray, vdvPhilipsInterface)

    // button event tried within the module the device defined in the module for testing purposes
    IF(button press for NEC)
    { vdvDisplay1= dvDisplay
    SEND_STRING vdvNecInterface, "'INITIALIZE'"
    }


    I tried this inside the module for a test with a rebuild events and it still did not work. The Data Event of the module continued to stay the vdvDisplay1 device.

    I believe Rebuild_events() only updates the button events which would just be the touch panel array, not the actual device.

    The only route I can see if passing the actual port into each module and having a boolean value that essentially disables/enables the entire module. I could atleast send a virtual command to turn on a module or turn it off.
  • jgreer9514 wrote: »
    All modules I have coded, each has an Initilization virtual command to resetup the port settings.
    I guess my question is once a module is instantiated is it possible for the Data event section to retrigured when assigning a new device?

    Here is an example of what I'm trying to do.

    DEFINE_DEVICE

    dvDisplay = 5001:1:0
    vdvDisplay1 = 33100:1:0
    vdvDisplay2 = 33101:1:0
    vdvDisplay3 = 33102:1:0

    DEFINE_START

    DEFINE_MODULE 'NEC LCD' NEC (vdvDisplay1, dvTP_NecArray, vdvNecInterface)

    DEFINE_MODULE 'LG' LG2 (vdvDisplay2, dvTP_LgArray, vdvLgInterface)

    DEFINE_MODULE 'Philips' PHILIPS (vdvDisplay3, dvTP_PhilipsArray, vdvPhilipsInterface)

    // button event tried within the module the device defined in the module for testing purposes
    IF(button press for NEC)
    { vdvDisplay1= dvDisplay
    SEND_STRING vdvNecInterface, "'INITIALIZE'"
    }


    I tried this inside the module for a test with a rebuild events and it still did not work. The Data Event of the module continued to stay the vdvDisplay1 device.

    I believe Rebuild_events() only updates the button events which would just be the touch panel array, not the actual device.

    The only route I can see if passing the actual port into each module and having a boolean value that essentially disables/enables the entire module. I could atleast send a virtual command to turn on a module or turn it off.

    You already defined vdvDisplay1=33100:1:0 in the define_device section. vdvDisplay1 is now not a variable. You should do this

    DEFINE_VARIABLE

    dev vdvDisplay1 , vdvDisplay2 , vdvDisplay3

    DEFINE_START

    vdvDisplay1 = 33100:1:0
    vdvDisplay2 = 33101:1:0
    vdvDisplay3 = 33102:1:0

    Then....

    IF(button press for NEC)
    { vdvDisplay1= dvDisplay
    SEND_STRING vdvNecInterface, "'INITIALIZE'"
    }

    I had hundreds of Elmo Cameras I needed to control but I did not want to use 100's of modules for all of the cameras. So this is how I did it.
  • Seeing same result

    I am still getting an assignment error on the variable but it looks like it is working. I am having a problem with my queue and buffers that is compounding trying to solve this. Save that headache for another day. Turning off the module approach I mentioned earlier is working without impacting the queues. I think I'll pick this up another day.

    DEFINE_DEVICE

    dvDisplay = 5001:1:0
    vdvNoDevice = 33100:1:0

    DEFINE_VARIABLE

    DEV vdvDisplay1, vdvDisplay2, vdvDisplay3


    DEFINE_START

    vdvDisplay1 = vdvNoDevice
    vdvDisplay2 = vdvNoDevice
    vdvDisplay3 = vdvNoDevice

    DEFINE_MODULE 'NEC LCD' NEC (vdvDisplay1, dvTP_NecArray, vdvNecInterface)

    DEFINE_MODULE 'LG' LG2 (vdvDisplay2, dvTP_LgArray, vdvLgInterface)

    DEFINE_MODULE 'Philips' PHILIPS (vdvDisplay3, dvTP_PhilipsArray, vdvPhilipsInterface)

    // button event tried within the module the device defined in the module for testing purposes
    IF(button press for NEC)
    { vdvDisplay1= dvDisplay
    SEND_STRING vdvNecInterface, "'INITIALIZE'"

    In the device notifications I can see the port 5001:1:0 being re-initalized with port speeds. I see the commands being sent out and the response coming back. Just my queue is not picking up the response back, ughhh.... Something is out of sync.
  • AuserAuser Posts: 506
    jgreer9514 wrote: »
    Just my queue is not picking up the response back, ughhh.... Something is out of sync.

    Not sure where your queue operates within your code. Be aware that rebuild_event() operates with limited scope - calling rebuild_event() within a module will not refresh the event table entries for other modules or your main program. You'll need to call rebuild_event() in multiple places if there is more than one portion of the program referencing the device that is being updated.

    This is the general scenario I use within my modules to achieve what you're trying to do (the waits probably aren't necessary in most situations):
    MODULE_NAME='A_Module' (dev dvDynamicDevice_Module, dev dvDynamicDevice_Physical, integer nOtherStuff[])
    (***********************************************************)
    (*               CONSTANT DEFINITIONS GO BELOW             *)
    (***********************************************************)
    DEFINE_CONSTANT
    #IF_NOT_DEFINED TL_MODULE_DYNAMIC_ALLOCATION
    	#DEFINE TL_MODULE_DYNAMIC_ALLOCATION 993
    #END_IF
    
    long			TL_MODULE_DYNAMIC_ALLOCATION_DATA[]		= { 5000 }
    
    (***********************************************************)
    (*               VARIABLE DEFINITIONS GO BELOW             *)
    (***********************************************************)
    DEFINE_VARIABLE
    volatile		dev				dvCurrentDevice_Module
    volatile		dev				dvCurrentDevice_Physical
    
    (***********************************************************)
    (*                STARTUP CODE GOES BELOW                  *)
    (***********************************************************)
    DEFINE_START
    timeline_create(TL_MODULE_DYNAMIC_ALLOCATION, TL_MODULE_DYNAMIC_ALLOCATION_DATA, 1, TIMELINE_ABSOLUTE, TIMELINE_REPEAT)
    timeline_restart(TL_MODULE_DYNAMIC_ALLOCATION)
    
    (***********************************************************)
    (*        SUBROUTINE/FUNCTION DEFINITIONS GO BELOW         *)
    (***********************************************************)
    define_function Module_SetInterfaceDevice(dev _dvDevice)
    {
    	dvCurrentDevice_Module = _dvDevice
    }
    
    define_function Module_SetPhysicalDevice(dev _dvDevice)
    {
    	dvCurrentDevice_Physical = _dvDevice
    }
    
    (***********************************************************)
    (*                THE EVENTS GO BELOW                      *)
    (***********************************************************)
    DEFINE_EVENT
    timeline_event[TL_MODULE_DYNAMIC_ALLOCATION]
    {
    	if(dvDynamicDevice_Module <> dvCurrentDevice_Module)
    	{
    		wait 10
    		{
    			Module_SetInterfaceDevice(dvDynamicDevice_Module)
    			//LogDebug('ModuleDynamicAllocation', "'Rebuilding event table, module device now [', DevToString(dvCurrentDevice_Module), ']'", DEBUG_NONE)
    			rebuild_event()
    		}
    	}
    	if(dvDynamicDevice_Physical <> dvCurrentDevice_Physical)
    	{
    		wait 10
    		{
    			Module_SetPhysicalDevice(dvDynamicDevice_Physical)
    			//LogDebug('ModuleDynamicAllocation', "'Rebuilding event table, physical device now [', DevToString(dvCurrentDevice_Physical), ']'", DEBUG_NONE)
    			rebuild_event()
    		}
    	}
    	if((dvCurrentDevice_Module <> 0:0:0) && (dvCurrentDevice_Physical <> 0:0:0))
    		timeline_kill(TL_MODULE_DYNAMIC_ALLOCATION)
    }
    (***********************************************************)
    (*                      END OF FILE                        *)
    (***********************************************************)
    
  • DHawthorneDHawthorne Posts: 4,584
    Personally, I'd make an array out of the devices and let the module initialize all of them, then set a variable in code as to which you are talking to at the moment. No reboots, no combines, no fuss. This assumes you have access to the module code; if not, you have to try the other solutions suggested.
  • Define_Start

    Just a thought about why I wasn't getting any feedback. I am using Create_Buffer under the define start of the module and use the buffer to tie what was sent/received. By using the INITIALIZE virtual command I cannot re-create the buffers to the new devices. Have you had this problem?
  • AuserAuser Posts: 506
    jgreer9514 wrote: »
    Just a thought about why I wasn't getting any feedback. I am using Create_Buffer under the define start of the module and use the buffer to tie what was sent/received. By using the INITIALIZE virtual command I cannot re-create the buffers to the new devices. Have you had this problem?

    That rings bells :D I just rewrote my feedback parsing routine to provide the functionality of the master managed buffer to get around it. I assume I'm paying a performance penalty, but it hasn't been an issue so far.
Sign In or Register to comment.