Last year, I worked with Timo Arnall and Einar Martinussen and Jørn Knutsen on a Processing library to read and write to Mifare RFID tags using the Sonmicro SM130 read/write module. Here it is, with a few improvements and bug fixes.
To use the library, unzip it and copy the folder to your Processing libraries folder. Then restart Processing. There are two example sketches, a simple reader that seeks new tags, and a full read/write example.
For more details, see the datasheet for the module. Code examples will follow in this blog.
The available commands are as follows:
SonMicroReader(PApplet p, Serial s) – initializes a new instance of the library
Example:
import processing.serial.*;
import sonMicroReader.*;
Serial myPort; // serial port instance
SonMicroReader myReader; // sonMicroReader instance
void setup() {
// set window size:
size(400,300);
// based on the list of serial ports printed from the // previous command, change the 0 to your port's number: String portnum = Serial.list()[0]; // initialize the serial port. default data rate for // the SM130 reader is 19200: myPort = new Serial(this, portnum, 19200); // initialize the reader instance: myReader = new SonMicroReader(this,myPort); myReader.start(); myReader.reset();
}
void start() - Starts the reader instance. Spawns a new thread to continually scan for new serial data, and generates a sonMicroEvent() when a new packet is received.
Example:
myReader.start();
void quit() – stops the reader instance
Example:
myReader.quit();
boolean available() - returns whether or not there’s an availble data packet
Example:
if (myReader.available() {
int[] newReading = myReader.sonMicroReading();
println(newReading();
}
int[] getSonMicroReading() – Used mainly for debugging, this method returns all the bytes that come in from the reader. Returns an array of all the bytes from the reader in response to a given command.
Example:
int[] newReading = myReader.sonMicroReading();
int getCommand()- returns the command byte as received by the reader
Example:
int lastCommand = myReader.getCommand();
int getPacketLength() – returns the length of the payload as reported by the reader
Example:
int packetLength = myReader.getPacketLength();
int getCheckSum() – returns the checksum from the reader
Example:
int checksum = myReader.getCheckSum();
int[] getPayload() – returns the array of bytes in the payload of the message
Example:
int[] payLoad = myReader.getPayload();
int[] getTagNumber() – returns the array of bytes in the tag number of the message
Example:
int[] tagNumber = myReader.getTagNumber();
String getTagString() – returns the ASCII-encoded hex string of the tag number of the message
Example:
String tagString = myReader.getTagString();
int getTagType() – Assuming there’s a valid tag read, this returns the tag type, as follows:
- 0×01 Mifare Ultralight
- 0×02 Mifare Standard 1K
- 0×03 Mifare Classic 4K
- 0xFF Unknown Tag type
Example:
int tagType = myReader.getTagType();
void reset() - Resets the reader by sending command 0×80
Example:
myReader.reset();
void getFirmwareVersion() – gets the firmware of the reader by sending command 0×81
Example:
myReader.getFirmWareVersion();
int getErrorCode() – Gets the error code returned by some messages, as follows:
Example:
int errorCode = myReader.getErrorCode();
Select Tag (command 0×83)
- 0x4E ‘N’ No Tag present.
- 0×55 ‘U’ Access failed due to RF Field is OFF
Seek for Tag (command 0×82)
- 0x4C ‘L’ Command in progress.
- 0×55 ‘U’ Command in progress but RF Field is OFF
Authenticate (command 0×85)
- 0x4C ‘L’ Login Successful
- 0x4E ‘N’ No Tag present or Login Failed
- 0×55 ‘U’ Login Failed
- 0×45 ‘E’ Invalid key format in E2PROM
Read Block (command 0×86)
- 0x4E ‘N’ No Tag present
- 0×46 ‘F’ Read Failed
Read Value Block (command 0×87)
- 0x4E ‘N’ No Tag present
- 0×49 ‘I’ Invalid Value Block
- 0×46 ‘F’ Read Failed
Write Block (command 0×89)
- 0×55 ‘U’ Read after write failed
- 0×58 ‘X’ Unable to Read after write
- 0x4E ‘N’ No Tag present
- 0×46 ‘F’ Write Failed
Write Value Block (command 0x8A)
- 0x4E ‘N’ No Tag present
- 0×49 ‘I’ Invalid Value Block. The block was not in the proper value format when read back. This could be because there was an error in writing
- 0×46 ‘F’ Read Failed during verification
Write 4-byte block (command 0x8B)
- 0×55 ‘U’ Read after write failed
- 0×58 ‘X’ Unable to Read after write
- 0x4E ‘N’ No Tag present
- 0×46 ‘F’ Write Failed
Write Master Key (command 0x8C)
- 0x4C ‘L’ Write Master key successful
- 0x4E ‘N’ Write Master key fail
Set Antenna Power (command 0×90)
- 0×00 RF Field switched Off
- 0×01 RF Field switched On
Set Baud Rate (command 0×94)
- 0x4C ‘L’ Change of Baud rate successful
- 0x4E ‘N’ Change of Baud rate failed
- @return an int for the error code.
String getErrorMessage() – returns a descriptive error message
Example:
String errorMsg = myReader.getErrorMessage();
int getAntennaPower() – returns the antenna power. 0×00 is off, anything else is on
Example:
int antennaPower = myReader.getAntennaPower();
void seekTag() – Sends the Seek Tag command (0×83)
Example:
myReader.seekTag();
void selectTag()- Sends the Select Tag command (0×82)
Example:
myReader.selectTag();
void setAntennaPower(int level) – Sets the antenna power. 0×00 is off, anything else is on
Example:
myReader.setAntennaPower(1); // turns antenna on
void sleep() – Sends the sleep command (0×96)
Example:
myReader.sleep();
void setBaudRate(int baudRate) – sets the baud rate. Possible baud rates:
- 9600 bps
- 19200 bps
- 38400 bps
- 57600 bps
- 115200 bps
Example:
myReader.setBaudRate(57600);
void writeBlock(int thisBlock, String thisMessage) – Writes a 16-byte string to a block. If the string is less than 16 bytes, it fills the empty bytes with 0×00. If more than 16 bytes, it generates an error message. You need to select and authenticate before you can read or write.
Example:
myReader.writeBlock(0x10, "Hello World!");
public void writeFourByteBlock(int thisBlock, String thisMessage) - Writes a 4-byte string to a block. If the string is less than 16 bytes, it fills the empty bytes with 0×00. If more than 4 bytes, it generates an error message. Used for Mifare ultralight tags. You need to select and authenticate before ou can read or write.
Example:
myReader.writeFourByteBlock(0x10, "Beep");
void authenticate(int thisBlock, int authentication) – Authenticates for reading and writing. You need to select and authenticate before you can read or write.
- thisBlock: Block to write to
- authentication: Authentication type to use (see SM130 datasheet for more; as a default, use 0xFF)
Example:
myReader.authenticate(0x10, 0xFF);
void readBlock(int thisBlock) – Reads a block of data. You need to select and authenticate before you can read or write. You need to select and authenticate before ou can read or write.
- thisBlock: Block to read from
Example:
myReader.readBlock(0x10);
void sendCommand(int thisCommand) – Sends a single-byte command
Example:
myReader.sendCommand(0x80); // resets the module
void sendCommand(int[] thisCommand) - Sends a multi-byte command
Example:
int[] thisCommand = {0x90, 0x01}; // setAntenna, power level 1
myReader.sendCommand(thisCommand);
int version() - returns the version number of the library
Example:
println(myReader.version());
Pingback: Sonmicro RFID Processing library