I want to send data from a Simulink model (running in real time) to a Python script (also running in real time. I am using Simulink's built-in "UDP Send" block, which works, but I don't know how to decode the data I'm getting. This is what my python script looks like:
import sys, struct
from socket import *
SIZE = 1024 # packet size
hostName = gethostbyname('0.0.0.0')
mySocket = socket( AF_INET, SOCK_DGRAM )
mySocket.bind((hostName,5002))
repeat = True
while repeat:
(data,addr) = mySocket.recvfrom(SIZE)
data = struct.unpack('d',data)
print data
I've suspected that the data stream should be something like a double, but while it's giving me numbers they aren't meaningful:
If simulink sends a constant "1", I get an output of "3.16e-322"
If Simulink sends a constant "2", I get an output of "3.038e-319"
Any ideas?
Turns out my network was reversing the packet bits. The solution was to read it in as bit-reversed:
data = struct.unpack('!d',data)
I have no clue why this happens over some networks and not others. Can someone comment on a way to tell if I need to use bit-reversal?
The problem occurs when the sender and receiver has different byte order.
See sys.byteorder.
Best practice should be to always convert to network order when sending and convert again when receiving.
Related
I'm trying to read and write data from an RFID tag using python whit this module:
https://es.aliexpress.com/item/32573423210.html
I can connect successfully whit serial but I don't know how to read any tag, because the datasheet from pr9200(the reader that I am working) use this:
Image for pr9200 operation It's like a raw packet whit only hex address that I need to send to the module for it works
my code on python is this:
import serial
ser = serial.Serial(port = "COM27", baudrate=115200, bytesize=8, parity='N', stopbits=1)
while(ser.is_open == True):
rfidtag = ''
incomingByte = ser.read(21)
print(incomingByte)
for i in incomingByte:
rfidtag = rfidtag + hex(i)
Some comments to jump start your coding:
-What you need to do is send a command to your device to ask it to start sending readings in auto mode. To do that you need to use ser.write(command). You can find a good template here.
-To prepare the command you just need to take the raw bytes (those hex values you mentioned) and put them together as, for instance a bytearray.
-The only minor hurdle remaining is to calculate the CRC. There are some nice methods here at SO, just search CRC 16 CCITT.
-Be aware that after writing you can not start immediately waiting for readings, you have to wait first for the device to acknowledge the command. Hint: read 9 bytes.
-Lastly, take a new count of the bytes you will receive for each tag. I think they are 22 instead of 21.
You can use pyembedded python library for this which can give you the tag id.
from pyembedded.rfid_module.rfid import RFID
rfid = RFID(port='COM3', baud_rate=9600)
print(rfid.get_id())
https://pypi.org/project/pyembedded/
I am using a raspberry pi to send data through TCP/IP where the raspberry pi is the server and my local windows machine is the client.
When I try to read data in python 3, I am getting weird characters for example:
send 20 decimal I receive #4
send 21 decimal I receive #5
send 22 decimal I receive #6
Below is the code running on my local machine:
import socket
host = '192.168.1.100'
port = 25000
mySocket = socket.socket()
mySocket.connect((host,port))
data = mySocket.recv(4).decode()
print (data)
Using python 2 is no problem and characters received with no decoding needed. I know I need to do some decoding on the data but not sure what. Any advise will be very helpful.
I finally figured this by using the following code:
data = mySocket2.recv(4)
newData = int.from_bytes(data, byteorder='big', signed=False)
The sender is sending uint32 data, that is obviously not-signed and is bigEndian. This has to be specified at the receiver side as well (my python3 script). If the sender changes and starts sending int8 data then I will need to update the receiver code to the following:
data = mySocket2.recv(1)
newData = int.from_bytes(data, byteorder='big', signed=True)
P.S. serial or TCP/IP receiving seem to follow the same logic in python, this means that data received requires the same encoding.
I'm trying to capture data from a hardware device that's connected via usb to my linux computer that's running ubuntu. Here's the very simple script I currently have:
import serial
ser = serial.Serial('/dev/ttyUB0', 9600)
s = ser.read(10000)
print(s)
How do I make this print continuously?
The data is coming through in hexadecimal which I'd like to interpret. Should I have the continuous data save to a text file and then have another script analyze? Essentially, I'm trying to build a sniffer to grab the data and interpret.
Thanks for your help! I'm a newbie :)
1)
Just put the read and print within a while True: section.
Example:
import serial
ser = serial.Serial('/dev/ttyUB0', 9600)
while True:
s = ser.read(10000)
print(s)
Checkout another answer for some more info if you need to sniff both send and receive. https://stackoverflow.com/a/19232484/3533874
2)
For speed I would save the data without processing to a file and have the other script do the decoding/processing of the hex data. Make sure you write to the file in binary mode.
Example:
import serial
ser = serial.Serial('/dev/ttyUB0', 9600)
# This will just keep going over and over again
with open('hexdatafile.dat', 'wb') as datafile:
datafile.write(ser.read(10000))
I want to my UDP data packet to have literately this information for example:
data = "83053163021478010102010370020000000000"
I'm using the follow code to send it which works fine(I can see it going out on wireshark):
listener = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
listener.sendto(data, (IP, PORT))
When I look at the data packet in wireshark i want the (wireshark)data packet == data. How do I declare/convert the data type to make this happen.
I think this should do the trick:
import codecs
data = codecs.decode("83053163021478010102010370020000000000", "hex_codec")
Then you can send data same as you are doing now.
ref: How to create python bytes object from long hex string?
I have a raw ethernet Frame that i want to send
How should i do that? i tried to send hex values of a frame but i still cant control packet header that contains src/dst address and ports
import socket
# the public network interface
HOST = socket.gethostbyname(socket.gethostname())
addr = ('46.165.204.237', 10000)
# create a raw socket and bind it to the public interface
s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_IP)
s.bind((HOST, 0))
netpacket = '\xDE\xB0\x7B\xE5\xA7\xCD\x4C\x17\xEB\x07\x0D\xBC\x08\x00\x45\x00\x00\x92\x68\x94\x40\x00\x78\x06\xDC\x94\x2E\xA5\xCC\xED\xC0\xA8\x01\x02\x27\x10\x07\xC8\x04\xD7\xEA\xEA\xC3\x2A\x4E\xA2\x50\x18\x01\x02\x39\xB0\x00\x00\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\x22\x31\x2E\x30\x22\x3F\x3E\x3C\x50\x61\x63\x6B\x65\x74\x3E\x3C\x6F\x70\x65\x72\x61\x74\x69\x6F\x6E\x3E\x33\x3C\x2F\x6F\x70\x65\x72\x61\x74\x69\x6F\x6E\x3E\x3C\x64\x61\x74\x61\x3E\x33\x24\x30\x24\x30\x24\x30\x24\x30\x24\x30\x3C\x2F\x64\x61\x74\x61\x3E\x3C\x65\x78\x74\x64\x61\x74\x61\x3E\x3C\x2F\x65\x78\x74\x64\x61\x74\x61\x3E\x3C\x2F\x50\x61\x63\x6B\x65\x74\x3E'
#netpaket = netpacket.encode('UTF-8')
s.sendto(netpacket.encode('UTF-8'), addr)
Is there in Python a function like sendRaw() or sendRawFrame()?
I know scapy can handle this, but i need to do that many many times, and every time with various payload data. How scapy can be automated? I mean python script that launch scapy creates packet with some payload and send it.
scapy.py
packet1 = IP(dst='46.165.204.237')/TCP(sport=1992, dport=10000)/'<?xml version="1.0"?><Packet><operation>99</operation><data><![CDATA[8 fast]]></data><extdata><![CDATA[]]></extdata></Packet>.'
send(packet1)
The goal for it is to send packet from a port that already in use. If there a better solution for that problem?
Offtopic: maybe someone knows how to send packets through the Open socket id in windows (not only in python)?
You can provide Scapy with raw input by using the Raw layer.
netpacket = Raw('\xDE\xB0...')
To send packets at the ethernet layer - see the documentation for sendp.
sendp(netpacket, iface="eth1")