A/C Unit Control over serial with some tweaks

Discussion in 'Pascal Logic Code Examples' started by muppets, Mar 30, 2008.

  1. muppets

    muppets

    Joined:
    Oct 26, 2007
    Messages:
    98
    Likes Received:
    0
    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;
     
    Last edited by a moderator: Mar 30, 2008
    muppets, Mar 30, 2008
    #1
  2. muppets

    muppets

    Joined:
    Oct 26, 2007
    Messages:
    98
    Likes Received:
    0
    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, Mar 30, 2008
    #2
  3. muppets

    muppets

    Joined:
    Oct 26, 2007
    Messages:
    98
    Likes Received:
    0
    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.
     
    muppets, Mar 30, 2008
    #3
  4. muppets

    intalect

    Joined:
    Oct 30, 2004
    Messages:
    5
    Likes Received:
    0
    AC Control via touchscreen and DLT

    I have a job at the moment which invloves control the AC via T/Screen and DLT. The job has the same IAS interface which you have mentioned in your posts. i ahve done some basic logic, but am a first timer when it comes to serial interface with AC controller and T/screen. I have would appreciate any help you could give me regarding this please...

    Grant
     
    intalect, Mar 5, 2009
    #4
  5. muppets

    ltlbigchief

    Joined:
    Jul 24, 2005
    Messages:
    32
    Likes Received:
    0
    Location:
    Gold Coast, Queensland, Australia
    Any Luck with your code?

    Hi Muppets,

    I was just curious if you had any luck with your code. I trying to
    code for the same A/C unit, and having problems working out how to get
    around the delayed response from the A/C unit.

    Any help would be great.


    Regards
    Ltlbigchief
     
    ltlbigchief, Mar 11, 2009
    #5
  6. muppets

    ltlbigchief

    Joined:
    Jul 24, 2005
    Messages:
    32
    Likes Received:
    0
    Location:
    Gold Coast, Queensland, Australia
    Has any used the above code, with success????

    Anyone???

    :confused:
     
    ltlbigchief, Mar 19, 2009
    #6
Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.