Announcement

Collapse
No announcement yet.

Serial Port 2s Compliment

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

  • Cliff Nichols
    replied
    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)

    Leave a comment:


  • Gary Ramey
    replied
    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?

    Leave a comment:


  • Michael Mattias
    replied
    >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."

    Leave a comment:


  • Cliff Nichols
    replied
    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

    Leave a comment:


  • Gösta H. Lovgren-2
    replied
    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
    ========================

    Leave a comment:


  • Cliff Nichols
    replied
    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

    Leave a comment:


  • Michael Mattias
    replied
    > 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

    Leave a comment:


  • Cliff Nichols
    started a topic Serial Port 2s Compliment

    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 (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???)
Working...
X