I am reading data from a serial port using python (pyserial) I am able to read the data but when I try using it, it seems like this $*%\xff\x06$*%\xff\x02 referred to few resources on stack overflow and found that it needs to be decoded, I tried decoding it to ascii using processed = (binascii.b2a_qp(raw))using the binascii library but received the following output $*%=FF=00$*%=FF=08 I have also tried decoding the same to UTF-8 but still no success. Any suggestions about how to process the input received from the read() function. I also tried using the readline() but the program then goes blank or infinite execution seems there is no EOL marker in the serial output.
The Demo Code snip is as follows :
with serial.Serial('/dev/cu.usbserial-Device',9600) as ser:
ser.flushInput()
ser.flushOutput()
ser.write('S')
inputVal=[]
while(len(inputVal)<10000):
val = ser.read(10)
inputVal.append(binascii.b2a_qp(val))
Any suggestions ? Thanks in advance.
You can try to encode whilst writing to the serial port.
ser.write(str.encode('S\r')
While, to read, I would use something like
a = ser.readline()
b = v.rstrip()
c = b.decode('utf-8')
Related
I'm relatively new to programming, so bear with me. I'm trying to communicate with the measurement device METEX M-4650CR https://sigrok.org/wiki/Voltcraft_M-4650CR and I'm using a windows 7 64bit OS. I simply want to read out the data the device measures to my python procedure and display it and calculate with it.
I found in the manual http://elektron.pol.lublin.pl/elekp/labor_instr/METEX_M-4650CR_Manual.pdf (page 25ff), that it works with a baudrate of 1200, a bytesize of 7 (with ASCII coding) and 2 stopbits.
Furthermore, it can be requested to send data to the computer by simply giving it the command "M". It then returns 14 bytes to the computer. Without anything to measured connected to it, it should return something like 'DC 00.0000V CR'. CR is the terminator here (I hope that is the right name).
Here is my code:
import pyserial
import time
ser = serial.Serial(port='COM5', baudrate=1200,
bytesize=7, stopbits=2, timeout=1,
rtscts=False, dsrdtr=True)
time.sleep(1)
ser.write("M")
time.sleep(1)
bytestoread = ser.inWaiting()
print bytestoread
output = ''
output += ser.read(1000)
print 'output:' + str(output)
time.sleep(1)
ser.close()
My problem is, that I cannot read out the data properly with pyserial. I send the command "M" to the METEX and in the display it says 'send' for a short moment, so I guess my write command works fine. But after that (it should have send the data), all I get when from ser.inWaitung is '0L' or '1L' and the ser.read command gives nothing at all.
I don't think it is a problem of the hardware, because with another programme, called 'serialwatcher', I'm able read out the data correctly. It gives exactly the characters described in the manual.
I also tried the following while loop, having the problem, that most of the time inWaiting == 0, such that it never initialises the loop.
while ser.inWaiting() > 0:
output += ser.read(1)
if output != '':
output = outpus.rstrip()
print output
So, how can I read out the data correctly, that were send to the serial port? Thanks in advance.
Unfortunately I cannot test your code because I have no serial device with me, but you could try the following:
You could set a flag, e.g. alive when you are expecting data and simply try to read something. This worked for me when I was trying to receive data from a really old spectrometer.
while alive: #loop
text = ser.read(1) #try to read one line
if text: #if there is data
n = ser.inWaiting() #look if there is more to read
if n: #if so
text = text + ser.read(n) #get all of it
A more sophisticated example can be found here wxTerminal - Pyserial example You could also simply try to modify this brilliant code for your purpose and see if you are more successful.
I am trying to setup a simple program to read from COM port on my windows. It is connected to a CAN bus(USB interface). I set up the serial configs correctly and know that the port is open. However I am unable to understand the output read.
Here is what I have:
>>> ser.write('v')
1L
>>> ser.write('0x7f3')
5L
>>> ser.write('0x7e1300323f351')
15L
WHat are the 1L, 5L and 15L? Some length of bytes read? How can I see what data is really being received then?
I also tried r= ser.read() and then tried to display it by typing print r.decode("hex")
thanks
EDITED:
I have also used the RealTerm Software to perform sanity check. I have send a "V" and it returns a version string. However I tried the same from my python program( ser.write("V"). I see nothing when I print the response got from read(). Please help
I have my Arduino connected to an OLIMEX-SHIELD-EKG-EMG, and there is this Arduino example for EKG capture and interface to Electric Guru for OLIMEXINO-328/Arduino boards.
I ran the Arduino software and then I made sure it's working using the Guru and it's all fine.
I tried to read the data from the serial port using Python and saving it to a text file, so I can use it for other stuff (Windows commands in my case). When I open the file the data is all garbage.
So what did I do wrong and how can I fix it?
Thank you all in advance.
This is my code:
import serial
from time import sleep
f = open("data2.txt", "w")
port = "\\.\COM4"
ser = serial.Serial(port, 38400, timeout=0)
while True:
data = ser.read(9999)
if len(data) > 0:
print ('Got:',data)
sleep(0.5)
print ('not blocked')
f.write( str(data) + "\n\n" )
f.close()
ser.close()
And this the data I get:
b'\x05\r\x1c\x1e\x10K\x12\x8a\x01\x0e\x14&\x1b\x1bW\x12\x80\x00\x7f\x11 \rZC:\x82\x12_.\x1a?\x10^\x12\x8a\x1a__\\x01:Q\x12\x8a\x15\x01\x1a\x1f\x1c6L\x1a\x82\x00t\x1e\x0c\x18\x19s:\x8a\x05]-\x01\x0e[G\x12\x8a\x15_\x0b9\x17>R\x12\x8a\x08__\x7f\x08:S\x1a\x82\x01\r\x18\x1d4\x10j:\x8a\n_0\x06\x10\x12Y\x10\x8a\nRH\x1c\x0bw#\x12\x80\x08\x7f\x0f7\x1f\x1bT:\x8a+\x7fU%\x18P:\x8a\x00\x0b}\x006\x11K\x12\x8a\x00Z\x19&\x16>\x1a\x82\x01\x02D\x1d\nYb:\x8a*$\x15\x12\x1cX:\x8a\x1b\x7f[\x06\x1bP\x12\x8a+\x0c\x1f?\x1b-F\x1a\x82\x05Z\x13\x0f7\x14}:\x8a\nUb\x19\n7^\x10\x8a\x15_\n\x14\x132_\x12\x80\x1d\x7f_x\x05\x15N:\x8a\x05<`\x025\x11I:\x8a\x0bZ1\x0f4\x18S\x12\x8a\x0bQK8\x0bvB\x1a\x82\x11\x7f\x0e\x1a\x18\x14q\x1a\x82\x07\xc1\xe1\x05\x14\x13q:\x8a+Sb\x02\x1b\x0cM\x12\x8a\x01\x1f\x1b%\x15\x15]\x1a\x82\x01B\x01.(\x1d\x7f\x1a\x82\xc2\xc1\x05,9\x1at\x10\x8a,__X\x024N\x1a\x80(xD!\x15\x10I\x1a\x82\x08|.
That looks to me like binary data. So i guess either each 16 or each 32 bit are a single numeric. You would have to cast the data you have and then format it into a text file.
It looks like ser.read() returns bytes not string. You need to decode that to if you want string. Use data.decode(your_encoding). You need to know the encoding.
For more see docs.
Decoding in UTF-16 could be promising...
data=b'\x05\r\x1c\x1e\x10K\x12\x8a\x01\x0e\x14&\x1b\x1bW\x12\x80\x00\x7f\x11 \rZC:\x82\x12_.\x1a?\x10^\x12\x8a\x1a__\\x01:Q\x12\x8a\x15\x01\x1a\x1f\x1c6L\x1a\x82\x00t\x1e\x0c\x18\x19s:\x8a\x05]-\x01\x0e[G\x12\x8a\x15_\x0b9\x17>R\x12\x8a\x08__\x7f\x08:S\x1a\x82\x01\r\x18\x1d4\x10j:\x8a\n_0\x06\x10\x12Y\x10\x8a\nRH\x1c\x0bw#\x12\x80\x08\x7f\x0f7\x1f\x1bT:\x8a+\x7fU%\x18P:\x8a\x00\x0b}\x006\x11K\x12\x8a\x00Z\x19&\x16>\x1a\x82\x01\x02D\x1d\nYb:\x8a*$\x15\x12\x1cX:\x8a\x1b\x7f[\x06\x1bP\x12\x8a+\x0c\x1f?\x1b-F\x1a\x82\x05Z\x13\x0f7\x14}:\x8a\nUb\x19\n7^\x10\x8a\x15_\n\x14\x132_\x12\x80\x1d\x7f_x\x05\x15N:\x8a\x05<`\x025\x11I:\x8a\x0bZ1\x0f4\x18S\x12\x8a\x0bQK8\x0bvB\x1a\x82\x11\x7f\x0e\x1a\x18\x14q\x1a\x82\x07\xc1\xe1\x05\x14\x13q:\x8a+Sb\x02\x1b\x0cM\x12\x8a\x01\x1f\x1b%\x15\x15]\x1a\x82\x01B\x01.(\x1d\x7f\x1a\x82\xc2\xc1\x05,9\x1at\x10\x8a,__X\x024N\x1a\x80(xD!\x15\x10I\x1a\x82\x08|.'
data.decode('UTF-16')
u'\u0d05\u1e1c\u4b10\u8a12\u0e01\u2614\u1b1b\u1257\x80\u117f\u0d20\u435a\u823a\u5f12\u1a2e\u103f\u125e\u1a8a\u5f5f\u785c\u3130\u513a\u8a12\u0115\u1f1a\u361c\u1a4c\x82\u1e74\u180c\u7319\u8a3a\u5d05\u012d\u5b0e\u1247\u158a\u0b5f\u1739\u523e\u8a12\u5f08\u7f5f\u3a08\u1a53\u0182\u180d\u341d\u6a10\u8a3a\u5f0a\u0630\u1210\u1059\u0a8a\u4852\u0b1c\u4077\u8012\u7f08\u370f\u1b1f\u3a54\u2b8a\u557f\u1825\u3a50\x8a\u7d0b\u3600\u4b11\u8a12\u5a00\u2619\u3e16\u821a\u0201\u1d44\u590a\u3a62\u2a8a\u1524\u1c12\u3a58\u1b8a\u5b7f\u1b06\u1250\u2b8a\u1f0c\u1b3f\u462d\u821a\u5a05\u0f13\u1437\u3a7d\u0a8a\u6255\u0a19\u5e37\u8a10\u5f15\u140a\u3213\u125f\u1d80\u5f7f\u0578\u4e15\u8a3a\u3c05\u0260\u1135\u3a49\u0b8a\u315a\u340f\u5318\u8a12\u510b\u384b\u760b\u1a42\u1182\u0e7f\u181a\u7114\u821a\uc107\u05e1\u1314\u3a71\u2b8a\u6253\u1b02\u4d0c\u8a12\u1f01\u251b\u1515\u1a5d\u0182\u0142\u282e\u7f1d\u821a\uc1c2\u2c05\u1a39\u1074\u2c8a\u5f5f\u0258\u4e34\u801a\u7828\u2144\u1015\u1a49\u0882\u2e7c'
I'm reading a value through Python from the serial port of a sensor of Arduino.
My code(Python):
arduino = serial.Serial(2, 9600, timeout=1)
print("Message from arduino: ")
while True:
msg = arduino.readline()
print(msg)
I don't know why the output result is something like b'[sensor-value]\r\n'.
So, I get something like b'758\r\n' b'534\r\n' b'845\r\n' etc (regarding to sensor change value).
How I convert this?
You need to decode it.
print(msg.decode('utf-8'))
Please check Lexical Analysis on Python 3 documentation to see what string prefixes means
Encountered a similar problem with a Raspberry Pi Pico where I needed to both decode and get rid of the extra characters. That can all be achieved with a one-liner. This relies on the pySerial package.
msg = ser.readline().decode('utf-8').rstrip()
For the above example, serial.Serial has been named arduino instead of ser, so the solution there would simply be:
msg = arduino.readline().decode('utf-8').rstrip()
Found the hint in this blog post.
I'm writing a serial adapter for some scientific hardware whose command set uses UTF-8 character encodings. All responses from the hardware are terminated with a carriage return (u'\r'). I would like to able to use pySerial's readline() function with an EOL character specified, so I have this setup, ala this thread:
import serial
import io
ser = serial.Serial(port='COM10', baudrate=128000)
sio = io.TextIOWrapper(io.BufferedRWPair(ser, ser, 1), encoding='utf-8', newline=u'\r')
ser.open()
# these commands move to coordintes (25000, 0, 25000)
cmd = 'M\x80\x1a\x06\x00\x00\x00\x00\x00\x80\x1a\x06\x00'
ucmd = u'M\x80\x1a\x06\x00\x00\x00\x00\x00\x80\x1a\x06\x00'
#this works
ser.write(cmd)
print sio.readline()
#this does not
sio.write(ucmd)
sio.flush()
print sio.readline()
Strangely, the first command string (non-unicode using pySerial directly) elicits the correct behavior from the hardware. The second (unicode via Python's io module) causes it to move erratically and then hang. Why would this be? Sending unicode command strings to the hardware does work IF the command string is only a couple of a characters. Once you start sending bytes with hex(ord(byte)) values > 0x7F (outside ASCII range), then you start running intro trouble. I can work around this problem without too much trouble, but would like to know what is going on. Thanks!
From io docs:
BufferedRWPair does not attempt to synchronize accesses to its
underlying raw streams. You should not pass it the same object as
reader and writer; use BufferedRandom instead.
I'm guessing that's your problem, as you are passing same object ser as reader and writer. BufferendRandom doesn't look like it quite fits the bill either.
So is your problem with serial that it hangs waiting for the EOL?