树莓派+Python读取USB HID模式RFID设备解码问题求助
Hey Federico, let's break down how to decode that HID RFID data and get your tag code properly!
First off, most HID-mode RFID readers act like USB keyboards—they don't send raw tag data directly; they send keyboard scan codes (the same signals your keyboard sends when you press a key). That's why you're seeing those random numbers instead of your 210054232F tag code.
Let's fix this step by step:
1. Map those scan codes to actual characters
You already noticed the output pairs like 1 31 1—this is likely the reader's way of sending a single key press. The middle number is the USB HID scan code, and the surrounding 1s are just framing bytes. Here's a quick mapping for the characters in your tag:
| Scan Code | Character |
|---|---|
| 30 | 0 |
| 31 | 1 |
| 32 | 2 |
| 33 | 3 |
| 34 | 4 |
| 35 | 5 |
| 39 | / |
| 44 | F |
Looking at your output, you can already match some entries to your tag:
1 31 1→11 30 1→01 32 1→2
2. Adjust your script to read the right chunk size
Your current code reads 16 bytes at once, which mixes multiple key press reports together. Try reading 3 bytes at a time (since each key press seems to be wrapped in 3 bytes):
import sys # Open the HID device with open('/dev/hidraw0', 'rb') as fp: # Mapping scan codes to your tag's characters (expand this as needed) scan_code_map = { 30: '0', 31: '1', 32: '2', 33: '3', 34: '4', 35: '5', 39: '/', 44: 'F' } while True: # Read 3 bytes per key press report buffer = fp.read(3) if len(buffer) != 3: continue prefix, scan_code, suffix = ord(buffer[0]), ord(buffer[1]), ord(buffer[2]) # Only process valid key presses (ignore empty/reset signals) if prefix == 1 and suffix == 1 and scan_code != 0: char = scan_code_map.get(scan_code, f"[UNKNOWN:{scan_code}]") print(char, end='') # Print without newlines to build the full tag code
3. Get the official HID report structure (if the above doesn't work)
If the 3-byte assumption is wrong, you can find the exact report format of your device using the hidraw-dump tool:
sudo hidraw-dump /dev/hidraw0
This will output the device's HID report descriptor, which tells you how many bytes per report, what each byte represents (e.g., modifier keys, scan codes), and more.
4. Use a dedicated HID library for easier handling
Manual byte parsing can get messy. Try the hidapi Python library, which handles HID device communication and report parsing out of the box:
- Install it first:
pip install hidapi - Find your device's Vendor ID (VID) and Product ID (PID) with
lsusb(look for your RFID reader entry, e.g.,ID 1234:5678where1234is VID and5678is PID) - Use this script:
import hid # Replace with your device's VID/PID from lsusb VENDOR_ID = 0x1234 PRODUCT_ID = 0x5678 device = hid.device() device.open(VENDOR_ID, PRODUCT_ID) try: scan_code_map = {30:'0',31:'1',32:'2',33:'3',34:'4',35:'5',39:'/',44:'F'} while True: # Read input reports (adjust the 64 to match your device's report size) report = device.read(64) if not report: continue # Extract the scan code (adjust the index based on your report descriptor) scan_code = report[1] if scan_code != 0: print(scan_code_map.get(scan_code, f"[?{scan_code}]"), end='') finally: device.close()
Final Notes
Since your reader outputs 210054232F directly in the terminal, it's definitely emulating a keyboard. Once you map the scan codes correctly, you'll see the full tag code printed out as a single string.
内容的提问来源于stack exchange,提问作者Federico Pinciaroli

