Announcement

Collapse
No announcement yet.

Serial Port 2s Compliment

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Serial Port 2s Compliment

    I have a situation where the device I am talking to will send Binary 255 but depending on the computer I am on when the character is read the ascii value will show as either -1 or 255

    I am trying to determine if this is due to the underlying Windows API or the PB COMM RECV but not sure which, nor why it is this way on some machines and not others.

    If memory serves then -1 is the 2s compliment of 255 which is my only lead at the moment

    I would hate to have to rewrite a terminal from scratch using pure API (although it is on my "Hit-List" of things to do when I get time (:shhh:hhhyaaaa Right??? "When I get TIME!!!")

    Anyways, hoping someone out there will know the why this is happening (or some way I could test using code already written???)
    Engineer's Motto: If it aint broke take it apart and fix it

    "If at 1st you don't succeed... call it version 1.0"

    "Half of Programming is coding"....."The other 90% is DEBUGGING"

    "Document my code????" .... "WHYYY??? do you think they call it CODE? "

  • #2
    > ascii value will show as either -1 or 255

    No ascii value of character is ever less than zero. Valid range 0-255.

    This is a casting issue in your program... show failing code.

    PS: Twos complement = NOT(integervar) + 1 (reverse all bits and add one)

    FWIW Ones complement = NOT(integervar)

    MCM
    Michael Mattias
    Tal Systems (retired)
    Port Washington WI USA
    [email protected]
    http://www.talsystems.com

    Comment


    • #3
      ok Mike I got part of what you said, but all I have been taught is 2s compliment, so even researching the docs I thought a typo when all I could find was 1s compliment???

      (kinda like arrays being 0 or 1 based)....its just ASSUMED that the base is the same (but as we all know the answer is "Application specific")

      As far as actual code (and notice the reason WHY??? I can not post, because I do not know what to test for is)
      1. Read whatever is at the port (valid invalid do not care till later)
      2. should be nothing there till some character is there
      3. print the character (even if its unprintable "and DO NOT GET ME STARTED on UnPirintable characters"
      4. take the ASC of what was recieved and process it

      The last is where the odd prob comes in...-1 = 255???
      only thought in my head is something I am not processing (KNOWINGLY)

      Hence I can not defend against what I can not see unless I am a Jedi Knight
      Engineer's Motto: If it aint broke take it apart and fix it

      "If at 1st you don't succeed... call it version 1.0"

      "Half of Programming is coding"....."The other 90% is DEBUGGING"

      "Document my code????" .... "WHYYY??? do you think they call it CODE? "

      Comment


      • #4
        Originally posted by Cliff Nichols View Post

        4) take the ASC of what was recieved and process it
        The last is where the odd prob comes in...-1 = 255???
        only thought in my head is something I am not processing (KNOWINGLY)
        How are you taking "the ASC of what was recieved", Cliff? It seems to me (and I know next to nothing about serial ports) there are only 0 to 255 possibilities. If you can show how you are arriving at -1, someone will spot it. Maybe subtracting 128 when it should be 127, or overflowing a byte soomewhere, or some such.

        Just a thought.

        ========================
        There are three truths:
        my truth,
        your truth,
        and the truth.
        ~ Chinese proverb
        ========================
        It's a pretty day. I hope you enjoy it.

        Gösta

        JWAM: (Quit Smoking): http://www.SwedesDock.com/smoking
        LDN - A Miracle Drug: http://www.SwedesDock.com/LDN/

        Comment


        • #5
          This is about the extent of testing I have been able to do

          I count the number of chars waiting to be read and then
          Code:
          IF FILEATTR(HwndPort, 0) THEN COMM RECV HwndPort, CharsInBuffer, TempBuffer
          DispYellow = MID$(TempBuffer, 1, INSTR(TempBuffer,CHR$(i)) + 1)
          '                        DispRed = $TAB + "*AscVal(" + TRIM$(CHR$(i)) + "), Binary(" +MID$(BIN$(i, 8), 1, 4) + "   " + MID$(BIN$(i, 8), 5) + ")*"
                                  DispRed = $TAB + "*Decimal(" + TRIM$(STR$(i)) + "), Binary(" +MID$(BIN$(i, 8), 1, 4) + "   " + MID$(BIN$(i, 8), 5) + ")*"
          LstTerminalSimpleAddLine "fontc12", "Red", DispRed, 2
          The DispYellow and DispRed are just the strings to indicate to me what color to print them as.

          If I can't figure it out, then maybe when I get back from the weekend I can post the COMMS.bas with my functions to demonstrate the problem?

          Thanx for taking a look at this
          Engineer's Motto: If it aint broke take it apart and fix it

          "If at 1st you don't succeed... call it version 1.0"

          "Half of Programming is coding"....."The other 90% is DEBUGGING"

          "Document my code????" .... "WHYYY??? do you think they call it CODE? "

          Comment


          • #6
            >INSTR(TempBuffer,CHR$(i)) + 1)

            When i >= 255, this creates an overflow to the CHR$() function

            Calculation/ assignment of 'i' not shown

            Just as a little suggestion, debugging is a heck of a lot easier if you avoid a lot of expressions, as you can trace/log/view in stepping debugger the intermediate values.

            eg
            Code:
            DispYellow = MID$(TempBuffer, 1, INSTR(TempBuffer,CHR$(i)) + 1
            ==>
            Code:
            ipos         =  INSTR(tempBuffer, chr$(I)) 
            ' if ipos 0, CHR$(I) not found in temp buffer.. which means...? (application specific)
            INCR            ipos      ' next position. 
            ' if Ipos > LEN(tempBUffer) then you are reading data off the reservation
            ' if all values in range ...
            DispYellow =  MID$(TempBuffer,1, iPos)
            Yes it's more typing but please see "Lunch, Free, no such thing."
            Michael Mattias
            Tal Systems (retired)
            Port Washington WI USA
            [email protected]
            http://www.talsystems.com

            Comment


            • #7
              Code:
              IF FILEATTR(HwndPort, 0) THEN COMM RECV HwndPort, CharsInBuffer, TempBuffer
              How are you setting the value of CharsInBuffer? Do you know for certain if there are any characters already in the Receive buffer? Are you already sure there are the CharsInBuffer number of characters waiting for you? I first use something like this to explicitly determine the number of waiting characters: CharsInBuffer = COMM(HwndPort, RXQUE). That way, I can control program flow without COMM RECV locking me up should the Comm port loose its stream of input data. You know your application specifics, but just because the Comm port has been initialized and is open doesn't mean there is data waiting to be processed. I haven't checked this out, but is there any chance you are sometimes getting back an error code or 'buffer empty' response if COMM RECV fails?

              Comment


              • #8
                I was able to do some deeper digging (when I found COMM.BAS revealed the same problem) and now know that the error is not even related to the serial port, it is in turn related to how strings are handled (both dynamic and fixed-length)

                Every version and flavor of programming that I have used has had some version of MID$ so it must be some documented error somewhere (I can not find) but even PB posted somewhere (can not find at the moment, but think it had to do with "What Changed?" postings...maybe the Powerbase forum)
                That a string is really not a string, but an array of characters

                From that comment I have determined from my learning of arrays and bounds and declaring that in the case of PB if I declare and not give dimensions that LBOUND always exists, UBOUND will be less than 1 element (zero element that is)

                That said...forgetting how strings are handled I tried the following
                Code:
                #COMPILE EXE
                #DEBUG ERROR OFF
                #DIM ALL
                #INCLUDE "Win32Api.inc"
                FUNCTION PBMAIN () AS LONG
                
                    LOCAL sBuffer AS STRING
                    LOCAL i AS LONG
                    LOCAL LastErrorValue AS LONG
                    LOCAL ErrorBuff AS ASCIIZ * %MAX_PATH
                    LOCAL MsgString AS STRING
                    LOCAL AscString AS STRING
                    LOCAL BinString AS STRING
                    LOCAL LenOfString AS STRING
                    LOCAL PbErrorString AS STRING
                    LOCAL ApiErrorString AS STRING
                    LOCAL msg AS STRING
                     MsgString = sBuffer
                     AscString = STR$(ASC(MID$(sBuffer, 1, 1)))
                     BinString = BIN$(ASC(MID$(sBuffer, 1, 1)), 8)
                     LenOfString = STR$(LEN(sBuffer))
                     PbErrorString = ERROR$(ERR)
                     LastErrorValue = GetLastError
                     FormatMessage %FORMAT_MESSAGE_FROM_SYSTEM, BYVAL %NULL, LastErrorValue, %NULL, ErrorBuff, SIZEOF(ErrorBuff), BYVAL %NULL     'Format the message
                     ApiErrorString = STR$(LastErrorValue) + SPACE$(5) + ErrorBuff
                     msg = "Doing a MID$ starting at 1" + $CR
                     msg = msg + "*****************************************" + $CR
                     msg = msg + "String = " + MsgString + $CR
                     msg = msg + "Asc Value of String = " + AscString + $CR
                     msg = msg + "Bin value of String = " + BinString + $CR
                     msg = msg + "Len of String = " + LenOfString + $CR
                     msg = msg + $CR
                     msg = msg + "Pb Error = " + PbErrorString + $CR
                     msg = msg + "API Error = " + ApiErrorString + $CR
                     MSGBOX msg
                
                     MsgString = sBuffer
                     AscString = STR$(ASC(MID$(sBuffer, 0, 1)))
                     BinString = BIN$(ASC(MID$(sBuffer, 0, 1)), 8)
                     LenOfString = STR$(LEN(sBuffer))
                     PbErrorString = ERROR$(ERR)
                     LastErrorValue = GetLastError
                     FormatMessage %FORMAT_MESSAGE_FROM_SYSTEM, BYVAL %NULL, LastErrorValue, %NULL, ErrorBuff, SIZEOF(ErrorBuff), BYVAL %NULL     'Format the message
                     ApiErrorString = STR$(LastErrorValue) + SPACE$(5) + ErrorBuff
                     msg = "Doing a MID$ starting at 0" + $CR
                     msg = msg + "*****************************************" + $CR
                     msg = msg + "String = " + MsgString + $CR
                     msg = msg + "Asc Value of String = " + AscString + $CR
                     msg = msg + "Bin value of String = " + BinString + $CR
                     msg = msg + "Len of String = " + LenOfString + $CR
                     msg = msg + $CR
                     msg = msg + "Pb Error = " + PbErrorString + $CR
                     msg = msg + "API Error = " + ApiErrorString + $CR
                     MSGBOX msg
                
                
                     MsgString = sBuffer
                     AscString = STR$(ASC(MID$(sBuffer, -1, 1)))
                     BinString = BIN$(ASC(MID$(sBuffer, -1, 1)), 8)
                     LenOfString = STR$(LEN(sBuffer))
                     PbErrorString = ERROR$(ERR)
                     LastErrorValue = GetLastError
                     FormatMessage %FORMAT_MESSAGE_FROM_SYSTEM, BYVAL %NULL, LastErrorValue, %NULL, ErrorBuff, SIZEOF(ErrorBuff), BYVAL %NULL     'Format the message
                     ApiErrorString = STR$(LastErrorValue) + SPACE$(5) + ErrorBuff
                     msg = "Doing a MID$ starting at -1" + $CR
                     msg = msg + "*****************************************" + $CR
                     msg = msg + "String = " + MsgString + $CR
                     msg = msg + "Asc Value of String = " + AscString + $CR
                     msg = msg + "Bin value of String = " + BinString + $CR
                     msg = msg + "Len of String = " + LenOfString + $CR
                     msg = msg + $CR
                     msg = msg + "Pb Error = " + PbErrorString + $CR
                     msg = msg + "API Error = " + ApiErrorString + $CR
                     MSGBOX msg
                END FUNCTION
                and found it interesting that although an exception (PB or API) that the error is handled, and hence not quote unquote crashable...nor (as far as I know) catchable.

                Length of the string will always return 0 so I can not test there, and filling the string shows quite other results that I have to check, but all in all the problem has NOTHING to do with Serial Ports, nor PB, and maybe even lesser extent M$ Api...since all the docs are technically correct, but do not fully warn of the caveats.

                (Either that or I found a bug report or a NFS)
                Engineer's Motto: If it aint broke take it apart and fix it

                "If at 1st you don't succeed... call it version 1.0"

                "Half of Programming is coding"....."The other 90% is DEBUGGING"

                "Document my code????" .... "WHYYY??? do you think they call it CODE? "

                Comment

                Working...
                X