Hi,
I try to communicate with equipment through serial port.
It is slightly order equipment so it requires to send command in a specified format ends CHECKSUM (Like start with 'STX' and end with 'ETX' etc and the command looks something like '020T025F00R000000000000000').

Issue with Python:
For my case they have given the code in TURBO PASCAL to calculate check sum. I copied that code here (sorry to tell, I don't know Turbo Pascal )
But with my limited knowledge I convert in to python ( pls see the code below the Pascal code)
Could anyone help to solve the problem? Also could you please confirm the Python code is right?
Issue with serial programming:
In equipment manual gave an information about sending string and corrosponding answer string:
sending string format is --> {STX}1?CS{ETX}
STX is Start of text and ETX is the end of text. it corospondingli 02 and 03
1 stands for port address
CS stands for checksum (calculated using the above code)
I send string to serial port in the above sending strinng format, but not getting a answer string back from equipment.

Could somebody help on my issue
Thanks in advance...Appreciate reply...

##Code is in Turbo Pascal

FUNCTION CHECKSUM
(TESTER STRING): STRING;

VAR L, I       :INTEGER;
B,J,K           :BYTE;
CH              :STRING[1];
BEGIN
L        :=LENGTH(TESTSTR);
B        :=0;
FOR I := 1 TO L DO BEGIN
CH     := COPY(TESTSTR,I,1);
J        := ORD(CH[1]);
B        := B-J;
END;
J        := B DIV 16;
IF J<10
THEN J:=J+48
ELSE  J:= J+55;
K        :=B MOD 16;
IF K<10
THEN K:= K + 48
ELSE K:= K + 55;
CHECKSUM:= CHR(J) + CHR(K);
END;

Converted to Python code

tempset = '020T025.0FR00R0000000000000000'

def checksum(tempset):
    b = 0
    for ch in tempset:
        j = ord(ch)
        b = (b - j) & 255
    
    j = (b /16)
    if j<10:
        j = j + 48
    else:
        j = j+ 55
    
    k = (b % 16)
    if k < 10:
        k = k + 48
    else:
        k = k + 55
    
    return chr(j) + chr(k)

print checksum(tempset)

Dani AI

Generated

A few things to clear up based on what , , , , and discussed:

  • The Pascal code returns two ASCII hex digits, not a single byte. So the checksum for a frame like ...0000 is meant to be appended as "8B", not "\x8B". ’s edit uses a single 0x8B byte, which does not match the Pascal logic. Doubling backslashes as suggested will literally send the characters \x02 instead of STX, which is also not what the device expects.

  • Compute the checksum over the payload only (between STX and ETX), then append the two ASCII hex characters, then ETX. Do not include STX/ETX in the checksum unless the manual explicitly says so.

Here is a small, drop-in example that mirrors the Pascal math and reads until ETX:

import serial, time

def pascal_checksum(payload):
    total = sum(ord(c) for c in payload)
    b = (-total) & 0xFF                 # BYTE arithmetic
    return "{:02X}".format(b)           # two ASCII hex chars

ser = serial.Serial(0, baudrate=9600, bytesize=8, parity='N', stopbits=1,
                    timeout=1, xonxoff=False, rtscts=False, dsrdtr=False)

payload = "1T025.0F00R1000000000000000"
frame = "\x02" + payload + pascal_checksum(payload) + "\x03"

ser.flushInput(); ser.flushOutput()
ser.write(frame); ser.flush()

# read until ETX (0x03)
t_end, rx = time.time() + 5, []
while time.time() < t_end:
    ch = ser.read(1)
    if not ch: continue
    rx.append(ch)
    if ch == "\x03": break

print "TX:", " ".join("{:02X}".format(ord(c)) for c in frame)
print "RX:", " ".join("{:02X}".format(ord(c)) for c in "".join(rx))

If you still see nothing back: confirm wiring and handshaking (try disabling XON/XOFF/RTS/CTS as above), match the device’s exact 8N1 settings, and check whether it wants CR/LF after ETX. For manual testing, use a terminal that can send raw control bytes (STX=0x02, ETX=0x03); RealTerm/minicom make this much easier than HyperTerminal.

Recommended Answers

All 5 Replies

I assume that you open the port, send the string, and read any returned bytes somewhere else in the code. Check out the PySerial and see if it would work for you. There is no point in reinventing the wheel when you have packages that are already tested and tried. It will open the port and you can then send any string you like, and issue a read command for any returned string. There is also USPP if PySerial doesn't work for some reason.

Hi Woooee,

Thanks for the reply!

I checked the port is open by

ser.isOpen()

i got 'True'
After that sent the string in particular format according to manufactures instruction, in to the serial port.
After that read back by

ser.inWaiting()

, but getting 0. If i use

ser.read()

, will get a blank.
I worried about the string sending through the port is not recoganize by the equipment
I believe , we can test the string sending through Hyperterminal. Could you tell me how to do that? I tried echo testing in Hyperterminal it is working. Pls give some idea how the string can test with the help of Hyperterminal to check the string?

Pls find my code below that try to write and read from the Equipment

import serial
import time

ser          = serial.Serial(0)
ser.baudrate = 9600
ser.parity   = 'N'
ser.bytesize = 8
ser.stopbits = 1
ser.timeout  = 5

print ser.isOpen()
data = '\x02' + "1T025.0F00R10000000000000008B" + '\x03'
print data

time.sleep(8)
ser.write(data)
print ser.inWaiting()

ser.close()

Thanks and appreciate your reply

Wheres the checksum?

Cheers and Happy coding


EDIT:

How about this?

data = '\x02' + '1T025.0F00R1000000000000000' + '\x8B' + '\x03'

In my past experience using pySerial, I convert each byte or character with chr() before passing to ser.write(). Not sure if this will work for you.

maybe try adding two "\":

data = '\\x02' + '1T025.0F00R1000000000000000' + '\\x8B' + '\\x03'

I've also noticed some serial communications require a new line char after each command try adding "\n" at the end.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.