Skip to content

Instantly share code, notes, and snippets.

@andrewvaughan
Last active January 7, 2024 14:52
Show Gist options
  • Save andrewvaughan/dc51a0370db1ec159d390c1b3a8b320a to your computer and use it in GitHub Desktop.
Save andrewvaughan/dc51a0370db1ec159d390c1b3a8b320a to your computer and use it in GitHub Desktop.
Reading RFID via UART on the RaspberryPi

RFID via UART on RaspberryPi

Download the Latest Version of Raspbian Lite

This can be downloaded here. It is highly recommended to download the Lite version. You can also download the full version, but most of the image is just bloat for this project.

Prepare the MicroSD Card

It is recommended to get a Class 10 or better card to improve speeds. Lower-quality cards will take tremendously longer to format, configure, and load on the RaspberryPi.

Flash the MicroSD card

This guide assumes you are developing with a Mac. You may need to follow slightly different commands, depending on your system.

Determine the mount point of your SD card:

After inserting the MicroSD card into the computer, open a Terminal and list the drives connected to the machine:

diskutil list

For a 32GB MS-DOS formatted card, you will likely see something like this in the list:

/dev/disk2 (internal, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:     FDisk_partition_scheme                        *32.0 GB    disk2
   1:                 DOS_FAT_32 U                       32.0 GB    disk2s1

Find your SD card and make note of it's mount point (/dev/disk2 in this case). You will need this for future steps.

Erase the SD Card

Important this will delete everything on the SD card. Ensure that you have backed up everything of importance on the card to a separate storage medium before continuing.

Erase the card (replace /dev/disk2 with your mount point):

sudo diskutil eraseDisk FAT32 NAME MBRFormat /dev/disk2

Note: While you can change NAME to any capitalized name you wish for the volume, this will be overwritten later in the process.

Load Raspbian Lite on to the SD Card

Transfer the downloaded Raspbian .img file to the drive. Note, if downloaded in a compressed format (e.g., .zip), you must decompress the file before continuing.

First, you must unmount the disk you just erased:

sudo diskutil unmountDisk /dev/disk2

Then, you need to transfer, byte-for-byte, the image file to the now-unmounted drive:

sudo dd bs=1m if=/path/to/your/raspbian-lite.img of=/dev/rdisk2

Note: Notice the use of rdisk instead of disk in this step. This will significantly improve your transfer speeds by removing buffering from the streaming process.

If you receive an error along the lines of dd: bs: illegal numeric value, change the 1m value to 1M and try again.

This step can take some time. You can press CTRL+T during the transfer process to see how many bytes have been transferred and the current speed:

$ sudo dd bs=1m if=./2017-09-07-raspbian-stretch-lite.img of=/dev/rdisk2
load: 1.71  cmd: dd 6338 uninterruptible 0.00u 0.04s
46+0 records in
45+0 records out
47185920 bytes transferred in 2.255203 secs (20923136 bytes/sec)

Configure Raspbian to Connect to WiFi by Default

In order to access the RaspberryPi without having to connect it to a display first, the wifi adapter must be configured to connect to your network by default.

To do this, you must configure the network in a special file on the root of the new volume. First visit the root and create a new file:

cd /Volumes/boot
touch wpa_supplicant.conf

You will need to make the wpa_supplicant.conf file you just created look like the following, in the text editor of your choice:

ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
country=US

network={
    ssid="your-network-name"
    psk="your-network-password"
}

Note: Obviously, modify the country, ssid, and psk to the settings for your network; but, generally leave everything else the same.

Note Also: More advanced networks might require additional settings in the wpa_supplicant.conf file. Those networks are outside the scope of this guide.

Configure Raspbian to Launch the SSH Server by Default

In order to access the RaspberryPi without having to connect it to a display first, the SSH server must be configured to launch by default.

To do this, simply navigate to the new volume and create a new ssh file in the root directory:

cd /Volumes/boot
touch ssh

That's it! An SSH server will be launched by default on first-boot of the drive.

Enable UART on the RaspberryPi

By default, UART is disabled to make room for other service on the RaspberryPi. We need to configure the kernel to enable UART before starting.

First, make a backup of your config.txt file, in case you mangle it:

cd /Volumes/boot
cp config.txt config.txt.backup

Then, carefully, open the config.txt file in the root of your boot volume.

There are a number of settings in this file we do not care about, and therefore should not change.

First, find the line for dtoverlay. We will need to modify this line to look like this:

dtoverlay=pi3-disable-bt

This will disable Bluetooth on the RaspberryPi, ensuring that it does not use the UART serial interface we wish to use. If you also need Bluetooth, you can move Bluetooth to a software serial port.

At the bottom of the file, add this line:

enable_uart=1

There is a large explanation for why this is needed here, but just know that this is extremely important for this to function on the RaspberryPi.

Remove Serial Configuration on Boot

As with the config.txt file, make a backup of the cmdline.txt file:

cd /Volumes/boot
cp cmdline.txt cmdline.txt.backup

Enter cmdline.txt and remove any segments that refer to tyyAMA0 or serial0. For instance, if your cmdline.txt file looks like this:

dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=PARTUUID=e2047fe4-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait

It should be changed to this:

dwc_otg.lpm_enable=0 console=tty1 root=PARTUUID=e2047fe4-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait

Save this file and exit.

Setup Raspbian

At this point, the SD card is ready for use. Unmount it from your computer, remove it, and place it into your RaspberryPi. If you apply power to the RaspberryPi, after a few moments, you should be able to connect to it using SSH:

As per default, the RaspberryPi username is pi and the password is raspberry.

General Configuration

As with most installs, a number of changes need to be made to fully-empower the RaspberryPi.

Run raspi-config to make necessary configuration changes:

sudo raspi-config

Recommended changes are as follows:

  • Option 1 Change the username and password to something other than the default
  • Option 2 Modify the hostname to something other than the default
  • Option 7-A1 Expand the filesystem to use the entire SD Card

You will be asked if you wish to reboot. You can optionally reboot now, or wait for the next step.

Setup Serial

Before beginning, disable the Bluetooth service and restart:

sudo systemctl disable hciuart
sudo reboot

Testing UART

Before continuing, connect the TX and RX pins on the RaspberryPi with a wire. These are generally pins 8 and 10.

SSH into the RaspberryPi and install minicom:

sudo apt-get install -y minicom

Then, run minicom:

minicom -b 115200 -o -D /dev/ttyAMA0

With this configuration, minicom should repeat whatever characters you type. If it does, this means that both transmission and reception via UART has been successful. If this does not work, there is an issue with UART you must resolve before continuing.

You can exit minicom by pressing CTRL+A and then X.

Preparing the RDM6400 RFID Board

The RDM6400 works on 5V logic. It contains the following pins:

RDM6400

The pintout is as follows:

P1:
   PIN1    TX
   PIN2    RX
   PIN3
   PIN4    GND
   PIN5    +5V(DC)
 P2:
   PIN1    ANT1
   PIN2    ANT2
 P3:
   PIN1    LED
   PIN2    +5V(DC)
   PIN3    GND

Because the RaspberryPi uses a 3.3V input for it's UART transmission, we will need to use a 2K2 and a 3K3 resistor to act as a voltage divider from the RDM6300's 5V signal.

As such, make the connections as shown in this schematic:

RFID Schematic

Once this is setup, power on the RaspberryPi, which should light LEDs on both the RaspberryPi and the RDM6300. Once it is loaded, you can confirm transmission from the RDM6300 using minicom:

minicom -b 9600 -H -o -D /dev/ttyAMA0

Note: The change of baud rate to 9600, as used by the RDM6300. The additional -H flag will output data in hexadecimal format, which will come in useful for later steps.

Once minicom is listening, wave a 125KHz RFID badge in front of the antenna to receive a signal. It is highly likely that the scanner will read the card multiple times:

Welcome to minicom 2.7

OPTIONS: I18n 
Compiled on Apr 22 2017, 09:14:19.
Port /dev/ttyAMA0, 20:13:16

Press CTRL-A Z for help on special keys

02 31 30 30 30 30 31 35 39 35 31 31 39 03 02 31 30 30 30 30 31 35 39 35 31 31 39 03 02 31 30 30 30 30 31 35 39 35 31 31 39 03 

Reading an RFID Card

In the example above, a real RFID card is used with the printed ID of 0000088401. The signal, as transmitted by the RDM6300, shows up in the minicom console. Upon close inspection, one can see that, in fact, the same card was read multiple times:

02 31 30 30 30 30 31 35 39 35 31 31 39 03
02 31 30 30 30 30 31 35 39 35 31 31 39 03
02 31 30 30 30 30 31 35 39 35 31 31 39 03 

Breaking down the meaning of this, in hexadecimal, is as follows:

Hex Meaning
02 Start-Read Byte (Always 02h)
31 30 30 30 30 31 35 39 35 31 Card ID (10-Bytes)
31 39 Parity Bytes (2-Bytes)
03 End-Read Byte (Always 03h)

So, of the 14-bytes sent each read, the first byte is always 02h, the next 10-bytes are the card ID, the next 2-bytes are parity bytes (see below), and the final byte is always 03h.

Decoding the Card ID

The card ID is not intuitive from the 10-bytes provided. To decode the actual ID of the card is a multi-step process:

  1. Convert the 10-byte hexadecimal values to their ASCII value
  2. Concatenate all results of the string
  3. Take the hexadecimal string produced and convert it to decimal

Using the example above:

Hex Ascii
31 1
30 0
30 0
30 0
30 0
31 1
35 5
39 9
35 5
31 1

IMPORTANT NOTE: The value above should have a 0 (30h) in the first digit. Discovery needs to be done as to why this is showing up as a 1 (31h) by testing more cards. The statement below is only correct if this byte is fixed:

This provides us with the hexadecimal string 0000015951. Converting this hexadecimal string into binary gives us 88401 - the ID of our card.

Checking the Parity Bytes

Two parity bytes are provided, in this case 31 and 39. Similar to the Card ID, these bytes are converted into ASCII and then concatenated.

Converting the ASCII values of the parity bits provides us the characters 1 and 5, respectively, or a concatenated string of 15, which we can treat as hexadecimal, just like the Card ID bytes.

All of the hexadecimal bytes for the Card ID are then XOR'd together to get a value that should be equivalent to the provided parity:

Card Hex 0000015951:

00h = 0000 0000
00h = 0000 0000

XOR = 0000 0000
01h = 0000 0001

XOR = 0000 0001
59h = 0101 1001

XOR = 0101 1000
51h = 0101 0001

XOR = 0000 1001   (09h - If first byte 00h)
XOR = 0001 1001   (19h - If first byte 10h)

PRT = 0001 0101   (15h - Incorrect)

Note: This needs more research - supposed XOR does not result in received parity byte. This may have to do with the incorrect card read?

@OluwatomiTomi
Copy link

OluwatomiTomi commented Apr 10, 2021

How did you get RDM component on Proteus please

#done

@OluwatomiTomi
Copy link

How do I emulate these schematic connections using R pI-4?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment