Can You ID This? ID-20 RFID Reader + Arduino

Wednesday, February 23 rd , 2011

A few weeks ago we showed you how to control your arduino over serial. Well this week are going to do the same thing. Only this time instead of using the serial monitor to send the commands, we will be using the Innovations ID line RFID reader.

RFID, or Radio Frequency Identification, is basically a wireless barcode, and in this implementation works by a reader sending out a signal that powers a “tag”, the RFID tag then responds with a unique 12 digit hex serial number. Because each tag sends back a unique number, it can be used as a semi-secure key system, or used to track individual objects.

The company Innovations, while they may have one of the worst sites I have seen in a while, makes some really easy-to-use and inexpensive RFID readers that are easily incorporated into your microcontroller project. The Innovations ID series of RFID readers come in 3 versions, the ID-2, ID-12, and ID-20. All 3 versions have the same pinout and work exactly the same. They all operate with common 125kHz Tags. In fact, the only difference is the antenna. The 2, has no antenna and requires an external one to work, the 12, a smaller antenna, and the 20, a larger antenna. While many other RFID readers offer USB connections, these require no computer to operate and simply send their data via 9600 baud serial which is easily read by your Arduino.

Operation

Hooking this guy is pretty simple, but note that the pins on these readers are not spaced properly for use with breadboard. Sparkfun does sell a board that will give you the .1in spacing needed to work with breadboard. If you do use the adapter board, just note that it changes the placement/ orientation of the pins, so it won’t match the look of the illustration.

The readers also support connecting an LED or buzzer that will light/buzz when a tag is read (pin 10).

Sensing Tag Presence

With the way the reader is hooked up in the product’s spec sheet, the reader will only scan a tag once, and will not rescan until the tag is moved out of, then back into range (watch the video below). But a lot of what I do with these requires knowing when a tag is present, not just when it was scanned. We can detect tag presence by connecting the reset pin (2) to the Arduino. Taking the reset pin LOW, then HIGH for at least 150ms will force the reader to rescan and re-post if a tag is present. So you can set a timer for 250ms, or so, and if the tag is not scanned during that time, you know the tag has been removed.

With how this is wired, Pin9 (Data 0) is going to output 9600 Baud serial every time it reads a tag, so we just connect this to Digital 0 (RX) on the Arduino. And… other than Ground, this is the only connection needed with the Arduino.

limitations

There are a few limitations I wanted to point out quickly. Sadly, the ID-2 / 12 /20 , as with most readers, can only read one tag at a time. In fact, having 2 or more tags in the readers range will cause it to not read any tags at all. So, if you need to detect the presence of many tags, you will need to figure out another way, get a different sensor, or buy a bunch of these. But… more than one reader right next to each other can cause none of them to work due to interference. You can wrap the bottom and sides with foil to help cancel the interference (be careful not to short the reader with the foil). Lastly, the range, even on the ID-20 is less than 4in real world. That means you can’t easily use these for detecting finish times in a race or anything like that.

Code

OK… So now that this is all hooked up, we need some code to read the output. As I said, this outputs serial, and because it is serial, we will need to read the output one byte at a time. This makes the code a little more complicated than our previous tutorial, but because this is bildr, we have it all setup for you. We will store the sequence into a 13 byte char array. 12 of the bytes are for the tag characters, and the 13th byte is to store an end-of-line character. (It’s just how it is done)

If you care, the tag outputs 16 bytes:
[start of text] – [12 bytes of hex] – [new line] – [carriage return] – [end of text]
We only need/want the 12 bytes that make up the tag. But we will use the rest to know what is the tag’s start and end.

This code will read a tag, and if it is in the list, light up an LED corresponding to the tag. If the tag is not in the list, it will output it to the serial monitor so you can copy it and add it to the list.

int RFIDResetPin = 13;

//Register your RFID tags here
char tag1[13] = "1E009A4067A3";
char tag2[13] = "010230F28243";
char tag3[13] = "01023C013A04";
char tag4[13] = "01023101093A";
char tag5[13] = "01023C0A4376";
char tag6[13] = "01023C000E31";
char tag7[13] = "01023C0A3207";
char tag8[13] = "1A004116317C";
char tag9[13] = "1E009A81F9FC";
char tag10[13] = "1A004162261F";

void setup(){
  Serial.begin(9600);

  pinMode(RFIDResetPin, OUTPUT);
  digitalWrite(RFIDResetPin, HIGH);

  //ONLY NEEDED IF CONTROLING THESE PINS - EG. LEDs
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);
}

void loop(){

  char tagString[13];
  int index = 0;
  boolean reading = false;

  while(Serial.available()){

    int readByte = Serial.read(); //read next available byte

    if(readByte == 2) reading = true; //begining of tag
    if(readByte == 3) reading = false; //end of tag

    if(reading && readByte != 2 && readByte != 10 && readByte != 13){
      //store the tag
      tagString[index] = readByte;
      index ++;
    }
  }

  checkTag(tagString); //Check if it is a match
  clearTag(tagString); //Clear the char of all value
  resetReader(); //eset the RFID reader
}

void checkTag(char tag[]){
///////////////////////////////////
//Check the read tag against known tags
///////////////////////////////////

  if(strlen(tag) == 0) return; //empty, no need to contunue

  if(compareTag(tag, tag1)){ // if matched tag1, do this
    lightLED(2);

  }else if(compareTag(tag, tag2)){ //if matched tag2, do this
    lightLED(3);

  }else if(compareTag(tag, tag3)){
    lightLED(4);

  }else if(compareTag(tag, tag4)){
    lightLED(5);

  }else if(compareTag(tag, tag5)){
    lightLED(6);

  }else if(compareTag(tag, tag6)){
    lightLED(7);

  }else if(compareTag(tag, tag7)){
    lightLED(8);

  }else if(compareTag(tag, tag8)){
    lightLED(9);

  }else if(compareTag(tag, tag9)){
    lightLED(10);

  }else if(compareTag(tag, tag10)){
    lightLED(11);

  }else{
    Serial.println(tag); //read out any unknown tag
  }

}

void lightLED(int pin){
///////////////////////////////////
//Turn on LED on pin "pin" for 250ms
///////////////////////////////////
  Serial.println(pin);

  digitalWrite(pin, HIGH);
  delay(250);
  digitalWrite(pin, LOW);
}

void resetReader(){
///////////////////////////////////
//Reset the RFID reader to read again.
///////////////////////////////////
  digitalWrite(RFIDResetPin, LOW);
  digitalWrite(RFIDResetPin, HIGH);
  delay(150);
}

void clearTag(char one[]){
///////////////////////////////////
//clear the char array by filling with null - ASCII 0
//Will think same tag has been read otherwise
///////////////////////////////////
  for(int i = 0; i < strlen(one); i++){
    one[i] = 0;
  }
}

boolean compareTag(char one[], char two[]){
///////////////////////////////////
//compare two value to see if same,
//strcmp not working 100% so we do this
///////////////////////////////////

  if(strlen(one) == 0) return false; //empty

  for(int i = 0; i < 12; i++){
    if(one[i] != two[i]) return false;
  }

  return true; //no mismatches
}
Unless otherwise stated, this code is released under the MIT License – Please use, change and share it.

Extending this

Even though the Arduino Uno/Duemilanove only have one serial in port, using the cd74hc4067 multiplexer we talked about a few weeks ago you could connect 16 of these through one serial pin.

OK, so now you are able to scan and recognize RFID tags, but what to do with it? You can’t just light up LEDs! What if you placed this under your door mat and placed a tag on your shoes so when you came inside, you would be greeted by a voice telling you the newest news?

You could also place RFID tags on snails and… OH wait, that has been done.

Whatever you do with this, we want to see it! And with these readers being so easy to use and extend, we think you will be doing some great things.

We want you to blog with us

bildr is looking for anyone interested in writing any sort of blog post for bildr. If you think you would like to help bildr by writing something, or have an idea for a post you think should be written, please contact us at blog@bildr.org or let us know in the forum.

Is it hot? Arduino + MLX90614 IR Thermometer

Tuesday, February 15 th , 2011

Being able to sense temperature is cool… But being able to read the temperature of an object without even touching it is simply awesome. The MLX90614 is a sensor that can do just that. By reading the infrared light coming off an object, this guy can sense between -95 and 720ºf (-70 to 382.2°C) with 17bit resolution. That’s 128X more precise than the Arduino’s ADC, and means this little guy can tell the difference between 25ºC and 25.02ºC without even coming in contact. (Though 17bits split between -70 and 382 should give us 0.0034ºC resolution).

I have had my eye on this guy ever since I saw it at Sparkfun, but never had a reason to get one. Then, looking around, the MLX90614 seemed to be giving some people a hard time when trying to connect it to their Arduino. So… we at bildr did what we do best, we bought one, and took some time to make your lives easier and get this running. This is an I2C device like many sensors we have talked about before, but unlike all the I2C sensors we have written about before this, the MLX90614 can’t use the wire library to communicate with it, so we will be using another library, also, unlike what we typically deal with, the MLX90614 is not on a breakout board, so it requires some pull-up resistors on both the data and clock lines (Typically, these are included on the board, we just don’t notice them.)

The standard wire library wasn’t working for people, so we will be using the i2cmaster library instead. To complicate things even more, the i2cmaster wont run on the Arduino out of the box, some files need to be renamed and changed, and an extra txt file is needed to get it working. But… because it is open-sourced I can make those changes, and redistribute it. So that’s what I’m going to do, I’m just giving it to you here in its working version to save you some time and headache. You will need to drop the library into your Arduino library folder for it to work, but we will get there.

As for hooking this up, on your Arduino (everything but the mega) SDA is on analog input pin 4, and SCL is on analog pin 5. On an Arduino mega, SDA is digital 20, and SCL is digital 21. Look at the picture to see how it should be connected, but a 4.7KΩ resistor needs to be connected from SDA to 3.3V, and another one from SCL to 3.3V. I also have a .1uf capacitor between power and ground as stated in the data sheet, but I have seen others not use it, and I have tested it without and it still worked.

Code

So, here is the code. Because it consists of many files, I am using bildr’s fancy bildrCode wrapper. This allows us to have wiki like control over many files for a single project – just like this. All this code does is output the temperature in both Celsius and Fahrenheit via serial. So open your serial monitor!

To make this code work, before you load the code, or even open the Arduino program, we need to place the “I2Cmaster” in your Arduino Library. If you don’t know where that is by default, Look to the right.

Once the I2CMaster folder is in there, you can just go ahead and open MLX90614.pde in your Arduino software, and upload it.

Default Library Folder Location

On your Mac:: In (home directory)/Documents/Arduino/libraries
On your PC:: My Documents -> Arduino -> libraries
On your Linux box:: (home directory)/sketchbook/libraries

Download

If you click the download button to the right of “Arduino” you can download the whole thing as a zip, so you dont need to copy all the files.

Conclusion

This is just such a cool sensor, and hopefully we saved you some time with is one. Let us know if you do anything with this guy, we would love to see it, and possible feature it on this very blog!

We want you to blog with us

bildr is looking for anyone interested in writing any sort of blog post for bildr. If you think you would like to help bildr by writing something, or have an idea for a post you think should be written, please contact us at blog@bildr.org or let us know in the forum.

Can you move over? The 74HC595 8 bit shift register

Tuesday, February 8 th , 2011

OK, so say you have this crazy cool idea where you need to control a ton of LEDs (I know, I know… LEDs). You looked at the multiplexer article, and that was great, but this idea is so cool, you need individual control of each LED, and turning them on one at a time just won’t do. Well again, we are here to help, and now it’s time to introduce you to the Shift Register. Not just any shift register, the super cheap, incredibly awesome 74HC595 8-bit Shift Register!

What does a Shift Register do?

Basically a shift register will, in the end, let you expand on the digital outputs you have on your mictrocontroller. Each one of these 74HC595s can act like 8 more digital outputs, and you can daisy chain them. So you could hook 8 of them up next to each other and have control of 64 outputs.

But the way it works is a little confusing to think of at first, and these are helpful enough that it is really worth understanding what the heck is going on under the hood.

You can imagine a shift register as a row of chairs. In this particular case, with the 74HC595, we have a row of 8 chairs. Each chair is either empty (0), or someone is sitting it (1).

Now, every 10 seconds or so, someone rings a bell, and everyone has to get up and move one chair to the right. If there was someone in that rightmost chair, well they just go away. In that leftmost chair, you can either tell someone to sit in it, or just leave it empty.

Now bringing this idea back to the 74HC595: This shift register consists of 8 output pins, which are either high (1) or low (0). When you pull the SRCLK (Serial Clock) pin high (analogy to ringing the bell), every pin moves one to the right. The Last pin drops out, and the new pin’s state is defined by the SER (Serial) pin, and you can set that to either 1 (HIGH) or 0 (LOW).

How does this let me control LEDs again? Well, say you have 8 LEDs hooked up to the shift registers outputs, and we want to turn on the 1st, 3rd and the 8th LED. So… what we can do is clear out the register so all LEDs are off. Then we put in one high, move it right 4 spots, add one high, move it over 1, then add another high. See the image on the right, it will make more sense.

The great thing is that the shift register has this pin called RCLK or register clock. You can hold this pin LOW while you get everything setup and nothing on the display pins will change. Then when you are done, and everything is how you want, you pull the RCLK HIGH and the 74HC595 will display the new settings. So even though we are changing values in the register in 8 steps, it looks like it was just one step.

Hooking it up

We are going to start simple. There are really just 3 connections you need aside from power to make this work. But as soon as power and the LEDs are all connected, it starts looking scary. But it’s not, so stick with us. – You can see a spec sheet for the 74HC595 here.

  • Vcc
    Up to 6V (needs to be the same voltage as your microcontroller) – Usually 3.3 / 5v
  • QA to QH
    Shift Register Outputs.
  • SER:
    (Serial) Input for the next pin that gets shifted in.
  • SRCLK
    (Serial Clock) When this pin is pulled high, it will shift the register.
  • RCLK
    (Register Clock) Needs to be pulled high to set the output to the new shift register values, This must be pulled high directly after SRCLK has gone LOW again.
  • SRCLR
    (Serial Clear) Will empty the whole Shift Register if pulled LOW, must be pulled High to enable.
  • OE
    (Output Enable) This pin enables the output when tied to GND, & disabled when HIGH.

How we make it work

Whenever the signal on the SERCLK-pin goes high, all the values get shifted to the right, and a new value gets shifted in (Whatever SER is set to). After you shifted in your new value, to see the changes made, you must also set the RCLK pin HIGH in order to update the output-pins with the new data. We wanted to get your’s up and running as quick as possible, so we put together some code for the Arduino, and AVR microcontrollers: see below for code examples.

The Arduino example enables individual control over the register pins. However the AVR example currently does not and must be fed a binary sequence. If you are interested in helping transcode the Arduino code into AVR (or any other language) so it will support individual pin control pleas let us know.

setRegisterPin(2, HIGH);
setRegisterPin(3, HIGH);
setRegisterPin(4, LOW);
setRegisterPin(5, HIGH);
setRegisterPin(7, HIGH);

//Once you have set the desired changes to the 
//register pins, you will need to call writeRegisters 
//before it is displayed. Only do this at the end, 
//and not after each setRegisterPin call because this
//function takes some time to write the values. 
//writeRegisters takes about 1ms per 10 of
//the shift registers you have chained (80 pins)
writeRegisters();
Unless otherwise stated, this code is released under the MIT License – Please use, change and share it.

Cascading Shift Register – AKA chaining them together

Like I said above, you could connect 20 of these together if you needed. Shift registers have a pretty clever option built in that allows them to be chained or Cascaded together. You know how the last register just dumps its value when it is shifted over? Well the Qh pin (pin 9) is where the 74HC595 dumps that value. So we just take that and use it as the SER input on a second (or next) shift register, and bam! they are chained together. You will also need to then connect the SERCLK and RCLK pins together, but then you are golden. Check out the schematics to the side and below to see how it is connected.

Code

Arduino code for Individual control over each pin – Support for 40+ shift registers

int SER_Pin = 8;   //pin 14 on the 75HC595
int RCLK_Pin = 9;  //pin 12 on the 75HC595
int SRCLK_Pin = 10; //pin 11 on the 75HC595

//How many of the shift registers - change this
#define number_of_74hc595s 1 

//do not touch
#define numOfRegisterPins number_of_74hc595s * 8

boolean registers[numOfRegisterPins];

void setup(){
  pinMode(SER_Pin, OUTPUT);
  pinMode(RCLK_Pin, OUTPUT);
  pinMode(SRCLK_Pin, OUTPUT);


  //reset all register pins
  clearRegisters();
  writeRegisters();
}               


//set all register pins to LOW
void clearRegisters(){
  for(int i = numOfRegisterPins - 1; i >=  0; i--){
     registers[i] = LOW;
  }
} 


//Set and display registers
//Only call AFTER all values are set how you would like (slow otherwise)
void writeRegisters(){

  digitalWrite(RCLK_Pin, LOW);

  for(int i = numOfRegisterPins - 1; i >=  0; i--){
    digitalWrite(SRCLK_Pin, LOW);

    int val = registers[i];

    digitalWrite(SER_Pin, val);
    digitalWrite(SRCLK_Pin, HIGH);

  }
  digitalWrite(RCLK_Pin, HIGH);

}

//set an individual pin HIGH or LOW
void setRegisterPin(int index, int value){
  registers[index] = value;
}


void loop(){

  setRegisterPin(2, HIGH);
  setRegisterPin(3, HIGH);
  setRegisterPin(4, LOW);
  setRegisterPin(5, HIGH);
  setRegisterPin(7, HIGH);


  writeRegisters();  //MUST BE CALLED TO DISPLAY CHANGES
  //Only call once after the values are set how you need.
}
Unless otherwise stated, this code is released under the MIT License – Please use, change and share it.

This code example just turns on the LEDs in a particular pattern and keeps it here. (This code will only support up to 4 shift registers. Because of it taking in a binary number, it is limited to 32 characters.)

Here is code for the AVR

#include <avr/io.h>
#include <util/delay.h>


#define number_of_74hc595s 1 //How many of the shift registers are there daisey chained?


int main(){
	DDRB = 0xFF;
	PORTB = 0x00;
	char counter = 0;

	while(1){
		counter++; 				// Counter used for displaying a number in binary via the shift register
		shift(PB1, PB2, PB3, counter);		// PB1 = SERCLK  PB2 = RCLK  PB3 = SER
		_delay_ms(500);				
		shift(PB1, PB2, PB3, 0x00);		// Set all pins to off
		_delay_ms(500);
	}
	return 0;
}


void shift(int SRCLK_Pin, int RCLK_Pin, int SER_Pin, unsigned long data){
	PORTB &= ~(1 << RCLK_Pin); 				// Set the register-clock pin low

	for (int i = 0; i < (8 * number_of_74hc595s); i++){	// Now we are entering the loop to shift out 8+ bits

		PORTB &= ~(1 << SRCLK_Pin); 			// Set the serial-clock pin low

		PORTB |= (((data&(0x01<<i))>>i) << SER_Pin ); 	// Go through each bit of data and output it

		PORTB |= (1 << SRCLK_Pin); 			// Set the serial-clock pin high

		PORTB &= ~(((data&(0x01<<i))>>i) << SER_Pin );	// Set the datapin low again	
	}

	PORTB |= (1 << RCLK_Pin);				// Set the register-clock pin high to update the output of the shift-register
}
Unless otherwise stated, this code is released under the MIT License – Please use, change and share it.

Conclusion

If you need an easy way to extend your output-pins, shift registers are definitely a good choice. They are cheap, fast and if you take the time to play with them, they are pretty simple too.

We want you to blog with us

This blog post was written by DrLuke, a user at bildr. Formatting, video, and images by Adam. We would love to have more community contributions, and they don’t need to be this long or complex. Adam will even do a lot of the work if needed!

bildr is looking for anyone interested in writing any sort of blog post for bildr. If you think you would like to help bildr by writing something, or have an idea for a post you think should be written, please contact us at blog@bildr.org or let us know in the forum.

« Older Entries