PDA

View Full Version : A/C Unit Control over serial with some tweaks


muppets
30 Mar 08, 11:55 PM
This has some stolen code from others in the code examples I hope they don't mind - Darren and Dave

contants:

SerialDataTimer = 7;

variables:

a, ModuleCheckString : string;
b, NudgeValue : integer;
c, NudgeValueString : string;
d, DLTActualTemp : string;
e, DLTSetPoint : string;
f, SkipLineNo : integer;
i, TemperatureString : string;
j, Temperature, LastCommaPosition : integer;
k, TemperatureString2 : string;
l, Temperature2 : integer;
m, OutdoorCoilTempString : string;
n, OutdoorCoilTemp : integer;
o, UnloaderString : string;
p, Unloader : integer;
q, Zone0Status : string;
r, Zone1Status : string;
s, Zone2Status : string;
t, Zone3Status : string;

initialisation:

OpenSerial(1, 1, 9600, 8, 1, 0, 0);
TimerStart(SerialDataTimer);

module 1:

{A/C Control And Data Aquisition only send a request once each second - this stops the serial
port from missing signals.....it also means we only get states each 8 seconds though. Note
I only do some of the statements (serial writes) if page 3 is showing - this is the only page
that will represent the data that will be in the response.....this should reduce the traffic a little.}

once TimerTime(SerialDataTimer)= "00:00:01"
then begin
WriteSerial(1, 'Q0,0,-,-'#13);
end;

once TimerTime(SerialDataTimer)= "00:00:02"
then if ShowingPage("Page 3") then
begin
WriteSerial(1, 'Q0,1,-,-'#13);
end;

once TimerTime(SerialDataTimer)= "00:00:03"
then if ShowingPage("Page 3") then
begin
WriteSerial(1, 'Q0,2,-,-'#13);
end;

once TimerTime(SerialDataTimer)= "00:00:04"
then if ShowingPage("Page 3") then
begin
WriteSerial(1, 'Q0,3,-,-'#13);
end;

{these were just in case I find out what these zones represent}

{once TimerTime(SerialDataTimer)= "00:00:07"
then begin
WriteSerial(1, 'Q0,4,-,-'#13);
end;}

{once TimerTime(SerialDataTimer)= "00:00:08"
then begin
WriteSerial(1, 'Q0,5,-,-'#13);
end;}

once TimerTime(SerialDataTimer)= "00:00:05"
then if ShowingPage("Page 3") then
begin
WriteSerial(1, 'Q0,6,-,-'#13);
end;

{read the serial and find the position of the last comma - this was stolen from Darren thanx btw}

ReadSerial(1, i, #13);
for j := 1 to length(i) do
begin
if i[j] = ',' then
LastCommaPosition := j;
end;
Copy(ModuleCheckString, i, LastCommaPosition - 9, 4);

{if zone 0 responds on the serial gather the data}

if ModuleCheckString = 'R0,0' then
if i <> 'Q0,0,-,-' then
begin

{ copy the text from the character after the last comma }
Copy(TemperatureString, i, LastCommaPosition + 1, 2);
{ copy the text from the character before the last comma }
Copy(TemperatureString2, i, LastCommaPosition - 2, 2);
{ copy the text from the character before the 2nd last comma }
Copy(Zone0Status, i, LastCommaPosition - 4, 1);

{ extract the temperature from the string }
Temperature := StringToInt(TemperatureString);
Temperature2 := StringToInt(TemperatureString2);

{zone 0 Status is the a/c's current state (on or off)}
if Zone0Status = '1' then SetStringSystemIO(23, 'On');
if Zone0Status = '0' then SetStringSystemIO(23, 'Off');

{the current temperature of the thermostat}

SetIntSystemIO(21, Temperature);

{the current set point on the OEM interface}

SetIntSystemIO(22, Temperature2);

{send the current temperature of the thermostat to the DLT for display}

Format(DLTActualTemp, 'Temp ',GetIntSystemIO(21)/2:0);
SetStringIBSystemIO("Label Group Text", 254, 136, 0, 0, DLTActualTemp);
end;

{DLT in bedroom alter label so that it represents the current set point}

if SkipLineNo = 5 then
begin
Format(DLTSetPoint, 'SetPt ',GetIntSystemIO(30)/2:0);
SetStringIBSystemIO("Label Group Text", 254, 136, 1, 0, DLTSetPoint);
SkipLineNo := 0
end
else
SkipLineNo := SkipLineNo + 1 ;

{if line is correct for the data we want to extract ie. zone 1 data}

if ModuleCheckString = 'R0,1' then
if i <> 'Q0,1,-,-' then
begin

{ copy the text from the character before the 2nd last comma }
Copy(Zone1Status, i, LastCommaPosition - 4, 1);

{ extract the temperature from the string }
if Zone1Status = '1' then SetStringSystemIO(24, 'On');
if Zone1Status = '0' then SetStringSystemIO(24, 'Off');

end;

{if line is correct for the data we want to extract ie. zone 2 data}

if ModuleCheckString = 'R0,2' then
if i <> 'Q0,2,-,-' then
begin

{ copy the text from the character before the 2nd last comma }
Copy(Zone2Status, i, LastCommaPosition - 4, 1);

{ extract the temperature from the string }
if Zone2Status = '1' then SetStringSystemIO(25, 'On');
if Zone2Status = '0' then SetStringSystemIO(25, 'Off');

end;

{if line is correct for the data we want to extract ie. zone 3 data}

if ModuleCheckString = 'R0,3' then
if i <> 'Q0,3,-,-' then
begin

{ copy the text from the character before the 2nd last comma }
Copy(Zone3Status, i, LastCommaPosition - 4, 1);

{ extract the temperature from the string }
if Zone3Status = '1' then SetStringSystemIO(26, 'On');
if Zone3Status = '0' then SetStringSystemIO(26, 'Off');

end;

{if line is correct for the data we want to extract ie. zone 6 (current unit) data -
outdoor coil temperature and unloading system (digital scroll)}

if ModuleCheckString = 'R0,6' then
if i <> 'Q0,0,-,-' then
begin

{ copy the text from the character after the last comma }
Copy(OutdoorCoilTempString, i, LastCommaPosition - 2, 2);
{ copy the text from the character before the last comma }
Copy(UnloaderString, i, LastCommaPosition + 1, 3);

{ extract the temperature from the string }
OutdoorCoilTemp := StringToInt(OutdoorCoilTempString);
Unloader := StringToInt(UnloaderString);
SetIntSystemIO(27, OutdoorCoilTemp);
SetIntSystemIO(28, Unloader);

end;

{restart the timer to loop the queries}

once TimerTime(SerialDataTimer)= "00:00:08"
then begin
TimerStart(SerialDataTimer);
end;

{if c-touch input is to start the unit}

Once GetTriggerLevel(004) = 255 then
begin
WriteSerial(1, 'Q0,0,1,-'#13);
end;

{if c-touch input is to stop the unit}

Once GetTriggerLevel(004) = 0 then
begin
WriteSerial(1, 'Q0,0,0,-'#13);
end;

{if DLT input requests increase set point - increase by 1 when on}

if GetCBusState(254, "Heating", 0) = ON then
SetIntSystemIO(30, GetIntSystemIO(30)+1);

{if DLT input requests decrease set point - decrease by 1 when on}

if GetCBusState(254, "Heating", 1) = ON then
SetIntSystemIO(30, GetIntSystemIO(30)-1);

{when page 3 is selected make displayed set point = the units current set point. This is mainly used
when the unit is started for the first time after download}

once ShowingPage("Page 3") then
if ModuleCheckString = 'R0,0' then
SetIntSystemIO(30, Temperature2);

module 2:

{if the unit set point differs from the set point as displayed on the c-touch and dlt and is the same
as the checking i/o (30=31) which means ....if 30 and 31 are the same then the change occured on the
OEM interface and not the DLT or c-touch. note I use a delay to stop jitters on the c-touch when it
displays I/O 30 which is the c-touch's/dlt's setpoint. 22 is the current OEM set point. 31 is the
set point that is used to check against - it only gets updated after 30 = or <> it. for this
statement to be true becuase 30=31 it means someone altered the set point on the OEM interface and not either
the c-touch or dlt}

if GetIntSystemIO(22) <> GetIntSystemIO(30)
then begin
if GetIntSystemIO(30) = GetIntSystemIO(31) then
if ModuleCheckString = 'R0,0' then
if i <> 'Q0,0,-,-' then
SetIntSystemIO(30, GetIntSystemIO(22));
SetIntSystemIO(31, GetIntSystemIO(22));
Delay(2);
end;

Module 3:

{note from previous module that 22 and 30 are different however in this module 30 and 31 are
checked and are different is the statement is to continue - this means someone altered the set
point on either the c-touch or dlt and not on the OEM interface}

if GetIntSystemIO(22) <> GetIntSystemIO(30)
then begin
if GetIntSystemIO(30) <> GetIntSystemIO(31) then
Delay(1);
Format(NudgeValueString, 'Q0,0,*,',GetIntSystemIO(30):0, #13);
WriteSerial(1, NudgeValueString);
SetIntSystemIO(31, GetIntSystemIO(30));
end;

muppets
30 Mar 08, 11:59 PM
please let me know what you think and if there is any way I can reduce the code with the same or better outcome...........I know coding isn't my strong area but I am still trying to get me head around some of it.

hopefully this could be of some help to someone.................................



anyone?

muppets
31 Mar 08, 12:16 AM
This is the document sent by accent - it is for their interface which I presume (badged internally by IAS) was built and supported by IAS - who do a few different models for different vendors. www.ias.net.au

Accent-RS232-Communication-Protocol
P R O T O T Y P E
The confi guration of the system address is preset to zero (0).
User feedback:
Green RS232 led will be lit when message comes in via RS232
Red RS232 led will be lit when BRG232 replies to the PC
Green Accent net led will be lit when the packets come in from Accent controller (should always be pulsing)
Red Accent net led will lit when BRG is sending message to Accent controller

PC messages:
ASCII format = “Q a, z, n, s<c r>”
Where ‘a’ is the board address which is fi xed at zero, ‘z’ is the selected zone to view / edit, ‘n’ is the desired
on off state (0/1) or ‘-’ to leave alone,’s’ is the desired set point in half ˚C steps (30 - 60 = 15˚C - 30°C) or ‘-’
to leave alone.

The RS485 Bridge reply format = “Ra, z, n, s, t <c r>”
Where ‘a’, ‘z’, ‘n’,’s’ are the current address / zone / on off as above, and ‘t’ is the current zone temperature
in half ˚C steps.
‘z’ fi eld can have the following values
0 - unit (if “on off” & “set point” fi eld equals - & - then returns, on off status, set point and control temp)
1 - zone1 (if “on off” & “set point” fi eld equals - & - then returns, on off status, set point and control temp)
2 - zone2 (if “on off” & “set point” fi eld equals - & - then returns, on off status, set point and control temp)
3 - zone3 (if “on off” & “set point” fi eld equals - & - then returns, on off status, set point and control temp)
4 - zone4 (if “on off” & “set point” fi eld equals - & - then returns, on off status, set point and control temp)

Examples:
Request current state of zone 2/address 0
Send: Q0,2,-,-
Reply: R0,2,1,45,36 (zone 2 / address 0 is on with a set point of 22.5°C and a room temp of 18.0°C)

Turn zone 2 / address 0 on
Send: Q0, 2, 0,-
Reply: R0, 2, 0, 45, 36 (reply refl ects updated status)

Q*,*, 0,-<CR> => turn all zones off for all addresses (no reply)

On off values: 0 = off, 1 = on, * = leave alone
Set values: 30 = 15°C, 60 = 30°C, * = leave alone

Accent -> PC communications
Replies (where a reply is possible [i.e. single address, single zone]) net = > 5 fi elds: (Board address, zone
#, on off, set point, actual temperature)

If zone # is 5 - 7 then you are accessing RTC, unit status and faults,
5 - READ RTC value (if “on off” & “set point” fi eld equals - & - then returns, day of week, hours and minutes)
6 - read unit status (if “on off” & “set point” fi eld equals - & - then returns, user status, outdoor coil temp and
unloader %)
7 - read faults and fault details (if “on off” & “set point” fi eld equals - & - then returns, faults general, fault
detail coil sensors and 3phase status).
Note; you cannot use 1 send string to change BOTH on off state & set point. You must do this as 2 separate
packets.