Reading bytes from ser.read() - python

I have one XBee router (XB-X) connected to an ultrasonic range sensor and the other XBee coordinator (XB-Y) connected to my PC. XB-X will send the sensor reading to XB-Y. I am trying to extract the bytes from ser.read() on my PC using Python.
I got a weird bytes of string consist of ">>~}3#zi167.89" on output, may I know how to extract only the floating point number (167.89 in this example)? The number of bytes are specified by setting ser.read(size=xx). Is there any alternative way of doing it?
import serial
import zigbee
from xbee import ZigBee
import re
ser = serial.Serial("COM4", 9600)
while True:
try:
input = ser.read(20)
m = re.search(r'(\d+\.\d+)', input)
if m:
num = m.group()
# statements...
It is working now, carelessly typed 'group' as 'groups'.

Just use a regular expression:
import re
input = ser.read()
m = re.search(r'(?P<num>\d+\.\d+)', input)
if m:
num = float(m.group('num'))

Related

(Micro)Python UART response ends with "#Eg[" or adds characters

from machine import Pin, I2C, UART
import utime
from ustruct import unpack
import time
checkCardCmd = bytes([0xff,0x00,0x01,0x83,0x84])
getFirmwareVersionCmd = bytes([0xff,0x00,0x01,0x81,0x82])
uart = UART(1, baudrate=19200, bits=8, parity=None, stop=1)
while True:
# Check if card is present
uart.write(checkCardCmd)
val = uart.read()
print(val)
utime.sleep_ms(250)
When a card is presented on the NFC reader I get this back from val b'\xff\x00\x06\x83\x02\x01#Eg['
This is the reply to the checkCardCmd. I have no clue why it ends with #Eg[ also the reply for no card found comes back as b'\xff\x00\x02\x83N\xd3' notice the N character on the 4th byte, that should just be x83.
Baud Rate is correct and with similar code in NodeJS I get the proper response from UART without the extra N or #Eg]
What am I missing here?

How to Read the serial port name from text box (editable)

I am trying to open the serial port in Linux with Python 2.7 PyQt4 with the below code and it works fine:
serialport.port = "/dev/ttyACM1"
serialport.baudrate = 115200
serialport.open()
I don't want to hard-code the serial port name as above. I want to take the serial port name as the input from user from an editable text box:
textbox.setText("/dev/ttyACM1")
serialport.port = textbox.text()
serialport.baudrate = 115200
serialport.open()
But I am unable to convert textbox.text() format to serialport.port.
The following error occurs:
ValueError: "port" must be None or a string, not < class 'PyQt4.QtCore.QString' >
You are using PyQt and have something like this:
w = QWidget()
textbox = QLineEdit(w)
right?!
The error message tells you that the result of textbox.text()is of type QString. But you need a string instead.
You can simply convert the result using str(textbox.text())
serialport.port = str(textbox.text())
should solve the problem.

Converting Serial data format using python

I am new to python,currently working on the project reading serial port from micro controller to capture sensor data. The serial data i received looks like this:
[5;17H 0.029[5;40H 0.736[5;63H 9.557[7;17H 0.038[7;40H 0.001 [7;63H 0.008[9;17H-34.199[9;40H 25.800[9;63H 13.799[14;17H -4.623[14;40H 0.597[14;63H218.920[19;14H
this serial data actually have escape sequence 'x1b' before open bracket. How do i get rid of them, escape sequence and text format(5;17H..) and just print sensor data x,y,z format line by line. Can somebody help me.. Thank you..
I'm using python serial code:
import serial
ser = serial.Serial('COM9', 115200, bytesize=8, timeout=0)
while True:
data = ser.read(size=8).decode("utf-8")
s = str(data)
print(data)
ser.close()
Sensor data record starts with \033, so split at this for instance:
data_list = data.split('\033')
for v in data:
print (v)

Python Socket Wireless scan strange output

i have this code here:
import socket
raw = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(0x0003))
raw.bind(("mon0", 0x0003))
ap_list = set()
out = open("out.cap", 'w')
while True:
pkt = raw.recvfrom(2048)[0]
if pkt[36:42] not in ap_list:
ap_list.add(pkt[36:42])
print (pkt)
out.writelines(str(pkt))
but the output is kinda strange to me. how to make it Human readable?
Example of output:
b'\x00!c\xf60\xbe\x807s\xa8\xe5#\x08\x00E\x00\x004\xea\xec#\x00$\x06\xd2\xcck\x15mA\xc0\xa8\x00\x0c\x00P\x90\xee\x9dx\xd9E=\xfd;[\x80\x10\x00no\xc0\x00\x00\x01\x01\x08\n)\xa0w\x10\x00\xd6J\xa8'
Update:
using this
decoded = pkt.decode("ISO-8859-1")
i've managed to do what i need but wireshark don't read my output file very well and i also need to remove useless data from the output
some help?
this is the new code:
import socket
import sys
raw = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(0x0003))
raw.bind((sys.argv[1], 0x0003))
ap_list = set()
out = open("out.cap", 'w')
while True:
pkt = raw.recvfrom(1024)[0]
if pkt[36:42] not in ap_list:
ap_list.add(pkt[36:42])
decoded = pkt.decode("ISO-8859-1")
print(str(pkt[0:20]).split("'")[1])
out.writelines(str(decoded) + "\n")
In Wireshark you should be able to see what protocols are being used. Then you can parse them, for example using the scapy package.
– John Zwinck

Problem reading data from serial port in python

I have a python program that is trying to read 14 bytes from a serial port that
are arriving very slowly. I want want to capture all of the bytes in a
bytearray[14]. I understand there are new byte array features in python 3.0, but
I'm only running python 2.6.6. Upgrading may have unexpected consequences so I have to
stick with 2.6.6.
Data only intermittently flows over the serial port. I get one message on the
port maybe every 2 minutes or so. This data flows very slowly. The problem I am seeing is
that my code does not relaibly read the data one byte at a time. I want to frame this
data at exactly 14 bytes, then process the data and start fresh with a new 14
bytes.
Am I taking the wrong approach here? Advice?
ser = serial.Serial('/dev/ttyUSB1', 1200, timeout=0)
ser.open()
print "connected to: " + ser.portstr
count=0
while True:
line =ser.readline(size=14) # should block, not take anything less than 14 bytes
if line:
# Here I want to process 14 bytes worth of data and have
# the data be consistent.
print "line(" + str(count) + ")=" + line
count=count+1
ser.close()
Here's what I'm expecting: line(1)=� 0~ 888.ABC� /ends in carriage return
----------begin output------
line(0)=0
line(1)=~ ??1. ABC � # here get some multiple bytes and stuff gets out of synch
�ine(2)=
line(3)=0
line(4)=~
line(5)=
line(6)=8
line(7)=8
line(8)=8
line(9)=.
line(10)=
line(11)=A
line(12)=B
line(13)=C
line(14)=
line(15)=�
line(16)=
#...
line(48)=
line(49)=�
line(50)=0
line(51)=~
line(52)=
line(53)=8
line(54)=8
line(55)=8
line(56)=.
line(57)=
line(58)=A
line(59)=B
line(60)=C
line(61)=
line(62)=�
line(63)=
line(64)=
----------end output------
The API documentation for PySerial says readline() reads until \n, or until size is reached. However, the read() function says it will block until size is reached. Both of these functions say they will return early if a timeout is set.
Possible values for the parameter timeout:
timeout = None: wait forever
timeout = 0: non-blocking mode (return immediately on read)
timeout = x: set timeout to x seconds (float allowed)
Maybe try timeout=None instead of timeout=0
Try this:
ser = Serial('/dev/ttyUSB1', 1200, timeout=0)
print "connected to: " + ser.portstr
count=0
while True:
for line in ser.readlines()
print "line(" + str(count) + ")=" + line
count=count+1
ser.close()
You might also be interested in the line.strip() function if you haven't used it. Also, emphasis on the s in ser.readlines(), different from .readline().
Change the baudrate.
ser = serial.Serial('/dev/ttyUSB1', 9600, timeout=0)
to a compatible baudrate.
For getting 14 byte data :
data = ser.read(size=14)

Categories

Resources