1

I have Matlab code that communicates over serial port, and I am trying to translate the code into python, however I am not getting the same "read" messages.

Here is the matlab code:

s = serial('COM3','BaudRate',115200,'InputBufferSize',1e6,'Timeout',2);  %OPEN COM PORT
fopen(s);
string=[];
while(length(st)<1)
    fwrite(s,30,'uint8');   %REQUEST CONNECTION STRING
    pause(0.1);
    st = fread(s,5);  %READ CONNECTION (5BYTES, "Ready")
    disp(st)
end
fwrite(s,18,'uint8');   % START ACQUISITION

while(1)
    st(1:131) = fread(s,131); .....
    disp(st)

OUT:

%first disp(st)
    82
   101
    97
   100
   121

%from disp(st) second time
  106
    85
   106
    59
   106
    61
   106
     0
   106...

Here is my attempt of python code:

# Open serial - 
import serial 
import time

s = serial.Serial('COM3', baudrate=115200, timeout=2 )
s.set_buffer_size(rx_size = 1000000, tx_size = 1000000)
 #serieal is open
print ("serial is open: ", s.isOpen())

s.write(30) #request connection string
time.sleep(0.1)
string = s.read(5) #read connection string (5 BYTESm "Ready)
print (string)

# start aquisition 
s.write(18) #request connection string
print (s.read(131))

however the output is, OUT:

serial is open:  True
b'Uj.jg'
b'jVj3j-i\xefjOj8jajJj"i\xb8j\x19j4j,j\x17\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00j\x9aj\x9aj\x8djfjkj/j\xa0j\x97jbjKj#i\xb9j\x1bj5j-j\x19\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00/\xaaUj\xe5j\xb7'

As you can see they aren't the same, so:

  1. How do I send via pyserial a 'uint8' encoded number like in matlabs: fwrite(s,30,'uint8');
  2. How do I read and display from pyserial similar to matlabs: st = fread(s,5);
Leo
  • 1,176
  • 1
  • 13
  • 33

1 Answers1

2

How do I read and display from pyserial similar to matlabs: st = fread(s,5);

uint8 means 8-bit number. So 1 byte.

In python, you get a bytes object which is a sequence of bytes. You can iterate over it to get each value. - Which is exactly what you want, because that would be a value of one byte, 0-255

first = b'Uj.jg'
for i in first:
    print(i)

This gives you:

85
106
46
106
103

How do I send via pyserial a 'uint8' encoded number like in matlabs: fwrite(s,30,'uint8');

You can convert your int to bytes object using int.to_bytes:

print((30).to_bytes(1, byteorder="big"))

Results in

b'\x1e'

First argument is number of bytes - in our case 1. Second argument is byte order - which is useless when we use 1 byte but it's still required.

So what you had as s.write(30) will be

s.write(b'\x1e')

or to keep the "30" thing visible just directly paste the conversion:

s.write((30).to_bytes(1, byteorder="big"))

Same for sending 18: s.write((18).to_bytes(1, byteorder="big"))

h4z3
  • 5,265
  • 1
  • 15
  • 29
  • I think the answer could be better if you take the Python code from the question and update the relevant parts. The question is not about printing, it's about writing to serial port. I also think that [this post](https://stackoverflow.com/questions/21017698/converting-int-to-bytes-in-python-3) shows more elegant ways for converting `int` to byte. – Rotem Jun 14 '22 at 10:22
  • @Rotem the answer you linked is literally what I use, tho? OP only wants uint8, so it's always 1 byte, there's no need for some magic to calculate number of bytes. – h4z3 Jun 14 '22 at 10:36
  • @h4z3 Don't you think `s.write(bytes([30]))` is more elegant than `s.write((30).to_bytes(1, byteorder="big"))`? I still think the answer could be better if you take the Python code from the question and update the relevant parts. As the way the question is asked your answer is adequate. – Rotem Jun 14 '22 at 10:51