{"id":309,"date":"2009-03-06T18:10:55","date_gmt":"2009-03-06T23:10:55","guid":{"rendered":"http:\/\/www.tigoe.net\/pcomp\/code\/?p=309"},"modified":"2009-03-07T11:26:40","modified_gmt":"2009-03-07T16:26:40","slug":"reading-and-writing-to-mifare-rfid-tags","status":"publish","type":"post","link":"https:\/\/www.tigoe.com\/pcomp\/code\/Processing\/309\/","title":{"rendered":"Reading Mifare RFID Tags"},"content":{"rendered":"<p>This tutorial explains how to read from Mifare RFID tags from your computer using a <a href=\"http:\/\/www.sonmicro.com\/1356\/sm130.php\">Sonmicro SM130<\/a> read\/write module.  The sketch below is written in <a href=\"http:\/\/www.processing.org\">Processing<\/a> using my <a href=\"https:\/\/tigoe.com\/pcomp\/code\/category\/Processing\/314\">SonmicroReader library<\/a>. The SM130 has a TTL serial interface that you can connect to a micocontroller, or to a personal computer through a USB-to-serial interface.\u00a0 Using the latter, it&#8217;s pretty simple to send serial commands to it and receive the data back. The entire Processing sketch can be downloaded here: <a href=\"https:\/\/tigoe.com\/pcomp\/code\/wp-content\/uploads\/2009\/03\/rfid_simple_0001.zip\">rfid_simple_0001<\/a>.<\/p>\n<p><!--more--><\/p>\n<h2>Circuit<\/h2>\n<p><strong>Parts:<\/strong><\/p>\n<ul>\n<li>Solderless breadboard<\/li>\n<li><a href=\"http:\/\/www.sonmicro.com\/1356\/sm130.php\">SM130<\/a> RFID read\/write module<\/li>\n<li><a href=\"http:\/\/www.sonmicro.com\/1356\/antenna.php\">RFID antenna<\/a><\/li>\n<li><a href=\"http:\/\/www.trossenrobotics.com\/store\/c\/2966-Mifare-1S50.aspx\">Mifare RFID tags<\/a><\/li>\n<li><a href=\"http:\/\/www.ftdichip.com\">FTDI<\/a> <a href=\"http:\/\/www.makershed.com\/ProductDetails.asp?ProductCode=TTL232R\">USB-to-serial cable<\/a><\/li>\n<li>22AWG solid-core hookup wire in red, black, and blue<\/li>\n<li>row of five male headers, 0.1 inch spacing.<\/li>\n<\/ul>\n<figure id=\"attachment_287\" aria-describedby=\"caption-attachment-287\" style=\"width: 346px\" class=\"wp-caption alignleft\"><a href=\"https:\/\/tigoe.com\/pcomp\/code\/wp-content\/uploads\/2009\/03\/rfid_00041.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-287\" style=\"border: 0pt none;\" title=\"rfid_00041\" src=\"https:\/\/tigoe.com\/pcomp\/code\/wp-content\/uploads\/2009\/03\/rfid_00041.png\" alt=\"rfid_00041\" width=\"346\" height=\"304\" srcset=\"https:\/\/www.tigoe.com\/pcomp\/code\/wp-content\/uploads\/2009\/03\/rfid_00041.png 800w, https:\/\/www.tigoe.com\/pcomp\/code\/wp-content\/uploads\/2009\/03\/rfid_00041-300x264.png 300w\" sizes=\"auto, (max-width: 346px) 100vw, 346px\" \/><\/a><figcaption id=\"caption-attachment-287\" class=\"wp-caption-text\">Figure 1. Click on the image to enlarge.<\/figcaption><\/figure>\n<p><strong>First you&#8217;ll need to wire up the solderless breadboard. <\/strong> Figure 1 shows the wiring layout.  The red and black wires at the top of the board connect the power and ground buses on either side of the board.  The next two  wires down, black and red respectively, connect the power and ground buses to the FTDI serial cable. The vertical blue wires connect serial transmit (TX) and receive (RX) from the SM130 module to the FTDI cable.  The red wires that come next power the module.  The black wires below that provide ground connections for the module and the antennas. Note that the  bottom black wire that connects to the ground bus has some slack in it.  This is because the SM130 module plugs in right next to it.<\/p>\n<p><strong>Next, add the SM130 module.<\/strong> The top of the module lines up with the red wires providing it with power.  Make sure to line the module up all the way to the left hand side of the breadboard so you have a row of holes on the right for the antenna.<\/p>\n<figure id=\"attachment_290\" aria-describedby=\"caption-attachment-290\" style=\"width: 229px\" class=\"wp-caption alignnone\"><a href=\"https:\/\/tigoe.com\/pcomp\/code\/wp-content\/uploads\/2009\/03\/rfid_0003.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-290\" style=\"border: 0pt none;\" title=\"rfid_0003\" src=\"https:\/\/tigoe.com\/pcomp\/code\/wp-content\/uploads\/2009\/03\/rfid_0003.png\" alt=\"Figure 2. Click on the image to enlarge\" width=\"229\" height=\"338\" srcset=\"https:\/\/www.tigoe.com\/pcomp\/code\/wp-content\/uploads\/2009\/03\/rfid_0003.png 477w, https:\/\/www.tigoe.com\/pcomp\/code\/wp-content\/uploads\/2009\/03\/rfid_0003-203x300.png 203w\" sizes=\"auto, (max-width: 229px) 100vw, 229px\" \/><\/a><figcaption id=\"caption-attachment-290\" class=\"wp-caption-text\">Figure 2<\/figcaption><\/figure>\n<p><strong>Next comes the antenna. <\/strong> The top pin lines up with the second pin on the right hand side of the reader, as shown in the Figure 3.<\/p>\n<figure id=\"attachment_301\" aria-describedby=\"caption-attachment-301\" style=\"width: 336px\" class=\"wp-caption alignnone\"><a href=\"https:\/\/tigoe.com\/pcomp\/code\/wp-content\/uploads\/2009\/03\/rfid_0001.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-301\" style=\"border: 0pt none; margin-left: 5px; margin-right: 5px;\" title=\"rfid_0002\" src=\"https:\/\/tigoe.com\/pcomp\/code\/wp-content\/uploads\/2009\/03\/rfid_0002.png\" alt=\"Figure 3. Click on the image to enlarge\" width=\"336\" height=\"295\" srcset=\"https:\/\/www.tigoe.com\/pcomp\/code\/wp-content\/uploads\/2009\/03\/rfid_0002.png 800w, https:\/\/www.tigoe.com\/pcomp\/code\/wp-content\/uploads\/2009\/03\/rfid_0002-300x264.png 300w\" sizes=\"auto, (max-width: 336px) 100vw, 336px\" \/><\/a><figcaption id=\"caption-attachment-301\" class=\"wp-caption-text\">Figure 3<\/figcaption><\/figure>\n<p><strong>Finally, connect the FTDI cable using the male headers.<\/strong> The black wire of the cable lines up with the black wire just below the power and ground bus wires, as shown in Figure 4.<\/p>\n<figure id=\"attachment_302\" aria-describedby=\"caption-attachment-302\" style=\"width: 336px\" class=\"wp-caption alignnone\"><a href=\"https:\/\/tigoe.com\/pcomp\/code\/wp-content\/uploads\/2009\/03\/rfid_0001.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-302\" style=\"border: 0pt none; margin-left: 5px; margin-right: 5px;\" title=\"rfid_0001\" src=\"https:\/\/tigoe.com\/pcomp\/code\/wp-content\/uploads\/2009\/03\/rfid_0001.png\" alt=\"Figure 4. Click on the image to enlarge\" width=\"336\" height=\"295\" srcset=\"https:\/\/www.tigoe.com\/pcomp\/code\/wp-content\/uploads\/2009\/03\/rfid_0001.png 800w, https:\/\/www.tigoe.com\/pcomp\/code\/wp-content\/uploads\/2009\/03\/rfid_0001-300x264.png 300w\" sizes=\"auto, (max-width: 336px) 100vw, 336px\" \/><\/a><figcaption id=\"caption-attachment-302\" class=\"wp-caption-text\">Figure 4<\/figcaption><\/figure>\n<p>That&#8217;s all the wiring.  Now you&#8217;re ready to start writing code for the module.<\/p>\n<h2>Code<\/h2>\n<p>There&#8217;s a lot you can make the SM130 do, but the simplest thing to do is to put it in seek mode and have it listen for a new tag. Here&#8217;s how to do that using my Processing library.<\/p>\n<p><strong>How do I read a tag&#8217;s ID number?<\/strong><\/p>\n<p>There are two ways to read a tag&#8217;s ID number: you can <strong>select tag<\/strong>, or you can <strong>seek tag<\/strong>. Select tag assumes that there&#8217;s a tag in the field of the antenna. Seek tag, on the other hand, puts the reader in a continuous loop where it waits for a tag to come into range, then automatically gives you the results when it has a tag.<\/p>\n<p>Seek tag would seem to be the more useful function, since you don&#8217;t always want to have to issue a command right when the tag is in place.\u00a0 But it can be a bit tricky, because you can&#8217;t continually send a seek tag command, or you&#8217;ll lock up the module.\u00a0 If you seek when the module is idle, everything&#8217;s fine. The sketch below solves this problem by having the user issue the initial seek tag by hitting a keystroke, then waiting for a response.\u00a0 If the response indicates that a seek tag command was issued, and that a tag has been successfully read (you can get this from the error messages that the commands return), then the sketch prompts the module to seek tag again.<\/p>\n<p>You&#8217;ll need to import both the sonMicroReader library and the serial library. You&#8217;ll also need a few global variables, as follows:<\/p>\n<pre>\/\/ import libraries:\r\nimport processing.serial.*;\r\nimport sonMicroReader.*;<\/pre>\n<pre>Serial myPort;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/ serial port instance\r\nSonMicroReader myReader;\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/ sonMicroReader instance\r\nint fontHeight = 24;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0  \/\/ font height for the text onscreen\r\nString lastTag;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0  \/\/ last tag read<\/pre>\n<p>In the setup() method, initialize the window size, the serial port, and the sonMicroReader. You&#8217;ll also start the library instance (it spawns a separate thread so that it can listen for new data all the time), then send the module a reset command. Finally, initialize a font for writing on the screen:<\/p>\n<pre>void setup() {\r\n  \/\/ set window size:\r\n  size(400,300);\r\n  \/\/ list all the serial ports:\r\n  println(Serial.list());\r\n\r\n  \/\/ based on the list of serial ports printed from the\r\n  \/\/ previous command, change the 0 to your port's number:\r\n  String portnum = Serial.list()[0];\r\n  \/\/ initialize the serial port. default data rate for\r\n  \/\/ the SM130 reader is 19200:\r\n  myPort = new Serial(this, portnum, 19200);\r\n  \/\/ initialize the reader instance:\r\n  myReader = new SonMicroReader(this,myPort);\r\n  myReader.start();\r\n  myReader.reset();\r\n  \/\/ create a font with the second font available to the system:\r\n  PFont myFont = createFont(PFont.list()[2], fontHeight);\r\n  textFont(myFont);\r\n}<\/pre>\n<p>The draw() method doesn&#8217;t do much. It just draws a string to the screen containing the last tag read:<\/p>\n<pre>void draw() {\r\n  \/\/ draw to the screen:\r\n  background(255);\r\n  fill(0);\r\n  textAlign(CENTER);\r\n\r\n  if (lastTag != null) {\r\n    text(lastTag, width\/2, height\/2);\r\n  }\r\n  else {\r\n    text(\"Hit any key to begin reading\", width\/2, height\/2);\r\n  }\r\n}<\/pre>\n<p>Use a keyReleased() handler to prompt the reader to seek for a tag. That way, any key you hit will send a &#8220;seek tag&#8221; command.\u00a0 When the reader is seeking a tag, it goes into a waiting loop and automatically sends you the tag ID when a tag comes in range.<\/p>\n<pre>void keyReleased() {\r\n  \/\/ for manually starting a seek:\r\n  myReader.seekTag();\r\n}<\/pre>\n<p>The sonMicro library generates an event whenever a new packet of data comes in from the reader called sonMicroEvent().\u00a0 You write an event handler to catch that event and read the results, as folllows.\u00a0 This method reads the packet from the reader, looks for the last command, tag type, tag ID in the packet as well as any error messages. If all&#8217;s well, it prompts the reader to seek for another tag.<\/p>\n<pre>\/*\r\n This function is called automatically whenever there's\r\n a valid packet of data from the reader\r\n *\/\r\nvoid sonMicroEvent(SonMicroReader myReader) {\r\n  \/\/ get all the relevant data from the last data packet:\r\n  if (myReader.getTagString() != null) {\r\n    lastTag = myReader.getTagString();\r\n  }\r\n  \/\/ get the error code and last command:\r\n  int errorCode = myReader.getErrorCode();\r\n  int lastCommand = myReader.getCommand();\r\n\r\n  \/\/ a little debugging info:\r\n  println(\"error code: \" + hex(errorCode, 2));\r\n  println(\"last command: \" +  hex(lastCommand,2));\r\n  println(\"last tag type: \" + myReader.getTagType());\r\n  println(\"last tag: \" + lastTag);\r\n  println(\"-----\");\r\n\r\n  \/\/ if the last command was seekTag, then you're either waiting,\r\n  \/\/ or ready to seek again:\r\n  if (lastCommand == 0x82) {\r\n    if (errorCode == 0x4C) {\r\n      \/\/ you're waiting for a tag to appear\r\n    }\r\n    if (errorCode == 0) {\r\n      \/\/ you got a successful read;\r\n      \/\/ wat, then read again\r\n      delay(300);\r\n      myReader.seekTag();\r\n    }\r\n  }\r\n}<\/pre>\n<p>You may have noticed the delay before the seekTag() command.\u00a0 The SM130 really doesn&#8217;t like getting a lot of commands at a time, so the delay is just there to give it time to settle after reading a tag.<\/p>\n<p>That&#8217;s the whole program.\u00a0 When you run it, hit any key to start it reading, then move different tags into the range of the antenna.\u00a0 You should see the different tags show up on the screen as you move them in range, as shown in the screenshot in Figure 5.<\/p>\n<figure id=\"attachment_323\" aria-describedby=\"caption-attachment-323\" style=\"width: 300px\" class=\"wp-caption alignnone\"><a href=\"https:\/\/tigoe.com\/pcomp\/code\/wp-content\/uploads\/2009\/03\/rfid_screenshot.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-323\" style=\"border: 0pt none;\" title=\"rfid_screenshot\" src=\"https:\/\/tigoe.com\/pcomp\/code\/wp-content\/uploads\/2009\/03\/rfid_screenshot-300x242.png\" alt=\"rfid_screenshot\" width=\"300\" height=\"242\" srcset=\"https:\/\/www.tigoe.com\/pcomp\/code\/wp-content\/uploads\/2009\/03\/rfid_screenshot-300x242.png 300w, https:\/\/www.tigoe.com\/pcomp\/code\/wp-content\/uploads\/2009\/03\/rfid_screenshot.png 480w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><figcaption id=\"caption-attachment-323\" class=\"wp-caption-text\">Figure 5. Processing RFID sketch screenshot<\/figcaption><\/figure>\n<p>A full list of the commands available in the sonMicro library is available on the <a href=\"https:\/\/tigoe.com\/pcomp\/code\/category\/Processing\/314\">documentation page<\/a>.<\/p>\n<p>Here&#8217;s the code in its entirety:<\/p>\n<pre>\/*\r\n SonMicro RFID Reader simple example\r\n Language: Processing\r\n\r\n This sketch uses the SonMicroReader library to demonstrate how to read from\r\n Mifare RFID tags using the SonMicro reader.\r\n\r\n created 6 March 2009\r\n by Tom Igoe\r\n *\/\r\n\r\n\/\/ import libraries:\r\nimport processing.serial.*;\r\nimport sonMicroReader.*;\r\nSerial myPort;                \/\/ serial port instance\r\nSonMicroReader myReader;      \/\/ sonMicroReader instance \r\n\r\nint fontHeight = 24;         \/\/ font height for the text onscreen\r\nString lastTag;              \/\/ last tag read\r\n\r\nvoid setup() {\r\n  \/\/ set window size:\r\n  size(400,300);\r\n  \/\/ list all the serial ports:\r\n  println(Serial.list());\r\n\r\n  \/\/ based on the list of serial ports printed from the\r\n  \/\/ previous command, change the 0 to your port's number:\r\n  String portnum = Serial.list()[0];\r\n  \/\/ initialize the serial port. default data rate for\r\n  \/\/ the SM130 reader is 19200:\r\n  myPort = new Serial(this, portnum, 19200);\r\n  \/\/ initialize the reader instance:\r\n  myReader = new SonMicroReader(this,myPort);\r\n  myReader.start();\r\n  myReader.reset();\r\n  \/\/ create a font with the second font available to the system:\r\n  PFont myFont = createFont(PFont.list()[2], fontHeight);\r\n  textFont(myFont);\r\n}\r\n\r\nvoid draw() {\r\n  \/\/ draw to the screen:\r\n  background(255);\r\n  fill(0);\r\n  textAlign(CENTER);\r\n\r\n  if (lastTag != null) {\r\n    text(lastTag, width\/2, height\/2);\r\n  }\r\n  else {\r\n    text(\"Hit any key to begin reading\", width\/2, height\/2);\r\n  }\r\n}\r\n\r\nvoid keyReleased() {\r\n  \/\/ for manually starting a seek:\r\n  myReader.seekTag();\r\n}\r\n\r\n\/*\r\n This function is called automatically whenever there's\r\n a valid packet of data from the reader\r\n *\/\r\nvoid sonMicroEvent(SonMicroReader myReader) {\r\n  \/\/ get all the relevant data from the last data packet:\r\n  if (myReader.getTagString() != null) {\r\n    lastTag = myReader.getTagString();\r\n  }\r\n  \/\/ get the error code and last command:\r\n  int errorCode = myReader.getErrorCode();\r\n  int lastCommand = myReader.getCommand();\r\n\r\n  \/\/ a little debugging info:\r\n  println(\"error code: \" + hex(errorCode, 2));\r\n  println(\"last command: \" +  hex(lastCommand,2));\r\n  println(\"last tag type: \" + myReader.getTagType());\r\n  println(\"last tag: \" + lastTag);\r\n  println(\"-----\");\r\n\r\n  \/\/ if the last command was seekTag, then you're either waiting,\r\n  \/\/ or ready to seek again:\r\n  if (lastCommand == 0x82) {\r\n    if (errorCode == 0x4C) {\r\n      \/\/ you're waiting for a tag to appear\r\n    }\r\n    if (errorCode == 0) {\r\n      \/\/ you got a successful read;\r\n      \/\/ wat, then read again\r\n      delay(300);\r\n      myReader.seekTag();\r\n    }\r\n  }\r\n}<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>This tutorial explains how to read from Mifare RFID tags from your computer using a Sonmicro SM130 read\/write module. The sketch below is written in Processing using my SonmicroReader library. The SM130 has a TTL serial interface that you can connect to a micocontroller, or to a personal computer through a USB-to-serial interface.\u00a0 Using the &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/www.tigoe.com\/pcomp\/code\/Processing\/309\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Reading Mifare RFID Tags&#8221;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7],"tags":[50,111,47,48,49],"class_list":["post-309","post","type-post","status-publish","format-standard","hentry","category-Processing","tag-mifare","tag-Processing","tag-rfid","tag-sm130","tag-sonmicro"],"_links":{"self":[{"href":"https:\/\/www.tigoe.com\/pcomp\/code\/wp-json\/wp\/v2\/posts\/309","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.tigoe.com\/pcomp\/code\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tigoe.com\/pcomp\/code\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tigoe.com\/pcomp\/code\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tigoe.com\/pcomp\/code\/wp-json\/wp\/v2\/comments?post=309"}],"version-history":[{"count":15,"href":"https:\/\/www.tigoe.com\/pcomp\/code\/wp-json\/wp\/v2\/posts\/309\/revisions"}],"predecessor-version":[{"id":329,"href":"https:\/\/www.tigoe.com\/pcomp\/code\/wp-json\/wp\/v2\/posts\/309\/revisions\/329"}],"wp:attachment":[{"href":"https:\/\/www.tigoe.com\/pcomp\/code\/wp-json\/wp\/v2\/media?parent=309"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tigoe.com\/pcomp\/code\/wp-json\/wp\/v2\/categories?post=309"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tigoe.com\/pcomp\/code\/wp-json\/wp\/v2\/tags?post=309"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}