loading
Picture of Twitter Poem Box
 
This is a project that was inspired by Marc de Vinck's Kitty Twitty Cat Toy http://makezine.com/22/kittytwitty/ . It incorporates an RFID reader and the BlinkM, a programable RGB LED. The lamp tweets random colored poems when it detects one of the three RFID cards which each represent one of the primary colors of light. These colors can be mixed allowing you to make seven different colors of poems. An example red poem is "Red sirens see. Clocks make a good bed."


Included are two versions of the same project. One version used the Seeed Studio 125Khz RFID module, while the other used the The Parallax Serial RFID Reader / Writer Module.

 

 
Remove these adsRemove these ads by Signing Up

Step 1: Parts

Picture of Parts
parallax-serial-rfid-reader-writer-module.jpg
ArduinoEthernetShield.jpg
tm_blinkm_closeup_obliq_sma.jpg
ArduinoWithEthernetShield.jpg
wizstraight3_t.jpg

Seeed Version Part List

* Seeed Studio 125Khz RFID module - Wiegand (RFR102A1M) http://www.seeedstudio.com/depot/125khz-rfid-module-wiegand-p-225.html?cPath=144_153
* 3 RFID 54mm x 85mm Rectangle Tags-http://www.parallax.com/Store/Accessories/CommunicationRF/tabid/161/ProductID/689/List/0/Default.aspx?SortField=ProductName,ProductName
*1  BlinkM http://thingm.com/products/blinkm
* 1 Arduino
* 1 Arduino Ethernet Shield-http://www.adafruit.com/index.php?main_page=product_info&products_id=83&zenid=9b755efcfe260b30eee32576599c81c5
* WIZ812MJ Ethernet SPI/Bus Module (RJ45) 2.54mm Pitch http://www.saelig.com/product/ETH042.htm
* 1 Ethernet Cable
* 1 USB Cable
* 1 Unused Ethernet Port with connection to internet
* 1 Solderless Breadboard
* 1 LED
* 1 220Ω resistor
* 22 AWG solid core wire
* Soldering Iron
* Lead-Free Solder
* Wire Strippers
* Wire Cutters
* Glue Gun
* Velum
* Tape
* Hot glue
* Box
* X-acto knife
* Drill
 

Parallax Version
* The Parallax Serial RFID Reader / Writer Module http://www.parallax.com/Store/Accessories/CommunicationRF/tabid/161/ProductID/688/List/0/Default.aspx?SortField=ProductName,ProductName
* 3 RFID 54mm x 85mm Rectangle Tags-http://www.parallax.com/Store/Accessories/CommunicationRF/tabid/161/ProductID/689/List/0/Default.aspx?SortField=ProductName,ProductName
* 1 BlinkM-http://thingm.com/products/blinkm
* 1 Arduino
* 1 Arduino Ethernet Shield-http://www.sparkfun.com/products/9026
* 1 Ethernet Cable
* 1 USB Cable
*  1 Unused Ethernet Port with connection to internet
* 1 Solderless Breadboard
* 22awg solid core wire
* Soldering Iron
* Lead-Free Solder
* Wire Strippers
* Wire Cutters
* Glue Gun
* Velum
* Tape
* Hot glue
* Box
* X-acto knife
* Drill
* Cardboard Tube


Step 2: Seeed RFID

Picture of Seeed RFID
seeed_schematic.png
The RDM 125KHz card mini-module is designed for reading code from 125KHz/ 134.2KHz card compatible read-only tags and read/write card . It can be applied in office/home security, personal identification, access control, anti-forgery, interactive toy and production control systems etc.


1. To connect the RFID reader to the arduino, attach pins 1 and 2 of the RFID reader to digital pins  2 and 3. Connect  the RFID reader to  5V and ground.

2. Attach the LED and the 220Ω resistor to the RFID reader. The LED will serve as a signal indicator.

3. Upload this code to your arduino:

/* Modified from 
* Crazy People
* By Mike Cook April 2009
* An RFID reader outputing 26 bit Wiegand code to pins:-
* Reader attached to Pins 2 & 3
* Interrupt service routine gathers Wiegand pulses (zero or one) until 26 have been received
* Then a string is sent to Serial
*/

volatile long reader1 = 0;
volatile int reader1Count = 0;

void reader1One(void) {
     reader1Count++;
     reader1 = reader1 << 1;
     reader1 |= 1;
}

void reader1Zero(void) {
     reader1Count++;
     reader1 = reader1 << 1;
}

void setup()
{
     Serial.begin(9600);
     // Attach pin change interrupt service routines from the Wiegand RFID readers
     attachInterrupt(0, reader1Zero, RISING);//DATA0 to pin 2
     attachInterrupt(1, reader1One, RISING); //DATA1 to pin 3
     delay(10);
     // the interrupt in the Atmel processor misses out the first negitave pulse as the inputs are already high,
     // so this gives a pulse to the reader input line to get the interrupts working properly.
     // Then clear out the reader variables.
     // The readers are open collector sitting normally at a one so this is OK
     for(int i = 2; i<4; i++){
          pinMode(i, OUTPUT);
          digitalWrite(i, HIGH); // enable internal pull up causing a one
          digitalWrite(i, LOW); // disable internal pull up causing zero and thus an interrupt
          pinMode(i, INPUT);
          digitalWrite(i, HIGH); // enable internal pull up
     }
     delay(10);
     // put the reader input variables to zero
     reader1 = 0;
     reader1Count = 0;
}

void loop() {
     if(reader1Count >=26){
          int serialNumber=(reader1 >> 1) & 0x3fff;
          int siteCode= (reader1 >> 17) & 0x3ff;

          Serial.print(" Reader 1:");
          Serial.print(reader1,HEX);
          Serial.print(" ");
          Serial.print("Reader 1 converted to DEC:");
          Serial.print(reader1& 0xfffffff);
          Serial.print(" ");
          Serial.print("siteCode:");
          Serial.print(siteCode);
          Serial.print(" ");
          Serial.print("serial number:");
          Serial.println(serialNumber);

          reader1 = 0;
          reader1Count = 0;
     }
}





4.Open the Serial monitor and record the numbers that the serial monitor spits out when you wave your RFID card in front of the RFID antenna.




Step 3: Seeed and BlinkM

Picture of Seeed and BlinkM
2097415814_5e63cc45c8_s.jpg
new_tab.png

1. Connect the BlinkM d pin (the data pin) to the analog 4 of the Arduino.

2. Connect the BlinkM c pin (the clock pin) to analog  5 of the Arduino.

3. Connect the BlinkM to 5V and GND.

4. Download the BlinkM_funcs.h file-http://todbot.com/blinkm/example_code/BlinkMTester/BlinkM_funcs.h  

5. Create a new sketch.

6. Create a new tab and name it BlinkM_funcs.h

7. Paste in the BlinkM_funcs.h code in the new tab

8. Paste the following code in the main sketch, compile  and upload. The code allows the user to control the BlinkM with the RFID tags:




#include <Wire.h>
#include "BlinkM_funcs.h"

volatile long reader1 = 0;
volatile int reader1Count = 0;

#define blue [your id tag # here]
#define red [your id tag # here]
#define green [your id tag # here]

long prevTime;
int card1;
int card2;
int count=0;

long dec;
int color;

byte r,g,b;

byte addr = 0x09;


void reader1One(void) {
     reader1Count++;
     reader1 = reader1 << 1;
     reader1 |= 1;
}


void reader1Zero(void) {
     reader1Count++;
     reader1 = reader1 << 1;
}


void setup(){
     BlinkM_beginWithPower();
     Serial.begin(9600);
    
    // Attach pin change interrupt service routines from the Wiegand RFID readers
    attachInterrupt(0, reader1Zero, RISING);//DATA0 to pin 2
    attachInterrupt(1, reader1One, RISING); //DATA1 to pin 3
     delay(10);

     // the interrupt in the Atmel processor misses out the first negitave pulse as the inputs are already high,
     // so this gives a pulse to the reader input line to get the interrupts working properly.
     // Then clear out the reader variables.
     // The readers are open collector sitting normally at a one so this is OK
    for(int i = 2; i<4; i++){
        pinMode(i, OUTPUT);

        // enable internal pull up causing a one
        digitalWrite(i, HIGH); 

       // disable internal pull up causing zero and thus an interrupt
       digitalWrite(i, LOW);
      
       pinMode(i, INPUT);
       digitalWrite(i, HIGH); // enable internal pull up
     }

    delay(10);

     // put the reader input variables to zero
     reader1 = 0;
     reader1Count = 0;
}


void loop() {
     readCard();
}

void readCard(){
     if(count<2){
          if(reader1Count >=26){
               int serialNumber=(reader1 >> 1) & 0x3fff;
               int siteCode= (reader1 >> 17) & 0x3ff;
               dec = (reader1& 0xfffffff);
               if(count==0){
                    r=0;
                    b=0;
                   g=0;
                }
               Serial.print("dec=");
               Serial.println(dec);


                switch(dec){
                case red:
                      r=255;
                      break;
          
                case green:
                       g=255;
                      break;
 
                case blue:
                       b=255;
                       break;
    
                default:
               color=0;

               Serial.print("new tag");
               Serial.print(reader1& 0xfffffff);
           }

           displayColor();
           reader1 = 0;
           reader1Count = 0;
      }else if(reader1Count == 0){
           displayColor();
      }

     if(millis()-prevTime>2000){
          count++;
          prevTime=millis();
       }
    }else{
      count=0;
    }
 }

void displayColor(){
     BlinkM_fadeToRGB(addr,r,g,b);
}

 

Step 4: Seeed and Twitter

Picture of Seeed and Twitter
P1150813.JPG
P1150814.JPG

1. Cut out holes for the USB and Ethernet and maybe a hole for the power jack if you want to power the arduino that way.

2.  Create a 2.5in by 2.5in by 2.5in box of velum with the 2.5in by 5in bottom open

3. Tape the vellum to the top of your box over the BlinkM and secure all the parts

4. Download the TrueRandom http://code.google.com/p/tinkerit/wiki/TrueRandom,
NewSoftSerial http://arduiniana.org/libraries/newsoftserial/,
and Twitter http://www.arduino.cc/playground/Code/TwitterLibrary libraries

5. Upload this code to your Arduino

#include <TrueRandom.h>

#include <SPI.h>

#include <avr/pgmspace.h>

#include <Wire.h>

#include <BlinkM_funcs.h>

#include <Client.h>

#include <Ethernet.h>

#include <Server.h>

#include <Udp.h>

#include <EthernetDNS.h>

#include <Twitter.h>


/*
 based on Kittty Twitty Cat Toy v1.0
 by Marc de Vinck
 Jan 6, 2010
 KittyTwitty cat toy project found in MAKE, Volume 22

 String (formerly TextString) Library by Tom Igoe
 http://www.arduino.cc/en/Tutorial/TextString
 */


// the push button
#define pushBtn 6


boolean printed=true;

int color;

volatile long reader1 = 0;
volatile int reader1Count = 0;

#define blue 57337134
#define red 23773468
#define green 23805695

long prevTime;
int card1;
int card2;
int count=0;

long dec;

int r = 0;
int g = 0;
int b=0;

#define addr 0x09

// used to store the status of pin (6)
int var; 

long randNum1;
long randNum2;
long randNum3;
long randNum4;

String dataString;
long prevtime = -30000;

// defining the network setting for the Ethernet Shield

// this can be made up
byte mac[] = {
0x1A, 0x6F, 0x99, 0xCD, 0xFF, 0xFF }; 

//get this from Settings, then change last byte
byte ip[] = {
10,0,1,197 };

//to get token: http://arduino-tweet.appspot.com/
Twitter twitter("[your_token_here]");


prog_char words1_0[] PROGMEM = "Red ";
prog_char words1_1[] PROGMEM = "Green ";
prog_char words1_2[] PROGMEM = "Blue ";
prog_char words1_3[] PROGMEM = "Yellow ";
prog_char words1_4[] PROGMEM = "Purple ";
prog_char words1_5[] PROGMEM = "Cyan ";
prog_char words1_6[] PROGMEM = "White ";

prog_char words2_0[] PROGMEM = "lights ";
prog_char words2_1[] PROGMEM = "arts ";
prog_char words2_2[] PROGMEM = "gases ";
prog_char words2_3[] PROGMEM = "circles ";
prog_char words2_4[] PROGMEM = "needles ";
prog_char words2_5[] PROGMEM = "doorknobs ";
prog_char words2_6[] PROGMEM = "sirens ";

prog_char words3_0[] PROGMEM = "sleep. ";
prog_char words3_1[] PROGMEM = "walk. ";
prog_char words3_2[] PROGMEM = "live. ";
prog_char words3_3[] PROGMEM = "exist. ";
prog_char words3_4[] PROGMEM = "perceive. ";
prog_char words3_5[] PROGMEM = "think. ";
prog_char words3_6[] PROGMEM = "see. ";

prog_char words4_0[] PROGMEM = "Cats are awesome.";
prog_char words4_1[] PROGMEM = "Quilts taste like gingerbread.";
prog_char words4_2[] PROGMEM = "Metal is highly interactive.";
prog_char words4_3[] PROGMEM = "Light is radiation.";
prog_char words4_4[] PROGMEM = "Sound is the wind.";
prog_char words4_5[] PROGMEM = "Clocks make a good bed.";
prog_char words4_6[] PROGMEM = "Glass is opaque.";

PROGMEM const char *words1_table[] ={
words1_0,
words1_1,
words1_2,
words1_3,
words1_4,
words1_5,
words1_6};

PROGMEM const char *words2_table[]={
words2_0,words2_1,words2_2,words2_3,words2_4,words2_5,words2_6};

PROGMEM const char *words3_table[]={
words3_0,words3_1,words3_2,words3_3,words3_4,words3_5,words3_6};

PROGMEM const char *words4_table[]={
words4_0,words4_1,words4_2,words4_3,words4_4,words4_5,words4_6};

char words1_buffer[7];
char words2_buffer[10];
char words3_buffer[10];
char words4_buffer[30];


void reader1One(void) {
     reader1Count++;
     reader1 = reader1 << 1;
     reader1 |= 1;
}


void reader1Zero(void) {
     reader1Count++;
     reader1 = reader1 << 1;
}



void setup(){
     // run this code once
     BlinkM_beginWithPower();

     //defining the btn as an input so we can read it
     pinMode(pushBtn, INPUT);

     // starts serial communications so you can debug easier
     Serial.begin(9600); 
    
     //DATA0 to pin 2
     attachInterrupt(0, reader1Zero, RISING);

     //DATA1 to pin 3
     attachInterrupt(1, reader1One, RISING); 

     for(int i = 2; i<4; i++){
         pinMode(i, OUTPUT);
         digitalWrite(i, HIGH); // enable internal pull up causing a one
         digitalWrite(i, LOW); // disable internal pull up causing zero and thus an interrupt
         pinMode(i, INPUT);
          digitalWrite(i, HIGH); // enable internal pull up
     }

    reader1 = 0;
    reader1Count = 0;

     //begins the Ethernet connection from the stored information
     Ethernet.begin(mac, ip); 

     connectToTwitter();

     Serial.println("Waiting"); // print, used for debugging
}


void connectToTwitter(){
     // print a blank line, used for debugging
     Serial.println("Connecting to Twitter..."); // print, used for debugging

     char testFN1[4]={int(random(4000,5000)) };

     if (twitter.post(testFN1)) { // Twitter that we are up and running
         int status = twitter.wait(&Serial); // wait for a response from twitter
          if (status == 200) { // if Twitter responds 200
               Serial.println("Tweet OK!"); // print success // print a blank line, used for debugging

          }else {
              Serial.print("Tweet failed : code ");
              Serial.println(status); // print error code
              connectToTwitter(); // print a blank line, used for debugging
          }
     }else {
           Serial.println("connection failed.");
           connectToTwitter();
     }
}

void loop(){
     // run over and over, never stop
     readCard();
    displayColor();

    // check status of wire sensor
    checkState(); 
}

void getString(){
     //concatenates poem
    dataString= strcpy_P(words1_buffer, (char*)pgm_read_word(&(words1_table[color])));
    dataString=dataString+ strcpy_P(words2_buffer,   (char*)pgm_read_word(&(words2_table[int(randNum2)])));

     dataString=dataString+ strcpy_P(words3_buffer, (char*)pgm_read_word(&(words3_table[int(randNum3)])));

     dataString=dataString+ strcpy_P(words4_buffer, (char*)pgm_read_word(&(words4_table[int(randNum4)])));

     dataString=dataString+ " - 1000000000";
}



void tweet(){
     // function tweet, this is called if status = 1
     char filename[88];

     dataString.toCharArray(filename, 88);

      Serial.println("Connecting to Twitter..."); // print, used for debugging
      Serial.println(); // print a blank line, used for debugging
      if (twitter.post(filename)) {
           // tweet the completed datastring of words
          Serial.print("Tweeting -- "); // print, used for debugging
          Serial.println(dataString); // print, used for debugging
          Serial.print(" -- Status: "); // print, used for debugging
         int status = twitter.wait();
         if (status == 200) {
               Serial.println("Successful!");
               Serial.println();
         }else {
              Serial.print("Tweet failed : code "); // print error code
              Serial.println(status); // print error code
         }
    }else {
          Serial.println("Connection to Twitter failed."); // print error code
    }
}





void readCard(){
     if(count<2){
          if(reader1Count >=26){
              int serialNumber=(reader1 >> 1) & 0x3fff;
              int siteCode= (reader1 >> 17) & 0x3ff;
             dec = (reader1& 0xfffffff);
             if(count==0){
                r=0;
                b=0;
                g=0;
             }
          
           Serial.print("dec=");
           Serial.println(dec);


         switch(dec){
         case red:
             r=255;
             break;
      
         case green:
               g=255;
               break;

          case blue:
                b=255;
                break;

          default:
              color=0;

              Serial.print("new tag");
              Serial.print(reader1& 0xfffffff);
           }

           reader1 = 0;
           reader1Count = 0;
           printed = false;
        }else if(reader1Count == 0){

     }
    if(millis()-prevTime>2000){
          count++;
          prevTime=millis();
     }

   }else{
         count=0;
   }

}//readCard()


void checkState(){ // check status of wire function
     if(!printed){
          doStuff();
          printed=true;
       }
}



void displayColor(){
    if(r==255 && g==0 && b==0){
         color=0;
     } else if(r==0 && g==255 && b==0){
         color=1;
     } else if(r==0 && g==0 && b==255){
         color=2;
     }else if(r==255 && g==255 && b==0){
          color=3;
     } else if(r==255 && g==0 && b==255){
         color=4;
     } else if(r==0 && g==255 && b==255){
        color=5;
     } else if(r==255 && g==255 && b==255){
        color=6;
    }
    BlinkM_fadeToRGB(addr,r,g,b);
}


void doStuff(){
     randNum2 = random(7);
     randNum3 = random(7);
     randNum4 = random(7);
     getString();
     tweet();
}





5. Connect your Arduino to the ethernet 

6. Test.

Step 5: Parallax Lamp

Picture of Parallax Lamp
28440-L.jpg
The Parallax Serial RFID Reader / Writer Module provides a low-cost solution to read and write passive RFID transponder tags up to 3 inches away. The RFID transponder tags provide a unique serial number and can store up to 116 bytes of user data, which can be password protected to allow only authorized access. The Parallax website suggests that the RFID Read/Write Module can be used for access control, user identification, robotics navigation, inventory tracking, payment systems, car immobilization, and manufacturing automation.

1. Wire SIN in digital pin 3.

2. Wire SOUT to digital pin 2.

3. Download the NewSoftSerial Library http://arduiniana.org/libraries/newsoftserial/

4. Upload the code to Arduino. This code will read the RFID cards:


#include <NewSoftSerial.h>
#define rxPin 2
#define txPin 3
byte r=0,g=0,b=0;
prog_char red[] PROGMEM = "2F00E69DFF";
prog_char green[] PROGMEM = "2F00E68BC6";
prog_char blue[] PROGMEM = "2F00E6C2D0";
PROGMEM const char *colorTags_table[] = {
red,green,blue};

char tags_buffer[12];

NewSoftSerial RFID = NewSoftSerial(rxPin,txPin);

void setup() {

Serial.begin(9600);
RFID.begin(9600);// RFID reader SOUT pin connected to Serial RX pin at 9600bps
}

void loop() {
sendRead();
readTag();
}

void sendRead() {
RFID.flush();
RFID.print("!RW");
RFID.print(0x0F, BYTE);
}

void readTag(){
byte code[12];
int bytesread = 0;
String msg;
while(bytesread<12){ // read 10 digit code
// this blocks and should ideally have a timeout
if( RFID.available()) {
code[bytesread] = RFID.read();
bytesread++;
}

if(bytesread == 12) {
if (code[0]==0x0A) {
Serial.print("TAG code is: ");
for(int i=1;i<11;i++){
msg = msg+code[i];
}

for(int i=0;i<3;i++){
strcpy_P(tags_buffer, (char*)pgm_read_word(&(colorTags_table[i])));

if(msg==tags_buffer) {
switch(i){
case 0:
Serial.println("red");
r=255;
break;

case 1:
g=255;
Serial.println("green");
break;

case 2:
b=255;
Serial.println("blue");
break;
}
}
}
}
}
}
}

 

Step 6: Parallax and BlinkM

Picture of Parallax and BlinkM
parallax_blinkM.png
1. Connect the BlinkM d (data pin) to the analog 4 of the Arduino.

2. Connect the BlinkM c (clock pin) to analog 5 of the Arduino.

3. Connect the BlinkM to 5V and GND.

4. Download the BlinkM_funcs.h file-http://todbot.com/blinkm/example_code/BlinkMTester/BlinkM_funcs.h

5. Create a new sketch.

6. Create a new tab and name it BlinkM_funcs.h

7. Paste in the BlinkM_funcs.h code in the new tab

8. Paste the following code in the main sketch, compile and upload. The code allows the user to control the BlinkM with the RFID tags. This code controls the  BlinkM while the RFID is not available. If you don't account for this period, the BlinkM will cycle through the colors rather than display the last color selected. Calling fadeToRGB when RFID is not available fixes this issue:

#include <Wire.h>
#include <BlinkM_funcs.h>
#include <NewSoftSerial.h>
#include <avr/pgmspace.h>
#define rxPin 2
#define txPin 3

byte r=0,g=0,b=0;
int blinkm_addr = 0x09;

int count=0;
long pt;

prog_char red[] PROGMEM = "[your RFID tag number]";
prog_char green[] PROGMEM = "[your RFID tag number]";
prog_char blue[] PROGMEM = "[your RFID tag number]";

PROGMEM const char *colorTags_table[] = { 
  red,green,blue};

char tags_buffer[12];

NewSoftSerial RFID = NewSoftSerial(rxPin,txPin);

void setup() { 

  Serial.begin(9600); 
  BlinkM_begin();
  BlinkM_setRGB(blinkm_addr, 0, 0,0);
  RFID.begin(9600);// RFID reader SOUT pin connected to Serial RX pin at 9600bps 


void loop() {
  BlinkM_setRGB(blinkm_addr,r,g,b); 
  sendRead();
  readTag();
}

void sendRead() {
  RFID.flush();
  RFID.print("!RW");
  RFID.print(0x0F, BYTE);
}

void readTag(){
     if(count<2){
          byte code[12];
          int bytesread = 0;
         String msg;
         while(bytesread<12){ // read 10 digit code
               // this blocks and should ideally have a timeout
              if( RFID.available()) {
                   code[bytesread] = RFID.read();
                   bytesread++;
               }else{
                    //this fixed the problem
                    BlinkM_fadeToRGB(blinkm_addr, r, g, b);//call which fades to desired color
                }

              if(bytesread == 12) {
                    if (code[0]==0x0A) {
                         Serial.print("TAG code is: ");
                         for(int i=1;i<11;i++){
                         // Serial.print(code[i], HEX);
                         msg = msg+code[i];
                      }
                     Serial.println(msg);
                     if(count==0){
                         r=0;
                         b=0;
                         g=0;
                      }
                      for(int i=0;i<3;i++){
                           strcpy_P(tags_buffer, (char*)pgm_read_word(&(colorTags_table[i])));
                           if(msg==tags_buffer) {
                                switch(i){
                                case 0:
                                      Serial.println("red");
                                      r=255;
                                      break;

                                 case 1:
                                       g=255;
                                       Serial.println("green");
                                       break;

                                 case 2:
                                       b=255;
                                       Serial.println("blue");
                                       break;
                                   }
                            }
                     } //end for loop

                }//end code[0]==0x0A
           }//end bytesread == 12
      }
     displayColor();
     if(millis()-pt>1500){
           count++;
           pt=millis();
       }
    }//end if count
     else{
           count=0;
     }


}

void displayColor(){
      BlinkM_fadeToRGB(blinkm_addr, r, g,b);
}
     



 

Step 7: Parallax and Twitter

Picture of Parallax and Twitter

1. Get a token to post a message using OAuth. http://arduino-tweet.appspot.com

2. To configure the network information in the code,start by looking at your computer’s network settings. On the Mac, go to System Preferences/Network, then click the Advanced button and select the TCP/IP tab. 

3.For the code’s free IP address, you can usually just take your network setting and increase the last number a little bit.If your IP address was: 192.168.1.2, you could try 192.168.2.12

4. Download the Twitter Library http://www.arduino.cc/playground/Code/TwitterLibrary

5. Create a new sketch. Paste in this code. make the necessary modifications:

#include <Wire.h>
#include <BlinkM_funcs.h>
#include <NewSoftSerial.h>
#include <avr/pgmspace.h>
#include <Ethernet.h>
#include <EthernetDNS.h>
#include <Twitter.h>

#define rxPin 2
#define txPin 3

byte r=0,g=0,b=0;
int blinkm_addr = 0x09;

int count=0;
long pt;

prog_char red[] PROGMEM = "[your RFID tag number]";
prog_char green[] PROGMEM = "your RFID tag number]";
prog_char blue[] PROGMEM = "your RFID tag number]";

PROGMEM const char *colorTags_table[] = {
  red,green,blue};

char tags_buffer[12];

NewSoftSerial RFID = NewSoftSerial(rxPin,txPin);


boolean ctt=false;
char testFN[80];

// modify the last two bytes-it can be anything
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFF, 0xFF }; 

//modify the last number so the ip is unique
byte ip[] = { 10,0,1,29 };

Twitter twitter("[your token here]"); 

String poem;
int color=7;
int lastColor=7;

long randNum2;
long randNum3;
long randNum4;

////poem
prog_char words1_0[] PROGMEM = "Red ";
prog_char words1_1[] PROGMEM = "Green ";
prog_char words1_2[] PROGMEM = "Blue ";
prog_char words1_3[] PROGMEM = "Magenta ";
prog_char words1_4[] PROGMEM = "Cyan ";
prog_char words1_5[] PROGMEM = "Yellow ";
prog_char words1_6[] PROGMEM = "White ";

prog_char words2_0[] PROGMEM = "clouds ";
prog_char words2_1[] PROGMEM = "seals ";
prog_char words2_2[] PROGMEM = "skyscrapers ";

prog_char words3_0[] PROGMEM = "lives. ";
prog_char words3_1[] PROGMEM = "fly. ";
prog_char words3_2[] PROGMEM = "sleep. ";
prog_char words3_3[] PROGMEM = "surround. ";
prog_char words3_4[] PROGMEM = "implode. ";

prog_char words4_0[] PROGMEM = "Pigs will fly but men will not.";
prog_char words4_1[] PROGMEM = "The red rose smashes into oblivion.";
prog_char words4_2[] PROGMEM = "Legends live but heros die.";
prog_char words4_3[] PROGMEM = "Small talk is large in the language of life.";

PROGMEM const char *words1_table[] = {
words1_0,
words1_1,
words1_2,
words1_3,
words1_4,
words1_5,
words1_6 };

PROGMEM const char *words2_table[] ={
words2_0,
words2_1,
words2_2
};

PROGMEM const char *words3_table[] ={
words3_0,
words3_1,
words3_2,
words3_3,
words3_4
};

PROGMEM const char *words4_table[] = {
words4_0,
words4_1,
words4_2,
words4_3 };

char word1_buffer[8];
char word2_buffer[12];
char word3_buffer[10];
char word4_buffer[44];

///
void setup() {

Serial.begin(9600);
BlinkM_begin();
RFID.begin(9600);// RFID reader SOUT pin connected to Serial RX pin at 9600bps
BlinkM_setRGB(blinkm_addr, 0, 0, 0);//call which fades to desired color

lastColor=7;

Ethernet.begin(mac, ip); //begins the Ethernet connection
delay(1000);
connectToTwitter();
     if(ctt){
          Serial.println("start everything");

     }
}
void connectToTwitter(){ // print a blank line, used for debugging
     Serial.println("Connecting to Twitter..."); // print, used for debugging
     char testFN1[4]={int(random(1000,2000)) };
     if (twitter.post(testFN1)) { // Twitter that we are up and running
           int status = twitter.wait(&Serial); // wait for a response from twitter
            if (status == 200) { // if Twitter responds 200
                  Serial.println("Tweet OK!"); // print success // print a blank line, used for debugging
                  ctt=true;
              }else {
                  Serial.print("Tweet failed : code ");
                  Serial.println(status); // print error code
                  connectToTwitter(); // print a blank line, used for debugging
              }
        }else {
             Serial.println("connection failed.");
             connectToTwitter();
      }
}

void loop() {
      BlinkM_setRGB(blinkm_addr,r,g,b);
      sendRead();
      readTag();
}

void sendRead() {
     RFID.flush();
     RFID.print("!RW");
RFID.print(0x0F, BYTE);
}

void readTag(){
if(count<2){
byte code[12];
int bytesread = 0;
String msg;
while(bytesread<12){ // read 10 digit code
// this blocks and should ideally have a timeout
if( RFID.available()) {
code[bytesread] = RFID.read();
bytesread++;
}
else{
//this fixed the problem
BlinkM_fadeToRGB(blinkm_addr, r, g, b);//call which fades to desired color
}

if(bytesread == 12) {
if (code[0]==0x0A) {

for(int i=1;i<11;i++){
// Serial.print(code[i], HEX);
msg = msg+code[i];
}
if(count==0){
r=0;
b=0;
g=0;
}
for(int i=0;i<3;i++){
strcpy_P(tags_buffer, (char*)pgm_read_word(&(colorTags_table[i])));
if(msg==tags_buffer) {
switch(i){
case 0:
r=255;
break;

case 1:
g=255;
break;

case 2:
b=255;
break;
}
}
} //end for loop

}//end code[0]==0x0A
}//end bytesread == 12
}
displayColor();
if(millis()-pt>1500){
count++;
pt=millis();
}
}//end if count
else{
count=0;
}
}
void getString(){
//concatenates poem
poem=strcpy_P(word1_buffer, (char*)pgm_read_word(&(words1_table[color])));
poem=poem+strcpy_P(word2_buffer, (char*)pgm_read_word(&(words2_table[randNum2])));
poem=poem+strcpy_P(word3_buffer, (char*)pgm_read_word(&(words3_table[randNum3])));
poem=poem+strcpy_P(word4_buffer, (char*)pgm_read_word(&(words4_table[randNum4])));
poem=poem+"-Lukas";


}
void getPoem(){


randNum2 = random(3);
randNum3 = random(5);
randNum4 = random(4);
getString();
tweet(poem);
lastColor=color;


}
void displayColor(){
if(r==255 && g==0 && b==0){
color=0;
}
else if(r==0 && g==255 && b==0){
color=1;
}
else if(r==0 && g==0 && b==255){
color=2;
}
else if(r==255 && g==0 && b==255){
color=3;
}
else if(r==0 && g==255 && b==255){
color=4;
}
else if(r==255 && g==255 && b==0){
color=5;
}
else if(r==255 && g==255 && b==255){
color=6;
}
else if(r==0 && g==0 && b==0){
color=7;
}

if(color!=lastColor){
getPoem();
BlinkM_fadeToRGB(blinkm_addr, r, g,b);
}
}
void tweet(String poem){
poem.toCharArray(testFN, 80);
Serial.println(poem);

//---------------- for twitter --------------
Serial.println("Connecting to Twitter..."); // print, used for debugging
Serial.println(); // print a blank line, used for debugging

if (twitter.post(testFN)) { // tweet the completed datastring of words
Serial.print("Tweeting -- "); // print, used for debugging
int status = twitter.wait();
if (status == 200) {
Serial.println("Successful!");
Serial.println();
}
else {
Serial.print("Tweet failed : code "); // print error code
Serial.println(status); // print error code
}
}
else {
Serial.println("Connection to Twitter failed."); // print error code
delay(500);
tweet(poem);
}
//digitalWrite(statusPin, LOW); // sets the status LED off
Serial.println("ready"); // print, used for debugging
Serial.println(); // print a blank line, used for debugging

//---------------- for twitter --------------


5.  Plug in the power supply and Ethernet cable, and flip the switch. The power LED should come on, and in a few seconds, the network status LED, too. The code tweets an "Up and Running" message to let you know everything is OK. You can plug a USB cable into the Arduino and listen in on the serial port for some debugging.

Step 8: Making the diffusor

Picture of Making the diffusor
drill_hole.png
cut_vellum.png
hole_punch.png
1. First you need to grab a tube

2. Next you need to cut off a length from the end of the tube (I cut a 3in portion)

3. Drill some holes on the side of the tube

4. Cut out a circle of velum that will fit on top of your tube

5. Using a hole puncher make some holes in the velum you cut out

6. Attach the velum to the top of your tube (tape is good)

7. Secure the tube to the box on top over the BlinkM