More stupid questions (I'm learning!)
dmurray14
Posts: 80
Hey guys,
I've made some progress with learning my AMX system and NetLinx. I've successfully created a web panel and am able to turn on and off my projector through serial. I know, real impressive, right? Anyway, still a lot left to do. I would like to hook up some IR devices, as well as figure out netlinx modules. Some concerns:
Sorry to be so long-winded. I'm sure these are some stupid questions to some of you long-time programmers, but I'm just learning as I go - so any help is much appreciated.
Thanks in advance!
Dan
I've made some progress with learning my AMX system and NetLinx. I've successfully created a web panel and am able to turn on and off my projector through serial. I know, real impressive, right? Anyway, still a lot left to do. I would like to hook up some IR devices, as well as figure out netlinx modules. Some concerns:
- Code Methods - Right now I have just one main source file. I've defined my projector on the serial port on the NXI. Then, under button events, I have something like the following:
BUTTON_EVENT[TP1,1] { PUSH: { TO[TP1,1] SEND_STRING PROJ, "'C00',$0D,$0A" } RELEASE: { } HOLD[5,REPEAT]: { } }
This is being triggered by button "1" on my web panel. I have one of these blocks of code for each button on my only touch panel. This doesn't seem like the right way to do it though - I feel like I should be defining the buttons for various devices, then referring to them in a more user friendly way (like SEND_STRING PROJ,"poweron") or something - but I don't know how to do this. It just doesn't seem like I should be writing code for each button, especially when a few buttons are likely to do the same things. What is the correct way? - IRL Files - How do I use them? I've found quite a few for my devices, but I'm not exactly sure what to do with them, nor how to use the commands from my program.
- NetLinx Modules - Again, found one for a one of my devices. How do I implement these?
Sorry to be so long-winded. I'm sure these are some stupid questions to some of you long-time programmers, but I'm just learning as I go - so any help is much appreciated.
Thanks in advance!
Dan
0
Comments
char powerCommand[] = "'C00',$0D,$0A" in the variable section.
you don't need the "to" command, from what I undestand its good only when you are listen to mulitple devices and want to pass it to a specific one.
About IRL, its very simple.
Add it to your project to IR (note that if its read only you will get error while uploading)
Then map it (right click) to the device that you have declared in the source ( same as you did for the pojector)
upload it and thats all from the project side.
to use it, open the irl file with IREdit and look on the command numbers.
if power on is command 1, all you need to do is to send a pulse command to the device like this:
pulse[yourDevice, 1]
Modules - http://www.amxforums.com/showthread.php?t=2752
Quting from the second response "Check out tech notes 271 (Module Example) and 375 (How to Write Your Own Netlinx Modules)"
Actually, the TO[TP1,1] statement will turn on channel 1 of TP1 while the PUSH event is active, in other words providing feedback to the panel that the button is active or being pushed. There are other ways to do that, but it's generally an easy and effective method of handling momentary type feedback from the code. In this way, it will act pretty much the same as if you had set the Feedback Type to Momentary in TPDesign.
thanks, I didn't know that...
I ususaly work with Momentary or channel, and turn it on like this if needed
[tp, channel] = 1
Good to know
What section do I declare this under? How do I then use that command? And how do I seperate them for the different devices? For instance, powerCommand for my projector won't be the same for powerCommand for my tuner.
Thanks!
Dan
put your strings like this
CHAR DEVICE_COMMAND[] = {$FE,$03,$A1,$10,$00,$B4}
in your code -
SEND_STRING PROJ, DEVICE_COMMAND
I have to admit that I don't use the variable declaration method if I'm only going to be doing the projector commnad once or twice. I don't like having to run up the scroll bar to see what the heck the command is. I only will do this if I find myself putting in a hex string command more than 3 or so times.
I usually just comment at the end that it's a projector on command.
It helps avoids the spagetti code syndrome.
I my opinion there is not such thing too much consts and defines in a program, even for one time use.
First, I would probably create a constant not a variable to hold this value.
DEFINE_CONSTANT
CRLF[2] = {$0D,$0A} ;
CHAR PROJ_PWR_OFF = 'C00' ;
CHAR PROJ_PWR_ON = 'C01' ; //just a guess!
and in the button_event:
SEND_STRING PROJ, "PROJ_PWR_OFF,CRLF" ;
I just find it easier to look at and know exactly what the command is. This is also likely one of only two places you'll use this. Here and a shut down routine. If I'm in a hurry then I probably wouldn't create any constants.
As far as spagetti goes, there was a thread a while back about creating multiple DEFINE_CONSTSANTs and DEFINE_VARIABLEs which I find very usefull to categorize constants or variables so that I don't have to scroll down endless lists. Long button arrays are the worst so I now create a seperate DEFINE_VARIABLE for each button_array or category and a seperate DEFINE_CONSTANT list for the various categories I need.
Here's an example of multiple DEFINE_CONSTANTs for a TV module. When the code is folded I can basically just have the section of constants I'm working with open for reference and the code I'm writing. I can't stand long scrolling lists and I prefer to have everything viewable at the same time although seldom can I view everything at the same time especially w/ my over bracing habits.
My mistake, you are right. should be in consts and not variable.
I'm stumped right now. Can any of you figure out why this code turns on the receiver:
yet this one does not?
Thanks in advance...
Dan
WAIT 1 PULSE[onkyo,27]
Try to add wait before the diffrent device command to eliminate the problem
I don't know the reason, I will happy to hear from someone that knows..
Only one channel of an IR port can be transmitting at any one time. Try this:
Accepting that this is your first attempt and that what you have coded will generally work, the "industrial strength" way to handle the receiver is to write a module which:
(a) tracks its (presumed) state - note that this can only be guesswork; the unit might not even be plugged in
(b) does not attempt to do things that it cannot do in a given state
(c) queues commands with appropriate pauses between
Why bother? If you code it and you use it then you will know its limitations. But for instance, if there is a switchon delay as I surmised, then if you switch it on and immediately switch it off, the switch off will be ignored.
The same goes for the projector, but more so!
NB don't assume that AMX modules do all of (a), (b) and (c). The Denon receiver serial module that I worked with recently certainly doesn't.
Again, much appreciated!
Dan
I guess I'd say that declaring a variable/constant to reference a single command is needless use of RAM. Granted that the bad old days of limited RAM are pretty much gone. But I think it's still a good code practice. All those little uses of RAM add up over the long haul.
uses more lines of code and more RAM than...
A good example of when I like to create a token for the command is for Rotel Processors. They have a myriad of commands that must be used over and over again. The hex strings are a nuisance. I then will declare a constant and/or variable to store the commands.
There's nothing really wrong with either method. They both have their advantages and disadvantages. As long as the code is well documented it doesn't really matter much.
As far as sending serial commands out to devices, and not really having to rely on remembering what the protocol is, or scrolling up to try and remember what exactly you named your CONSTANT, I make an array of the commands and then put them in standard IR order. That way, when I'm doing my touch panel, 1 = play, 2 = stop, 3 pause, 27 = power on, and so forth. Since we work with certain equipment on a regulalr basis (the Integra recievers, DVD and CD players / changers) I've made the list for all of them. Here's a bit of sample code:
For some reason the formatting looks really funky, sorry about that but hopefully this helps someone. nALL_CMDS would go from 1 to 99. I figure 99 is a good number for maximum control commands for a device. I rarely see a device that can use most of that.
Anyway, this is just my 2 cents on controlling serial devices and not really having to worry about the protocol too much. I know this works great devices that don't use a checksum, and I know it's not an end-all solution, but it has turned out to be very usefull with my code.
Variables do use up RAM (slowly), but constants do not. Constants are processed and substituted by the compiler at compile-time. The two examples you gave, one with a constant and one without, will use an identical amount of storage space in RAM and binary code. Only the source code will be different.
With that said, I don't see much point in using a constant for a one-time-use string. The nice thing about them is having a centralized place to change values globally for your program, as well as being able to give them "self-documenting" names, so you can say:
state = STATE_SEND_PASS
rather than
state = 5 // send the password
Auto-completion makes them even more useful.
Jeremy
So you'd do something like Send_Command onkyo,"'SP",27" and then 84 and the pulses would get stacked and fired as per the parameters setup by cton and ctof
Thanks in advance...
Dan[/QUOTE]
Naturally priority 1 is to write code that works.
Somewhere further down the list is "write code that can be understood" and when you get into practice this doesn't conflict with "write code quickly". Using a constant instead of a literal almost always enhances readability.
Also on the list is "write code that can be extended / modified easily". If you start by entombing absolutely every literal value into a constant, then you never need to worry about getting it wrong later when you re-use the value.
"Write code that's small or fast" isn't on the list at all, until you run out of space or time, which is improbable with NetLinx and you can fix it easily when it arises.
Some of the larger system programs I've done do get quite memory-hungry and require a lot of RAM.
I think I may have started a fire storm by what was meant as a simple comment. I originally said that there were times that I didn't create a token for a one-time-only serial string. I wasn't necessarily condoning the act, just an admission.
What I've learned over the many years of doing this is that programmers bristle when you start to discuss ways of going about doing something. I personally don't enjoy these disucssion because they seem to disolve into an argument over something that is strictly an opinion. We do have guidelines that are helpful to follow. But, for the most part, programming is still the 'Wild West.'
A big 'here-here' to Marks comment that first and foremost, get it working. All the pretty code is useless if it doesn't work. I've suffered through that here for about a year and a half.
The NetLinx language is clearly very new to me - but I appreciate all the help you guys have given. This forum has proven to be a great resource with very helpful individuals - while this started as me just messing around with some hand-me-down equipment, I've since bought 3 touchscreens and an audio switcher, I'm sure more to come. Which actually brings me to my next question (they keep coming!) - Whats the best way to reuse pieces of code for another panel? Just copy-paste and maybe do a find-replace on the touchpanel device? And one other question - I somehow ended up with two 315mhz panels - are they going to play nice?
Again all the help is much appreciated. You've all made me into an AMX freak - I want to do this more often now!
Thanks,
Dan
I'd like to learn what makes that happen. Are you doing something interesting with it?
How would I use this same logic to place my char array or constant definitions into my module but then call them from my main line?
You can pass constants to to module as a parameter if you create an array of constants or you can create an include file .axi of constants and #include MyModConstants.axi inside your module. They when the module is compiled it pulls in or includes the include file. It you have allot of constants to use in the main and module use the include but it there's just a couple then pass them into the mod as a constant array or element of a constant array.