Differential Controller source code listing
' Firmware Program for Comfile CB210 - Dual Pump - Differential Temperature Controller
' Version 17 of 18 Feb. 2013
'
' Cubloc Studio Configuration:
' Com Port # of Debug Terminal = that assigned by MS Windows: see Control Panel
' /Hardware Devices, [typically COM4].
' Baud Rate: default 115,200, Parity: default none, Data bits: default 8
' Cabling between PC and CB210: ordinary USB cable [used for debug only,
' cabling and PC un-necessary in final installation]
'
' Hardware Configuration:
' I/O Port Usage:
' A0 16 = solar collector thermistor divider, A to D input;
' A1 17 = storage tank thermister divider, A to D input;
' A10 = input port, "test push button", active low; only polled right after
' port 30, 3 second LED goes "OFF" [ie: push during LED "ON" and hold until
' LED goes "OFF"] - useful for manually testing activation of pumps
' during installation. Push button circuit consists of a momentary SPST
' switch, a capacitor of 0.001 to 0.01 micro-farads across the switch
' contacts, one switch contact is tied to ground, the
' other switch contact has both a 4.7k resistor up to + 5 Volts, and a
' "sense wire" to input port A10.
' 11 = output port, "main" pump "1" pwr control, 1- enable, 0- disable,
' drives gate of a IRF540 power FET-1 switching to ground level;
' 12 = output port, "secondary" pump "2" pwr control, 1- enable, 0- disable,
' drives gate of a IRF540 power FET-2 switching to ground level;
' 13 = output port, thermistor power, 0- enable, 1- disable,
' drives gate of a VN10K FET-3, turning on current at ground end;
' 30 = CB210 onboard LED, used to blink LED on each 60 second sense loop.
'
' Power and Grounds:
' The POS terminal of a lead acid auto battery [~ +13.3Vdc under charge] directly
' powers both circulator pumps via the interface board [note: there is no
' direct +13.3 Vdc connection to the CB210 processor board!], an in-line fuse
' is recommended at the battery + terminal [~ 7 to 10 amp.];
' A small 45W PV panel can be used to partially charge the battery during sunny
' periods, however a diode must be installed to prevent power drain during
' dark periods [perhaps a 5 amp. Schottky MBR560];
' Pump FET switch "1" controls the "main" pump and additionally powers the coil
' of a relay to energize the 110Vac input to a "cooler adapter" being used
' as a charger for the auto battery [when the main pump in energized];
' The auto battery +13.3Vdc feeds an LM317T voltage regulator generating
' +6.125 Vdc for the sensor circuit and an AN7808 8V regulator that feeds
' both the EXT [9 To 10 Vdc] on-board power socket connection to CB210 main
' board, and a 78L05 5.0V regulator for voltage reference AREF;
' Note: On the CB210 board, be sure to set power select switch to "EXT"!
' All circuit grounds, including the CB210 are directly tied to 0VDC (negative
' terminal of auto battery, [note: the negative pump terminals, and the
' negative terminal of the coil of the relay (for 110vac battery charger) are
' tied to FET switches (ie. not direct to ground)], [note: to avoid ground
' loop noise, ensure all grounds are of appropriate current handling size,
' and are not duplicated.]
' AREF the analog reference, +5.0 Vdc pin 15 [long header], is taken from 78L05
' +5.0 V output terminal and filtered;
'
Const Device = CB210 ' advise Cubloc Studio [& compiler] that a CB210 board is being used
' Info: On power up, all I/O is set to tri-state inputs
'
' Store Constants to Program Memory [ie: to semi-permanent flash memory, thus saving RAM]
'
' analog input voltage catagory separations
Const Integer VAINP = (212,282,371,477,594,713) ' intervals of A to D integer readings.
' slope by category
Const Single SLOPE_M = (-38.09506,-29.06588,-23.02484,-19.28649,-17.42676,-17.29524,-19.07771)
' offset by category
Const Single OFFSET_B = (99.06181, 89.75561, 81.48384, 74.78804, 70.55928, 70.30456, 76.65089)
' analog input to divider voltage factor (resolution)
Const Single ATOVD = (0.004887586) ' Volts per division=5 volts/1023 reading intervals
'
' End User defined offset temperature (in deg.C) to account for line losses back from
' collector and to minimize short cycling of the pump.
'
Const Single OFFSET_T0 =(2.222) ' deg. C. or 4.0 deg.F. main pump offset temperature
Const Single OFFSET_T1 =(3.333) ' deg. C. or 6.0 deg.F. secondary pump offset temperature
'
' Allocate Variable Storage in RAM
'
Dim AIN As Integer ' dummy for analog input
Dim AIN0 As Integer ' analog input(0), positive integer 0 to 1023
Dim AIN1 As Integer ' analog input(2), positive integer 0 to 1023
Dim M As Single ' slope, float
Dim B As Single ' offset, float
Dim TEMP As Single ' sensed temperature in deg.C, float
Dim TEMPC0 As Single ' solar collector temperature [main] in deg.C, float
Dim TEMPC1 As Single ' solar collector temperature [secondary] in deg.C, float
Dim TEMPS As Single ' storage tank temperature in deg.C, float
Dim INDEX As Byte ' used for curve fit index and pump port selection
Dim INDEX2 As Byte ' used in manual test routine
Dim KEYPRESS As Byte ' active low when push button depressed
'
START:
Ramclear ' clear all variables
'
' de-activate both pumps
Out 11,0 ' initialize Port 11 to output & turn off main pump "1"
Wait 25 ' short wait to stabilize EMF transient
Out 12,0 ' initialize Port 12 to output & turn off secondary pump"2"
INDEX = 0 ' initialize flag to both pumps OFF
INDEX2 = 0 ' initialize manual push button index
Input 10 ' initialize Port 10 (push button) to input
'
Wait 2000 ' wait 2 sec for Debug Terminal program to load
Debug "CB210 Differential Temperature Control For ",Cr
Debug " BIS $1k Solar Water Heater,",Cr
Debug "Source File: CB210_diff_version_017 of 18 Feb 2013.",Cr,Cr
'
CONTINUE: ' entry point to 60 second endless loop
Out 30,1 ' enable 3 second looping run indicator LED(CB210 board)
Wait 3000 ' for manual test, depress push button when LED "ON",
Out 30,0 ' and withdraw when LED goes "OFF"
'
' Manual test of proper pump operation [useful for checking for syphon loss or leaks]
'
KEYPRESS = Keyin(10,10) ' check status of push button
If KEYPRESS = 0 Then ' if pushed, cycle pump states
Select Case INDEX2
Case 0
INDEX = 1
Debug "Push Button Depressed: Engaging Main Pump",Cr
Case 1
INDEX = 2
Debug "Push Button Depressed: Engaging Both Pumps",Cr
Case 2
INDEX = 0
Debug "Push Button Depressed: Disabling Both Pumps",Cr
End Select
INDEX2 = INDEX
Goto ACTIVATION ' manual activation of pumps
End If ' otherwise continue down
KEYPRESS = 1 ' set flag to inactive
'
' power up the thermistor sensors so they can be read
'
Out 13, 0 ' enable thermistor via LM317 & VN10K FET (active low)
Wait 600 ' wait 0.6 second for voltage pulse to stabilize
'
' input the average of ten analog voltage samples from storage tank thermistor
AIN1 = Tadin(1)
If (AIN1 > 901 Or AIN1 < 168) Then
Debug "Storage Temp. Out of Range, check wiring: ",Dec AIN1, Cr
End If
AIN = AIN1
Debug "tank sense raw: ",Dec AIN,", "
Gosub CONV_TO_C ' convert storage reading to Celsius
TEMPS = TEMP '
Debug "tank sense: ",Fp(TEMPS,3,2)," deg. C.",Cr
'
' input the average of ten analog voltage samples from solar collector thermistor
'
AIN0 = Tadin(0)
If (AIN0 > 1022 Or AIN0 < 140) Then
Debug "Collector Temp. Out of Range, check wiring: ",Dec AIN0, Cr
End If
AIN = AIN0
Debug "coll sense raw: ",Dec AIN,", "
Gosub CONV_TO_C ' convert collector reading to Celsius
Debug "coll sense: ",Fp(TEMP,3,2)," deg. C.",Cr,Cr
TEMPC0 = TEMP - OFFSET_T0(0) ' collector must be warmer by 2.222 deg.C
' due to line losses
TEMPC1 = TEMP - OFFSET_T1(0) ' collector must be warmer by 3.333 deg.C
' to justify using secondary pump too!
'
Out 13, 1 ' disable power to thermistor via VN10K FET-3 to
' reduce error causing heating effect on thermistors
'
If (TEMPC0 > 75 Or TEMPS > 65) Then
' turn both pumps on to either keep collector from overheating beyond
' 75 deg. C. due to stagnation or to eventually cool the overly hot
' storage tank down to 65 deg.C
Debug "Caution: Overheating!! Pumps ON!!",Cr
INDEX = 2
Else
If TEMPC1 > TEMPS Then
' flag need for both pumps
INDEX = 2
Else
If TEMPC0 > TEMPS Then
' flag need for pump1 (main pump)
INDEX = 1
Else
' flag need to turm off pumps
INDEX = 0
End If
End If
End If
'
ACTIVATION:
Select Case INDEX
Case 0
Out 11,0 ' turn off main pump "1"
Wait 25 ' short wait to stabilize EMF transient
Out 12,0 ' turn off secondary pump"2"
Case 1
Out 11,1 ' turn on main pump "1"
Case 2
Out 11,1 ' turn on main pump "1"
Wait 25 ' short wait to stabilize EMF transient
Out 12,1 ' turn on secondary pump "2"
End Select
Wait 25 ' short wait to stabilize EMF transient
'
Wait 56330 ' main loop wait of a little over 56 seconds
' (thus approx. 60 second total loop time)
'
Goto CONTINUE ' endless loop around for another temperature comparison
'
' subroutine to convert AIN an integer A to D reading, to a Celsius float
'
CONV_TO_C:
' select appropriate slope m and offset b parameters
If AIN <= VAINP(0) Then
INDEX = 0
Elseif AIN <= VAINP(1) Then
INDEX = 1
Elseif AIN <= VAINP(2) Then
INDEX = 2
Elseif AIN <= VAINP(3) Then
INDEX = 3
Elseif AIN <= VAINP(4) Then
INDEX = 4
Elseif AIN <= VAINP(5) Then
INDEX = 5
Else
INDEX = 6
End If
'
' grab the appropriate slope and offset
M = SLOPE_M(INDEX)
B = OFFSET_B(INDEX)
'
' convert a 10 bit A to D reading (single) to degrees Celsius (single)
TEMP = (AIN * ATOVD(0) * M) + B ' convert reading to Celsius
Return
'
' Copyright Gord Scale, Adolphustown Schoolhouse, February 2013.
' Permission is granted for non-commercial use by individuals implementing a
' Khanh master/slave and other variants of builditsolar.com "$1k Domestic Hot"
' Water Systems. Use at Own Risk. There are no warranties of any type.