Jump to content

Need help converting c script to autoit


Recommended Posts

I need a little bit of help transfering a script to auto it. I have two examples of the same script one in c and the other in basic. But I can not get them to work with my translated version.

Script in C

CODE
// Define Global variables

// message buffer variables

unsigned char msg_buf[20], nbytes, bit_point;

unsigned char * byte_point;

// Switch to select VPW PWM or ISO 0, 1, 2, respectively

unsigned char protocol;

// values to define protocol variable

#define vpw 0

#define pwm 1

#define iso 2

/*********************************************************************

CRC CALCULATION SUBROUTINE

Calculates the crc as defined by SAE, or the checksum for ISO

*********************************************************************/

// This routine assumes that all the data bytes are in the array msg_buf[]

// Starting with msg_buf[0] as the first byte.

// nbytes indicates how many bytes are in the array.

// The subroutine calculates both the checksum and the CRC byte as

// defined by SAE and ISO specifications.

// Either the CRC or the Checksum is returned, depending on what

// protocol is selected.

unsigned char crc(void)

{

unsigned char crc_reg=0xff,poly,i,j, checksum=0;

for (i=0, byte_point=msg_buf; i<nbytes; ++i, ++byte_point)

{

for (j=0, bit_point=0x80 ; j<8; ++j, bit_point>>=1)

{

if (bit_point & *byte_point) // case for new bit =1

{

if (crc_reg & 0x80) poly=1; // define the polynomial

else poly=0x1c;

crc_reg= ( (crc_reg << 1) | 1) ^ poly;

}

else // case for new bit =0

{

poly=0;

if (crc_reg & 0x80) poly=0x1d;

crc_reg= (crc_reg << 1) ^ poly;

}

}

checksum += *byte_point; // Calculate checksum

}

if (protocol==iso) return checksum; // Iso uses checksum,

return ~crc_reg; // Otherwise, use CRC

Script in Basic

CODE
' Calculates the checksum and crc (as defined by SAE)

' for a string of numbers

CLS

DIM buf%(12)

begin:

INPUT "Number of bytes"; nbytes%

FOR i% = 1 TO nbytes%

PRINT "Enter number"; i%; " ";

INPUT buf%(i%)

NEXT i%

GOSUB ErrByte

PRINT "CRC= "; HEX$(CRC%); " hex "; CRC%; "dec"

PRINT "Checksum= "; HEX$(checksum%); " hex "; checksum%; "dec"

PRINT

GOTO begin

ErrByte:

checksum% = 0

CrcReg% = 255

FOR i% = 1 TO nbytes%

BitPoint% = 128

Byte% = buf%(i%)

FOR j% = 0 TO 7

IF BitPoint% AND Byte% THEN

IF CrcReg% AND 128 THEN Poly% = 1 ELSE Poly% = 28

CrcReg% = (((CrcReg% * 2) OR 1) XOR Poly%) AND 255

ELSE

IF (CrcReg% AND 128) THEN Poly% = 29 ELSE Poly% = 0

CrcReg% = ((CrcReg% * 2) XOR Poly%) AND 255

END IF

BitPoint% = BitPoint% \ 2

NEXT j%

checksum% = (checksum% + Byte%) AND 255

NEXT i%

CRC% = (NOT CrcReg%) AND 255

RETURN

Here is what I have.

Dim $buf[12]
Dim $checksum = 0
Dim $CrcReg = 255

$nbytes = InputBox("Bytes","Number of bytes","")
for $i = 1 to $nbytes
    $buf[$i] = InputBox("Number","Enter Number","")
Next

For $i = 1 to $nbytes
    Dim $BitPoint = 128
    $Byte = $buf[$i]
    for $j = 0 to 7
        If $BitPoint and $Byte Then
            If $CrcReg and 128 Then
                $Poly = 1 
            Else 
                $Poly = 28
            EndIf
            $CrcReg = ((($CrcReg * 2) or 1) or $Poly) and 255
        Else
            If ($CrcReg and 128) then 
                $Poly = 29 
            Else 
                $Poly = 0
            EndIf
            $CrcReg = (($CrcReg * 2) or $Poly) and 255
        EndIf
        $BitPoint = $BitPoint/2
    Next
    $checksum = ($checksum + $Byte) and 255
Next
$CRC = (not $CrcReg) and 255

Msgbox (0, "Checksum", "CRC =     " & Hex($CRC) & " hex    "& $CRC & " dec" & @CRLF & "Checksum=   " & Hex($checksum) & "  hex     " & $checksum & " dec")

I am pretty sure that the reference to 255 and 128 are memory allocations or something like that. Any C guys out there that could explain what the code is trying to check would be of great help. Not looking for someone to code it for me, just give me a really good explanation of what is going on with the if statements. Thanks in advance.

Link to comment
Share on other sites

255 and 128 are not memory allocations, they are just numbers. Your if statements are correct, don't worry with them. The Problem with you code is your use of And, Or, and Not. The c Code you show uses the & | and !, which are all bitwise manipulations of numbers. In Autoit, those are functions called BitAnd(), BitOR(), BitXOR(), and BitNot(). Look those up, and you'll have your solution.

Link to comment
Share on other sites

For anybody that can use this. Here is the final code that does work with the obdII checksum calculation.

Func _obd2checksum($string)
; #FUNCTION# ====================================================================================================================
; Name...........: _obd2checksum
; Description ...: Returns the crc and checksum of a OBD2 HEX string
; Syntax.........: _obdchecksum($string)
; Parameters ....: $string        - string to be checked
; Return values .: Success      - Array with the following format:
;                  |[0] - Number of bytes checked (n)
;                  |[1] - Hex value of CRC
;                  |[2] - Dec value of CRC
;                  |[3] - Hex value of Checksum
;      |[4] - Dec value of Checksum
;                : Failure     - Returns 0   
; Author ........: Jason Amet
; Modified.......: 
; Remarks .......: Thanks to SkinnyWhiteGuy for his help
; Related .......: 
; Link ..........; http://obddiagnostics.com/obdinfo/CrcBAS.txt
; Link2 .........; http://obddiagnostics.com/obdinfo/CRC.txt
; Example .......; 
; ===============================================================================================================================   
    Dim $buf[12]
    Dim $checksum = 0
    Dim $CrcReg = 255
    $string = StringRegExpReplace($string," ","")   ;clear out whitespace
    $b = (StringIsXDigit($string))        ;makes sure all characters are HEX compliant
    $nbytes = (stringlen($string)/2)     ;get string length and calculate number of bytes
    for $i = 1 to $nbytes                           ;loop to add bytes to array
        $buf[$i] = Dec(stringmid($string,1,2))      ;grab first two  characters from left
        $string = stringtrimleft($string,2)         ;trim off those same letters from left
    Next
    For $i = 1 to $nbytes                           ; calculate crc and checksum for obdII 
        Dim $BitPoint = 128
        $Byte = $buf[$i]
        for $j = 0 to 7
            If BitAND($BitPoint, $Byte) Then
                If BitAND($CrcReg, 128) Then
                    $Poly = 1 
                Else 
                    $Poly = 28
                EndIf
                $CrcReg = BitAND(BitXOR(BitOR($CrcReg * 2,1),$Poly),255)
            Else
                If BitAND($CrcReg, 128) then 
                    $Poly = 29 
                Else 
                    $Poly = 0
                EndIf
                $CrcReg = bitand(BitXOR($CrcReg * 2,$Poly),255)
            EndIf
            $BitPoint = $BitPoint/2
        Next
        $checksum = BitAND($checksum + $Byte, 255)
    Next
    $CRC = BitAND(BitNOT($CrcReg), 255)
    Local $retbuffer[5]            ; return array
    $retbuffer[0] =  $nbytes
    $retbuffer[1] = StringRight(Hex($CRC),2)
    $retbuffer[2] = $CRC
    $retbuffer[3] = StringRight(Hex($checksum),2)
    $retbuffer[4] = $checksum
    if $b = 0 Then
        $retbuffer = 0
    EndIf
    Return $retbuffer
EndFunc

I am sure that there is alot of ugly code in there but it does work. Would appreciate any thoughts on clean up Thanks and enjoy

to get OBD2 hex strings for testing a list is available from here.

Control byte and frame number are not to be included in the string. CRC is what your trying to get.

Edited by nhardel
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...