Home AMX User Forum NetLinx Studio

IR Pulsing Implementation

I wonder how the experienced Netlinx programmers implement their IR pulsing duration for multiple devices. Is there a better way than changing the Pulse time all the time in code using the SET_PULSE_TIME? For example , I would like the pulse time for a DVD to be fixed always on 0.3s whenever an IR channel is pulsed on the DVD, a VCR to 0.4s and so on. Maybe in a DATA_EVENT. Usually I create an include file that itiliazes all my IR devices like this:

DATA_EVENT[dvDVD]
{
ONLINE: //IR device comes ONLINE
{
SEND_COMMAND dvDVD,'SET MODE IR'
SEND_COMMAND dvDVD,'CARON'
}
}

I would appreciate if anybody could share a piece of code that takes care of setting the PULSE_TIME to each IR device only once in code. I want to be able to use the PULSE command without having to use the SET_PULSE_TIME all the time.
«1

Comments

  • jeffacojeffaco Posts: 121
    Hmm. This hasn't been a problem for me.

    There are two "classes" of I/R codes for me: PULSE, and TOGGLE.

    In the PULSE case, I don't care what the pulse time is, as long as it works. I've picked 0.2 seconds for a pulse time, and this works with all of my devices. I've had no need to change this for any of my devices.

    In the TO case (i.e. volume, or channel up, or fast forward, or whatever), it's based on when the button is released, so the pulse time has no bearing (to the best of my knowledge, anyway).

    Finally, I like to write my code to be data driven. Thus, very rarely do I pulse (or toggle) I/R signals via hardlined code. Instead, I generally pulse or toggle based on whatever I got from the panel.

    In the case of Viewpoints (2-way), I use two devices. Device one is for PULSEd codes, device two is for TO codes. Whatever channel I get for a button, I turn around and PULSE (or TO) to whatever the current source device is. This means that, when setting up a new device, the panel entirely decides what code is sent to the audio/video device, and if it's PULSE or TO.

    In the case of Moderos, I do something similar, but in this case, I use two ports on the same device. The modulo of the device (or port) by two == 0 means pulse, == 1 means toggle.

    Hope this helps,

    -- Jeff
  • The "Stack Pulse" command is what you are looking for - SEND_COMMAND device,"'SP',irChannel". Look it up in Software History (I think all current IR output devices have this functionality).
  • alexanboalexanbo Posts: 282
    I use the SP command to send IR typically. This way you can use CTON and CTOF to set pulse time for each device individually.

    Aparently there is a problem in the firmware for NI's (.118) where this can cause problems after a while in that the device will stop sending out IR. I've had to roll the firmware back to 115 to get rid of this problem.
  • Thomas HayesThomas Hayes Posts: 1,164
    I use the 'CTon/of' command as well but unless they added it to the latest Netlinx Help section you will have a hard time locating info on its protocol. I was on the phone with AMX tech support (back in May) about using multi IR pulse times and we could not find it listed in the Netlinx help section. I finally found it in an old Axcess manual I had on my desk.
  • It is a device function not a Netlinx function. Look up any IR device (ie NXC-IRS4, or NXI-x000), in Software History (under the Tools menu in Studio2), and it is all there.
  • frthomasfrthomas Posts: 176
    Originally posted by icraigie
    It is a device function not a Netlinx function. Look up any IR device (ie NXC-IRS4, or NXI-x000), in Software History (under the Tools menu in Studio2), and it is all there.

    While there is a logic to that and credit should go to AMX for sticking with it it pretty consistently, I am not a big fan of the distinction. After all PULSE does, like 'SP', send IR so one wonders why finding about one doesn't at least reveal the existence of the other.

    Fred
  • Thomas HayesThomas Hayes Posts: 1,164
    I am surprised the person on tech-support didn't tell me to look it up in Software history. I just checked and bang there it was. Anyways maybe with alot of the newer IR devices using a much wider range of 'pulse time' AMX should create a new command that would allow you to set the pulse time for individual devices only once in the code. ex: SET_DEVICE_PULSE[device,time]
  • I haven't tried this out, but it seems that a easy way would be to create a modified Pulse command.

    DEFINE_CALL 'Pulse Device' (DEV aDevice, INTEGER aChannel)

    {
    SWITCH (aDevice)
    {
    CASE 8: SET_PULSE_TIME(.5)
    CASE 9: SET_PULSE_TIME(.3)
    }
    PULSE[aDevice,aChannel]

    }

    In this example device 8 could be a VCR, device 9 could be a DVD player

    in your Main Line or Button Events, instead of the traditional Pulse statements, just type:

    Call 'Pulse Device' (dvDVD,2)
  • well, i just do SET_PULSE_TIME = 1 during boot.

    it's worked well with all IR devices i've used so far (various DVDs, TVs, VCR and Cable boxes)

    the default is 5 (0.5 seconds i think) - and it is too long.

    many devices get doubled up IR codes and repeat their functions with the default setting

    i then use send_command device SP,IrCodeNumber

    just set and forget - it worked for me
  • DHawthorneDHawthorne Posts: 4,584
    Originally posted by Ghrae
    I haven't tried this out, but it seems that a easy way would be to create a modified Pulse command.

    DEFINE_CALL 'Pulse Device' (DEV aDevice, INTEGER aChannel)

    {
    SWITCH (aDevice)
    {
    CASE 8: SET_PULSE_TIME(.5)
    CASE 9: SET_PULSE_TIME(.3)
    }
    PULSE[aDevice,aChannel]

    }

    In this example device 8 could be a VCR, device 9 could be a DVD player

    in your Main Line or Button Events, instead of the traditional Pulse statements, just type:

    Call 'Pulse Device' (dvDVD,2)
    The default is undoubtably too long for many devices, but 1 is too short for reliable response from some as well.

    My own advice is stop using SET_PULSE_TIME and PULSE[IR, xx] altogether. Using SEND_COMMAND IR, "'CTON', xx" allows you to individually set the pulse timing per device when using the SP command. In turn, that lets you use the same code for multiple devices, and it lets you tweak the timing for devices that are sensitive either way.
  • Also note that the 'SP' command does just as it suggests, it Stacks Pulses. So IR pulses are stacked into a queue and executed one at a time. Also SEND_COMMANDS such as "'XCH'" and others obey the parameters of "'CTON'", "'CTOF"', not SET_PULSE_TIME. Typically this is what I use. E.G.

    DATA_EVENT[dvDSS1]
    {
    ONLINE:
    {
    SEND_COMMAND dvDSS1, "'CTON',2"
    SEND_COMMAND dvDSS1, "'CTOF',2"
    }
    }

    BUTTON_EVENT[dvTP1,31]
    {
    PUSH:
    {
    IF(![dvDSS1,255]) SEND_COMMAND dvDSS1, "'SP',9" //PWR
    SEND_COMMAND dvDSS1, "'XCH123'"
    }
    }
  • This is what I like about this forum!

    I don't remember any mention of the "SP" command in any of the programming classes I took. So between the numerous mentions in this column, as well as the examples posted, I was able to learn a new technique instead of building my own stacking function.

    Thanks
  • Originally posted by icraigie
    The "Stack Pulse" command is what you are looking for - SEND_COMMAND device,"'SP',irChannel". Look it up in Software History (I think all current IR output devices have this functionality).

    Use the "Stack Pulse" if you can. The benefit is that the Master does not need to manage the pulse duration. The IR device will do this. No need to manage a series of IR commands with Waits or a Timeline_Event.
  • jjamesjjames Posts: 2,908
    Well, I know it's an old post - but I have a question. Whenever using the SP function, it doesn't seem to work all the time. I'll watch in notifications, and here's what I see:

    Line 1 :: Input Status:Pushed [81:1:1] - Channel 26 - 10:34:47
    Line 2 :: Command To [5001:9:1]-[SP+] - 10:34:47
    Line 3 :: Command To [5001:9:1]-[SP$0A] - 10:34:47
    Line 4 :: Command To [5001:9:1]-[SP$00] - 10:34:47
    Line 5 :: Command To [5001:9:1]-[SP$06] - 10:34:47
    Line 6 :: Command To [5001:9:1]-[SP>] - 10:34:47
    Line 7 :: Command To [5001:9:1]-[SP$01] - 10:34:47
    Line 8 :: Input Status:Released [81:1:1] - Channel 26 - 10:34:47

    I normally see only three (but sometimes four) flashes from the IR port on the NI-3000 I've got. I'm assuming it's pulsing lines 3,4,5 and 7, though one will seem to drop out. I don't know why it's sending an "SP+" and "SP>", aside that 43 is an ASCII "+" and 62 is an ASCII ">". Does anyone have any ideas? Would the ITOA have anything to do with it? Here's the code I'm using - it's for a "Random Album" function on an Imerge S1000 (old piece of hardware.)
    DEFINE_CALL 'CD RANDOM'
    {
    	LOCAL_VAR CHAR RNDM_NUM[2]
    	
    	RNDM_NUM=ITOA(RANDOM_NUMBER(30))
    	
    	WHILE(RNDM_NUM='0')
    		RANDOM_NUMBER(30)
    	IF(LENGTH_STRING(RNDM_NUM)=1)
    		RNDM_NUM="'0',RNDM_NUM"
    	
    	SEND_COMMAND IMERGE_IR,"'SP',43"	// ALBUM
    	SEND_COMMAND IMERGE_IR,"'SP',10"	// 0
    	SEND_COMMAND IMERGE_IR,"'SP',ATOI(LEFT_STRING(RNDM_NUM,1))"		// SEND LEFT DIGIT OF THE RANDOM NUMBER
    	SEND_COMMAND IMERGE_IR,"'SP',ATOI(RIGHT_STRING(RNDM_NUM,1))"	// SEND RIGHT DIGIT OF THE RANDOM NUMBER
    	SEND_COMMAND IMERGE_IR,"'SP',62"	// RED-X BUTTON (OR "OKAY" IN PROCESS)
    	SEND_COMMAND IMERGE_IR,"'SP',PLAY" // PLAY
    }
    
  • The diagnostic software is interpeting the command "'SP',43" and showing you the command as if it was all ASCII. The diagnostic does show that the processor thinks it's sending out the correct sequence

    It looks like you may want to add 10 to your random numbers if you have the numbers at IR slots 10-19 as per standard IR files.
  • Joe HebertJoe Hebert Posts: 2,159
    jjames wrote:
    I don't know why it's sending an "SP+" and "SP>", aside that 43 is an ASCII "+" and 62 is an ASCII ">". Does anyone have any ideas?
    The ?SP+? is logged as a result of your first SEND_COMMAND. The notifications window will log strings as ASCII printable characters if it can. If not it will log the data in it?s hex value. (Unless your data contains a NULL ($00) in which case I believe the debugger stops printing the rest of the string-I think it?s a bug) So SEND_COMMAND ??SP?,43? is the same as SEND_COMMAND ?SP+? and it would be the same as SEND_COMMAND ??SP?,$2B? All three of those mean the same thing, it?s a matter of preference of how you want to see it. The computer doesn?t care because they all mean the same thing. So the debugger is logging correctly.
    jjames wrote:
    Whenever using the SP function, it doesn't seem to work all the time.
    DEFINE_CALL 'CD RANDOM'
    {
    	LOCAL_VAR CHAR RNDM_NUM[2]
    	
    	RNDM_NUM=ITOA(RANDOM_NUMBER(30))
    	
    	WHILE(RNDM_NUM='0')
    		RANDOM_NUMBER(30)
    	IF(LENGTH_STRING(RNDM_NUM)=1)
    		RNDM_NUM="'0',RNDM_NUM"
    	
    	SEND_COMMAND IMERGE_IR,"'SP',43"	// ALBUM
    	SEND_COMMAND IMERGE_IR,"'SP',10"	// 0
    	SEND_COMMAND IMERGE_IR,"'SP',ATOI(LEFT_STRING(RNDM_NUM,1))"		// SEND LEFT DIGIT OF THE RANDOM NUMBER
    	SEND_COMMAND IMERGE_IR,"'SP',ATOI(RIGHT_STRING(RNDM_NUM,1))"	// SEND RIGHT DIGIT OF THE RANDOM NUMBER
    	SEND_COMMAND IMERGE_IR,"'SP',62"	// RED-X BUTTON (OR "OKAY" IN PROCESS)
    	SEND_COMMAND IMERGE_IR,"'SP',PLAY" // PLAY
    }
    
    Moving on the the code: If I?m reading your logic correctly you want a random number between 01-99. It looks to me like you didn?t account for the IR code offset (the number 0 is IR code 10 ? the number 9 is IR code 19) And it also looks like any number divisible by 10 (evenly of course :) ) won?t ever be generated.

    You really don?t need a while loop and you don?t need the conversions between ASCII and decimal. All you really need are two numbers.

    There are many ways to accomplish the same thing but here is one way to send out random IR codes for the digits 01-99:
    DEFINE_CALL 'CD RANDOM'
    {
       INTEGER nTensDigit
       INTEGER nOnesDigit
       
       nTensDigit = RANDOM_NUMBER(10)+10  //IR code 0-9
       
       //if the 10's digit is IR code 0 then ask for 1's digit to be between IR code 1-9
       IF (nTensDigit = 10) nOnesDigit = RANDOM_NUMBER(9)+11 //IR code 1-9
       
       //if we have a number alreay > 9 (10's digit > 0) then pick any 1's digit
       ELSE nOnesDigit = RANDOM_NUMBER(10)+10  //IR code 0-9
       
       SEND_COMMAND dvIR,"'SP',43"	// ALBUM
       SEND_COMMAND dvIR,"'SP',10"	// 0
       SEND_COMMAND dvIR, "'SP',nTensDigit"  
       SEND_COMMAND dvIR, "'SP',nOnesDigit" 
       SEND_COMMAND dvIR,"'SP',62"	// RED-X BUTTON (OR "OKAY" IN PROCESS)
       SEND_COMMAND dvIR,"'SP',PLAY" // PLAY 
    
    }
    

    Hope this helps.
  • jjamesjjames Posts: 2,908
    I'm actually trying to have a random number between 1 and 30. The RANDOM_NUMBER function gives you a number from 0 to the number you specificy . . . RANDOM_NUMBER (max number).

    I'm making it a CHAR that way I can do a LEFT&RIGHT_STRING on the RANDOM_NUMBER that was just generated. Unless there's another way of extracting the first digit of a two digit decimal number, this is how I can see doing it. I did forget the offset of the IR codes, and did add 10 to the broken random number.

    Anyway, it would certainly help if the right Imerge IR file was in the master. I guess I was more concerned with the + and the >. It LOOKS like it's only sending 5 of the 6 IR pulses. However, the first pulse looks different from the others. The 43 and 62 were copy and pasted from a WACI file, do you think this could make any difference? Plus, when looking at the pulses (43 & 62) in IREdit, the repeat count is "0", total repeat time, and first pulse times are all different from the other pulses. Could this make much difference?

    Anyway, thanks for the help!
  • Have you actually hooked up a visible LED (or watched the IR led with something that can show it up, like a digital camera) to see what's going on? I'm not sure how SP handles IR codes that are learnt just way too long. In my experience I've had to relearn for myself many codes from AMX's database, because they're just way too long. To learn shorter codes, just do a shorter squirt of IR into the learner - kinda crude but it works. I find myself going away from using SP to just using Pulse and managing in code any timing issues. Sending two codes the same sequentially can cause problems - the receiving device just sees it as one. On my home system for Tivo presets, I look at the channel number and compare adjacent digits. If I see they're all the same I know I can select it very fast. If I see two adjacent digits the same, I select a slower timeline.

    Hope this helps

    OP
  • Actually now that you mention it I think the old Imerge's used a toggle bit in the IR code. I think what this meant was that you'd send a command out using the A code, and then if you needed to send out that command again you'd need to send the B code for that command. I think we got around it by sending out a B code that didn't do anything before sending out the A code that did something.

    Now I think Immerge has a CCF file for Pronto's on their website which you can use to verify codes and what not.

    Not sure if you're using Axcess or Netlinx but you can control the Unit via IP if you're using Netlinx.
  • Joe HebertJoe Hebert Posts: 2,159
    jjames wrote:
    I'm actually trying to have a random number between 1 and 30.

    Okay, here is one way:
    DEFINE_CALL 'CD RANDOM' {
    
       //Random between 01-30
       
       INTEGER nTensDigit
       INTEGER nOnesDigit
       
       nTensDigit = RANDOM_NUMBER(4)+10  //IR code 0-3
       
       SWITCH (nTensDigit) {
       
          CASE 10: { //if 10's is a zero then give us 1's between 1-9
    	 nOnesDigit = RANDOM_NUMBER(9)+11 //IR code 1-9
          }
    
          CASE 13: { //if 10's is a 3 then 1's has to be 0
    	 nOnesDigit = 10
          }
          
          DEFAULT: { //else any 1's digit will do
    	 nOnesDigit = RANDOM_NUMBER(10)+10  //IR code 0-9
          }
       }
       
       SEND_COMMAND dvIR,"'SP',43"	// ALBUM
       SEND_COMMAND dvIR,"'SP',10"	// 0
       SEND_COMMAND dvIR, "'SP',nTensDigit"  
       SEND_COMMAND dvIR, "'SP',nOnesDigit" 
       SEND_COMMAND dvIR,"'SP',62"	// RED-X BUTTON (OR "OKAY" IN PROCESS)
       SEND_COMMAND dvIR,"'SP',PLAY" // PLAY //I'm assuming PLAY is defined as a constant with value of 1
    
    }
    

    Does that get you where you want to go? The reason you weren't seeing all the pulses in your original code is because sometimes your code was trying to send out IR code function 0...which doesn't exist. What you really wanted was function 10 which is 0.
  • Here's another approach for what it's worth...
    DEFINE_CALL 'CD RANDOM'
    {
    	LOCAL_VAR Integer nRandomNum
    	
            // Get a random number between 1 and 30
    	nRandomNum = RANDOM_NUMBER(29) + 1
    	
    	SEND_COMMAND IMERGE_IR,"'SP',43"	// ALBUM
    	SEND_COMMAND IMERGE_IR,"'SP',10"	// 0
    	SEND_COMMAND IMERGE_IR,"'SP',(nRandomNum/10) + 10"		// SEND LEFT DIGIT OF THE RANDOM NUMBER
    	SEND_COMMAND IMERGE_IR,"'SP',(nRandomNum%10) + 10"	// SEND RIGHT DIGIT OF THE RANDOM NUMBER
    	SEND_COMMAND IMERGE_IR,"'SP',62"	// RED-X BUTTON (OR "OKAY" IN PROCESS)
    	SEND_COMMAND IMERGE_IR,"'SP',PLAY" // PLAY
    }
    


    --D
  • Joe HebertJoe Hebert Posts: 2,159
    dchristo wrote:
    Here's another approach for what it's worth...
    --D

    Much more straight forward then mine. To get a number between 1-30 you would have to change:

    nRandomNum = RANDOM_NUMBER(29) + 1

    To:
    nRandomNum = RANDOM_NUMBER(30) + 1
  • GSLogicGSLogic Posts: 562
    Just for the fun of something to think about...

    In a Random_Number sequence from 1 to 30, the numbers 1 and 30 (the outside numbers) will show up around 16% LESS of the time than all the other numbers 2-29. The Randon_Number() method looks at the numbers on each side of the string of sequenced numbers to get a randomized number, since 1 and 30 are on the outside, they don't get looked at as often. There is a fix if anyone really needs to know but I don't want to bore you. :)
  • Joe HebertJoe Hebert Posts: 2,159
    GSLogic - I should be sleeping since I?m driving to CEDIA in the morning but I?m trying to figure out why the outside numbers in a random sequence will show up 16% less of the time than the middle numbers. Is that just an AMX RANDOM_NUMBER generator thing or is it a statistical fact? I thought over time (many numbers drawn) all the numbers should be weighted somewhat equally. I for one would be interested in the ?fix? although I?d be even more interested in why the problem exists.

    jjames ? I laughed at your new avatar. Been there done that many more times then I?d care to remember. :)
  • Joe Hebert wrote:
    Much more straight forward then mine. To get a number between 1-30 you would have to change:

    nRandomNum = RANDOM_NUMBER(29) + 1

    To:
    nRandomNum = RANDOM_NUMBER(30) + 1

    Yup, you're right. I don't use Randoms that much, and had forgotten it returns one less than the value passed.

    ;-)

    --D
  • GSLogic wrote:
    There is a fix if anyone really needs to know but I don't want to bore you. :)


    No - please, feel free to try and bore me. :)

    - Chip
  • GSLogicGSLogic Posts: 562
    I came across the random number sequence being uneven when I was programming my Blackjack game. After investigating, I found if you're looking at the results through a microscope all computers do a rather poor job of getting random numbers. Computer-generated random numbers are more properly referred to as pseudorandom numbers, and pseudorandom sequences of such numbers. A variety of clever algorithms have been developed which generate sequences of numbers, but they are not perfect.

    One of the problems is the algorithms look at the numbers next to each other not just at the individual number, by doing this the out-most numbers will get picked less often. IF YOU MUST - ONE FIX IS: to get a random number between 1 and 10, get a Random_Number on 1-12 and if 1 or 12 popup repeat the function until it?s between 2-11, then subtract one to get back to the original 1-10.

    I know this is crazy and I don't do this for everyday random numbers, but I thought it was interesting. You should see what Casinos do to generate random numbers for their slots and video poker games. Casinos can't use the computer algorithms because the patterns could be detected by a super human and give them an advantage. I'd like to see that! :)
  • Breaking Vegas is a pretty cool show on one of those channels that shows that type of show..

    One episode had a programmer in charge of making sure the slot machine code was correct get mad that the agency he worked for cheated the public out of more than the cheaters they were fighting. He put a trojan in the software that spot checked the machine that would modify the code after it verified it.

    After a while that wasn't enough money for him and Keno came out. He went into the operating system the keno code ran on and debuged how it's random number code worked (after all, someone had to code that). He found that given a set of numbers of one game gave him a 50% chance of guesing the next set of numbers. Adding in each following game's numbers increased his odds as his program narrowed down what part of the 'loop' the code was in. He hit all numbers correctly on his third game...




    Related to the code, I'm not seeing anyone save the last random number generated. If you don't compare new vs old, your 'random' will be a 'repeat' every so often.

    Kevin D.
  • Speaking of random numbers and computers and how predictable they are. Many years ago in High school I wrote a program to randomly pick different screen colours. I used 4 different Apple II's and ran the program. Each computer displayed the exact same random colour in the exact same squence. I then started the program at different times and logged each colour displayed. They matched again. Makes one wonder if random numbers really exist or just complex calculations to appear random.
  • GSLogicGSLogic Posts: 562
    Each computer displayed the exact same random colour in the exact same squence.

    This is because most computer us what is called a "seed" to start the random number process, the seed is the starting point for the randomization algorithm. That's why each computer will always get the same starting number.

    As Kevin mentioned:
    I also think it is more important to store the "so called" random numbers in a array so they don't repeat until all sequenced numbers have been picked. I use this in my random MP3 function.
Sign In or Register to comment.