Ladder logic takes some getting used-to when you start working with it, but once you know the rules and possible pitfalls to avoid, you will find that you can accomplish almost anything using a rather minimalist instruction set.

Ocelot Ladder Logic

Guy Lavoie


Guy Lavoie

Ladder logic takes some getting used-to when you start working with it, but once you know the rules and possible pitfalls to avoid, you will find that you can accomplish almost anything using a rather minimalist instruction set. 

If you have any questions about anything you read here, you can contact me at: guy@lavoie.com  I only request that you do not ask me any support questions or ask for custom programming. I have no link with Applied Digital, I'm simply a happy owner of an Ocelot who wants to share his knowledge and experience with other users of this neat little controller.


I first got started in home automation about 2 years ago and like many people, my first controller was the CM11A with ActiveHome software. This package offers good basic performance at an attractive price, and helps a lot of people to get started with the concept of automating their home. This field is still quite new and evolving at a fast pace, not unlike personal computing in the early 80's ( you bought a computer…what for ?). The problem, even as recently as a year ago, was that very few controllers were available, and those that were were either quite inexpensive with basic functionality (eg. ActiveHome), or very costly but sophisticated ( eg. JDS TimeCommander units); there was no "middle ground". The inexpensive solutions are usually macro oriented, sparing you the trouble of learning a programming language and making it easy to use Windows to choose options. The more sophisticated systems, like the JDS units, allow you to create scripts to do conditional logic. This past year has finally managed to fill some of that middle ground with affordable systems that provide scripting and expandability options. One of the more popular of these new units is the Ocelot controller ( formerly called the CPU/XA ) from Applied Digital. This unit has an industrial control heritage and thus uses a programming model called "ladder logic" to control it. The JDS systems also use a higher-level form of ladder logic. This model is a natural fit for event control ( I bought the Ocelot specifically because it uses this type of logic ).

The concept of conditional logic to control hardware with delays and AND/OR conditions has been around for many years in the industrial field. I remember programming an industrial PLC (programmable logic controller ) back in 1981. These controllers are built and engineered to replace hardwired relays and switches which were the norm before that. The relay based circuits were called "ladder" circuits because the circuit diagrams for these resembled a ladder ; the two power lines were the long rails, and switches and relays looked like the rungs. I have included a sample relay diagram to illustrate this:

When programmable controllers were designed to replace the relays, engineers wanted to retain the same logic model to allow existing designs to be adapted to the new hardware. This has resulted in Ladder Logic controllers ( LL from now on ). Since most users of home automation are usually more computer literate than industrial control minded, they have learned the usual crop of languages like BASIC or C . These languages work fine because we are usually doing things one-at-a-time, like entering data, performing calculations, or accessing files. We don't even stop to think about problems like "what if I'm in the middle of entering a field on a menu and the program needs to read a file ?" because our program is sitting there, waiting for us to finish entering a value before it can do anything else. Newer languages like Visual Basic ( VB ) took some re-thinking because suddenly, the program did not have absolute control over events; the user could click on any of several buttons, even if it made no sense, like clicking on "OK" without having entered required information beforehand. Programmers found themselves doing a whole lot more error checking and enabling/disabling controls to "idiot proof" the process as much as possible. LL is a bit like VB, needing a lot of idiot proofing of its own. What does all this bring you ? In a word: multitasking. We are already used to multitasking operating systems, running several programs at once. Here, we are talking of a multitasking program.

In principle, LL assumes that any changing conditions are immediately reflected throughout the system. Since a computer program cannot be everywhere at once, it runs as one big long loop at high speed, sampling for any changing conditions and making the new information immediately available to the entire system. Like any sampling system, the sampling rate must be at least as fast as the nominal resolution of the system. In the Ocelot, timers have a resolution of 1 second, so the entire program must be run at least once per second to be effective. Daniel Smith of Applied Digital (who makes the Ocelot) tells me that a full 2000 line program would take about 1 second to execute, so a typical 500 line program would be repeated about 4 times per second, more than enough to match the timer accuracy. We thus have rule #1 of a LL language: The entire program runs as one long loop, NEVER stopping, waiting, or looping at one spot. The important word here is "never"! Thus, gone are things like GOTO, WAIT, and GOSUBS. In fact, pure LL is nothing but IF/THEN statements looking for conditions and updating them. To illustrate this, here is a program in both BASIC and LL. The BASIC is pseudo code not reflecting any existing version, LL is using the Ocelot. This program waits to receive an X-10 A-1 ON command, waits 3 seconds, and then sends out a B-1 ON:

Example #1

BASIC

LABEL TopOfLoop
INPUT X10receive$
.
.
IF X10receive$ = "A1-ON"
WAIT 3
X10send$="B1-ON"
OUTPUT X10send$
ENDIF
.
.
GOTO TopOfLoop
Ocelot

STATEMENT		        COMMENT

IF X10 A/1 ON Command          	If an X-10 A-1 ON was received
  THEN Timer0=1                	start timer 0 by setting to 1
.
.
IF Timer0 Becomes > 3          	on the first time timer 0 reaches 4
  THEN Timer0=0                	stop the timer
  THEN X10 Quick On B/1        	and send an X-10 B-1 ON command
.
.
END OF PROGRAM

As you can see, they look similar. The big difference is the WAIT 3 statement in BASIC; during that time, the program is doing nothing else, so you can imagine that a macro that simulates your being at home would always be stuck waiting for a delay to end, unable to check other things like the temperature or a security system. With the Ocelot, the A-1 ON command simply starts a timer that runs independently from your program. Another code segment looks at the timer on-the-fly during the long loop to see if it is time for the next step, and updates conditions if so. The output X-10 command is put in an output buffer, freeing the program right away to keep looping. A better example of multitasking is shown below. This program checks if an X-10 A-1 ON command is received 3 times within 10 seconds of receiving the first one, and if so sends a B-1 ON. This would be nearly impossible to do in BASIC:

Example #2

STATEMENT			         COMMENT

IF X10 A/1 ON Command            if A-1 ON was received
 AND Timer0 > 0                  and if timer is already started
  THEN v0=v0+1                   then increment count

IF X10 A/1 ON Command            if A-1 ON was received
 AND Timer0 = 0                  but timer was not yet started
  THEN v0=1                      then start with count of 1
  THEN Timer0=1                  and start timer

IF Timer0 Becomes > 10           if 10 seconds have elapsed
 AND v0 > 2                      and A-1 ON received 3 or more times
  THEN v0=0                      then reset count
  THEN Timer0=0                  and stop timer
  THEN X10 Quick On B/1          send B-1 ON command

IF Timer0 Becomes > 10           if 10 seconds have elapsed
 AND v0 < 3                      and A-1 ON received less than 3 times
  THEN v0=0                      then reset count
  THEN Timer0=0                  and stop timer

END OF PROGRAM                      

Note several things here; there are two IF statements looking for the triggering input condition, and two more IF lines looking to see if the output condition is met. This covers every possible outcome (remember: "idiot proofing"). In the first two cases, we are determining if the count was already started or not by checking if the timer was started. The last two IFs do different things depending on weather the count had reached 3 or more by the time 10 seconds was up. This is a good place to introduce a warning about trying to use ELSE statements to "save" on conditional tests…lets try this to replace the last two IFs:

Bad Example:

IF Timer0 Becomes > 10           if 10 seconds have elapsed
 AND v0 > 2                      and A-1 ON received 3 or more times
  THEN v0=0                      then reset count
  THEN Timer0=0                  and stop timer
  THEN X10 Quick On B/1          and send B-1 ON command
  ELSE v0=0                      else reset count
  ELSE Timer0=0                  and stop timer

END OF PROGRAM 

Doesn't that look great…now you load that into your Ocelot…and discover that no matter how fast and furiously you can generate A-1 ON commands, you never get the B-1 ON you are expecting! That is because the ELSE statement is executed EVERY TIME the ENTIRE conditional statement is false (just like THENs are executed every time the statement is true) …so if the timer has not yet reached 10 seconds, you are resetting the count to 0 …and stopping the timer! Remember, the ELSE statement is not an IF (statement is true) but (AND condition is not true)…Even worse is if you were to send an X-10 command in an ELSE statement, it would be sent continuously, and your Ocelot may appear to be locked up. So the rule with ELSE statements is: ELSE statements are executed EVERY TIME the ENTIRE conditional test is false! Just make sure you understand this rule and you will find yourself using ELSE very little if at all. It can be useful for things like setting a variable to reflect the status of an input, but beware of trying to use it to output commands that produce individual events like transmitting X-10 or Infrared. The following example is OK because turning ON a relay that is already ON (or turning OFF a relay that is already OFF ) has no real effect, it's just updating the relay driver latch continuously:

Example #3

IF Module#1/Point#0 Is ON               if input 0 on SECU-16 is ON
  THEN Module#0/Point#8 Turns ON        turn ON first relay 
  ELSE Module#0/Point#8 Turns OFF       else turn OFF first relay 

Now, lets improve on example #2 a bit; we would like to have our B-1 ON generated as soon as the A-1 ON has been received 3 times, and not have to wait for the 10 second maximum interval to be elapsed if the three A-1 ONs were received in less than that. The last two conditional tests would become:

Example #4

IF Timer0 Becomes > 10            if 10 seconds have elapsed
  THEN v0=0                       then reset count
  THEN Timer0=0                   and stop timer

IF v0 > 2                         if count has reached 3
  THEN v0=0                       then reset count
  THEN Timer0=0                   and stop timer
  THEN X10 Quick On B/1           and send B-1 ON command

This actually simplifies the program by eliminating the ANDs since we are testing for a single parameter being satisfied. Either the count has reached 3 and thus stopped the timer and reset the count (and sent the command), or the timer has reached 10 seconds, which means our count hadn't reached 3 when the timer expired (because if it did, the timer would have been stopped). The point of this example is that the timer counts up independently of the count of A-1 ONs received.

Timers and variables make for a powerful combination, as a variable can be used as a step counter to progress through a number of timed events. Most Ocelot users want it to be able to simulate an occupied house by turning lights on or off while they are absent. I have integrated this into my security system; when I arm the alarm system, the Ocelot starts to do its sequence to make the home look occupied. This is a good example of how to use variables as status indicators and event step counters. First, here is the routine that looks for the security system being armed or disarmed (my alarm system sends a D-13 OFF when in exit delay and a D-14 OFF when disarmed):

Example #5

IF X10 D/13 OFF Command                 * IF ALARM IS IN EXIT DELAY *
  THEN Transmit X10 A/All Lights OFF    turn off main floor lights
  THEN Transmit X10 B/All Lights OFF    turn off basement lights
  THEN v0=1                             V 0 = 1 = system armed
   
IF X10 D/14 OFF Command                 * IF ALARM IS DISARMED *
  THEN v0=0                             V 0 = 0 = system disarmed
  THEN v1=0                             V 1 = 0 (not-absent)
  THEN v2=0                             V 2 = 0 (stop progression)
  THEN Timer2=0                         stop progression timer

This section already shows all the timers and variables that will be used for the purpose of making the house look occupied. Variable V0 is a status indicator, it will be either 0 or 1, depending on weather the alarm system is armed or not. This can then be used by any routine that wants to take action depending on alarm system status ( like turn off water heater, lower thermostat setting, etc). V2 and Timer 2 are used as a progression counter and timer, we'll see this later. Here, we are just showing that they are stopped by setting them to zero when the alarm system is disarmed. V1 is the absent mode status indicator. A value of zero means we are not absent ( thus at home ). If we are absent, V1 will be set to either 1,2, or 3 by the following routine:

Example #6

IF Day of Week = 0                     if today is Sunday
 OR Day of Week = 3                    or Wednesday
 OR Day of Week = 5                    or Friday
 AND v0 = 1                            and alarm is armed
  THEN v1=1                            set absent mode to 1

IF Day of Week = 1                     if today is Monday
 OR Day of Week = 4                    or Thursday
 AND v0 = 1                            and alarm is armed
  THEN v1=2                            set absent mode to 2

IF Day of Week = 2                     if today is Thursday
 OR Day of Week = 6                    or Saturday
 AND v0 = 1                            and alarm is armed
  THEN v1=3                            set absent mode to 3

As you can see, V1 will be set to 1,2,or 3 depending on the day of the week, this is to allow running different "lived-in" routines every next day so the place doesn't look too "robotic". Now, note that V1 can only be set to 1,2, or 3 if the alarm system is armed, and that disarming it sets V1 to zero. Thus V1 being 1,2,or 3 implies that the alarm system is armed. This is important to know, because it will save us many conditional tests during the "lived-in" sequence. Knowing the exact meaning and implications of your variables makes programming a lot easier and consistent.

Now for the actual "lived-in" routine. I will only show one of the three possible "days" to save space, as only the difference is in the X-10 commands sent and the time delays used.

Example #7

IF v1 = 1                               	*ABSENT mode 1 step 1*
 AND TimeOfDay > Sunset + -30 minute(s) 	and half hour before sunset
 AND v2 = 0                             	and progression not started
  THEN Transmit X10 A/4                 	living room
  THEN Transmit X10 A/11                	kitchen
  THEN Transmit X10 A/15                	den
  THEN Transmit X10 A/ON                	turn ON units
  THEN v2=1                             	set progression = 1
  THEN Timer2=1                         	start timer 2 for progression

IF v1 = 1                               	*ABSENT mode 1 step 2*
 AND v2 = 1                             	if progression = 1
 AND Timer2 Becomes > 9600              	and ( 2h 40min) has elapsed
  THEN Transmit X10 A/All Lights OFF    	turn all lights off
  THEN Transmit X10 A/2                 	entrance
  THEN Transmit X10 A/3                 	daughter's room
  THEN Transmit X10 A/5                 	bathroom
  THEN Transmit X10 A/6                 	hall
  THEN Transmit X10 A/13                	kitchen counter 
  THEN Transmit X10 A/ON                	turn ON units
  THEN v2=2                             	set progression = 2
  THEN Timer2=1                         	start timer 2 for progression

IF v1 = 1                               	*ABSENT mode 1 step 3*
 AND v2 = 2                             	if progression = 2
 AND Timer2 Becomes > 5400              	and ( 1.5h ) has elapsed
  THEN X10 Quick Off A/5                	turn off bathroom
  THEN Transmit X10 A/4                 	living room
  THEN Transmit X10 A/14                	laundry
  THEN Transmit X10 A/ON                	turn ON units
  THEN v2=3                             	set progression = 3
  THEN Timer2=1                         	start timer 2 for progression

IF v1 = 1                               	*ABSENT mode 1 step 4*
 AND v2 = 3                             	if progression = 3
 AND Timer2 Becomes > 2400              	and ( 40 min ) elapsed
  THEN Transmit X10 A/6                 	hall
  THEN Transmit X10 A/13                	kitchen sink
  THEN Transmit X10 A/OFF               	turn OFF units
  THEN Transmit X10 A/5                 	bathroom
  THEN Transmit X10 A/10                	main bedroom
  THEN Transmit X10 A/ON                	turn ON units
  THEN v2=4                             	set progression = 4
  THEN Timer2=1                         	start timer 2 for progression

IF v1 = 1                               	*ABSENT mode 1 step 5*
 AND v2 = 4                             	if progression = 4
 AND Timer2 Becomes > 3600              	and ( 1 hr ) elapsed
  THEN Transmit X10 A/All Lights OFF    	turn everything OFF
  THEN v2=5                             	set progression = 5
  THEN Timer2=0                         	stop progression timer

Note how each IF section can only be entered if: we are in absent mode 1, we are at the correct step number; and the time duration for the previous step has been reached. See how easy it would be to add more steps, or to change the duration or commands within a step. To make the routine for absent mode 2, just copy and paste the whole routine and change the IF statements to IF v1 = 2. Also notice that when the last step is reached, the progression timer is stopped, but the progression variable is set to 5, and not zero. If it was set to zero, and midnight had not yet been passed, the whole routine would start over again because the first IF would again be satisfied. This means that we need an additional section to determine when the routine could be restarted:

Example #8

IF v1 = 1                               *ABSENT mode 1,2 or 3 step 6*
 OR v1 = 2                              if in any absent mode
 OR v1 = 3                              (V1 = 1,2,or 3)
 AND v2 = 5                             if progression = 5
 AND TimeOfDay = 300              	and time is 3:00 AM
  THEN v2=0                             set progression to 0 for
                                        the next day

IF v1 = 1                               *CUT ROUTINE IF LATE ENOUGH*
 OR v1 = 2                              if in any absent mode
 OR v1 = 3                              (V1 = 1,2,or 3)
 AND TimeOfDay = 2330                   and time has reached 11:30 PM
  THEN Transmit X10 A/All Lights OFF    turn OFF all "A" units
  THEN Transmit X10 B/All Lights OFF    turn OFF all "B" units
  THEN v2=5                             progression = 5
  THEN Timer2=0                         stop progression timer

When progression variable is set to 5, the "lived-in" routine has stopped progressing and is just waiting for time to be past midnight (in this case 3:00 AM) before being set to zero so that the next day's routine can be launched when its start time is reached. Also look at the "CUT ROUTINE…" section: I added that because the actual time that my lighting routines start is based on sunset, which varies widely between the summer and winter months. Each routine lasts around 6 hours or so, fine for winter but would end much too late in the summer, where sunset can be past 8:00 PM. The cut routine just looks to see that on any "absent" day, if the time has reached 11:30 PM, all lights are turned off and the progression is set to 5 and stopped, just as if we had reached the last step of a regular progression.

This rather long example (examples 5 through 8) shows that a great deal can be accomplished with just a few variables and a timer. Note that a timer can be reused many times if it's enabled or tested by mutually exclusive events (in this case, each routine is unique because of the progression counter and the absent mode number). For more random events, like a user triggered macro or input, it is best to use a timer exclusively for that routine, because the only parameter you will be testing is the timer itself (as in example #1). To use the same timer for two different such routines would cause interaction between them.

Stack Based Logic

A subject that needs some explanation is the stack based logic used with the Ocelot. This is somewhat similar to the last result on calculators, in that the internal stack always contains the result of the last calculation ( or logic test in this case ). This implies that you cannot use "parenthesis" to influence the order in which tests are done. On the Ocelot every logical test is done against the previous result (ie: there is no hierarchy of operations). Since you cannot use parenthesis, the order in which you place the tests becomes very important! Look at example 8 above: If v1 is equal to either 1,2,or 3 after executing the first three lines, the test will be TRUE at that point because any one of those lines will be satisfied. Lets examine the process in detail; suppose v1 equals 2 and v2 equals 5: The first line will test FALSE. The second line tests TRUE, being ORed with the previous result yields a cumulative TRUE. The third line is FALSE, but being ORed with a previous TRUE still gives us a TRUE at this point. The fourth line is an AND test, so it must be TRUE as well as the previous cumulative result for the THEN clause to be executed. Notice the word "previous" in each explanation…Now lets change the order of those 4 lines:

Example #9

IF v2 = 5                    if progression = 5
 AND v1 = 1                  and in any absent mode
 OR v1 = 2                   (V1 = 1,2,or 3)
 OR v1 = 3                             	

Seems to make sense doesn't it ? Using line by line analysis however: the first line and the second line will give us a FALSE result because in our test case, v1 is not equal to 1. However, these two lines could ALSO give us a FALSE result if v2 is not equal to 5 (it's an AND test, right ?). Now we get to the third line, which will test TRUE because yes, V1 is equal to 2. Since the third line is ORed with the previous result ( and so is the fourth line ), the statement could test true even if v2 is NOT equal to 5 ! Concretely, this reworked example would execute its THEN statements if both v1=1 AND v2=5; or if v1 is equal to 2 or 3 REGARDLESS of the value of v2. So remember: if you require one of several possible conditions plus some mandatory condition(s), put the OR statements FIRST !

One other point about this type of logic is that because you cannot have parenthesis, it's impossible to code for one of several AND conditions (ie: IF (a AND b) OR (c AND d)). You'll have to break this up into individual IF statements. For example ( suppose from the previous example that another valid condition would be if v1=4 and v2=6):

Example #10

IF v1 = 1                            *ABSENT mode 1,2 or 3 step 6*
 OR v1 = 2                           if in any absent mode
 OR v1 = 3                           (V1 = 1,2,or 3)
 AND v2 = 5                          and if progression = 5
  THEN bla bla bla 1
  THEN bla bla bla 2
   	
IF v1 = 4                            if in absent mode 4
 AND v2 = 6                          and if progression = 6
  THEN bla bla bla 1
  THEN bla bla bla 2

This works fine, but you have to repeat the THENs (and any ELSEs) twice. If the number of these is large, or if there are several groups of AND conditions that would require the same THENs/ELSEs to be executed, you could save on the number of program lines by using a variable to hold the result of each test (here we add a third valid possibility: if v1=5 and v2=7):

Example #11

IF v1 = 1                           *ABSENT mode 1,2 or 3 step 6*
 OR v1 = 2                          if in any absent mode
 OR v1 = 3                          (V1 = 1,2,or 3)
 AND v2 = 5                         and if progression = 5
  THEN v3 = 1                       set v3=1 because test is TRUE
   	
IF v1 = 4                           if in absent mode 4
 AND v2 = 6                         and if progression = 6
  THEN v3 = 1                       set v3=1 because test is TRUE

IF v1 = 5                           if in absent mode 5
 AND v2 = 7                         and if progression = 7
 OR v3 = 1                          or one of prev. tests was TRUE
  THEN v3 = 0                       reset variable for next tests
  THEN bla bla bla 1                and execute commands ...
  THEN bla bla bla 2

Here, any of several tests sets v3 equal to 1. The final test in the sequence looks for v3 having been set to 1 as a valid condition independently of any other test(s) of its own (hence the OR after an AND sequence). In its THEN statements, it also resets v3 to 0 so that the next iterations of the loop will be able to signal a new occurance of the right conditions being met (in LL, it is important to acknowledge that a one-time condition has been "consumed" by the targeted routine).

One-time vs Retriggered events

The last example of the previous paragraph introduces the notion of one-time events being recognized as such. This very important concept must be well understood for successful LL programming. Look at the following example:

Example #12

IF TimeOfDay = 2330                   	if time has reached 11:30 PM
  THEN Transmit X10 A/All Lights OFF    turn OFF all "A" units

Since our LL programs execute as a long continuous loop several times per second, you could argue that the all-lights-off command will be sent continuously during the entire minute that the time of day is equal to 11:30 PM, and you are technically correct! The way to do this only once would be to 1: Look for the time-of-day as well as a variable indicating that this is the first time we "see" the time being met. 2: Execute the command only if the variable is thus set and change the variable to indicate that command has now been executed. 3: Have another test check that the time has now been past so that the variable my be reset for the next day where the time is met again. Whew!

Fortunately, The Ocelot's language recognizes the need for tests to be normally satisfied only once per first occurance, and thus we have the "becomes" versions of the "=", "<", and ">" tests. Now, I used the IF TimeOfDay above as an example because it is an exception (and a slight inconsistency in my opinion) because it IMPLIES the "becomes" behavior. Thus example #12 really means "For the FIRST TIME that time of day becomes 11:30 PM…" All other tests that offer the regular conditional tests as well as "becomes" versions offer both possibilities. Make sure you understand and choose the right one! Here is an example of a use that could give unexpected results:

Example #13

IF Timer0 > 60                          after 1 minute
  THEN X10 Quick On A/1                 turn on A/1 device

Unless another THEN statement turns off Timer 0 in the same group of THENs, this routine will send A/1 ON commands continuously as long as Timer 0s value stays above 60. To correct that without needing an explicit "timer OFF" command (because you may want the timer to keep going for some other reason), you should change the above IF statement to: IF Timer0 becomes > 60. That way, the THEN will only be executed the first time Timer 0 is greater than 60. For this line to execute again (and any other "becomes" statement for that matter), the condition has to become FALSE again. Here is an example of how both types of test could be useful; We have an analog input representing a temperature on the first input of a SECU-16. We want to turn on the first output relay of the SECU-16 to turn on a heater if the voltage drops below 3V. Since the SECU-16 will report a voltage of 0 to 5V as a value from 0 to 255, this means that an input value less than 153 should turn ON the relay, otherwise we want it OFF:

Example #14

IF Module#1/Param#10 < 153              if input drops below 3V
  THEN Module#1/Point#8 Turns ON        turn ON first relay
  ELSE Module#1/Point#8 Turns OFF       else turn it OFF

This is also a good example of how ELSE can be used. Here, at every loop iteration, the relay will be updated to reflect the condition of the analog input, basically in real-time. Now, suppose we cannot use a relay, but have to send an X-10 command instead. Since X-10 commands only turn things ON or OFF once, we need an additional test to know when to turn the heating device OFF. This requires the following two test sequences:

Example #15

IF Module#0/Param#10 Becomes < 153      if input drops below 3V
  THEN X10 Quick On A/1                 turn ON X-10 device A/1

IF Module#0/Param#10 Becomes > 152      if input rises to 3V or more
  THEN X10 Quick Off A/1                turn OFF X-10 device A/1

See how we use the "becomes" version this time, to avoid having the Ocelot sending A-1 ON commands continuously as long as the input value test is TRUE. Notice how it would also be easy to introduce dead-band (hysterisis) by simply looking for a greater value than 152 in the second test statement.

Other Things You Should Know

As you program the Ocelot, some questions may come to your mind about certain conditions and how long they last. Daniel Smith of Applied Digital has provided the following information:

Received X-10 commands and status information is updated internally between program passes (loops). This means that you may look for such "one time" events as receiving a given X-10 ON command pair at several places in your code; each such test will be TRUE during the entire single pass following the status change.

At power-on, all timers are set to 0 (disabled) and all X-10 devices are deemed to be OFF. In an upcoming version of C-MAX (the programming utility for the Ocelot), there will be a parameter that will allow you to set a "cutoff" point in the variables; all variables below that point will be initialized to 0 upon power-on, all variables above that point will be retained (potentially very useful for recovering from power failures).

Conclusion

Ladder logic takes some getting used-to when you start working with it, but once you know the rules and possible pitfalls to avoid, you will find that you can accomplish almost anything using a rather minimalist instruction set. The only real disadvantages of a ladder logic system are that you'll find that you need many lines of code to accomplish otherwise simple tasks, and that the minimum time resolution of the system is limited by the speed of the processor, since you are always verifying the whole loop, even though most tests will be unnecessary in any given pass. These limitations are not much of a problem for a low speed application such as home automation and the Ocelot, with its 2000 line capacity, can handle quite a few tasks before the total number of lines becomes a problem. My hope is that this article will allow you to get the most out of your Ocelot and at the same time help you avoid some of the traps that ladder logic can spring upon you due to its unusual programming model.


Comments (0)

This post does not have any comments. Be the first to leave a comment below.


Post A Comment

You must be logged in before you can post a comment. Login now.

Featured Product

Light sockets; Not just for lights anymore

Light sockets; Not just for lights anymore

Smart Bulbs are out there and they can do far more then just provide light. Speakers, projectors, wi-fi extenders and more. The standard light socket that is wired up and ready to go in nearly every home in North America is now providing an easy and affordable option for home owners and renters alike to enter into the world of the "Smart Home". Here is a look at some of the Smart Bulbs and Smart Lighting options out there, and this list is just the beginning. In this ongoing article we hope to continue to add to and grow this list, so stay tuned!