serial port data sending got splitted in receiver - python

I send a data from the serial port as
1H|\^&|||c111^Roche^c111^2.0.0.0710^1^3334
44|||||host|TSREQ^REAL|
To serial port and at receiving end string got split as
1H|\^
and
&|||c111^Roche^c111^2.0.0.0710^1^3334
44|||||host|TSREQ^REAL|
why it happened, i want to send it as a single string.
This is my code
import serial
import requests
ser = serial.Serial(port='COM1',baudrate=9600,parity=serial.PARITY_NONE,stopbits=serial.STOPBITS_ONE,bytesize=serial.EIGHTBITS,timeout=0.5)
concat = str()
concat01=str()
header = "b'\x021H|\^&||||||||||P||'\r\n"
sample = "b'\x023Q|1|^0101645900^10^0^4^^SAMPLE^NORMAL||ALL||||||||O'\r\n"
eol="b'\x024L|1|I'\r\n"
patient_info = "b'\x022P|1'\r\n"
while 1:
z=ser.readline()
print(z)
print("Str Result",str(z))
if str(z)!="b''":
if str(z) == str(b'\x06'):
print("verfied 06")
concat = header + patient_info + sample + eol
ser.write(concat.encode())

Related

Writing to serial port but only receiving first character?

I'm reading data in from a machine to windows 7. Using python, I read the serial port, process the data then write the data to a different serial port. Using com0com null modem emulator, the data is sent to another program. Here is the code I'm using:
import serial
import time
ser = serial.Serial(port='COM7', baudrate=9600)
ser2 = serial.Serial(port='COM8', baudrate=9600)
value_one = None
while (True):
# Check if incoming bytes are waiting to be read from the serial input
# buffer.
# NB: for PySerial v3.0 or later, use property `in_waiting` instead of
# function `inWaiting()` below!
if (ser.in_waiting > 16):
# read the bytes and convert from binary array to ASCII
data_str = ser.read(ser.in_waiting).decode('ascii')
if (value_one == None):
time.sleep(1)
print(data_str)
value_one_parse = data_str[7:9]
print(value_one_parse)
value_one = float(value_one_parse)
print(value_one)
else:
time.sleep(1)
print(data_str)
value_two_parse = data_str[7:9]
print(value_two_parse)
value_two = float(value_two_parse)
print(value_two)
avg = ((value_one + value_two)/2)
print(avg)
avgprep = str(avg) + '\r\n'
print(avgprep)
ser2.write(avgprep.encode('utf-8'))
value_one = None
value_two = None
time.sleep(0.01)
So if avgprep = 71.1, why am I only receiving the first digit 7 to the program?
I changed ser.in_waiting > 16 to ser.in_waiting > 0 and put a time.sleep(5) after that.

After changing from Python 2.7 to Python 3.7 data getting an additional letter?

I'm working on a program that receives a string from an Android app sent through WiFi, the program was originally written for Python 2.7, but after adding some additional functionalities I changed it to Python 3.7. However, after making that change, my data had an extra letter at the front and for the life of me I can't figure out why that is.
Here's a snippet of my code, it's a really simple if statement to see which command was sent from the Android app and controls Raspberry Pi (4) cam (v.2) with the command.
This part sets up the connections and wait to see which command I send.
isoCmd = ['auto','100','200','300','400','500','640','800']
HOST = ''
PORT = 21567
BUFSIZE = 1024
ADDR = (HOST,PORT)
brightness = 50
timelapse = 0
tcpSerSock = socket(AF_INET, SOCK_STREAM)
tcpSerSock.bind(ADDR)
tcpSerSock.listen(5)
while True:
print ('Waiting for connection')
tcpCliSock,addr = tcpSerSock.accept()
try:
while True:
data = ''
brightness = ' '
data = tcpCliSock.recv(BUFSIZE)
dataStr = str(data[1:])
print ("Here's data ",dataStr)
if not data:
break
if data in isoCmd:
if data == "auto":
camera.iso = 0
print ('ISO: Auto')
else:
camera.iso = int(data)
print ('ISO: '), data
When I start the program this is what I see:
Waiting for connection
#If I send command '300'
Here's data b'300'
Here's data b''
Waiting for connection
I'm not sure why there's the extra b'' is coming from. I have tested the code by just adding the "b" at the beginning of each items in the array which worked for any commands that I defined, not for any commands to control the Pi camera since well, there's no extra b at the beginning. (Did that make sense?) My point is, I know I'm able to send commands no problem, just not sure how to get rid of the extra letter. If anyone could give me some advice that would be great. Thanks for helping.
Byte strings are represented by the b-prefix.
Although you can see the string in output on printing, inherently they are bytes.
To get a normal string out of it, decode function can help.
dataStr.decode("utf-8")
b'data' simply means the data inside quotes has been received in bytes form, as mentioned in other answers also, you have to decode that with decode('utf-8') to get it in string form.
I have updated your program below, to be compatible for v3.7+
from socket import *
isoCmd = ['auto','100','200','300','400','500','640','800']
HOST = ''
PORT = 21567
BUFSIZE = 1024
ADDR = (HOST,PORT)
brightness = 50
timelapse = 0
tcpSerSock = socket(AF_INET, SOCK_STREAM)
tcpSerSock.bind(ADDR)
tcpSerSock.listen(5)
while True:
print ('Waiting for connection')
tcpCliSock,addr = tcpSerSock.accept()
try:
while True:
data = ''
brightness = ' '
data = tcpCliSock.recv(BUFSIZE).decode('utf-8')
print ("Here's data "+data)
if not data:
break
if data in isoCmd:
if data == "auto":
camera.iso = 0
print ('ISO: Auto')
else:
camera.iso = int(data)
print ('ISO: '+ data)
except Exception as e:
print(e)

Python xbee library no output for incoming frames

I am using 2 XBee pro S1, I want to read the packets received by the co-ordinator on my PC , it is enabled with API_2 and all other connections are done properly, I can see the packets with XCTU, I am using the python xbee library , but it gives no output :
The Code :
import serial.tools.list_ports
from xbee import XBee
import serial
ports = list(serial.tools.list_ports.comports())
for p in ports: #print the list of ports
print p
def toHex(s):
lst = []
for ch in s:
hv = hex(ord(ch)).replace('0x', '')
if len(hv) == 1:
hv = '0'+hv
hv = '0x' + hv
lst.append(hv)
def decodeReceivedFrame(data):
source_addr_long = toHex(data['source_addr_long'])
source_addr = toHex(data['source_addr'])
id = data['id']
samples = data['samples']
options = toHex(data['options'])
return [source_addr_long, source_addr, id, samples]
PORT = '/dev/ttyUSB0'
BAUD_RATE = 9600
ser = serial.Serial(PORT, BAUD_RATE)
print "Serial ports initialised...."
xbee = XBee(ser,escaped=True)
print "XBee object created"
while True:
try:
response = xbee.wait_read_frame()
sleep(0.5)
decodedData = decodeReceivedFrame(response)
print decodedData
print "data decoded"
except KeyboardInterrupt:
break
ser.close()
The port number and baudrate are connect, I change it to the appropriate portnumber every time I replug the coordinator to my PC.
My output looks like :
Serial ports initialised....
XBee object created
It stays like that and gives no output, even if I see the RX led blinking.
Below is the code written with only pyserial :
import serial
from time import sleep
port = '/dev/ttyUSB0'
baud = 9600
ser = serial.Serial(port, baud)
data = ""
while True:
try:
while ser.in_waiting:
sleep(1)
data = ser.read()
print data
except KeyboardInterrupt:
break
ser.close()
It gives the following output.
Could someone kindly help.
Are you sure you have the correct serial port and baud rate? Does the xbee package support API mode 2? It might only work with API mode 1.
Does that package have methods for accessing the raw byte stream instead of trying to read frames? Can you configure it to throw exceptions on parsing errors?
I would start with just printing response until you see that you're receiving data. And why include the sleep() call in that loop?
I'm not sure what you're trying to accomplish in toHex() but you might want to look at the Python method struct.unpack() or replace all of the work you do on hv with '0x%02X' % ord(ch).

python broadcast 802.11 frames, using the socket module

I'm trying to capture and send a beacon frame using the following code
def SniffIncomingProbes():
#create a general socket to monitor ongoing traffic
sniffer = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(0x0003))
sniffer.bind((interface, 0x0003))
#byte [30] in the packet is the packet type/subtype field
#\x40 is a probe request, \x80 is a beacon probe
while True:
if frame_subtype==8:
packet = sniffer.recvfrom(2048)[0]
if packet[30] == "\x80":
#byte [67] in the packet contains the length of the SSID
SSID = packet[68: 68 + ord(packet[67])]
MAC = packet[40:46].encode('hex')
association_set.add((MAC,SSID))
PrintNicely()
#try and send a beacon on my own
if len(SSID) == 4:
newPacket = packet[:68] + "MOSS" + packet[72:]
newPacket = newPacket[:46] + ("\xAC\xDC\xDE\xAD\xBE\xEF") + newPacket[52:]
#get the FRC into unsigned form, convert to a
#string, and remove the "0x" characters in the beginning of the string
FCS = str(hex(abs(binascii.crc32(newPacket[:len(packet)-4]))))[2:]
if len(FCS)%2 == 1:
FCS = "0" + FCS
print FCS
print len(FCS)
newPacket = newPacket[:len(newPacket)-4]+ FCS.decode("hex")
sniffer.send(newPacket)
elif frame_subtype==4:
packet = sniffer.recvfrom(2048)[0]
if packet[30] == "\x40":
#byte [55] in the packet contains the length of the SSID
SSID = packet[56: 56 + ord(packet[55])]
MAC = packet[40:46].encode('hex')
association_set.add((MAC,SSID))
PrintNicely()
when I run Wireshark and airodump I can see the packets with SSID "MOSS" going through, and it shows up as a beacon on airodump.
yet when I run Windows Network Monitor on a remote machine, I don't see these packets going through.
also, my CRC checksum seems to be wrong (checked with wireshark).
seems like I am not sending the packet correctly and the FCS check failed
any input will be appreciated,
thank you in advance.
UPDATE:
The frame seqeuence check(FSC) returns Good and is not marked by wireshark anymore, BUT the packet is still not transmitted to any remote machine on the network.
i changed the FSC code to:
def FSCCheckSum(data):
#get the crc32 checksum of the data,
#without the radiotap header(first 30 bytes) and the FSC (last 4 bytes)
#and change it to unsigned form
#convert the hex representation to a string
#and remove the "0x" characters at the beginning of the string
FSC = binascii.crc32(data[30:-4]) % (1<<32)
FSC = str(hex(FSC))[2:]
#we might get zeroes(not showing) from the left,
#so we pad the number from the left with "0"s to match 4 bytes(4 hex pairs)
FSC = "0" * (8-len(FSC)) + FSC
#reverse the byte ordering
return FSC.decode("hex")[::-1]
so I just use the following code to modify the packet. *
Notice I also change the source address now
newPacket = packet[:68] + "MOSS" + packet[72:]
newPacket = newPacket[:40] + ("\xAC\xDC\xDE\xAD\xBE\xEF") + newPacket[46:]
newPacket = newPacket[:46] + ("\xAC\xDC\xDE\xAD\xBE\xEF") + newPacket[52:]
newPacket = newPacket[:-4] + FSCCheckSum(newPacket)
sniffer.send(newPacket)
(i split setting it with the BSSID so it would be easier to read and understand, i know it can be merged)

Sending png file via socket in Python

I'm using python version 2.7.9 and i try to send png file.
But something strange happens..i using sockets and sends a post request(or kind of).
I send the request to the server from the client,then i prints the length of the request received on the server, for example, the length is:1051.
Then I do a regex to take the png file data, and then prints the length, and the length is 2632, that he larger than the response?!
I think the problem is that it's actually write the content, but not the right of representation, I tried different things but they did not work, so I ask here how to solve this problem.
Server source code:
import socket
import re
server = socket.socket()
server.bind(('0.0.0.0',8080))
while True:
server.listen(2)
(client, client_addr) = server.accept()
print 'IP :',client_addr
res = client.recv(0xfffffff)
print len(res)
#get file name
file_name = res.split('&')[0]
file_name = str(file_name.split('=')[1])
print repr(res)
#get the data of the file
raw_img = str(re.findall("&photo_data=(.*)" ,res ,re.DOTALL))
print "File name:" + file_name
print "Size:" + str(len(raw_img))
with open(file_name, 'wb') as f:
f.write(raw_img)
print "Done"
Client source code:
import socket
client = socket.socket()
client.connect(('127.0.0.1',8080))
raw_data = open('test.png', 'rb').read()
save_file_name = raw_input("Enter the file name:")
print len(raw_data)
output = 'POST /upload HTTP/1.1\r\n'
output += 'Content-Length:' + str(len(raw_data)) + str(len(save_file_name)) + '\r\n\r\n'
output += 'file_name=' + save_file_name + '&'
output += 'photo_data=' + raw_data
print len(output)
client.send(output)
client.close()
First, you should use while True to receive the full data:
res = ''
while True:
data = client.recv(1024)
if not data:
break
res += data
print len(res)
Then, re.findall actually returns an array, not a string. So you should do this:
r = re.findall("&photo_data=(.*)" ,res ,re.DOTALL)
raw_img = str(r[0])
Now it works fine.
Why doesn't the code before work? Let's say we have a list:
r = ['\x45']
The data in raw_img part is basically like this. If we brutely convert this list to a str, we have:
print len(str[r])) # ['E'], 5
Actually, what we need is r[0]:
print len(str[r[0])) # 1
That's why the size of the file became larger.

Categories