New to Programming
RlxdN10sity
Posts: 10
*First post, glad to be here! I'm excited to learn from you and look forward to interacting with everyone!
I have never programmed anything aside from a few page flipping Pronto remotes. I am learning to program with Netlinx by watching online videos on Harman University.
Apparently some of the information there is outdated.
The thing I'm trying to implement now is feedback that references variables.
The videos I have seen all instruct feedback statements to be placed in the "Define_Program" section. I've found information contradicting that in the NX-3200 documentation that I'm actually working with.
Here is the feedback I want to use:
[dvTP_SOURCEio,21] = nAUDIOSW_OutStatus
[dvTP_SOURCEio,11] = nAUDIOSW_Out1
[dvTP_SOURCEio,1] = nAUDIOSW_Out1
Since it is advised against placing these lines in the "Define_Program" section, where do I put them?
The research I've done is pointing me in the direction of creating a Timeline Event of some sort but I have not been able to figure out how to create one that applies, or if that is even the best approach.
I'm not asking anyone to do this for me. I need to learn and understand this myself, I just don't seem to have been able to find the proper reference material to learn about this. Thank you for your time and any guidance you may provide.
I have never programmed anything aside from a few page flipping Pronto remotes. I am learning to program with Netlinx by watching online videos on Harman University.
Apparently some of the information there is outdated.
The thing I'm trying to implement now is feedback that references variables.
The videos I have seen all instruct feedback statements to be placed in the "Define_Program" section. I've found information contradicting that in the NX-3200 documentation that I'm actually working with.
Here is the feedback I want to use:
[dvTP_SOURCEio,21] = nAUDIOSW_OutStatus
[dvTP_SOURCEio,11] = nAUDIOSW_Out1
[dvTP_SOURCEio,1] = nAUDIOSW_Out1
Since it is advised against placing these lines in the "Define_Program" section, where do I put them?
The research I've done is pointing me in the direction of creating a Timeline Event of some sort but I have not been able to figure out how to create one that applies, or if that is even the best approach.
I'm not asking anyone to do this for me. I need to learn and understand this myself, I just don't seem to have been able to find the proper reference material to learn about this. Thank you for your time and any guidance you may provide.
0
Comments
The "Define_Program" section was being used on the previous masters series but for the new NX ones is not suggested. Instead, you have to make a timeline which will being fired every some seconds ( e.g. 1 second ).
The timeline event will have the code being executed every that time (1sec). In your case, the code will be the feedback. Something like :
timeline_event[TL]
{
switch (timeline.sequence)
{
case 1 :
{
[dvTP_SOURCEio,21] = nAUDIOSW_OutStatus
[dvTP_SOURCEio,11] = nAUDIOSW_Out1
[dvTP_SOURCEio,1] = nAUDIOSW_Out1
}
}
}
I appreciate you helping me. Forgive my ignorance, but I literally have zero programming experience and my only references are what I can look up in the NS help files and the Harman University videos that have not yet mentioned this aspect of programming.
I've watched all of the CP131 lessons and many others. Unfortunately this just hasn't been covered.
From what you wrote, I see that it is an event so I would write this in the "Define_Event" section.
How do I define the timeline duration? Should it repeat or should I trigger it with a button event relevant to the feedback in the timeline?
timeline_event[TL] // What goes in the [TL] brackets? The device? [dvTP_SOURCEio] ? The defined timeline [TLfeedback]?
{
switch (timeline.sequence) // Is "switch" a conditional like an "if/else" ? What is the (timeline.sequence)? Do I define this somewhere? Is it a command?
{
case 1 : // Is this a condition? Do I define case 1? Is case one the lines that follow it?
{
[dvTP_SOURCEio,21] = nAUDIOSW_OutStatus
[dvTP_SOURCEio,11] = nAUDIOSW_Out1
[dvTP_SOURCEio,1] = nAUDIOSW_Out1
}
}
}
Firstly: Welcome to the forum. Secondly, I would highly recommend that you take the classes offered by AMX/Harman/Samsung. They cover a lot of these details and plus, you get certified in the process. Your boss (who is an AMX dealer I assume) can get you there for the classes with no cost other than your travel and hotel. Also, many of them are now done remotely right from the comgort of your laptoop.
So to your question.
I timeline is created, started, paused, stopped(killed) via a set of keyword/functions like timeline_create() timeline_kill(), et...
The arguments in the timeline_Create() are:
Timeline_Create(
<a unique constant LONG value>,
<a LONG integer array which denotes the various timed steps>,
,< a value for whether the time slots are absolute based upon the values in the arrar, or built relatively based upon the value of each cell from the previous>,
< is the timeoline "one shot" or "repeating"> )
there are built-in keywords for the last two: timeline_absolute / timeline_relative and timline_once / timeline_repeat.
You have to declare your own Timeline IDs. I tend to format the constants like this:
define_constant
long TL_MyTImline_01= 1;
Then for the timing array
define_variable
volatile long TL_MyTimeline_Times[]={1,2000,4000};
so, in this cawse the timeline has three event sequences. They occur at tick 1 (essentially at the start), tick 2000 (2 seonds after the first sequence, and tick 4000 which is 4 seconds after the start.
You basically call the Timeline_Create() whenever you want to start the timeline running and do a timeline_kill() when you're done. You can also pause, resume and so forth. You can even dynamically change the timings in the long array prior to starting the timeline to adjust when things happen on the fly.
Hope that helps. And do get your boss to get you to those classes. You can thank me later.
Another way to update the state of the button would be to just drop the state code right below where you update the variable value.
The problem with doing it this way, and the reason people use the timeline, is because doing the timeline method requires a single instance of the feedback code in the timeline to make it work for any updates to the variable anywhere in your code, so it makes the code easier to manage. This is because every time the timeline fires the gui will get all the current variable status.
So how do you do this?
A few things need to happen: you will need to define some constants/variables, you will have to define a timeline event, and you will have to create the timeline.
Every timeline needs an ID to reference it by and this is best handled by defining a constant to use as the timeline ID. Every timeline also needs to know how long to run for before it fires it's event. There may be reasons to define the times as variables, as opposed to constants, but for this timeline a constant will be fine.
Next is defining the timeline event.
With that done all you have to do now is turn the thing on. Since this is emulating the mainline, you will want it to run continually, and you will need it to start every time the processor boots.
That's it. Now anytime in code that you update the value of nPage, [dvTP,1] will also update within 0.35 seconds.
I definitely agree on this point. I never use a repeating TL to do feedback. If you think about it - the only two times you need to do any feedback changes are 1) when something changes and 2) when a panel comes online or goes to a page/popup with feedback for the first time.
So for me I just watch for those two things and update feedback only then. There is just no need to loop around
the way I organize my feedback is I'll track all states in status vars. Those get updated when something changes on the device. immediately after the change has occured, the status var is updated, I then call the feedback .
Feeddback functions are 1) fn_Update_Whatefver_fb(tp_id) and then 2) fn_Update_Whatefer_fb_All();
the first function is really only called when the TP comes online or that specific page/popup is called firrst time after the TP comes online. Then the _aa() function just has a loop for all the UIs in the UI array. It cycles through each UI looking to see if it's online or not. If so, send the FB uipdate. It's very clean and low-bulk.
Thank you Tony and Eric for the amazing step by step, kid gloves breakdown on how this is accomplished.
Thank you Chris for pointing out Lesson Section 9. I feel like I just kinda got busted by the principle cheating on my homework. I thought I had studied all the CP131 videos minus a couple exercises. There are still about 15 I haven't watched including 3 lessons and 2 exercises concerning Timelines. Can't believe I didn't see that. Sometimes I get ahead of myself.
I'll be diligently studying Lesson 9 and your step by step instructions in this post today until I have a working knowledge on this aspect of programming.
Thank you all!
Yea, I really only use the "mainline timeline" for scheduled events and do all my feedback actions only when they need to happen.
But this method is perfectly acceptable and I would suspect is the dominate one in use among AMX programmers.
I notice that in Tony's "Timeline_Create", in the 3rd parameter he used a 1 to indicate the number of times provided in the array. In lesson 9 it was stated that using keyword
"length_array"
was "a better method".
This violated all my senses of efficiency and intuition but I wrote it as shown in the lesson instead of just placing a 1 there.
As you may have guessed, I'm not a savvy forum poster so I'm unaware of how to post code in the grey boxes with a slide bar. So I edited together some screen shots and uploaded the file.
Here are shots of my Timeline:
I expect I will prefer to run this at shorter intervals than once per second. Something more like the 350 ms Tony recommended.
I'll post an upload of the button events and feedback statements in the timeline_event next. Thank you!
Can I reference a variable in an if/else conditional as anything other than a 1 or 0 as I have in these button events?
Can I control more than 1 channel in a feedback statement by separating with a comma as I did in these feedback statements?
Will this work as I intend or is there some noob fail in this code?
I tried to convey my intentions with each line in the commented out text next to each line.
The reason to use length_array(My_Timing_Long_Array) has more to do with the larger goal of writing code that is more virtualized as opposed to 'hard coded" What I mean by this is (taking the example of the length_array) it's better to write your code in such a way that scaling it to allow for changes in size or scope is easy and less prone to 'gotchas' and errors.
so, follow me down this rabbit hole as I tell the story.
So, you're writing a timeline routine where you want three things to happen (say a projector On sequence) You know that you need three things to happen: Power On command, Input Select Command, and Aspect Ratio command.
so you set up your timeline to do three steps in the proper amount of time to send each command when you want.
You set up your timing array something like
so you'd write your timeine_create as follows.
Okay fine, everything works. But a month later you realize you also need to send that annoying Eco Power Saver Feature Off so the dumb thing doesn't ignore your power on command to save the planet. No big deal. You just add another cell to the timeing array and put the new forth command in the timeline, right?
But then you forget to run over to your timeline and change the "3" to a "4"
It compiles just fine. And you spend the next hour trying to figure out why the stupid thing never fires the fourth command.
But, if you always try to virtualize your code, you don't have to worry about changing the size or scope of your timeline. By rewriting your timeline_create to
you can tweak or change the timeline size all you want and it will always work.
In fact you should always take this approach in all your code. The trick is to catch yourself in the act. Any time you find yourself entering in a hard number for something - don't.
esamples:
button_event[TP,3]
send_level TV,1,MyVolume
channel_event[vdvDevice,199]
change those numbers into constants that can be altered later if need be without breaking your code. You might think you can easily remember all these hard-coded numbers but trust me - later when you've written tens of thousands of lines of code, you'll forget where you did a lot of that.
In addition, the same thing can be practiced for devices and functions.
if you find yoruself writing
button_event[TP,My_Power_Off_button]
You're only writing code for one touch panel. so, say you've written an entire system and the client loves it. they love it so much they want to add a second touch panel. Now you're stuck going through and fixing all these single button events to include the new panel.
I always write my code with device arrays, especially for touch panels. (Even when I know there's only one panel)
this way, if the client adds another touch panel later, or even 20 panels, your code automatically grows with it without changing one line.
That's a lot of discussion over one simple item, but I think understanding the 'why' behind it helps make better sense of why we use it. It's all about making your code easily scaleable.
But as a rule, any time you use some arbitrary number somewhere in your code, like the 1 in the timeline_create, you should ask yourself "will this number ever change?" and if it might, you should not hardcode it but use a variable or function instead.
I also feel like the way the my mind works that Derricks counterpoint is something I can relate too.
I certainly intend to follow the lesson advise for now. I know I don't know nearly enough about this to decide what to represent with a constant and when its all the same to just use the number. I suppose everyone has a nuanced style of coding with experience and time within a given programming language.
Am I to assume that there is nothing blatantly wrong with the code I've written for button events, feedback and timeline that I posted since there is no comment from you guys addressing what I wrote or how it is written?
Thank you all for your insight and help!
Edit - I've been thinking about the code I posted screenshots of and am anxious to get feedback from you. It occurs to me that my feedback statements may not work the way I have written them with the intention of turning on or off multiple channels in the same statement. I'm thinking those channels may need to be an array to get the result I was going for.
Short of making them into an array I could just write a separate statement for each channel
Am I on the right track here, or would it have worked the way I wrote them previously?
Thank you again.
PS - figured out the grey box
I deleted my posts to honor your wishes to delete your post.