How to use an uhf rfid module with python? - python

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/

Related

Is there a python-periphery library i2c code example or detailed explanation other than the documentation?

This is my first question in Stackoverflow if I have made a mistake while writing this question please give me a feedback to correct myself.
I want to use i2c communication for my raspberry pi. I want to use python-periphery(I know there is smbus out there). In the documentation https://python-periphery.readthedocs.io/en/latest/i2c.html there is not much information how to use the library. Here is the code in the documentation:
from periphery import I2C
# Open i2c-0 controller
i2c = I2C("/dev/i2c-0")
# Read byte at address 0x100 of EEPROM at 0x50
msgs = [I2C.Message([0x01, 0x00]), I2C.Message([0x00], read=True)]
i2c.transfer(0x50, msgs)
print("0x100: 0x{:02x}".format(msgs[1].data[0]))
i2c.close()
I have tried to write/read with a sensor and It was successful. However in my test code I used this:
#Write to 0x09 register,this byte: 0x13
W9 = [I2C.Message([0x09,0x13])]
i2c.transfer(DFLT_ADDRESS,W9)
#Read from 0x09 register
R = [I2C.Message([0x09]), I2C.Message([0x00], read=True)]
i2c.transfer(DFLT_ADDRESS,R)
print(R[1].data[0])
(I have used smbus to check the data is written in the register and read correctly. So, test code is working.)
What I want to know is where is the 0x100(I think [0x01, 0x00] this is 0x100) in this line: msgs = [I2C.Message([0x01, 0x00]), I2C.Message([0x00], read=True)], And when i tried this, it writes 0x00 to the register in my sensor. Is it beause my sensor has 8 bit but I tried to write 16 bit? So, Can anyone explain what is going on in the documentation example?
Maybe you could try this code I use on my raspberry pi zero :
# coding=utf-8
# date : 25/05/2021
# dossier : piPeri
# fichier : pP_readByte01.py
# check the result with these commands :
# i2cset -y 1 0x51 0x10 0x01
# i2cget -y 1 0x51
# 3x times
from periphery import I2C
print(" Read 3 bytes starting at register address 0x1001 of EEPROM at I2C address 0x51 ")
# Open i2c-0 controller
i2c = I2C("/dev/i2c-1")
# create array to hold received data ( 3 bytes in my case )
dataRX = [0,0,0]
# create message to place 16 bits in memory register of eeprom
msgWritePointer = I2C.Message([0x10,0x01],read=False)
# create message to read data according to length of array 'dataRX'
msgRead = I2C.Message(dataRX,read=True)
# messages are assembled, order is important
msgs = [msgWritePointer, msgRead]
# call transfer function
i2c.transfer(0x51, msgs)
# print received bytes
for i in range(0,len(msgs[1].data)):
print(hex(msgs[1].data[i]))
i2c.close()

pyserial - how to continuously read and parse

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))

how to combine following three values in python/pyserial to get one value

I'm trying to combine three values that I got through serial port using pyserial. These values are corresponding to 3 parts of a 24bit data transmitted from and fpga board and I want to get the 24 bit data in python script. What kind of a conversion and combination process can give me back this 24 bit data? I'm reading data using below simple while loop...
import serial
port = serial.Serial('/dev/ttyUSB0', 115200)
file = open("my_file.txt","a")
while True:
message = ord(port.read())
print(message)
file.write(str(message) + "\n")
file.close()
Thanks in advance :)
You can use the struct module (built-in Python) for pack those 3 bytes into one:
import struct
#Your code ...
while True:
message = port.read(3) #Read 3 bytes at once
combined = struct.unpack(">I", b'\x00' + message)[0]
The >I means you decoding 32-bit unsigned integer (I) saved in big-endian (>). Because struct.unpack() doesn't support 24-bit numbers I added 1 zero byte to the start of the 24-bit number which effectively creates 32-bit number.

Read data from load cell

Your help is badly needed...
I'm trying to read data and print it to the python console from a load cell. My setup is as follow:
The load cell is a MD type from Eilersen connected to a load cell signal converter of type MCE2040 Seriel Communication Module also from Eilersen. The MCE2040 is connected to my PC through a USB to seriel connector like this link_http://www.usbgear.com/USB-COM-I-SI.html (I'm only allowed two links) one.
The load cell is connected to COM 1.
I have tried to run this snippet:
import serial
ser = serial.Serial(0) # open first serial port
print ser.portstr # check which port was really used
#ser.write("hello") # write a string
ser.close()
...and that prints 'COM1' to the console so I guess my connection should be okay.
My problem is that I don't know how to proceed. In the end I'd like to plot a graph of the incoming data and output a data file with time stamps, but for starters I'd like to print some load cell data to the console.
Any help will be highly appreciated. If further information is needed, please let me know.
Thx in advance.
Edit:
I have some documentation re MCE2040:
3.1 EVC Mode (without time stamp)
Specification: RS232/RS4422
Baudrate: 115200 bps
38400 bps (select with SW1.5)
Data bits: 7
Parity: Even
Stop bits: 1
Protocol: EVC protocol described below (Transmit Only)
3.1.1 EVC Protocol Format
After each sample period a new weight telegram is transmitted. The transmitted telegram has the following format:
<LF>WWWWWWWW<CR>
Each telegram contains a line feed character, a weight result and a carriage return character. The telegram contains:
<LF> Line Feed character (ASCII 0Ah).
WWWWWWWW Weight value for the loadcell. The value is an 8 byte ASCII hex number with MSB first.
<CR> Carriage Return character (ASCII 0Dh).
I was able to get some output from the following code:
import serial
ser = serial.Serial(0, baudrate=115000 ,timeout=100)
print ser.portstr
x = ser.read(50)
print x
ser.close()
print 'close'
Output:
COM1
ÆÆÆÆA0·5
ÆÆÆÆA0·6
ÆÆÆÆA0·5
ÆÆÆÆA0·±
ÆÆÆÆA0·±
close
First of all make sure it's really your com port, since COM1 is used by a lot of computers i'm not sure it's your com port.
You can use a simple wire to loop back info by connecting TX to RX at the USB to Serial converter, it will result in an echo (you will read what you write) it's a very simple way to verify that you are talking with the right com port.
Regarding how to continue:
Useful basic commands:
ser.write("command") with this command you send to the device some command.
ser.read(n) is for read n bytes from the device
ser.readline() will read line until it reached \n (new line)
Steps:
Send a command to your device.
Read all the data by some end byte (Frame Synchronization).
Parse data to structure (list or something like that..)
Plot it to graph.
Useful Links:
pyserial docs
tips for reading serial
plotly for graphs in python

Reading data from Simulink into Python over UDP

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.

Categories