PAC / RS232 Advice Needed

Discussion in 'General Discussion' started by xrmichael, Jan 28, 2008.

  1. xrmichael

    xrmichael

    Joined:
    Nov 20, 2006
    Messages:
    113
    Likes Received:
    1
    Location:
    uk
    Rs232

    HEX - Added #$ and sorted decimal problem

    CODE

    Sorry forget the last code over complex this works faster and better, but still cannot convert the vol level section of the string to an integer, i think due to the conversion not returning a number so it returns a 0. Tried string to int/real with no luck.

    ReadSerial(1,serialIn,'');{read port}

    {WRITELN ('SERIALIN = ', SERIALIN); {test comms ok remove this when complete}

    position := pos(#$20,serialIn);{find #20 ZONE STATUS POSITION}

    {WRITELN ('POSITION = ', POSITION); {test line remove when done}

    if (POSITION > 0) AND (SERIALIN[POSITION]=#$20){LOOKING FOR #20 ZONE STAT MESSAGE} AND (SERIALIN[POSITION+1]=#$00)
    {LOOKING FOR #01 ZONE 1} then

    BEGIN

    Copy(ReceivedData, SERIALIN, POSITION,12);{COPYS SERIAL DATA TO STRING}

    ZONE1STATUS:=(RECEIVEDDATA[4]);
    ZONE1SOURCE:=(RECEIVEDDATA[5]);
    ZONE1VOL:=(RECEIVEDDATA[6]);

    ZONE1VOLUME :=STRINGTOINT (ZONE1VOL); {PROBLEM CODE HERE}
    SetStringSystemIO("ZONE 1 VOL LEVEL", ZONE1VOL);

    once ZONE1STATUS = #$00 THEN SetCBusState("COUNTING 1", "AV Control", "ZONE 1 ON OFF", OFF);
    once ZONE1STATUS = #$02 THEN SetCBusState("COUNTING 1", "AV Control", "ZONE 1 ON OFF", ON);

    {CLEARBUFFER}

    FOR COUNTER1:= 1 TO 23 DO
    BEGIN
    RECEIVEDDATA[COUNTER2]:='0';
    COUNTER1:=COUNTER1+1;
    COUNTER2:=COUNTER2+1;
    END;
    COUNTER1:=0;
    COUNTER2:=1;
    END

    else

    begin
    ExitModule;
    end;
     
    xrmichael, Jan 31, 2008
    #21
  2. xrmichael

    filpee

    Joined:
    May 31, 2006
    Messages:
    204
    Likes Received:
    0
    Location:
    Western Australia

    OK ill have a look at this for you tonight.

    what values does ReceivedData[7] return?
    is it a hex value 0 through to ff
    or is it an ascii number, hex 30 through 39

    I think youll find that stringToInt will only return valid if each byte is between hex 30 -> 39
     
    filpee, Feb 1, 2008
    #22
  3. xrmichael

    Darren Senior Member

    Joined:
    Jul 29, 2004
    Messages:
    2,361
    Likes Received:
    0
    Location:
    Adelaide, South Australia
    This is correct.

    According to a previous post, byte 7 of the data is "zone level % value". This implies that it is a numerical value from 0 to 100, not an ASCII string.

    You need to convert characters #000 to #100 into numbers 0 to 100. This can be done using the Ord function (see logic help file).

    Your code should be something like :

    Code:
    Zone1Volume := Ord (ReceivedData[6]);
    
    By the way, you might want to change your code to use lower case / camel case. Having it all in capitals is very distracting :eek:
     
    Darren, Feb 1, 2008
    #23
  4. xrmichael

    filpee

    Joined:
    May 31, 2006
    Messages:
    204
    Likes Received:
    0
    Location:
    Western Australia


    Ord.. thats it. For the life of me I couldnt remember it. Thought it was chr or byte.


    :)

    how you going there xrmichael. Fixed it yet?
     
    filpee, Feb 1, 2008
    #24
  5. xrmichael

    xrmichael

    Joined:
    Nov 20, 2006
    Messages:
    113
    Likes Received:
    1
    Location:
    uk
    Rs232

    Yes at last, zones 1 to 6 showing status, selected source and vol level.

    Around 20hrs of time, i am probably not destined to become a programmer.

    Thank you all for the help, now on to displaying all transmitted metadata on the ctouch ?

    Thanks.
     
    xrmichael, Feb 1, 2008
    #25
  6. xrmichael

    Darren Senior Member

    Joined:
    Jul 29, 2004
    Messages:
    2,361
    Likes Received:
    0
    Location:
    Adelaide, South Australia
    Being a good programmer takes a long time. The next time you do something like this it will be much easier.

    No worries. It would be good if you could post your final logic code so that others can benefit from your work. There may also be some improvements which can be suggested.
     
    Darren, Feb 2, 2008
    #26
  7. xrmichael

    xrmichael

    Joined:
    Nov 20, 2006
    Messages:
    113
    Likes Received:
    1
    Location:
    uk
    Rs232

    I will post it up shortly just adding a few more bits to it, gets quite addictive once you see some working results.
     
    xrmichael, Feb 3, 2008
    #27
  8. xrmichael

    xrmichael

    Joined:
    Nov 20, 2006
    Messages:
    113
    Likes Received:
    1
    Location:
    uk
    Rs232

    As requested, the code.

    This is repeated 6 time in a module to collect and display each of the 6 zones, i tried separating it into 6 modules but it took around 2 Min's for the serial data to get i sync, this code syncs all 6 zones in around 2~4 seconds.

    I know the capitalisation and indent is all to cock but ill sort the when i get a moment.

    Any comments appreciated.





    {ZONE 1 CODE HERE}

    WriteSerial(1, REQZONE01STAT); { REQUEST ZONE 1 STATUS FROM MZC }

    DELAY (0.58); {WAIT FOR RESPONSE}

    ReadSerial(1,serialIn,'');{READ DATA TO STRING SERIALIN}

    position := pos(#$69,serialIn);{FIND #$69 IN STRING ANC COPY POSITION TO POSITION}

    if (POSITION > 0) AND (SERIALIN[POSITION]=#$69) {CHECKS #$69} and (SERIALIN[POSITION+1]=#$01) {CHECKS FOR #$01 ACK} AND
    (SERIALIN[POSITION+2]=#$00) {CHECKS ZONE ID} AND (SERIALIN[POSITION+3]=#$00) {CHECK RESERVED BYTE} then

    BEGIN
    ZONE1STATUS:=(SERIALIN[POSITION+4]);
    ZONE1SOURCE:=(SERIALIN[POSITION+5]);
    Zone1Vol:= Ord (SERIALIN[POSITION+6]);

    IF ZONE1STATUS = #$00 THEN
    BEGIN
    SetStringSystemIO("ZONE 1 STATUS", 'OFF');
    SetStringSystemIO("ZONE 1 SOURCE", 'NONE');
    SetintSystemIO("ZONE 1 VOL LEVEL", 0);
    END

    ELSE

    BEGIN

    IF ZONE1STATUS <> #$00 THEN IF (GetIntSystemIO("ZONE 1 VOL LEVEL") <> ZONE1VOL) then SetintSystemIO("ZONE 1 VOL LEVEL", ZONE1VOL);
    IF ZONE1STATUS = #$03 THEN SetStringSystemIO("ZONE 1 STATUS", 'MUTE');
    IF ZONE1STATUS = #$02 THEN SetStringSystemIO("ZONE 1 STATUS", 'ON');
    IF ZONE1STATUS = #$06 THEN SetStringSystemIO("ZONE 1 STATUS", 'PARTY-S');
    IF ZONE1STATUS = #$0E THEN SetStringSystemIO("ZONE 1 STATUS", 'PARTY-M');
    IF ZONE1SOURCE=#$00 THEN SetStringSystemIO("ZONE 1 SOURCE", SOURCE1);
    IF ZONE1SOURCE=#$01 THEN SetStringSystemIO("ZONE 1 SOURCE", SOURCE2);
    IF ZONE1SOURCE=#$02 THEN SetStringSystemIO("ZONE 1 SOURCE", SOURCE3);
    IF ZONE1SOURCE=#$03 THEN SetStringSystemIO("ZONE 1 SOURCE", SOURCE4);
    IF ZONE1SOURCE=#$04 THEN SetStringSystemIO("ZONE 1 SOURCE", SOURCE5);
    IF ZONE1SOURCE=#$05 THEN SetStringSystemIO("ZONE 1 SOURCE", SOURCE6);

    END;

    {ZONE 2 CODE HERE}

    WriteSerial(1, REQZONE02STAT); { REQUEST ZONE 1 STATUS FROM MZC }

    DELAY (0.58); {WAIT FOR RESPONSE}

    ReadSerial(1,serialIn,'');{READ DATA TO STRING SERIALIN}

    position := pos(#$69,serialIn);{FIND #$69 IN STRING ANC COPY POSITION TO POSITION}

    if (POSITION > 0) AND (SERIALIN[POSITION]=#$69) {CHECKS #$69} and (SERIALIN[POSITION+1]=#$01) {CHECKS FOR #$01 ACK} AND
    (SERIALIN[POSITION+2]=#$01) {CHECKS ZONE ID} AND (SERIALIN[POSITION+3]=#$00) {CHECK RESERVED BYTE} then

    BEGIN
    ZONE2STATUS:=(SERIALIN[POSITION+4]);
    ZONE2SOURCE:=(SERIALIN[POSITION+5]);
    Zone2Vol:= Ord (SERIALIN[POSITION+6]);

    IF ZONE2STATUS = #$00 THEN
    BEGIN
    SetStringSystemIO("ZONE 2 STATUS", 'OFF');
    SetStringSystemIO("ZONE 2 SOURCE", 'NONE');
    SetintSystemIO("ZONE 2 VOL LEVEL", 0);
    END

    ELSE

    BEGIN

    IF ZONE2STATUS <> #$00 THEN IF (GetIntSystemIO("ZONE 2 VOL LEVEL") <> ZONE2VOL) then SetintSystemIO("ZONE 2 VOL LEVEL", ZONE2VOL);
    IF ZONE2STATUS = #$03 THEN SetStringSystemIO("ZONE 2 STATUS", 'MUTE');
    IF ZONE2STATUS = #$02 THEN SetStringSystemIO("ZONE 2 STATUS", 'ON');
    IF ZONE2STATUS = #$06 THEN SetStringSystemIO("ZONE 2 STATUS", 'PARTY-S');
    IF ZONE2STATUS = #$0E THEN SetStringSystemIO("ZONE 2 STATUS", 'PARTY-M');
    IF ZONE2SOURCE=#$00 THEN SetStringSystemIO("ZONE 2 SOURCE", SOURCE1);
    IF ZONE2SOURCE=#$01 THEN SetStringSystemIO("ZONE 2 SOURCE", SOURCE2);
    IF ZONE2SOURCE=#$02 THEN SetStringSystemIO("ZONE 2 SOURCE", SOURCE3);
    IF ZONE2SOURCE=#$03 THEN SetStringSystemIO("ZONE 2 SOURCE", SOURCE4);
    IF ZONE2SOURCE=#$04 THEN SetStringSystemIO("ZONE 2 SOURCE", SOURCE5);
    IF ZONE2SOURCE=#$05 THEN SetStringSystemIO("ZONE 2 SOURCE", SOURCE6);

    END;
     
    xrmichael, Feb 5, 2008
    #28
  9. xrmichael

    Darren Senior Member

    Joined:
    Jul 29, 2004
    Messages:
    2,361
    Likes Received:
    0
    Location:
    Adelaide, South Australia
    I will be nice to you ;)

    Delays can actually only be in increments of 0.2 seconds. This will get rounded one way or the other.

    You could have a problem here. You don't know how long the string actually is, so SERIALIN[POSITION+3] could actually be reading past the end of the string and reading random data. Check the length of the string before doing this.

    You don't need to check that ZONE1STATUS is not equal to zero. You know that already because it is in the else clause.
     
    Darren, Feb 6, 2008
    #29
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.