turning on relays in startup code
fogled@mizzou
Posts: 549
I've got an NI-3100 that won't turn on a relay during startup code. If I put a command to start up the relay:
on[dvRelays,1]
...into the startup code stack, it does not turn the relay on and, in fact, won't execute any other statements after that statement. If I make this my last statment in the startup code stack, at least the rest of the initialization works OK, but it still won't execute the relay on command.
There's got to be a way to get a relay turned on at system startup, I just don't know the trick. Can someone point me in the right direction?
Thanks,
on[dvRelays,1]
...into the startup code stack, it does not turn the relay on and, in fact, won't execute any other statements after that statement. If I make this my last statment in the startup code stack, at least the rest of the initialization works OK, but it still won't execute the relay on command.
There's got to be a way to get a relay turned on at system startup, I just don't know the trick. Can someone point me in the right direction?
Thanks,
0
Comments
Data_Event[dvRELAYS]
{
ONLINE:
{
ON[dvRELAY,1]
}
}
Mostly because I'm fairly new to AMX programming, and I don't know any better. ;-)
Thanks for the tip - I'll give it a whirl and confirm the fix to the forum.
These devices are very likely NOT to be online at the time startup code runs and the command will be missed.
You could try and create a wait to cover this 'device coming online' period....but this is basically exactly what the online_event is all about!
:-)
Using the online_event will ensure your command is issued only when the dev is online and not before.
Very good practice to do it for all devices actually.
If you need to configure a device at startup, you put it in a ONLINE event of the device.
If you need to initialize a variable at startup, you put it in a ONLINE on master of system.
My 2 cents tip of the day
Vinc
The point is good and well made but if you use table-driven logic you still need to populate the tables some time and define_start is the right place to call your Initialisation function.
I guess I should explain table-driven coding; I find I use it more and more. My latest project has dozens of tables in the mainline describing the rooms, the devices, etc and typically one table in each device module - for the commands that drive the device.
Use a table whenever you have repetitive information, and there tends to be a LOT of that in AV control systems code. For serial commands that might be the command string, the description of the command (for debugging purposes), the time to wait for the command to be executed, and the enumerated value of the state it will be in afterwards. Or whatever.
The idea is that instead of writing lots of code to say what happens in each logical variation of whatever, you should create a table of information with flags saying what to do, and some code that consults the table instead of laboriously doing those things for each enumerated case.
The key advantage is that the "doing what needs doing" code is written only once in one place (the code that interprets the table) and the "list of what needs doing" is listed in only one place (the code that populates the table.) It is particularly valuable when you suspect or expect that the rules might change later, or the code might be expected to drive more than one device, or the behaviour rules may be different in different rooms, or whatever.
But to get to the point, the direct benefit is that code that looks like it works is much more likely to work in all cases than it would if the code laboriously spelled every case out one by one.
What's a table? It's an array of structures. When you create a new table you need:
define_constant
<The enumerated instances in the array eg CommandPowerOn = 1, etc>
<The constant that says how many commands you will have in the array>
define_type
<The struct that describes the commands>
define_variable
<The array of structs>
define_function <The function to populate one command in the array>
define_start
<The function calls to populate the array>
No, you still need it for CREATE_BUFFER, and CREATE_LEVEL. I've also used it to populate data structures in modules (apply parameter data to an internal structure since you can't pass structures as a parameter). So it's not quite obsolete yet.
You don't need CREATE_BUFFER anymore though some say there is an efficiency advantage. Don't need CREATE_LEVEL either. I haven't used either in several years (except for the odd Axcent program). I find DEFINE_START useful on occasion, but not a lot. If it were no longer available, I'd get by.
But, it's all a matter of preference, I'd say. If you try, you can probably find a way to do just about everything without resort to DEFINE_START, but there's surely nothing wrong with it if it's convenient and the pitfalls are kept in mind.
There is no other way to "read" the value of a level that is defined in a module (especially when you don't have the axs, but only a compiled tko) except for DEFINE_LEVEL. I admit, sometimesf it is just programming style, so I'm certainly not going to argue that there aren't other ways to do it. Just trying to say they do have their uses, and if you do use them that way, you have to put it in DEFINE_START.
Is this the same as create_buffer in define start?
Data_Event[RS_232]
{
String:
{
buffer="buffer,data.text"
}
}
Here is the output when button 1 is pushed 3 times. It should grow by 750 bytes each time. Notice that the length never grows past 15999
Line 1 :: Sending cArray2 - 12:37:40
Line 2 :: Length of cBuffer = 15750 - 12:37:40
Line 3 :: Sending cArray2 - 12:37:43
Line 4 :: Length of cBuffer = 15999 - 12:37:43
Line 5 :: Sending cArray2 - 12:37:44
Line 6 :: Length of cBuffer = 15999 - 12:37:44
So that being the case I believe you can?t do without CREATE_BUFFER and if we need CREATE_BUFFER then we can?t do without DEFINE_START since that?s the only place that CREATE_BUFFER can go. That?s my story and I?m sticking to it.