Muses Shoe, EL Wire and You

Here’s something for the locals. I knew there had to be some fun locked away in the light-up Mardi Gras throws that have become more popular in recent years. Unfortunately, I’m not cute enough to have a Muses shoe thrown to little old me, so I had to wait for somebody to throw it away at the Really Really Free Market held at Art House this past weekend.

A few notes about this. It’s not hard. Not really very impressive, either. There’s a lot that I don’t know as I only had one shoe and one 4ft EL wire that I picked up from Electronics Goldmine a while ago. For those same reasons, I could have documented this much better. The longest part was dealing with my miserable skills with a soldering iron.

Up on the top there, if you peel back the circuit board you’ll see a coil telling you we are dealing with a high voltage AC inverter here (running on two AAs), which is why I did this; I was too lazy to ever order an AC inverter for the EL wire I had. For those that haven’t read up on EL wire, it won’t run on DC current, so these little pocket inverters, usually found in a 9V variety, are the way way to go if you want to, say, mount it on a bike like I did. Be careful, I shocked myself about 15 times messing with this, and though it wasn’t too bad it was because I was clumsy, not because I liked it.

The shoe half is mostly useless to this project. If you notice, I pulled off some of those pins from the shoe end. Don’t bother with that, I thought they’d make it easier to attach the EL wire to the leads from the board, but they didn’t stick on there well.

You need to strip one end of your EL wire a little to use it (the other end is free to dangle). The outer layer is essentially the tint of the wire. Underneath there are two very fragile wires, I’ve seen them called Corona wires or Angel Wires. They are important and frustratingly brittle. Then there’s the relatively fat, sheathed wire in the middle. You’ll need to strip that as well.

A couple of guides recommend a strip of copper tape wrapped around the white wire. That way your brittle angel wires can be soldered to the tape, then the next thing you solder to the tape without worrying about tension on the angel wire. If you’ve got some copper tape DO IT, it will probably make your life much easier. It made my life harder because I checked out Radio Shack, Lowes and Home Depot, and none of them have copper tape. Instead I broke the angel wires a good 6 times until I finally managed to put the thing together intact, taping it all together so they wouldn’t be jostled much. But I’m skipping a step

This part’s a little shaky, but here’s what worked for me. The main rule that I discerned is that one wire from the EL has to be soldered to one of the two outside wires, the other to any of the middle three. Since different parts of the original shoe were supposed to work in certain ways, each one will behave differently. I found my favorite combo to be the fat wire on the lead the corresponds to the leftmost joint on the inverter’s circuit board, with the angel wire going right next to it. That’s the only configuration I found that allowed a sustained glow.


From there I taped it up tight, waterproofed it by sticking it in a ziplock with a hole in one non-zip corner for the wire to escape (and taped that corner too) and packaging-taped it around my bike! There’s a lot more I’d like to learn about this, such as how long of an EL wire it can drive, whether it’ll run two wires just as easily etc., and I don’t even know about battery life just yet, but for once your Mardi Gras beads have some worth.

Posted in Tutorial/Documentation | 2 Comments

Radioshack Infrared receiver <--> Arduino

I recently came across the need to read some IR signals from my universal remote. Having hacked around with IR in the past, I had an idea of what I was looking for so I stopped by RadioShack and found one of these:

Radioshack 38khz IR receiver module

A Brief Overview of IR

The idea behind transmission of data over infrared is dirt simple. Reading about it just reminds me of how overly-complicated some communication protocols have become. The idea is that you have a transmitter, which is just an LED that emits light in the infrared spectrum and you have a receiver, which is just a phototransistor that changes the current flowing through it based on how much infrared light is hitting it. The transmitter pulses out light and the receiver is able to ’sense’ those pulses in the exact condition they were in when they left the other circuit. All information is sent in a binary format. In most protocols, you have two different types of pulses, a long and a short. The long usually corresponds to 1 and the short to 0. Here is a diagram of Sony’s IR protocol:

Sony IR protocol

Sony IR protocol source:http://www.sbprojects.com/knowledge/ir/sirc.htm

Here you can see that the 1 corresponds to a 1.2 millisecond pulse and the 0 a 0.6 millisecond pulse. So, there is one more detail that slightly complicates the issue. An astute reader may note:

“IR light is everywhere. How does the receiver know the difference between a pulse and noise or ambient light?”

The light coming from the transmitter is modulated at a very high frequency, usually between 38kHz and 40 kHz. It is then demodulated or integrated on the other end and turned into a solid waveform. Think of it like a high pass filter, which it may actually be in implementation, I didn’t look it up. Any naturally occurring IR light is likely to be changing at a low frequency, so this gives us a way to distinguish the signal from the noise. On top of that, many commercial products cover their receiver with a piece of plastic or lens that is coated in a material that only lets in infrared light. This helps further eliminate noise that bright visible light may cause.

The Radioshack module

This thing was extremely easy to hook up. All you need to do is supply a resistor (I used 200 Ohms, with a 3.3V supply) to the power line, GND it, then connect the data line to one of your digital pins (I used pin #2). The module itself contains the demodulation circuit so what you see is a solid signal.

Arduino connected to IR module

Arduino connected to IR module

At this point, I decided to hook up my oscilloscope to see what was coming out of this thing. I programmed a free channel on my universal remote for a Sony DVD and started hitting some buttons. This is generally what I saw:

Sony IR protocol

Signal captured

This signal was upside-down from what I had expected. The data pin appears to be idling HIGH and the signal drives it LOW. I verified this on my multimeter just to be sure. After this, I looked it up online and it appears to be the expected behavior. Not really a problem for our software, a pulse is a pulse, it is just a need to know detail for later. Another note, that first long low pulse is what is often called a start bit. It is an extra long, 2.4 millisecond pulse to notify the receiver that some bytes are coming. To read more about the protocol, take a look at this link: http://www.sbprojects.com/knowledge/ir/sirc.htm.

This is usually the point where I go online to see what others have done with the device and see if there is any code I can steal. I looked around for a bit and found this link and this code:

// 0.1 by pmalmsten
// 0.2 by farkinga
 
#define IR_BIT_LENGTH 12
#define BIT_1 1000          //Binary 1 threshold (Microseconds)
#define BIT_0 400           //Binary 0 threshold (Microseconds)
#define BIT_START 2000      //Start bit threshold (Microseconds)
#define DEBUG 0             //Serial connection must be started to debug
#define IR_PIN 7            //Sensor pin 1 wired through a 220 ohm resistor
#define LED_PIN 9           //"Ready to Recieve" flag, not needed but nice
#define POWER_PIN 11     // the red LED that indicates if the power button is pressed.
 
int runtime_debug = 0;
int output_key = 0;
int power_button = 0;
 
void setup() {
  pinMode(LED_PIN, OUTPUT);		//This shows when we're ready to recieve
  pinMode(POWER_PIN, OUTPUT);		//This is the "power on" indicator
  pinMode(IR_PIN, INPUT);
  digitalWrite(LED_PIN, LOW);	    //not ready yet
  Serial.begin(9600);
}
 
void loop() {
  digitalWrite(LED_PIN, HIGH);	   //Ok, i'm ready to recieve
 
  int key = get_ir_key();		    //Fetch the key
 
  digitalWrite(LED_PIN, LOW);
 
  do_response(key);
 
  delay(200);
}
 
void do_response(int key)
{
  switch (key)
  {
    case 1437:
      Serial.println("toggle debug pulse");
      runtime_debug = 1 - runtime_debug;
      break;
    case 1498:
      Serial.println("Toggle key output");
      output_key = 1 - output_key;
      break;
    case 1429:
      Serial.println("Power");
      power_button = 1 - power_button;
      if (power_button)
      {
        digitalWrite(POWER_PIN, HIGH);
      }
      else
      {
        digitalWrite(POWER_PIN, LOW);
      }
      break;
    case 1424:
      Serial.println("Channel Up");
      break;
    case 1425:
      Serial.println("Channel Down");
      break;
    default:
      if (output_key)
      {
        Serial.print("Key ");
        Serial.print(key);
        Serial.println(" not programmed");
      }
      break;
  }
}
 
void read_pulse(int data[], int num_bits)
{
  for (int i = 0; i < num_bits; i++)
  {
    data[i] = pulseIn(IR_PIN, LOW);
  }
}
 
void pulse_to_bits(int pulse[], int bits[], int num_bits)
{
  if (DEBUG || runtime_debug) { Serial.println("-----"); }
 
  for(int i = 0; i < num_bits ; i++)
  {
    if (DEBUG || runtime_debug) { Serial.println(pulse[i]); }
 
    if(pulse[i] > BIT_1) //is it a 1?
    {
      bits[i] = 1;
    }
    else if(pulse[i] > BIT_0) //is it a 0?
    {
      bits[i] = 0;
    } 
 
    else //data is invalid...
    {
      Serial.println("Error");
    }
  }
}
 
int bits_to_int(int bits[], int num_bits)
{
  int result = 0;
  int seed = 1;
 
  //Convert bits to integer
  for(int i = 0 ; i < num_bits ; i++)
  {
    if(bits[i] == 1)
    {
	result += seed;
    }
 
    seed *= 2;
  }
 
  return result;
}
 
int get_ir_key()
{
  int pulse[IR_BIT_LENGTH];
  int bits[IR_BIT_LENGTH];  
 
  do {} //Wait for a start bit
  while(pulseIn(IR_PIN, LOW) < BIT_START);
 
  read_pulse(pulse, IR_BIT_LENGTH);
 
  pulse_to_bits(pulse, bits, IR_BIT_LENGTH);
 
  return bits_to_int(bits, IR_BIT_LENGTH);
}

This seemed to me like a lot of code and logic for such a simple protocol. I could go on about how wasteful I think the code is but honestly, it works and that is what is important. So, I don’t want to make it sound like it is a ‘bad’ implementation. His is actually meant to be general and to debug different protocols. I just want to make it simpler for the processor and the human reader to understand and optimized for this one particular protocol. Here is my implementation, which itself may be more flaky:

#define BITS_PER_MESSAGE 12    
#define B_1 1000              //1.2 milliseconds        
#define B_0 400                //0.6 milliseconds       
#define START_BIT 2000   //making it a little shorter than the actual 2400   
#define IR_PIN 2
 
//find the threshold time b/w the two pulse sizes
#define BIT_THRESH B_0+((B_1-B_0)/2)
 
void setup() {
  pinMode(IR_PIN, INPUT);
  delay(1000);
  Serial.begin(9600);
  Serial.println("Ready...");
}
 
void loop() {
  //int where we are storing code, must start at 0
  unsigned int code = 0x00;
 
  Serial.println("Waiting for first pulse");
 
  //block until start pulse
  while (pulseIn(IR_PIN, LOW) < START_BIT) {}
 
  //read in next 12 bits shifting and masking them into the unsigned int 'code'
  //remeber boolean is basically 0 [false] or 1 [true]
  for (byte i = 0; i < BITS_PER_MESSAGE; i++) {
      code |= (pulseIn(IR_PIN, LOW) > BIT_THRESH) << i;  
  }
 
  Serial.println(code);
  delay(500);
}

My general idea was this, calculate a threshold, the midpoint between the 2 bit pulse sizes, and compare every incoming pulse to that. So in this situation, BIT_THRESH is 700. First thing we do is create an unsigned int to store the code. Remember, an integer is 16 bits so it has more than enough space to store the 12 bits of the message. I just made it unsigned just in case but it is not likely that we will reach all the way to the sign bit on the MSB side. The next thing we do in the algorithm is wait for the start bit:

while (pulseIn(IR_PIN, LOW) < START_BIT) {}

It is set to 2000 instead of 2400 so we have a little bit of leeway. You can increase it if you start getting noise but it is not likely to happen. This is just an empty while loop or a blocking conditional. It just holds the program until it’s condition is met. In this case, we find a pulse longer than START_BIT. PulseIn is a really nice function if you aren’t familiar. The first parameter is the pin you are waiting on, and the next parameter describes how the pulse will come. From the reference:

if value is HIGH, pulseIn() waits for the pin to go HIGH, starts timing, then waits for the pin to go LOW and stops timing

Remember that our signal is inverted, so we are waiting for the pin to go LOW. Our pulse is defined as a LOW then HIGH trough. That is why we chose LOW here. Once we get our start bit, we perform the meat of the logic:

for (byte i = 0; i < BITS_PER_MESSAGE; i++) {
      code |= (pulseIn(IR_PIN, LOW) > BIT_THRESH) << i;  
}

This one is full of microcontroller jargon but shouldn’t be too hard to figure out. We are going through 12 steps, one for each bit, and calling pulseIn to get the pulse length then comparing that length to BIT_THRESH. That is going to give us a true or false which is in actuality a 1 or 0. After we get a result, we shift the 1 or 0 over by i bits and perform a bitwise OR to set the corresponding bit in the code variable. See here for an explanation of bit logic. So when the result is 0, it effectively skips the number. When it is 1, it sets bit i of the code to 1. This is relying on the fact that the code starts out as all 0 at first. Now that I think about it, it may be more efficient to do something like this:

for (byte i = 0; i < BITS_PER_MESSAGE; i++) {
      if (pulseIn(IR_PIN, LOW) > BIT_THRESH) code |= (1 << i);  
}

That way you only do the bitwise OR when you encounter a 1. Honestly consistency is much more important than efficiency in this situation so do whatever works for you. Also, the performance would be completely unnoticeable.

Technically, depending on the protocol, that integer may contain different control messages, devices, etc. But if you are just trying to map a button on your remote to an action in arduino, this should be good enough. If you are concerned about other people using your code with different remotes for different devices, I suggest further reading.

One last thing to note, I just realized that the B_1 and B_0 values don’t match with what the Sony specification says. I just took those values from that guy’s original code and didn’t think about it. It still works so I am not changing it without testing. Just a head’s up.

Hope this helps someone. I will address any questions in the comments section.

Posted in Arduino | 13 Comments

iPhone App Development Study Group

How would you like to learn iPhone App Development this summer? Me too. That’s why I decided to organize a group to watch the video lectures from the Stanford class together. We can work thru the assignments together. Learn together, get to know each other, figure things out, etc. It’s going to be awesome. Here are the details:

What: a free iPhone App development “class” where we watch the Stanford lectures together and do the assignments with help from each other
When: Mondays & Thursday nights from 7-9pm, May 31st-August 12th.
Where: Gumbo Labs, 4820 Banks St. Studio #5, New Orleans, LA 70119
Who: Anyone interested. I’ll be the organizer and video projectionist. I wont be the “teacher” though. I’ll be learning this along with everyone else.
Registration: To sign up, just introduce yourself on this forum thread. Also, add the App Dev Forum RSS feed to your newsreader to keep up with discussion on the forum.

Other Notes:

  • I’m going to try and get a Mac set up at Gumbo Labs with the iPhone developer tools installed for those folks who are interested, but don’t have a Mac. But it would be best if you had your own Intel Mac laptop.
  • These lectures were recorded for iPhone OS3. Even though iPhone OS4 beta is out now, I suggest sticking with iPhone OS3 for this class.
Posted in Class | Tagged | 7 Comments

DSO nano and synth circuit

A few days ago, a co-worker let me borrow his DSO nano to run a few tests. First thing I decided to do was throw a really chaotic waveform at it. I built this little synth with 2 square wave oscillators.


Square wave oscillator schematic

It is kind of comical to call this a synth or even a set of oscillators. It is basically a simple NOT gate arranged in a feedback loop. The capacitor fills up until it reaches the breakdown voltage of the internal diode in the NOT gate, at that point, the signal is inverted to GND and the capacitor discharges. When it reaches ground, the output signal inverts again and the process starts over. The result is a square wave. The potentiometer controls the amount of current flowing into the capacitor and thus alters the amount of time it takes to fill up. In effect, altering the frequency of the square wave. I built two of these and muxed the signals together with some resistors, kind of like a fixed mixer. The overall signal is pretty hectic, with weird beat frequencies and strange tiny oscillations in the individual frequencies themselves.

I found it pretty hard to get the DSO nano to get a good read on it but it was pretty hard with my regular scope as well. Probably not the best waveform to start with. So, I decided to try out some simpler waveforms. I programmed an Arduino to just spit out ‘a’ on the UART every second and used a rising slope trigger to freeze the waveform. It worked really well for that. It also worked really well for just a square wave generated on the Arduino. It was able to guess the frequency with accuracy. Unfortunately my phone had died at that point and I couldn’t get any pictures or video.

Overall I found it pretty simple to use and a surprising amount of functionality for it’s small size and price. I have to admit though, I wouldn’t find much use for it as I am almost always in front of a desk where I can use my USB scope and software. I think this would be more helpful for someone who works in ‘the field’ so to speak. It is pretty much as good as you are going to get in a pocket-sized package.

Posted in Uncategorized | 1 Comment

RFID <--> Ethernet Shield Client <--> Rails

Last week A few months ago, I wrote an article on connecting the Parallax RFID reader to the the Arduino. The reason I was revisiting that device was because I am working on a system for our hackerspace which will allow people to find out who is in the hackerspace at any given time. The overall system requires the Arduino to connect to the internet as a client and tell the Ruby on Rails application that person with RFID tag XXXXXXXXXX has walked into or left the space. The Rails application will be able to ‘publish’ this information to different mediums [web, twitter, facebook, IRC, etc] by providing a simple API for other programmers in the space to utilize.

The whole system is too complicated to explain right now and I am not finished. I plan on writing my next article about that. For now, I just wanted to document some of the issues I had with the Arduino Ethernet Shield and how I resolved them as it may be of help to others trying to figure it out.

Arduino Ethernet Shield

Arduino Ethernet Shield

The ethernet shield, like the RFID reader, was not as simple to use as I hoped it would be. The information out there was decent, but nothing beyond explaining the examples. First I must explain my use cases to put context to the example code.

My goals for the code are to first send two pieces of information to the Rails application:

  1. A secret API key [to prevent fraud]
  2. The Tag code read by the RFID reader

Then I want to read the response and differentiate between four situations:

  1. The user has been marked as “Logged In”
  2. The user has been marked as “Logged Out”
  3. There is no user with the tag code that was sent
  4. The wrong API key was supplied

The ethernet shield allows your Arduino to operate as a Client or a Server. In this situation, I just want to use the client interface as I am connecting to a server to get information. Now let’s just look at the code required to make a simple HTTP GET request client with no parameters. I just modified this from the examples.

#include <Ethernet.h> // load ethernet SPI functions
 
// a MAC address that you make up to identify the Arduino
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
// this is the IP that will identify the Arduino
byte ip[] = { 192, 168, 0, 160 };
// this is the IP of the server that we are trying to connect to
byte server[] = { 192, 168, 0, 101 }; 
 
//create the client
//wide area HTTP networks are on port 80 but my local rails app is on 3000
Client client(server, 3000);
 
void setup()
{
  //start ethernet
  Ethernet.begin(mac, ip);
  Serial.begin(9600);
 
  delay(1000);
 
  Serial.println("connecting...");
 
  if (client.connect()) { 
    Serial.println("connected");
    //this constructs the GET request, it is the equivalent
    //going to the browser and entering http://192.168.0.101:3000/main/index
    client.println("GET /main/rfid HTTP/1.1");
    client.println(); // print a newline char to tell the server we are done?
  } else { // this is called if conenction fails
    Serial.println("connection failed");
  }
}
 
void loop()
{
  if (client.available()) { // need to see if response has been read into the buffer yet
    char c = client.read(); //get next character and print it
    Serial.print(c);
  }
 
  if (!client.connected()) { //if we lose connection
    Serial.println();
    Serial.println("disconnecting.");
    client.stop(); // disconnects from the server
    for(;;)
      ;
  }
}

Some of this warrants a little more explanation for some…

Configuring the ethernet shield

First is the MAC address.

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

For those unfamiliar with basic networks, a MAC address is a unique number assigned to your network card that never changes. You don’t need to know much about it other than you need to make it up. You should be good if you use the one I have just used in this example but keep in mind that if you have multiple Arduinos connected to the same network, you may need to make up unique MAC addresses for each one.

Next is your IP.

byte ip[] = { 192, 168, 0, 160 };

This array refers to the IP that you want your Arduino to take. The Arduino Ethernet Shield currently ?doesn’t support DHCP?, so you have to choose an unused IP yourself. There are a variety of ways and steps to do this. First what you need to do is figure out what the first three bytes in this array need to be. This is determined by the local router you are connecting to. For instance, Linksys is usually 192.168.1.XXX and D-Link, in my case, is usually 192.168.0.XXX. You can find out what your situation is by checking the IP of a computer on that network. Then you need to choose an unused number for the last byte, usually between 100 and 255. If you are on a network with few computers, around 150 is usually a safe bet. If you are not sure or have a lot of computers on the network, you should find a way to log into your router’s admin interface and check the DHCP information. It will tell you all the IP addresses that are currently assigned and you can make one up an unused one based off that.

Last is the server’s IP.

byte server[] = { 192, 168, 0, 101 };

This is the IP of the server that you are trying to connect to. In my case, it is a laptop running my Rails application connected to the same network. If you want to connect to a server outside your network, on the internet, you need to find it’s IP. Your computer usually does this under the surface using DNS but you will have to do it manually here. One way you can do this is by pinging the domain name and seeing what IP it resolves to.

Sending information to a server

So, this example works out for many situations, but how can I send information to the server where my Rails app is being run? In my case, I need to send the API key and and the RFID tag I just read. What we need to do is build a query string. If you aren’t sure what that means, you will have to read that wikipedia article carefully. Let’s reexamine the code:

//I changed this line
client.println("GET /main/rfid HTTP/1.1");
//to this line
client.println("GET /main/rfid?apikey=123&tag=0123456789 HTTP/1.1");

When I run this code, I see this on the serial port:

connecting…
connected
HTTP/1.1 200 OK
Connection: close
Date: Mon, 26 Oct 2009 01:12:43 GMT
ETag: “8da44df37e592a5020e852d50fc31a64″
X-Runtime: 8
Cache-Control: private, max-age=0, must-revalidate
Content-Type: text/html; charset=utf-8
Content-Length: 8

^=NOUSER

This is the HTTP response. The last bit:

^=NOUSER

Is what I have defined in the Rails application to tell the Arduino what has happened. Just for clarification, this is what the rfid function looks like in the Rails app:

  #login via rfid service, has no view
  def rfid    
    if params[:apikey] == $api_key
      @user = User.find_by_rfid_tag(params[:tag])
      if @user
        @user.in_space = !@user.in_space
        @user.save
        if @user.in_space
          render :text => "^=IN"
        else
          render :text => "^=OUT"
        end
      else
        render :text => "^=NOUSER"
      end 
    else
      render :text => "^=KEYFAILED"
    end
  end

I tested a few different query strings and made sure it worked for all conditions and it did. Now I need a way to dynamically send the tag that we read from the reader. As you might have read in my RFID post, I am storing the RFID tag in a 10 character array:

#define CODE_LEN 10
 
char tag[CODE_LEN];

I initially thought I could do this:

client.print("GET /main/rfid?apikey=123&tag=");
client.print(tag);
client.println(" HTTP/1.1");
client.println();

Notice that I am using a series of print()s to build a string and ending it with println() to close it out with a newline. The only problem is that this doesn’t work. My Mongrel server (the Rails server) was telling me that my HTTP request were invalid. It seems like a lot of other people were running into this problem as well. After temporarily giving up, I realized the problem. I was reading an essay by Brian Kernighan, one of the creators of the C programming language, about a simple regular expression parser that he uses to teach students about programming methodologies. Scanning through the code, I was reminded that a character array cannot be interpreted as a string without a terminal null character ‘\0′ as the last element. So, I handled this situation like this:

#define CODE_LEN 10
 
char tag[CODE_LEN + 1];
tag[CODE_LEN] = '\0';

This didn’t affect any of my other code and now the tag array can be interpreted as a legit string :) I love simple solutions.

Now I need a way to parse the response. The reason my responses had this format ‘^=XXXXXXX’ was so I could do something like this:

/**
 * Finds result that we are looking for in the returned HTTP response
 */
char getHTTPResult() {
  while (client.read() != '^') {}
  if (client.read() == '=') {
    return client.read();
  } 
  return 'x';
}

This would return the first character for the response I am looking for. For example, with the NOUSER message, I would get back the ‘N’ character. I implemented this but the problem is that it was really slow. Or at least, it was a lot slower than it could be. The problem is the amount of pointless HTTP data you have to read before you get to the actual message, or it could be that I am printing all that data? Doesn’t matter because I can make it faster. I could have configured my server to not spit out so much junk, or I could just place the message earlier in the response.

Reverse REST

The first thing you return is the status code so why not put it there? As I said before, there are only four states I am trying to identify and there are plenty of HTTP status codes to represent them. So I modified the Rails controller to look like this:

 
  #login via rfid service, has no view
  def rfid    
    if params[:apikey] == $api_key
      @user = User.find_by_rfid_tag(params[:tag])
      if @user
        @user.in_space = !@user.in_space
        @user.save
        if @user.in_space
          render :status => 400 #IN
        else
          render :status => 401 #OUT
        end
      else
        render :status => 402 #NOUSER
      end 
    else
      render :status => 403 #FAILED
    end
  end

I can’t help but wanting to call this ‘reverse REST’, LOL. Rerunning my simple “no user” test, I now get this:

HTTP/1.1 402 Payment Required
Connection: close
Date: Sat, 06 Feb 2010 02:45:19 GMT
X-Runtime: 12
Content-Type: text/html; charset=utf-8
Cache-Control: no-cache
Content-Length: 0

This is much quicker to parse. I probably could have used some nice code to make this more flexible, but just hardcoding the digit read process in is probably easier and just as reliable, if not more efficient:

char getHTTPResult() {
  while (client.read() != '4') {} 
  if (client.read() == '0') { //just to make sure
    return client.read();  // return either '0' or '1' or '2' or '3'
  } 
  return 'x';  // something bad happened
}

At this point a simple switch allows us to define the behavior of the response:

void sendToServer() {
   client.flush(); //just to be sure
   if (client.connect()) {
      client.print("GET /main/rfid?apikey=123&tag=");
      client.print(tag);
      client.println(" HTTP/1.0");
      client.println();
 
      Serial.println();
      switch (getHTTPResult()) {
        case '0':
           Serial.println("logged in"); break;
        case '1':
           Serial.println("logged out"); break;   
        case '2':
           Serial.println("no user"); break; 
        case '3':
           Serial.println("API key failed"); break;    
        default:
          Serial.println("broke"); break;
      }
      client.flush(); //just to be sure, probably not needed here
      client.stop(); //should stop it
  } else {
    Serial.println("connection failed");
  }
}

A few more troubleshooting tips (will keep updated as they come in)

  1. Be sure to use flush() when appropriate. This ensures that your input buffer is clean and that you don’t have any left over remnants.
  2. I noticed that sometimes the ethernet shield would not power up when I plugged in my Arduino. You can tell by the group of lights on the top. I could only get it to start up when I had unplugged anything that was leaching power from my board (in my case the RFID reader which is leaching current off the 5V pin). I am not 100% sure why this is but my guess is that it has something to do with some components on the ethernet shield not getting enough current to start it up. If this happens to you, you will often find that client.connect() will return false every time. I will try to investigate this further.

Conclusion

Hopefully this isn’t too far out of context for your applications. Feel free to post questions about this device and I will try to help out.

Posted in Arduino, Tutorial/Documentation | Tagged , , , | 6 Comments

Agenda For Our First Official Board Meeting

Gumbo Labs, Inc. Board Meeting

4820 Banks Street, Studio #5, New Orleans, LA 70119

Jan 19, 2010, 7:30-9:00PM

Call Meeting to Order

Membership Business

  1. Review Applications
  2. Confirm Membership

Board Business

  1. Confer Incorporators as Officers
  2. Elect Board of Directors
  3. Discuss Board Waiver
  4. Adopt Bylaws
  5. Authorize Treasurer’s Duties
  6. Elect Officers
  7. Authorize Officers’ Duties
  8. Discuss Indemnification
  9. Discuss Officer Reimbursements
  10. Select Agent for the Corporation

Adjourn Meeting

Posted in Board of Directors | Leave a comment

Simon Dorfman’s Pecha Kucha Presentation about Gumbo Labs Video

Above video also viewable on vimeo. And the slides from this presentation were posted here.

I’ll try to update this post later with a summary and some links from the slides.

Posted in Uncategorized | 2 Comments

Tuesday Night Meeting 7:30 – 9:00

Is there anything in particular you’d like people to bring or prepare for this Tuesday’s meeting? Leave a comment. Otherwise it will be the usual hanging out, socializing, working on stuff together, what-have-you…

Posted in Uncategorized | 1 Comment

Slides from My Gumbo Labs Presentation at Pecha Kucha Last Night

Posted in Presentation | Leave a comment

Parallax RFID Reader <--> Arduino

A while back, I purchased a Parallax RFID reader and used it for authentication for my house door. It was kind of a hack job and wasn’t as stable as I would have liked so I never documented it and put it on the backburner. I recently decided to revisit the device for a project for Gumbo Labs.

The Parallax reader

The Parallax reader

BTW, you can now get this at your local Radioshack?!?. Maybe they are starting to move in the right direction again? Who knows.

Anyway, this device was initially easy to get running but it was not as stable as I hoped it would be. The example code online did not fully account for the quirks of this reader. I had to closely read the manual to make it work as expected. I am going to briefly describe how to get the best out of this reader and properly integrate it with your Arduino.

First you want to get them connected. The quickest way to do this is with a breadboard and some wires like this guy does:

Connecting Arduino to RFID reader

Connecting Arduino to RFID reader

The mapping should be similar to this:

  • Arduino serial RX to Parallax TX
  • Arduino GND to Parallax GND
  • Arduino digital pin (i.e. #2) to Parallax /ENABLE
  • Arduino +5V to Parallax Vcc

Keep in mind that when you upload your binary to the Arduino, you may need to disconnect the Parallax TX connection, just a warning.

Now to the Arduino code…

I will explain each piece in detail and give the whole code at the end. If you are impatient and hate learning, go there.

First let’s deal with this /ENABLE pin. Here is what the documentation says about it:

The RFID Card Reader is activated via the /ENABLE line. When the RFID Card Reader is powered and the /ENABLE line is pulled HIGH, the module will be inactive (standby mode) and the LED will be GREEN. When the /ENABLE line is pulled LOW, the RFID Card Reader enter its active state and enable the antenna to interrogate for tags. The current consumption of the module will increase dramatically when the module is active.

So, when the pin is HIGH, the reader is inactive and in a low current consumption mode. When the pin is LOW, the reader is active and can read tags. To utilize this pin, I created two functions:

#define RFID_ENABLE 2  //pin connected to ENABLE
 
void enableRFID() {
    digitalWrite(RFID_ENABLE, LOW);
}
 
void disableRFID() {
    digitalWrite(RFID_ENABLE, HIGH);
}

The usage of this functionality depends on your application. If you (and by you here I mean the Arduino) know when you will need to read a tag, keep the reader inactive until then to conserve current. This situation is not as likely as you usually want the Arduino to just know when a tag is next to it at any time. In this case, we will use it to briefly deactivate the reader after a tag is read. This will keep the Arduino from getting duplicate or junk/half reads and it will reset the reader for the next tag.

Reading a Tag’s Unique ID

As the documentation describes, when the reader is in active mode and a tag is placed near the antenna, a 12 byte message will come across the Parallax TX serial line. The documentation says this about the serial configuration:

All communication is 8 data bits, no parity, 1 stop bit, and least significant bit first (8N1). The baud rate is configured for 2400 bps, a standard communications speed supported by most any microprocessor or PC, and cannot be changed.

8N1 is the standard for your Arduino, you just have to tell it to start up the UART at 2400 baud in your setup() function:

Serial.begin(2400);

The designer of the RFID reader, KingPin if I am not mistaken, designed a custom protocol so we can determine where the tag starts and ends. Once again, we refer to the documentation (click to get a larger view of the picture):

RFID tag message protocol

RFID tag message protocol

The start byte and stop byte are used to easily identify that a correct string has been received from the
reader (they correspond to a line feed and carriage return characters, respectively). The middle ten bytes are the actual tag’s unique ID.

In other words, you should read the incoming serial bytes until you find the start byte [hex 0x0A || decimal 10 || line feed]. You should then read the next 10 bytes as the tag’s unique ID and hope that the stop byte [hex 0x0D || decimal 13 || carriage return] shows up last. BTW, if you ever need to know something like the hex and decimal values of line feed, check here.

Now let’s take a look at the piece of code which reads the tag. I am going to litter it with comments, it looks huge but it is actually pretty concise:

//you need to define these
#define CODE_LEN 10          //Max length of RFID code
#define START_BYTE 0x0A   //decimal 10 or LINE-FEED
#define STOP_BYTE 0x0D     //decimal 13 or CARRIAGE-RETURN
 
char tag[CODE_LEN];    //this is the character where we store the tag
 
/**
 * Blocking function, waits for and gets the RFID tag.
 */
void getRFIDTag() {
 
  /**
   * next_byte is temporary storage for every byte we read
   */
  byte next_byte;
 
  /**
   * this next part blocks the code until we get something in
   * the incoming serial buffer. This is what makes this a
   * "blocking function". You may want to comment this out
   * if you have stuff to do if a tag is not present.
   */
  while(Serial.available() <= 0) {}
 
  /**
   * if we get here, there is at least one byte in the buffer
   * the next if reads it and checks to see if it is the start_byte
   * if it isn't, we are just moving on.
   */
  if((next_byte = Serial.read()) == START_BYTE) {
    //bytes_read keeps track of how many bytes into the tag we are
    byte bytes_read = 0; 
 
   /**
    * This while loop makes sure we don't read
    * more bytes than we can store in tag array.
    */
    while(bytes_read < CODE_LEN) {
      if(Serial.available() > 0) { //wait for the next byte
 
          /**
           * Here we read the next byte and make sure it
           * is not the STOP byte, if it is, we must break
           */
          if((next_byte= Serial.read()) == STOP_BYTE) break;        
 
          /**
           * Now we store that byte into the
           * tag at the next position by incrementing
           * bytes_read and storing next_byte at that position
           * in the tag array.
           */
          tag[bytes_read++] = next_byte;
      }
    }
  }
}

Dealing with radio interference

Let’s say you implement the getRFIDTag() function like this:

void loop() {
  enableRFID();
  getRFIDTag();
  disableRFID();
  sendCode();
  delay(3000); //wait 3 seconds
  Serial.flush();
  clearCode();
} 
 
/**
 * Clears out the memory space for the tag to 0s.
 */
void clearCode() {
  for(int i=0; i<CODE_LEN; i++) {
    tag[i] = 0; 
  }
}
 
/**
 * Sends the tag to the computer.
 */
void sendCode() {
    Serial.print("TAG:");  
    for(int i=0; i<CODE_LEN; i++) {
      Serial.print(tag[i]); 
    } 
}

So, you have this running and you are using the Arduino’s serial listener in the IDE, and you notice that every once in a while, you get a random tag for no reason. This kind of bug can be a problem and it is one of the things that made my door authentication device so unstable. I wish I would have RTFM a little closer:

The Parallax RFID Card Reader, like many RF devices, may experience RF noise in its frequency range.
This may cause the reader to transmit a spurious tag response when no tag is near the unit. This will not
affect most uses of the RFID Card Reader. To completely prevent spurious responses, it is recommended
to simply read two responses in a row within a given amount of time (e.g. 1 second) to ensure that you
are reading a valid tag and not a “tag” generated by noise.

I originally thought I was the lone genius who came up with this solution until I read that paragraph :( Oh well.

Let’s look at a way we can implement this idea. I noticed when you hold a tag to the reader, considering you don’t deactivate after a read, it just continues to spit out the number until you pull the tag away. So, what we need is a function that is called immediately after getRFIDTag() that reads the code again and validates that it is the same. Most of this function is the same as getRFIDTag(), and I hate to break DRY principles, but we are going for simplicity here and I don’t want this to turn into tutorial on pointers!:

/**
 * Waits for the next incoming tag to see if it matches
 * the current tag.
 */
boolean isCodeValid() {
  byte next_byte;
  while(Serial.available() <= 0) {}
  if((next_byte = Serial.read()) == START_BYTE) {
    byte bytes_read = 0;
    while(bytes_read < CODE_LEN) {
      if(Serial.available() > 0) { //wait for the next byte
          if((next_byte = Serial.read()) == STOP_BYTE) break;
          /**
           * this is the only part that is really different,
           * if we find one byte that is off, we return false,
           */
          if(tag[bytes_read++] != next_byte) return false;
      }
    }
  }
  return true; // if we get here, 'it must be good'
}

So, this is all good right? No, not really. If you were able to see a problem with this line:

  while(Serial.available() <= 0) {}

you are very perceptive. This will work for real tags but will make things complicated when noise occurs. Consider the believable case in which we get a junk tag from noise every 30 minutes. When we get that junk tag, we will be stuck on that line. One way to get around it is to apply a timeout. Here is a pretty ghetto way to implement that, just change the above line to this [UPDATE, there is a bug with this, see end of page]:

  int count = 0;
  while(Serial.available() <= 0) { //passes when we get a byte
    delay(1); //wait one millisecond
    if(count++ > VALIDATE_LENGTH) return false; //else check again
  }

We define VALIDATE_LENGTH to be the number of milliseconds, roughly, that the isCodeValid() function will wait until it realizes the tag you are asking to validate is just noise.

#define VALIDATE_LENGTH 200 //wait 200 ms

So, now you should be good to go. If you are looking to storing and comparing keys in non-volatile memory, I suggest looking at the EEPROM library. I already wrote some code to do this so if you are curious let me know in the comments. As promised, here is all the code for this article:

/**
 * author Benjamin Eckel
 * date 10-17-2009
 *
 */
#define RFID_ENABLE 2   //to RFID ENABLE
#define CODE_LEN 10      //Max length of RFID tag
#define VALIDATE_TAG 1  //should we validate tag?
#define VALIDATE_LENGTH  200 //maximum reads b/w tag read and validate
#define ITERATION_LENGTH 2000 //time, in ms, given to the user to move hand away
#define START_BYTE 0x0A 
#define STOP_BYTE 0x0D
 
char tag[CODE_LEN];  
 
void setup() { 
  Serial.begin(2400);  
  pinMode(RFID_ENABLE,OUTPUT);   
}
 
void loop() { 
  enableRFID(); 
  getRFIDTag();
  if(isCodeValid()) {
    disableRFID();
    sendCode();
    delay(ITERATION_LENGTH);
  } else {
    disableRFID();
    Serial.println("Got some noise");  
  }
  Serial.flush();
  clearCode();
} 
 
/**
 * Clears out the memory space for the tag to 0s.
 */
void clearCode() {
  for(int i=0; i<CODE_LEN; i++) {
    tag[i] = 0; 
  }
}
 
/**
 * Sends the tag to the computer.
 */
void sendCode() {
    Serial.print("TAG:");  
    //Serial.println(tag);
    for(int i=0; i<CODE_LEN; i++) {
      Serial.print(tag[i]); 
    } 
}
 
/**************************************************************/
/********************   RFID Functions  ***********************/
/**************************************************************/
 
void enableRFID() {
   digitalWrite(RFID_ENABLE, LOW);    
}
 
void disableRFID() {
   digitalWrite(RFID_ENABLE, HIGH);  
}
 
/**
 * Blocking function, waits for and gets the RFID tag.
 */
void getRFIDTag() {
  byte next_byte; 
  while(Serial.available() <= 0) {}
  if((next_byte = Serial.read()) == START_BYTE) {      
    byte bytesread = 0; 
    while(bytesread < CODE_LEN) {
      if(Serial.available() > 0) { //wait for the next byte
          if((next_byte = Serial.read()) == STOP_BYTE) break;       
          tag[bytesread++] = next_byte;                   
      }
    }                
  }    
}
 
/**
 * Waits for the next incoming tag to see if it matches
 * the current tag.
 */
boolean isCodeValid() {
  byte next_byte; 
  int count = 0;
  while (Serial.available() < 2) {  //there is already a STOP_BYTE in buffer
    delay(1); //probably not a very pure millisecond
    if(count++ > VALIDATE_LENGTH) return false;
  }
  Serial.read(); //throw away extra STOP_BYTE
  if ((next_byte = Serial.read()) == START_BYTE) {  
    byte bytes_read = 0; 
    while (bytes_read < CODE_LEN) {
      if (Serial.available() > 0) { //wait for the next byte      
          if ((next_byte = Serial.read()) == STOP_BYTE) break;
          if (tag[bytes_read++] != next_byte) return false;                     
      }
    }                
  }
  return true;   
}

I have tested this as well as I can. I have yet to catch any noise events ‘in the wild’ so to speak, which concerns me [read Updates, lol]. But I have tested each case in the isCodeValid() function. I have caused a false validation by timeout and by differing keys [repetitive noise]. But I have also broken it by causing it to read “half” of a key. If it still doesn’t work for you, get creative, there are many ways around the interference issue.

Please let me know if you find faults or improvements and Enjoy :)

Updates

02/07/2010 – For those of you who have been using this code and still getting some noise, I apologize because I just found a bug with the isCodeValid function. For some reason, I was not getting past the line:

if ((next_byte = Serial.read()) == START_BYTE) {

I ran this code right before that line:

  for (int i = 0; i < 30; i++) {
    Serial.print("a");
    Serial.print(Serial.available(), DEC);
    Serial.print("r");
    Serial.print(Serial.read(), DEC);
    Serial.println();
  }

And this came on the port:

a1r13
a0r-1
a0r-1
a0r-1
a0r-1
a0r-1
a0r-1
a0r10
a6r48
a10r52
a9r49
a8r54
a9r50
a15r66
a17r69
a16r65
a15r49
a14r54
a13r13
a12r10
a11r48
a10r52
a9r49
a8r54
a7r50
a6r66
a5r69
a4r65
a3r49
a2r54

Now, ignore the line a0r10. It is not a bug, it is just that it takes so long to print to the serial port at 2400 baud. Anyway, what is obvious is that my whole function was breaking b/c the STOP_BYTE (13), was still in the buffer. I tried to do a flush before the function but that didn’t work for whatever reason. So what I did is change the while loop to this:

while (Serial.available() < 2) {

and then after the while loop breaks, throw that 13 away:

Serial.read();

Sorry this took so long for me to figure out, I was on hiatus, I hope it didn’t mess anyone up. This change is reflected in the whole piece of code.

Posted in Arduino, Tutorial/Documentation | Tagged , , , | 19 Comments