Button_event and array definition question
alan.heric
Posts: 18
Hello all,
i think i heard about this when i was on programer 1 course but cant recall how it went
Anyhow the idea is to either fill array from 1-600, but i dont want 2 type numbers from 1 to 600...
integer some_array[]={1,....,600}
and then do
BUTTON_EVENT[devTp,some_array]
{
PUSH:
{
// something
}
}
OR
do 600 button events ...
BUTTON_EVENT[devTp,1]
... // and then type it fot 599 times :P
BUTTON_EVENT[devTp,600]
{
PUSH:
{
/// something
}
}
So... is there a way to fill the array from 1 to 600?
Or as i have it in my memory 2 make the button_event from 1 to 600 in 3 lines of code:
BUTTON_EVENT[devTP,1]
// some code or something.!?!?!
BUTTON_EVENT[devTP,600]
{
PUSH ...
}
Hope my question is understandable.
Tnx,
Alan
i think i heard about this when i was on programer 1 course but cant recall how it went
Anyhow the idea is to either fill array from 1-600, but i dont want 2 type numbers from 1 to 600...
integer some_array[]={1,....,600}
and then do
BUTTON_EVENT[devTp,some_array]
{
PUSH:
{
// something
}
}
OR
do 600 button events ...
BUTTON_EVENT[devTp,1]
... // and then type it fot 599 times :P
BUTTON_EVENT[devTp,600]
{
PUSH:
{
/// something
}
}
So... is there a way to fill the array from 1 to 600?
Or as i have it in my memory 2 make the button_event from 1 to 600 in 3 lines of code:
BUTTON_EVENT[devTP,1]
// some code or something.!?!?!
BUTTON_EVENT[devTP,600]
{
PUSH ...
}
Hope my question is understandable.
Tnx,
Alan
0
Comments
So forget the array, use what ever numbers you want on your buttons and create a single button event: In your PUSH, HOLD and/or RELEASE handlers you then just use BUTTON.INPUT.CHANNEL instead of GET_LAST to determine the button channel that caused the event.
Of course if you're hell bent on using the array, then define it with it's desired size and then in define_start run a for loop using the defined length and populate each index position with the index value.
I remember our tutor at Programer1 course mentioned a command in case we have a situation like this and we want to avoid having loads of BUTTON_EVENT code.
For example:
This code: would look like:
the two dots in the second part of the code is what im looking for.
i know in this case i have only 10 BUTTON_EVENT but this is just an example. Im talking here about 64 or more BUTTON_EVENTs...and also i know i can sort this out by making an array with 64 number in and then doing this:
i really wanna know if im imagining that those two dots have a replacement code or what?
tnx
Don't forget to do a REBUILD_EVENT after changing that array otherwise your BUTTON_EVENT won't work.
One would think that issuing a REBUILD_EVNET for such-and-so device will only rebuild that event. but that is not what happens. If you issue it, the master will rebuild all events i the code. This can take significantly longer a process that you might imagine. It's just about as long as a reboot. I do not use this command as the benefit does not outweigh the negatives.
never ever had this probem
If it wouldn't work is that becuase the working length of the array at complile time is 0, max length would be as defined, or does it need the values in the array in the table building. If it's the latter then you wouldn't be able to dynamically alter the array at runtime with out calling the rebuild event either.
Like e. said rebuild_event takes a fair amount of time. Last time I tested it took over 30 seconds during which time events are not processed so it's not so bad if it's part of the start up routine cuz that just means it will take a bit longer but at runtime you affectively halt events from being processed for around 30+ seconds so it should be used with caution.
I believe the ".." doesn't work anywhere else.
Eric: The Reference states "REBUILD_EVENT() works on a module-by-module basis (i.e. calling the function in one module does not affect the event table of another module)." Have you found that calling a REBUILD_EVENT inside a module causes the same delay, or are you only calling it in the main program?
#1 is the case:
I know I would have come across this issue at some point and I'm pretty sure I've populated button arrays in def_start before with out the rebuild.
result: Pushing the button using emulate device using the virtual vTest's DPS
No rebuild required.
Here's the whole program I ran. The only difference is the addition of PROGRAM_NAME, DEFINE_DEVICE for vTEST, DEFINE_EVENT before the BUTTON_EVENT, and a "}" to close the BUTTON_EVENT:
Also, here's what the Language Reference guide says about the event table:
This basically would work exactly as desired but not as expected and the only real difference is the button_event isn't filtering so that only channels in the array will trigger the push. Any channel on that port will trigger the push handler but only channels that are in the array will return an index number when using get_last, otherwise nBtn would == 0.
My first thoughts go to DEVICE HOLDOFF:
I doubt DEVICE HOLDOFF has any direct effect on building the event table, but the explanation leads me to wonder if each device reports ONLINE as it's portion of the event table is built. If so, a particularly large program with a large event table may allow a DEFINE_START to run that initializes a variable before its associated portion of the event table is built.
If you get a chance I'd love to find out what results you get if you only run the minimal code I posted. If not, what processor, firmware, and version of NetLinx Studio are you running?
I don't want to beat this to death, but when code run by one person runs differently for another, it throws up a big red flag. Those sort of bugs are the ones that have you up at midnight incapable of reproducing the problem or writing some unnecessary "fix".
Running this small code as requested with some slight modifications for added analysis: Where I'm using Which I thought would be built as I get nothing on any pushes. I even added a non_volatile var just so the system had one since that used to matter and still nothing. Not what I expected at all.
So I actually changed the button event to compiled and sent and now pushes work just like the catch all should so the previous method isn't resolving to 0 "catch all". What I didn't expect is that GET_LAST doesn't work. so GET_LAST must be tied to the event table and since there is no array built into the table it doesn't work. Everything I thought in my last post is wrong which goes back to your question of why it worked in my larger system's code. I don't use the hold-off command anywhere, ever, so this is a bit of a puzzle.
The system starts up so fast I can't get diagnostics to run in time to see the send string 0's I have in define start but in debug I can see the arrays have been populated.
This is not what I expected to see!
Why did it work differently in a large file than it did in the small file.
Why if the array isn't defined until after the table was built didn't it resolve to 0 "catch all" when built since when built the array lenght would have been 0. An un-initialized var would have initialized the event table with 0, catching all. Does an un-initialized array differ in the way the table is built. Does it cause an error so the table isn't built or built with out the ability to catch any channels since the array wasn't defined, if so why didn't it default to 0 and catch all? And most curiously why did it work in the large file and not the small?
Now I can catch the send_string 0' in def start again. Out of curiosity I tried: with very odd results. The channels pushed would be filtered by these 2 arrays so anything that is not in either array doesn't get through but get_last results are a bit odd. it seems if the channel doesn't match anything in the array it returns the last known match to the specific array. I tried this out of curiosity (using 2 arrays), don't know why anyone would want to do this but I tried anyway. This is obviously attributable to having 2 arrays defined in the event_table and otherwise get_last would work properly since channels that didn't match the array wouldn't get through in the first place.
So back on point, it seems on a large system there is some sort of delay or ......... ya know, I bet somewhere in my code in this big file I'm using rebuild_event somewhere else and it must be rebuilding all the tables like e. originally said. Maybe NJ's original assumption that it is limited to scope it true in a module but not if it's in the main or any include. I thought the instructions for it said it only affected the event tables related to items with in the braces where it's called so maybe this isn't exactly the case. I'm pretty sure any time I use it it's properly braced and isolated, usually after set_virual_ports or channels, etc.
So I gonna assume it works in the big file because of a rebuild_event called elsewhere in the main or includes and that an un-defined array that's not later intialized and rebuilt will not work and will not default to 0 catch all like would be the case with a regular var that's not defined. Now I need to verify I actually do have a rebuild_event some where in this code ro it's back to the drawing board.
I've messed around with some test code and your assumptions seem to be correct with what I've found.
1. An array length of 0 equaled no events.
2. REBUILD_EVENT only affected the module it was called in.
3. ALL events were rebuilt regardless of scope or which array was just modified. As long as an array had a SET_LENGTH > 0, it's event table was rebuilt.