Help with developing new HVAC application

I work for a HVAC manufacturer. We make commercial/industrial units. We’re looking to put a BACnet controller on our units to control & monitor the heating & cooling, as well as communicate with a BMS (when there is one).

Has anyone done something similar to this? Or Maurice, can you take a look at this? Thanks in advance for your help, I look forward to developing this project and implementing it on our units.

Below is some information to give you an idea of what we’re looking for.

Here are some items I want the BACnet controller to Control:
• Main fan/blower control - The ability to start/stop unit from the BMS or remote software
• Burner control – on/off, 2 stage or mod (0-10 vDC)
• Cooling control – relays to energize condensing units or chillers and also an analog output for modulating CW valves.
• Scheduling to setback the burner during unoccupied periods
• Economizer control for free cooling (using sensors mentioned below)
• Smoke detector shutdown - Shutdown unit and close dampers if smoke is detected

Here are some items I want the BACnet controller to Monitor:
• Burner status - send notification if it locks out
• Dirty filter alarm - send notification if pressure is too high
• Fan status / Fan failure - use current switch - shut down burner and send notification if current is not sensed when it should be
• CO2 sensor (maybe)
• Return air temp & humidity sensor, outside air temp & humidity sensor, discharge temp & humidity sensor

Thanks,
Jim

OUTPUTS:
First we can start by entering all the outputs, give each item a long name at Tab1 and a short name used in the programming at Tab2. Notice the analog outputs are lower down, you can see which output is analog or binary at Tab3. Configure the range field at Tab4, for our example all of them are just left at their defaults of off-on and 0-100% (over 0-10V).

This program will be suitable for systems with either on-off cooling & heating, or analog. We can build and program both types in this single example program.

1 Like

INPUTS:
Next do the same for all the inputs, give them a long and short name the same as we did for the outputs. The range is configured at Tab5, there are built in ranges for most common sensors and you can build custom tables for things like pressure sensors and so on.

There’s no sensors connected to the controller just now so the temperature shows as -40F and the status is showing as ‘Open’ at Tab6 for now.

The humidity sensors are set up as virtual inputs at Tab7 for now, we’ll assume you are using an external device connected over Bacnet RS485 subnet. Temco’s HUM series sensors have both temperature and humidity built in so the inputs configured at IN1 and IN2 are redundant but we can leave them there for now as an example of both directly wired sensors
at IN1 and IN2, and the networked sensors at Tab7.

Its not mentioned in your sequence but I have assumed there would be a button in the space to allow the user to put the unit into occupied mode after hours. It could also be an occupancy sensor to take care of this automatically. The input is wired to IN5.

We’ll write a small program later to poll the humidity readings from the networked sensors. I’ve temporarily set the values to manual mode at Tab8 for visual effect, when the program is written and the subnet sensors are connected they can be set to auto.

1 Like

VARIABLES
Here’s a first stab at the variables filled in and range configured. Its fairly similar to the other examples on this forum with a couple of additions:

  1. After hours override for the override button wired to IN5
  2. Lead and lag operation to even out the usage for both stages of heat and cool.
  3. OFF-ON two stage heating and cooling, with optional modulating heating and cooling outpus. Set these options up at Tab10.
  4. Enthalpy based free cool decision, as opposed to dry bulb only decision.
  5. Changeover and minimum run time for heating and cooling.
  6. Smoke alarm shutdown with prealarm.
  7. MIN and MAX supply temperature control

We’re going all in with the US egineering units here with enthalpy in BTU/LB, this is a custom range you can enter in in the custom units table. Also be sure to configure the timers with range 50 (time) as opposed to the other similar ones for hours, minutes and seconds. This will make it easier to do math with timers.

If there’s more you’d like to see let me know.

Schedules and Holidays

This is an easy step, just fill in the on and off times for the occupied hours at Tab11. My example just shows a single on and off time each day but you can set up several on and off events like lunch hours and recess times as appropriate.

The schedules for special holiday hours are set up at Tab13. You link a particular calendar to the schedule at Tab12, here we have linked ‘AR1’, short for Annual Routine. I noticed while doing this we should actually show the nickname ‘HOLIDAY’ as the calendar is named at Tab15, we’ll fix that in the next update.

Bring up the calendar and select all the special days as shown further down at Tab16, you can select several special days for each calendar with up to four separate calendars in each controller.

TIP: Calendars and schedules can be shared over the network with other controllers in order to simplify the work for the building operator later when adjusting schedules.

10 IF OCCUPIED THEN SETP101 = DAYSET ELSE SETP101 = NITESET

The OCCUPIED mode is one schedule in one of the controllers, any of them can be used but most logically it would be set up on PANEL1 of the system. This schedule can be used in the programming of all the controllers in the building. OCCUPIED will be automatically updated and shared over the network transparently.

PID Control Loops
We will use PIDs to stage the heating and cooling outputs as well as for the modulating damper during free cooling mode. Also it will be used for the analog heating and cooling equipment if that option is available in the system.

We could program some staging based on fixed offsets from the setpoint but a system without PID can sit near the setpoint for a long time without kicking on the heating or cooling. A system using PID will nudge the system along and be more responsive to lingering offsets from the setpoint.

At Tab17 is the feedback from the system, the temperature in the duct or the room or whatever process you are monitoring. It could be a variable containing the average of several sensors or any single input in the system. In this case we use the return air temperature in rows 3 and 4 to monitor the space conditions and we’ll use the supply duct temperature in rows 1 and 2 to keep the supply temp in the comfortable range, not too hot and not too cold.

At Tab19 are the setpoints, we’re using a separate variable for heating and another for cooling so as to have some deadband between the heating and cooling modes. At Tab20 we set the action to ‘+’ for cooling which means as the sensor goes over the setpoint the feedback increases. Heating is the opposite and if you forget which does what a popup will remind you every time you change it.

The P terms are a parameter which sets the ‘responsiveness’ of the system, a larger number means the system will be more tolerant of deviations (large number = lazy) from setpoint and a smaller number means the system will respond at the slightest deviation (small number = hyper active). For a PID loop such as one based on the return air temperature in rows 3 and 4, a degree or two from setpoint is a big deal so we will use ‘2’ here, this means the system will respond by 100% when the temperature is 2 DegF over or under setpoint. Regardless of whether you are in DegF or C you can start with 1 or 2 Deg and tune it up later. The P terms for the supply air PIDs will need to be a larger (lazier) numbers because the feedback loop is faster, as soon as a heat or cool stage comes on we’ll be seeing the supply air temperature rising or falling very quickly so start with something like a 5 as shown here.

The I term is set to zero to get started, this is the integral term which will add up the temperature error over time and nudge the system along into heating or cooling, set it to zero to keep things simple during inital debugging.

So this is all set to go, PID1 is for the supply air minimum supply temp. PID2 is for the maximum supply air temp. PID3 is the cooling action of the space (return air) and PID4 is for the heating action of the space.

Now we need a small program to connect the outputs to these PIDS.

Todo: Free cooling PID

PROGRAMS

Now for the programming, its not done yet but here’s where I am at.

10 REM ********** ENABLE FAN ACCORDING TO SCHEDULE *********
20 IF OCCUPIED OR AHU1OVMD THEN START AHU1FAN
30 IF AHU1NITH OR AHU1NITC THEN START AHU1FAN
40 IF NOT AHU1OVMD AND NOT OCCUPIED AND NOT AHU1NITH AND NOT AHU1NITC THEN STOP AHU1FAN
50 IF AHU1SMKS THEN STOP AHU1FAN

OCCUPIED is the schedule that we set up earlier, AHU1OVMD is the overide mode which is triggered by a momentary contact wired to input5. The program was getting a little long so I put the logic for this button and timer in a separate timer program #2. A hit on the override button triggers a counter to a certain value and then decrements it every second till it hits zero at which time the AHU1OVMD overide mode then goes to off. The fan will come on if the schedule or overide mode are true. The fan can also come on for night heating and cooling, if either of these are true the fan can also come on in the unoccupied period to maintain the night setpoints.

The nigh cooling and night heating variables, if they are ON then heating and/or cooling can come on at night. If you want to lock out night cooling or heating you just toggle these to OFF.

The smoke detector shutdown is the last line related to the fan, this means it has higher priority than all the preceding lines. If there’s smoke you want to shut this unit down, no matter what logic is up above. Normally there’d be a hardwired interlock anyway but its good to have it in the logic as well.

60 REM ********** COOLING ****************
70 IF PID1 > 30 THEN START AHU1COL1
80 IF PID1 > 50 THEN START AHU1COL2
90 IF PID1 < 25 THEN STOP AHU1COL1
100 IF PID1 < 45 THEN STOP AHUCOL2
110 IF NOT AHU1COK THEN STOP AHU1COL1 , STOP AHU1COL2
120 IF AHU1KFAN = 2 THEN STOP AHU1COL1 , STOP AHU1COL2
130 IF NOT OCCUPIED AND NOT AHU1NITC THEN STOP AHU1COL1 , STOP AHU1COL2
140 IF NOT AHU1FAN THEN STOP AHU1COL1 , STOP AHU1COL2

The cooling is done by staging of stage1 and 2 at the rather arbitrary trip points as shown. The trip points have a hysterisis of 5%, this is a small gap to avoid short cycling around the trigger points. The stage1 and stage2 also have a small gap to avoid jumping between one stage and two stage cooling.
Lines further down in the program will override the earlier lines, so we put some lockouts further down, like line 140 if the fan is off we dont want the compressor on. Similarly in line 130 if the building is unoccupied and the night cooling is OFF then we dont want the cooling coming on. Line 120 is for the case where the program is loaded into a Tstat10, the user can command the system into heating (2) or cooling (1) and so on from the keypad.

150 REM ********** HEATING ****************
160 IF PID2 > 30 THEN START AHU1HEA1
170 IF PID2 > 50 THEN START AHU1HEA2
180 IF PID2 < 25 THEN STOP AHU1HEA1
190 IF PID2 < 45 THEN STOP AHU1HEA2
200 IF NOT AHU1HOK THEN STOP AHU1HEA1 , STOP AHU1HEA2
210 IF AHU1KFAN = 1 THEN STOP AHU1HEA1 , STOP AHU1HEA2
220 IF NOT OCCUPIED AND NOT AHU1NITH THEN STOP AHU1HEA1 , STOP AHU1HEA2
230 IF NOT AHU1FAN THEN STOP AHU1HEA1 , STOP AHU1HEA2

The heating works in the same way as the cooling but using its own heating PIDs to drive the staging.

240 REM *************** SETPOINTS ***************
250 IF OCCUPIED OR AHU1OVMD THEN AHU1SETP = AHU1DSET ELSE AHU1SETP = AHU1NSET
260 IF AHU1SETP > AHU1MAXS THEN AHU1SETP = AHU1MAXS
270 IF AHU1SETP < AHU1MINS THEN AHU1SETP = AHU1MINS
280 AHU1CSET = AHU1SETP + COOLDB
290 AHU1HSET = AHU1SETP - HEATDB

If the building is in occupied or overide mode then the main ‘setpoint’ is equal to the ‘daytime setpoint’, otherwise set it to the night time setback setpoints. The main ‘setpoint’ is a single setpoint which the user can see on the dipslays to manage it manually. It could also be on the display of the Tstat10 and managed from the keypad if this program were to be loaded into one of those.

The heating and cooling setpoints are offset from the main ‘setpoint’ by the cooling and heating deadbands in lines 280 and 290. Normally these will be a degee or two DegF or C. The gap provided by these deadbands helps prevent simultaneous heating and cooling which can happen when you are using integral control, the I term in the PID settings screens above. We also have the changeover delay so this gap could in theory be zero… but I like to use the gap and adjust it for day and night in the program. During the daytime we can program in a small gap for optimum comfort and at night the gap can be loosened up.

Lines 260 and 270 will clip the main ‘setpoint’ between the min and max settings. This is done to keep the user from cranking the value too high or low, either from the T3000 user screens and/or the Tstat10 keypad if that applies to your project.

ToBeDone:
lead/lag operation,
modulating option,
free cooling & damper
min and max supply temp limits
Tstat10 option, occupant control from keypad.

https://temcocontrols.com/ftp/software/28_TwoHeatTwoCoolPlusModulatingOption_Rev3.prog

CHANGEOVER DELAY

320 REM *************CHANGEOVER DELAY *******
330 IF AHU1COL1 OR AHU1COL2 THEN START AHU1COOL ELSE STOP AHU1COOL
340 IF AHU1HEA1 OR AHU1HEA2 THEN START AHU1HEAT ELSE STOP AHU1HEAT
350 AHU1TOC = TIME-OFF ( AHU1COOL )
360 AHU1TOH = TIME-OFF ( AHU1HEAT )
370 IF AHU1TOH > AHU1DELA THEN START AHU1COK ELSE STOP AHU1COK
380 IF AHU1TOC > AHU1DELA THEN START AHU1HOK ELSE STOP AHU1HOK
390 REM *** TSTAT10 KEYPAD OVERRIDE IF APPLICABLE
400 IF AHU1KMOD = 0 OR AHU1KMOD = 1 THEN STOP AHU1HOK
410 IF AHU1KMOD = 0 OR AHU1KMOD = 2 THEN STOP AHU1COK

Lines 330 and 340 are two flags that are true whenever heating or cooling is active.

The next two lines 350 and 360 are two timers keeping track of how long cooling and heating have been off. Lines 370 and 380 compare these timers to the changeover delay parameter, AHU1DELA, if the timer is greater than the delay then the heating & cooling OK flags AHU1COK and AHU1HOK become true.

Lines 400 and 410 are there for when this program is used in a Tstat10, the user can override the modes from the keypad by setting the system into various modes: off mode = 0, cooling only mode = 1, heating only mode = 2, and auto mode = 3. This setting is stored in VAR3 and has the user name "AHU1 KEYPAD MODE’ or short name AHU1KMOD. When the user toggles the modes on the Tstat10 keypad this variable cycles through the various values and gives the occupants some local control. If the program is running in a T3 controller which has no keypad you can just toggle these three vars to manual mode as I have done here. To make things even simpler and clearer you could delete these vars and associated programming.

HI AND LOW SUPPLY AIR TEMP LIMITS
In the first draft of the program we used just the return air temperature to control the staging of the heating and cooling, this is fine for maintaining the space temperature but we can do better by limiting the upper and lower supply temperatures to a comfortable range. We have these high and low limits stored in variables 18 and 22 and they are used in PID’S 1 & 2. Line 70 will take the smaller of the two cooling PIDs, one based on supply air and the other based on return air, and use that to control the staging. If the supply air temp should drop down to an uncomfortable temperature PID1 is going to fall below PID3 and limit the staging.

The same thing applies to the heating, in line 170 we check the supply air and return air based heating PIDs 2 & 4 and take the lower of these two PIDs. If the supply air rises to an uncomfortably high temperature PID2 is going to be lower than PID4 and it will reduce the supply air temp.

Moving a little further down in the program, now we have two local variables PIDCOOL and PIDHEAT, you can see they are local variables since they are greyed out. We use local variables since we dont really need to see the result of this simple calculation anywhere in the displays or trend logs, also we save one global variable doing this. In the next few lines we now use this temporary variable to stage the cooling ad heating rather than the PID itself in the examples further up.

ToBeDone:
lead/lag operation,
modulating option,
free cooling & damper