Home AMX User Forum NetLinx Studio

Where is an error?

Hello all, i'm trying to program a function which will turn lights on, smoothly, during specified period of time. The function has two parameters - the first (max_bright) is level of brightness, which must be achieved, and the second parameter (max_time) is time, in 1/10 parts of seconds. My code now looks like this (the whole source file included in .zip archive):
define_function light_on(max_bright,max_time){
    local_var long start_time   //time when we start increasing the brightness
    local_var char start_bright //our brightness before any changes
    local_var long temp_level   //temporary variable of type 'long', which will store brightness
    local_var long delta_bright  //the difference between current brightness and max_bright
    local_var long delta_time    //time, which passed since we began to change brightness
    start_time = get_timer //set starting time
    start_bright = bright_current //set starting brightness
    delta_bright = max_bright - start_bright //difference that should be eliminated
    temp_level = bright_current //
   //Now questions begin
   //what is the right condition for finishing loop??!
   //while((abs_value(bright_current - max_bright))>10){
   //while((get_timer - start_time) < max_time){
   while (bright_current < max_bright) //bright_current is global variable
   {
	    delta_time = get_timer - start_time
//now let's increase the brightness
	    temp_level = start_bright + delta_bright/max_time * delta_time
//simple check to avoid overflow
	    if (temp_level <= max_bright) 
		bright_current = temp_level 
	    else bright_current = max_bright //are these statements ok?
	    SEND_LEVEL LIGHT,6,bright_current //update light control
	    SEND_LEVEL TP,8,bright_current //update bargraph
    } //end while
    SEND_COMMAND TP,"'!T',3,'99'" //just a string for debugging
    return 
}
I'm a beginner in NetLinx programming, and i need your advice... What's wrong with this function? It's buggy. It works only one or two times, and then, when i try to use it, NetLinx master just hangs up.
Does Radia lighting system (rdd-dm6) have any tricks to do the same thing by only hardware means? Where can i get more help on programming with NetLinx language, maybe some examples?

----
sorry for my english. my $native_language = $perl

Comments

  • I would definately stay away from using get_timer for these kind of operations. And if you must then use set_timer (0) to reset it everytime you set your start-time.
    Now i personally don't know much about Radia systems but the Lightec systems we use a lot here in the Netherlands support ramping values. The string for this dimmer looks like "<channel>,<level>,<ramp-time>"

    I bet that the Radia system uses something similar.

    Furthermore i would use LEVEL_EVENTs to control lighting.
  • veraviewveraview Posts: 44
    Your WHILE loop is exiting by default after 0.5 seconds, which is done to prevent uncontrolled ramping of levels. Since you're trying to ramp a level, try a LONG_WHILE, which doesn't time out.

    The Radia has all of the preset functionality with levels and feedback channels built-in, so you may be reinventing the wheel here...the radia does cool things like track levels for you, allow you to ramp presets, etc.

    Its all in the document http://www.amx.com/techdocs/0432283.pdf , which documents all of the channels, levels, and send_commands you will need.
  • veraview wrote:
    Your WHILE loop is exiting by default after 0.5 seconds, which is done to prevent uncontrolled ramping of levels. Since you're trying to ramp a level, try a LONG_WHILE, which doesn't time out.

    In NetLinx, a WHILE will NOT timeout!!!
    Any WHILE, MEDIUM_WHILE, and LONG_WHILE will work like a MEDIUM_WHILE (no timeout, no bus handling). If a WHILE condition is always true, you may run into an endless loop, resulting in a master lockup.

    Because of this, in most WHILE operations I'll track the number of loops run thru the WHILE, to eventually make the condition false manually.

    I've not checked the example code, but this may be a cause.
  • frthomasfrthomas Posts: 176
    I would definately stay away from using get_timer for these kind of operations. And if you must then use set_timer (0) to reset it everytime you set your start-time.

    You mean because of the wrap up after so many months?
  • frthomasfrthomas Posts: 176
    Ilya wrote:
    It works only one or two times, and then, when i try to use it, NetLinx master just hangs up.

    When it hangs up, can you get to the web interface of the master, connect to it with studio and that sort of things? If yes, then the master is not hung, your program is, for example as mentioned in a WHILE loops that never ends for some reason. If no, then your program has pretty much confused the master.

    Apparently Radia can perform this for you, so you do not need to code this function any longer. Nevertheless, from the perspective of learning Netlinx, I have the following comments on the routine:
    - It should work in principle
    - For the question about the while condition, the answer should be the business motive and constraints: if you are programming for a stage, say, where timing is the key, then stop when the time is up. If your programming ramping for interior lightning mood, then use the brightness; now one will come to you and complain it took 11 seconds instead of 10 to reach the desired brightness. Your master may be called upon to perform other more important tasks while ramping (responding to button presses, say), and that could (and should IMHO) delay the ramping.
    - The problem with your code is that as mentioned, the master will not do anything else than loop in your while statement for the entire duration of the ramp. In a tick (the interval of time of GET_TIMER), the master will loop at least 10 or 20 times through the loop, resulting in nothing concrete since the desired step brightness calculation yields the same result each time since GET_TIMER has not changed. This has two consequences:
    -- As mentioned above, the master will not handle any other event while ramping. This may or may not be an issue.
    -- The SEND_COMMANDs to Radia do a number of behind the scenes things like actually sending data to the controller. In your case you are piling up messages (since the master has no way of knowing you keep on repeating the same one) in the queue. And the server may hang up for that reason (the test above would tell you if your loop or messaging is the culprit).

    What you'd probably do in Perl is insert a sleep statement somewhere in the loop. There is no equivalent statement in Netlinx but you could simulate it using a while loop that waits on GET_TIMER to change by N ticks or something.
    Doing this would probably fix the SEND_COMMAND issue if there is one, by only sending something when there something new to send. But your master would still do nothing else.

    TIMELINEs are the most likely Netlinx "correct" native solution to implement ramping. You can define a timeline to trigger an event every N millisecond. What your routine would do is calculate stuff for the ramp (how often to increase the level by which amount for how long), program the timeline then fire it off. In the TIMELINE_EVENT, you would put the equivalent of the WHILE loop content. In between TIMELINE_EVENTs, the master is ready to handle other events.

    Like "simple" Perl, Netlinx is essentially single threaded.

    HTH

    Fred
  • veraviewveraview Posts: 44
    I knew I was going to screw myself up programming that Axcent 3 last week, Netlinx WHILE loops do indeed never timeout. I knew that. Really. However, because netlinx code is processed in multiple threads, WHILE loops no longer time out because bus updates are handled in a different thread, so why would the master lock up due to one that never exits?

    Tom
  • frthomasfrthomas Posts: 176
    There is a thread "How Netlinx Really Works" that you may want to search and read to learn all of the details, but in short, your Netlinx program is single threaded. The Netlinx master is multithreaded, but your program runs in a single of its threads. A WHILE loop that never ends locks your program (no events are handled), but not the master (web access, f.e., still works).

    Fred
  • Thank you all for answers, i'll try to use a document about PROlink/AXlink lighting, by veraview )) I was in hope that something like this should exist, but i thought that i have all available documentation about lighting systems. I think, this was my main error)
Sign In or Register to comment.