Ana səhifə

Leopard II manual Table of Contents


Yüklə 3.21 Mb.
səhifə15/16
tarix24.06.2016
ölçüsü3.21 Mb.
1   ...   8   9   10   11   12   13   14   15   16

5.3A Sample C-Max Application, Heat/Cool Thermostat



Introduction
The purpose of this application note is to demonstrate how C-Max logic tests can be used to create home automation control programs. The intent is not to present a “ready made” solution for a particular problem, but to show how the ideas for how you want to do things can be translated into actual program code.

A simple thermostat for heating
For most people, the first example that comes to mind when thinking about a user settable setpoint application is a thermostat; so let’s use it. This sample application supposes that the programmer wants to use a Leopard II controller with a temperature Bobcat to turn on a heating appliance when the temperature reading from the Bobcat goes below a setpoint that can be selected by the touch screen user. The Leopard II screen will have two buttons defined; one for raising and one for lowering the setpoint. Additionally, the touch screen will display the setpoint and the current temperature. Finally, the buttons and displayed temperatures will have appropriate text labels. An Ocelot user will obviously not have the same user interface to choose the setpoint, but alternate methods (such as X-10 signals) can be used, and the actual control logic will work just as well with either controller.
These examples make the following assumptions: The controller is module 0 and the Temperature Bobcat is module 1. The heat will be turned on by sending an X-10 “N/1 N/On” command pair (with the “Quick ON” controller commands) and conversely be turned off with a N/1 N/Off command pair. Variables and timers are assigned from 0 on up as needed. Of course, feel free to substitute other module numbers and Variable/Timer numbers as you see fit, if you are trying or using these examples in an existing system.
User Interface
This section assumes that the programmer is familiar with setting up Leopard screens. If not, review the procedures earlier in the manual. Create the first button with a “-“ caption and the second one with a “+”.

Also note the “object #” displayed when the pointer is positioned over the buttons you just created, these become the button numbers used when programming. For this example, the “-“ button is object #1 and the “+” button is object #2. Create the two text fields that will display the setpoint and the actual temperature by using the “Large Numbers Only” font setting when adding these text fields. The “%3d” caption allows for displaying up to 3 digits. Also be sure to link the setpoint to the right Variables by clicking “Variable Data in Text” in the field properties. In this example, the setpoint will be in Variable #0 and the actual temperature in Variable #1. Finally, create the text labels to properly identify the temperatures. Feel free to position the various buttons and text fields to your liking; this is what a programmable controller is all about! Below is a picture of the screen created for this example (fig. 94):





Fig. 94


Program Logic
The first thing we want to do is convert our button presses on the touch screen to a setpoint stored in Variable #0. We need two program segments to do this, one for the “-“ button and one for the “+” button (fig. 95).
User interface logic
0001 - IF Touch Object #1, Button Leopard is pressed

0002 - THEN Variable #0 - 1

0003 - IF Touch Object #2, Button Leopard is pressed

0004 - THEN Variable #0 + 1
Fig. 95
We then need to create two more program segments to actually read the temperature and compare it against the setpoint. One segment looks for the temperature being below the setpoint and will turn on the heat if that is the case, the other segment tests for the setpoint having been exceeded so that the heat can be turned off (fig 96).
Control logic (version 1)
0005 - IF Module #1 -BOBCAT-T becomes < Variable #0

0006 - THEN X-10 House N / Unit 1, Turn ON

0007 - IF Module #1 -BOBCAT-T becomes > Variable #0

0008 - THEN X-10 House N / Unit 1, Turn OFF
Fig. 96
That’s it. We now have a simple heating thermostat. A few things to note here. First: notice how we look for the temperature to have exceeded the setpoint instead for just reaching it? This was done to avoid short, inefficient heating cycles by having the program look for a full 1 degree increase in temperature before stopping the heater, and for a 1 degree drop before turning it back on (in a control system, this is called hysterisis). A razor-sharp detection precision would not be in our best interest here. Second: we used the “becomes” versions for the compare instructions because a simple “<” test would have been sending X-10 commands continuously as long as the test was true. By using single triggering instructions like these, we are free to send single shot events like X-10 commands or using continuous state commands like turning on SECU16 or RLY8/XA relays. Now, as good and functional as this may look, there is one slight potential shortcoming that could be improved upon. If the heat is turned on and the temperature rises to the setpoint, but then dips below it again because of air movement or someone opening a door, another X-10 “on” command will be sent. This means that unnecessary repeated On or Off commands will still occur if there are slight variations on subsequent temperature readings (in digital systems, this is sometimes called digit bobble). To avoid these extraneous X-10 signals, the first solution that comes to mind is to use a variable as a flag to know that if the heat has already been turned on, there is no need to do it again until the setpoint is exceeded. Here thus is a modified version of the control logic, using Variable #2 as a flag (fig. 97):
Control logic (version 2)
0005 - IF Module #1 -BOBCAT-T becomes < Variable #0

0006 - AND Variable #2 is = 0

0007 - THEN X-10 House N / Unit 1, Turn ON

0008 - THEN Variable #2 = 1

0009 - IF Module #1 -BOBCAT-T becomes > Variable #0

0010 - AND Variable #2 is = 1

0011 - THEN X-10 House N / Unit 1, Turn OFF

0012 - THEN Variable #2 = 0
Fig. 97

That will work and could be left this way without any further changes, but there is a better way to do this with C-Max. The controller maintains an internal status table of all 256 X-10 addresses and of all module (ie:SECU16) outputs. This means that if it turns on an X-10 module or “sees” and external command coming from any X-10 transmitter to turn a module on or off, it will update its table with the appropriate status. Since our own program is turning the heater on or off, we can consult the status table to see if the unit is already on or off instead of using a Variable to “remember” if this was done. Rewritten to use this, our control logic becomes (fig. 98):


Control logic (version 3)
0005 - IF Module #1 -BOBCAT-T becomes < Variable #0

0006 - AND X-10 House N / Unit 1, Is OFF

0007 - THEN X-10 House N / Unit 1, Turn ON

0008 - IF Module #1 -BOBCAT-T becomes > Variable #0

0009 - AND X-10 House N / Unit 1, Is ON

0010 - THEN X-10 House N / Unit 1, Turn OFF
Fig. 98

Now, not only is the program easier to understand, but we have “saved” a Variable and also eliminated the two “Then” statements used to update the Variable.


Initialization
We bring up the subject of initialization at this point because now is a good time to look at some potential problems with our control logic and with the controller in general. The question is: what do we do when the power is first applied to the controller, or if the power fails and comes back on? Suppose for example that the power is interrupted briefly and the heater was left ON. Many X-10 appliance modules have a latching relay that will cause it to be ON when the power comes back. The module also has no method to tell the controller that it is ON. The controller will reboot and start with a blank status table (everything assumed OFF). Also suppose that the ambient temperature was warm enough that the setpoint is exceeded (or at least reached) at the time the power comes back. Looking at our program logic, the second segment can never test true because the status table assumes the module is OFF. So the heater keeps heating and the controller cannot do anything to stop it! For this reason, and others (like wanting an initial setpoint to be other than zero!) an initialization sequence may be desirable and even necessary. Assuming that we are using variables below that specified in Parameter 22 of the controller (variables at and above this value are retained after a power interruption), you can create a sequence of commands that will be executed only once, right after a power on. Use a spare Variable and look for it being equal to zero, and then at the end of your initialization sequence set it to a non-zero value so that it is not executed again. For our example, lets set an initial setpoint of 72 degrees, and lets turn OFF the heater if the ambient temperature is above the setpoint. Using spare Variable #9, our code is (fig 99):
Initialization
0011 - IF Variable #9 is = 0

0012 - THEN Variable #0 = 72

0013 - IF Variable #9 is = 0

0014 - AND Module #1 -BOBCAT-T is > Variable #0

0015 - THEN X-10 House N / Unit 1, Turn OFF

0016 - IF Variable #9 is = 0

0017 - THEN Variable #9 = 1
Fig. 99
If you wanted a non-volatile setpoint, then you could use a Variable for it whose number is greater than or equal to the number in Parameter 22 of your controller.

A full featured thermostat for heating and cooling
The first application above gave us a feel for how a user interface and control logic can create a workable thermostat. However functional, it is still rather primitive compared to commercially built units. After all, how many thermostats have you seen that let you raise the setpoint all the way up to 65535! The following application takes the same principles as the first one and brings it up to standards similar to those of commercial units. Specifically, it adds the following features:
- Two stage heating and single stage cooling ( if the heating setpoint is not reached after 15 minutes of having turned on the heat, a second heating source is turned on ).
- A high setpoint limit of 90 degrees and a low one of 50, with an error “beep” if the user tries to exceed these values.
- A minimum spread of 2 degrees between the heat and cool setpoints (eg: you can’t raise the heat setpoint above 72 if the cooling setpoint is set to 74).
- A 3 second delay before turning on heating or cooling whenever the setpoint(s) are being modified by the user. This is to avoid damaging the heating/cooling equipment caused by powering it on and then off quickly.
- Indicator lights on the Leopard screen to show which heating or cooling stages are turned on.
User Interface
Here is the new, modified Leopard screen to allow the setting of the heating and cooling setpoints, as well as showing the indicator lights showing current status (fig. 100).
This example screen has the following characteristics:
Heat “-“ button is object #1

Heat “+“ button is object #2

Cool “-“ button is object #8

Cool “+“ button is object #9


Heat setpoint display is linked to Variable #0

Cool setpoint display is linked to Variable #1

Room temperature display is linked to Variable #4
Heat status light is linked to X-10 status for N/1

Aux Heat status light is linked to X-10 status for N/3

C
ool status light is linked to X-10 status for N/2
Fig. 100
Program Logic

For this application, the entire program will be shown first, and we will then analyze the various program segments, explaining each one by referring to line numbers. This will allow you to see each function in its logical context and make the whole program easier to understand. Here is the program listing (fig. 101):


initialization
0001 - IF Variable #0 is = 0 // if heat setp. is 0

0002 - THEN Variable #0 = 72 // then set heat to 72

0003 - THEN Variable #1 = 75 // then set cool to 75

0004 - THEN X-10 House O / Unit 1, Turn OFF // turn off heat

0005 - THEN X-10 House O / Unit 2, Turn OFF // turn off cooling

0006 - THEN X-10 House O / Unit 3, Turn OFF // turn off aux heat

0007 - IF Touch Anywhere Button #0, Button Leopard is pressed // if on blank screen

0008 - THEN Variable# 63 / Screen# = 1 // go to screen 1
continuously calculate spread…
0009 - IF Variable #2 is = Variable #2 // dummy "if" (always)

0010 - THEN Variable #2 = Variable #1 // take the cool setpt

0011 - THEN Variable #2 - Variable #0 // and subtr heat setpt
and display current temperature
0012- THEN Variable #3 = Data for Module# 1 // get temp. from bobcat

0013 - THEN Variable #3 - 100 // subtract 100

0014 - THEN Variable #4 = Variable #3 // put in display var.
user-error beep section
0015 - IF Touch Object #2, Button Leopard is pressed // if heat + button

0016 - OR Touch Object #8, Button Leopard is pressed // or cool - button

0017 - AND Variable #2 is < 3 // and setpt at min spread

0018 - THEN Variable# 61 / Beep-Variable = 1 // then beep user!

0019 - IF Touch Object #1, Button Leopard is pressed // if heat - button

0020 - AND Variable #0 is = 50 // and at low setp lim

0021 - THEN Variable# 61 / Beep-Variable = 1 // then beep user!

0022 - IF Touch Object #9, Button Leopard is pressed // if cool + button

0023 - AND Variable #1 is = 90 // and at hi setp lim

0024 - THEN Variable# 61 / Beep-Variable = 1 // then beep user!
heat setpoint setting
0025 - IF Touch Object #2, Button Leopard is pressed // if heat + button pressed

0026 - AND Variable #0 is < 90 // and setpoint is below 90

0027 - AND Variable #2 is > 2 // and spread is > than 2

0028 - THEN Variable #0 + 1 // increment heat setpoint

0029 - THEN Timer #0 = 1 // and start the setp timer

0030 - IF Touch Object #1, Button Leopard is pressed // if heat - button pressed

0031 - AND Variable #0 is > 50 // and setpoint is above 50

0032 - THEN Variable #0 - 1 // decrement heat setpoint

0033 - THEN Timer #0 = 1 // and start the setp timer
cool setpoint setting
0034 - IF Touch Object #9, Button Leopard is pressed // if cool + button pressed

0035 - AND Variable #1 is < 90 // and setpoint is below 90

0036 - THEN Variable #1 + 1 // increment cool setpoint

0037 - THEN Timer #0 = 1 // and start the setp timer

0038 - IF Touch Object #8, Button Leopard is pressed // if cool - button pressed

0039 - AND Variable #1 is > 50 // and setpoint is above 50

0040 - AND Variable #2 is > 2 // and spread is > than 2

0041 - THEN Variable #1 - 1 // decrement cool setpoint

0042 - THEN Timer #0 = 1 // and start the setp timer
setpoint timer expiry test
0043 - IF Timer #0 becomes > 4 // if setp timer expires

0044 - THEN Timer #0 = 0 // then stop it.

turn ON heat
0045 - IF Module #1 -BOBCAT-T becomes < Variable #0 // if temp is below setp

0046 - AND Timer #0 is = 0 // and not in setp timeout

0047 - AND X-10 House O / Unit 1, Is OFF // and heat is off

0048 - THEN X-10 House O / Unit 1, Turn ON // then turn if on

0049 - THEN Timer #1 = 1 // start aux heat timer

0050 - IF Module #1 -BOBCAT-T is < Variable #0 // if temp is below setp

0051 - AND Timer #0 becomes = 0 // and setp timer expires

0052 - AND X-10 House O / Unit 1, Is OFF // and heat is off

0053 - THEN X-10 House O / Unit 1, Turn ON // then turn if on

0054 - THEN Timer #1 = 1 // start aux heat timer
turn OFF heat
0055 - IF Module #1 -BOBCAT-T becomes > Variable #0 // if setpoint is exceeded

0056 - AND Timer #0 is = 0 // and not in setp timeout

0057 - AND X-10 House O / Unit 1, Is ON // and heat is already on

0058 - THEN X-10 House O / Unit 1, Turn OFF // then turn it off

0059 - THEN X-10 House O / Unit 3, Turn OFF // and turn aux heat off

0060 - THEN Timer #1 = 0 // stop the aux heat timer

0061 - IF Module #1 -BOBCAT-T is > Variable #0 // if setp is exceeded

0062 - AND Timer #0 becomes = 0 // and setp timer expires

0063 - AND X-10 House O / Unit 1, Is ON // and heat is already on

0064 - THEN X-10 House O / Unit 1, Turn OFF // then turn it off

0065 - THEN X-10 House O / Unit 3, Turn OFF // and turn aux heat off

0066 - THEN Timer #1 = 0 // and stop aux heat timer
Aux Heat timer expiry test
0067 - IF Timer #1 becomes > 900 // if aux heat timer expires (15 mins.)

0068 - AND X-10 House O / Unit 1, Is ON // and 1st stage heat is on

0069 - THEN X-10 House O / Unit 3, Turn ON // then turn on aux heat

0070 - THEN Timer #1 = 0 // stop the aux heat timer
turn ON cooling
0071 - IF Module #1 -BOBCAT-T becomes > Variable #1 // if temp is above setp

0072 - AND Timer #0 is = 0 // and not in setp timeout

0073 - AND X-10 House O / Unit 2, Is OFF // and cooling is off

0074 - THEN X-10 House O / Unit 2, Turn ON // then turn if on

0075 - IF Module #1 -BOBCAT-T is > Variable #1 // if temp is above setp

0076 - AND Timer #0 becomes = 0 // and setp timer expires

0077 - AND X-10 House O / Unit 2, Is OFF // and cooling is off

0078 - THEN X-10 House O / Unit 2, Turn ON // then turn if on
turn OFF cooling
0079 - IF Module #1 -BOBCAT-T becomes < Variable #1 // if setp is exceeded

0080 - AND Timer #0 is = 0 // and not in setp timeout

0081 - AND X-10 House O / Unit 2, Is ON // and cooling is on

0082 - THEN X-10 House O / Unit 2, Turn OFF // then turn it off

0083 - IF Module #1 -BOBCAT-T is < Variable #1 // if setp is exceeded

0084 - AND Timer #0 becomes = 0 // and setp timer expires

0085 - AND X-10 House O / Unit 2, Is ON // and cooling is on

0086 - THEN X-10 House O / Unit 2, Turn OFF // then turn it off

0087 - End Program //
Fig. 101
Explanatory Notes:
Beginning with the initialization section, note how we can use Variable# 0 as an initialization flag this time. This is because our low and high setpoint limits prevent us from ever setting this variable (the heat setpoint) to zero again, so the only time it can be zero is upon power up. The segment that looks for button 255 being pressed (line 7) is looking for the first time the touch screen is pressed, and then displays our thermostat screen.

Line 9 might seem a bit odd at first. This is just a way of having the following five “Thens” executed on every pass. Line 12 is a good example of the usage of extended variables. These variables refer to the module number of a bobcat + 128. In our case, the Leopard is module #0 and the temperature bobcat is module #1 (as you can deduce from looking at line 45). This allows you to copy the bobcat’s temperature reading into a variable, instead of just comparing against it like in line 45. We need to do this because we want to do some math manipulation on it before displaying it (and you cannot link a Leopard screen object to a variable greater than 127 anyway). Also note that this copies the bobcat’s raw data value, which is 100 higher than the temperature in degrees F. (this is to allow reading temperatures below zero without running into negative numbers, which are not implemented as such in C-Max). Be careful with this distinction if you mix bobcat compares and extended variables in your program, like in this application. The final calculated temperature is placed in Variable #4 for screen display.


The “user-error beep” is watching for the user trying to either exceed a high or low setpoint limit, or trying to set either limit less than 2 degrees from the other. Note that there is no need to look for the user trying to raise the heat setpoint to the high limit or lower the cool setpoint to the low limit, because trying this will be caught by the minimum spread instead (ie: if cooling is set to the high limit of 90, the minimum 2 degree spread rule will prevent the heat sepoint from going any higher than 88 automatically). Notice that these routines only look for the user trying to press buttons that will violate the limits; the actual enforcing of these limits is done in the setpoint setting routines, which come next. Lines 18,21 and 24 make the Leopard “beep” for 1 second, by copying a “1” into Variable #61, which is specially designated by design to beep for the number of seconds copied into it. Another very important thing to understand is that any single triggered events, like X-10 commands, screen button presses, etc., are valid for one entire pass through the program, so lines 15 and 25 are actually detecting the same button press! Single events are thus NOT “consumed” by the first program line that detect them, which would otherwise oblige us to flag the single event into a variable and then compare against the flag in other segments where we need to detect the event, and finally we would need to reset the flag near the end of our pass. This would burden our program code considerably! Lastly, single triggered events always get detected between passes through the program, so lower line-numbered statements will always see them first. This is important to know if you have order-sensitive code. We have a good example of this right here: lines 22 and 23 produce the error beep if the high limit of 90 degrees is already reached and the user tries to exceed it. Lines 34 and 35 look to allow setting the setpoint all the way up to 90 if it not reached yet. If you were to invert the two routines, you would get an error beep when the cool setpoint is set exactly to 90 degrees, because the line 22,23 segment would then test true later in the pass, after the setpoint was set to 90.
The heat setpoint setting section is quite straightforward and needs little explanation; verify if a limit or spread is going to be violated by the change and if not, do it. The cool setpoint setting section is virtually identical except that it modifies Variable #1 instead of Variable #0. If you carefully followed the description of the error-beep section in the last paragraph, you will notice that lines 26 and 39 are actually superfluous, since the checking of the setpoint spread will never allow these limits to be reached (these lines were deliberately left in the code to illustrate this...). It also shows how you can quickly code similar segments by copying and pasting code and then editing the differences. The other item of interest in the setpoint setting routines is Timer #0 started by lines 29, 33, 37 and 42. This means that any setpoint button presses start (or restart ) the timer at 1. This is used in later program sections to prevent any heating or cooling action to be started until we are sure the user has finished modifying the setpoints (to prevent damaging equipment, especially compressors, with very short on or off cycles caused by the user modifying the temperature settings). The setpoint timer expirey section simply looks for the setpoint timer to have exceeded 4 seconds of continuous incrementing, which means the user has not pressed a button for at least 4 seconds, and then stops the timer. The way this is used will become clear in the next sections.

The four routines for turning the heat on or off, or the cooling on or off are all quite similar and also illustrate a very important point about steady state and single triggering events. First of all, you’ll notice that each of those program sections have two sets of test statements for doing the same thing (if we had parenthesis, these could have been coded as IF (line 45 AND line 46 AND line 47) OR (line 50 AND line 51 AND line 52) THEN lines 48 and 49... this is equivalent here). The reason for the two sets of tests is that to turn on the heat (to use that one as an example), either: 1-The temperature drops below the setpoint due to the room getting colder, with the setpoint timer not running because the setpoint has been set a while ago (lines 45 and 46) or : 2- the temperature was fine, but the user has decided to raise the setpoint, which means the room temperature might have been below the new setpoint for some time, but now we have to wait for the setpoint timer to expire before turning on the heat ( lines 50 and 51). The lesson here is that you will want one and only one single triggering event to cause a single shot action like sending an X-10 command. If you were to look for Timer# 0 becoming 0 AND the setpoint becoming less than Variable #0, these two single triggering events would have to occur during the same pass through the program for the segment to test true, which is almost impossible. Conversely, to look for both conditions simply being true, you would be sending X-10 commands continuously as long as the setpoint is not yet exceeded by the heating in the room. You want to look for a single triggering event plus any other required conditions being already true. Two possible single triggering events thus means two sets of test conditions. This is the reason for all those “becomes” versions of the IF statements. Without them, prgramming would be a nightmare, with the need once again to use variables as flags to accomplish what we can do here with a lot less code. Make sure you understand this concept thoroughly and you will find your programs much easier to design. You must “think through” all the possible conditions and code them appropriately.


Like in the first simple heat-only thermostat example, we look at the existing state of the X-10 module to determine if an on or off command is needed. Note that all four program segments are very similar, with the only differences being the variables being compared and the X-10 module addresses being turned on or off. The only real difference is that the heating mode also starts Timer #1 whenever the heat is turned on. This timer is used to determine if the heat has been turned on for 15 continuous minutes (lines 67 and 68). If that is the case, an auxiliary heating source is turned on, as a second stage to provide faster heating. Note that lines 59 and 65 in the turn off heat section always send an off signal to turn off auxiliary when the setpoint is finally exceeded, whether auxiliary heat had been turned on or not (this occurs rarely enough to not warrant a seperate test section, but it could be done if needed). It is easy to see how auxiliary cooling could be implemented if required.
1   ...   8   9   10   11   12   13   14   15   16


Verilənlər bazası müəlliflik hüququ ilə müdafiə olunur ©atelim.com 2016
rəhbərliyinə müraciət