/ / Introduction
This assignment began as a challenge to use Physical Computing to solve a problem at school. The initial problem selected was to deal with students entering school in the morning. Rather than typing a password or swiping a card, we decided that students should be able to walk by a reader that records their id from a tag on their bag.
From the initial proposal, we decided to use the RFID reader in a more interactive way. The ID tags could be associated with colors and person could mix colors by using two cards. A RGB LED would reflect the colors that were chosen. In addition to creating a RFID controlled lamp, A randomly generated color poem that matched the selected color would be tweeted. This way one person could enjoy the lamp locally and other people could enjoy the selection remotely.
/ / Introduction
We started with 3 different readers
After distributing the readers, we first looked for help at the Arduino Playground:
Tagging / Labeling
- RFID
- GumboLabs write-up on how to get the best out of your Parallax RFID reader and how to account for noise. Using the Parallax reader and accounting for noise.
- Code for using the Parallax RFID reader with Arudino. Based on the Wiring tutorial.
- Innovations ID-12 RFID Reader (from sparkfun)
- Innovations ID-12 RFID Reader using software serial and detecting removed RFID tags
Stronglink HF RFID Module SL018
Unit Price: $18.00
From http://www.stronglink.cn/english/reader.htm

The Stronglink HF RFID Module SL018 is developed based on the China Fudan 13.56MHz transponder IC. The SL018 is an inexpensive Mifare reader/writer. The SL018 can support all the functions of Mifare 1K, Mifare 4K and Ultralight. It does auto Real-time detecting tag which moves into or out of detective range and reports through one output pin's logic level. In addition, it integrates all necessary components and antenna in one PCB.
FEATURES
- Frequency 13.56MHz
- Protocol ISO14443A
- Tag supported Ultralight, Mifare Mini, Mifare 1k,
- Mifare 4k, FM11RF08
- Interface I2C
- Supply voltage 4.4 - 7.0VDC
- Unit Price (USD) 1 - 9 $18.00
User Manual
When testing this module out, we started with this website http://rfid.marcboon.com/ and found that the SL018 comes with a library for Arduino which made using this reader the easiest of the three.
Here is the simple example code which allowed us to read the tags:
/**
* @title: StrongLink SL018/SL030 RFID reader demo
* @author: marc@marcboon.com
* @see: http://www.stronglink.cn/english/sl018.htm
* @see: http://www.stronglink.cn/english/sl030.htm
*
* Arduino to SL018/SL030 wiring:
* A4/SDA 2 3
* A5/SCL 3 4
* 5V 4 -
* GND 5 6
* 3V3 - 1
*/
#include <Wire.h>
#include <SL018.h>
SL018 rfid;
void setup()
{
Wire.begin();
Serial.begin(19200);
// prompt for tag
Serial.println("Show me your tag");
}
void loop()
{
// start seek mode
rfid.seekTag();
// wait until tag detected
while(!rfid.available());
// print tag id
Serial.println(rfid.getTagString());
}Seeed Studio 125Khz RFID module - Wiegand
Model: RFR102A1M
$13.50

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.
FEATURES
- Support external antenna
- Maximum effective distance up to 150mm
- Less than 100ms decoding time
- Wiegand interface
- Support EM4100 compatible read only or read/write tags
- Built-in external bi-color LED and buzzer driver
- Small outline design
Datasheet
Working Code that reads in tags
/* 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 recieved
* 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;
}
}
This reader was difficult to use at first as we did not know if it used the TTL or Wiegand interface. After using code for the TTL interface and continually getting 254 or FE in the Serial Monitor, we tried using code for the and we were finally able to get consistent results.
Wiegand
Wiegand cardWiegand card technology is a patented technology using embedded ferromagnetic wires strategically positioned to create a unique pattern that generates the identification number. Like magnetic stripe or bar code, this card must be swiped through a reader to be read. Unlike those other technologies the identification media is embedded in the card and not susceptible to wear. This technology once gained popularity because of the difficulty in duplicating the technology creating a high perception of security. This technology is being replaced by proximity cards because of the limited source of supply, the relatively better tamper resistance of proximity readers, and the convenience of the touch-less functionality in proximity readers.
Proximity card
The Wiegand effect was used in early access cards. This method was abandoned in favor of other technologies. Card readers are still referred to as "Wiegand output readers" but no longer use the Wiegand effect. The new technologies retained the Wiegand upstream data so that the new readers were compatible with old systems. A Proximity reader radiates a 1" to 20" electrical field around itself. Cards use a simple LC circuit. When a card is presented to the reader, the reader's electrical field excites a coil in the card. The coil charges a capacitor and in turn powers an integrated circuit. The integrated circuit outputs the card number to the coil which transmits it to the reader.
A common proximity format is 26 bit Wiegand. This format uses a facility code, sometimes also called a site code. The facility code is a unique number common to all of the cards in a particular set. The idea is that an organization will have their own facility code and a set of numbered cards incrementing from 1. Another organization has a different facility code and their card set also increments from 1. Thus different organizations can have card sets with the same card numbers but since the facility codes differ, the cards only work at one organization. This idea worked fine for a while but there is no governing body controlling card numbers, and different manufacturers can supply cards with identical facility codes and identical card numbers to different organizations. Thus there is a problem of duplicate cards. To counteract this problem some manufacturers have created formats beyond 26 bit Wiegand that they control and issue to organizations. In the 26 bit Wiegand format, bit 1 is an even parity bit. Bits 2-9 are a facility code. Bits 10-25 are the card number. Bit 26 is an odd parity bit. Other formats have a similar structure of a leading facility code followed by the card number and including parity bits for error checking.
More Information about Wiegand
Parallax Reader/Writer
$42.99
Item code 32390 from parallax.com

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.
FEATURES
- Low-cost method for reading and writing passive, 125 kHz RFID transponder tags
- Up to 116 bytes of user data storage on a single tag
- Power requirements: +5 VDC
- RoHS compliant
- RFID 54mm x 85mm Rectangle Tag
- RFID 50mm Round Tag
- RFID Disk Tag 25mm
- RFID Blue Eye Key Fob Tag
Working Code that reads in tags
#include <NewSoftSerial.h>
#define rxPin 2
#define txPin 3
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;
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++){
Serial.print(code[i], HEX);
Serial.print(' ');
}
Serial.println("");
}
}
}
}
Our Process
We started with this code found on the Arduino Playground for working with the older read only module:
// Modified by Worapoht K.
#include <SoftwareSerial.h>
int val = 0;
char code[10];
int bytesread = 0;
#define rxPin 8
#define txPin 9
// RFID reader SOUT pin connected to Serial RX pin at 2400bps to pin8
void setup()
{
Serial.begin(2400); // Hardware serial for Monitor 2400bps
pinMode(2,OUTPUT); // Set digital pin 2 as OUTPUT to connect it to the RFID /ENABLE pin
digitalWrite(2, LOW); // Activate the RFID reader
}
void loop(){
SoftwareSerial RFID = SoftwareSerial(rxPin,txPin);
RFID.begin(2400);
if((val = RFID.read()) == 10){ // check for header
bytesread = 0;
while(bytesread<10){ // read 10 digit code
val = RFID.read();
if((val == 10)||(val == 13)){ // if header or stop bytes before the 10 digit reading
break; // stop reading
}
code[bytesread] = val; // add the digit
bytesread++; // ready to read next digit
}
if(bytesread == 10){ // if 10 digit read is complete
Serial.print("TAG code is: "); // possibly a good TAG
Serial.println(code); // print the TAG code
}
bytesread = 0;
delay(500); // wait for a second
}
}
' =========================================================================
'
' File...... rfid_rw_test.bs2
' Purpose... System-level test code for the Parallax RFID Read/Write Module
' Author.... Joe Grand, Grand Idea Studio, Inc. [www.grandideastudio.com]
' E-mail.... support@parallax.com
' Updated... 15 Dec 2009
'
' {$STAMP BS2}
' {$PBASIC 2.5}
'
' =========================================================================
' -----[ Program Description ]---------------------------------------------
'
' This program performs a system-level test of the Parallax RFID Read/
' Write Module by:
'
' 1) Reading tag's unique ID
' 2) Writing and verifying a block of data to the tag
' -----[ I/O Definitions ]-------------------------------------------------
RFID_TX PIN 0 ' Connects to RFID R/W Module SIN
RFID_RX PIN 1 ' Connects to RFID R/W Module SOUT
' -----[ Constants ]-------------------------------------------------------
#SELECT $STAMP
#CASE BS2, BS2E, BS2PE
T9600 CON 84
#CASE BS2SX, BS2P
T9600 CON 240
#ENDSELECT
Baud CON T9600
' RFID R/W Module Commands
' Number of bytes returned in ()
RFID_Read CON $01 ' Read data from specified address, valid locations 1 to 33 (5)
RFID_Write CON $02 ' Write data to specified address, valid locations 3 to 31 (1)
RFID_Login CON $03 ' Login to tag with password (1)
RFID_SetPass CON $04 ' Change tag's password from old to new (1)
RFID_Protect CON $05 ' Enable/disable password protection (1)
RFID_Reset CON $06 ' Reset tag (1)
RFID_ReadLegacy CON $0F ' Read unique ID from EM4102 read-only tag (for backwards compatibility with Parallax RFID Card Reader, #28140 and #28340) (12)
' Memory map/address locations for EM4x50 tag
' Each address holds/returns a 32-bit (4 byte) value
ADDR_Password CON 0 ' Password (not readable)
ADDR_Protect CON 1 ' Protection Word
ADDR_Control CON 2 ' Control Word
' ADDR 3-31 are User EEPROM area
ADDR_Serial CON 32 ' Device Serial Number
ADDR_DeviceID CON 33 ' Device Identification
' Status/error return codes
ERR_OK CON $01 ' No errors
ERR_LIW CON $02 ' Did not find a listen window
ERR_NAK CON $03 ' Received a NAK, could be invalid command
ERR_NAK_OLDPW CON $04 ' Received a NAK sending old password (RFID_SetPass), could be incorrect password
ERR_NAK_NEWPW CON $05 ' Received a NAK sending new password (RFID_SetPass)
ERR_LIW_NEWPW CON $06 ' Did not find a listen window after sending old password (RFID_SetPass)
ERR_PARITY CON $07 ' Parity error when reading data
' -----[ Variables ]-------------------------------------------------------
buf VAR BYTE(12) ' data buffer
idx VAR BYTE ' index
idy VAR BYTE
' -----[ EEPROM Data ]-----------------------------------------------------
' -----[ Initialization ]--------------------------------------------------
Initialize:
PAUSE 250 ' let DEBUG open
DEBUG CLS ' clear the screen
DEBUG "Parallax RFID Read/Write Module Test Application", CR,
"------------------------------------------------", CR, CR
' -----[ Program Code ]----------------------------------------------------
Main:
DEBUG "Reading tag's unique serial number..."
Read_Tag:
SEROUT RFID_TX, Baud, ["!RW", RFID_Read, ADDR_Serial] ' Read tag's serial number
SERIN RFID_RX, Baud, [STR buf\5] ' Get status byte and data bytes
IF buf(0) <> ERR_OK THEN Read_Tag ' If we get an error, keep trying until the read is successful
FOR idx = 1 TO 4 ' Print data
DEBUG HEX2 buf(idx)
NEXT
DEBUG CR
DEBUG "Writing and verifying data to tag..."
Write_Tag:
SEROUT RFID_TX, Baud, ["!RW", RFID_Write, 3, $FE, $ED, $BE, $EF] ' Write $FEEDBEEF into address 4 (user EEPROM area)
SERIN RFID_RX, Baud, [buf(0)] ' Wait for status byte
IF buf(0) <> ERR_OK THEN Write_Tag ' If we get an error, keep trying until the write is successful
DEBUG "Success!", CR
DEBUG "End of test.", CR
END
' -----[ End of File ]----------------------------------------------------
And while we got some values, they appeared to be error codes.
By rewriting the program, we could clearly determine that the particular error we were getting was #2, or "could not find listen window."
Here is that code:
#include <NewSoftSerial.h>
#define txpin 3
#define rxpin 2
unsigned long time;
NewSoftSerial RFID=NewSoftSerial(rxpin,txpin);
int val = 0;
int bytesread = 0;
void setup(){
Serial.begin(9600);
RFID.begin(9600);
}
void loop(){
readTag();
}
void readTag(){
bytesread=0;
byte code[5];
RFID.print("!RW"); // preamble to address the module
RFID.print(0x01, BYTE); // hex code for a read request
RFID.println(32, BYTE); // decimal address you want to read, in this case the one for the tag's serial number
if( RFID.available()) {
while(bytesread<5) {
val = RFID.read();
if(val!=0x01){
switch(val){
case 2:
Serial.println("could not find listen window");
break;
case 3:
Serial.println("Received a No Acknowledge (NAK), possible communication error or invalid command/data");
break;
case 4:
Serial.println("Received a No Acknowledge (NAK) sending the current password during the RFID SetPass command, possible incorrect password");
break;
case 5:
Serial.println("Received a No Acknowledge (NAK) sending the new password during the RFID SetPass command");
break;
case 6:
Serial.println("Could not find a Listen Window (LIW) from the tag after setting the new password during the RFID SetPass command");
break;
case 7:
Serial.println("Parity error when reading data from the tag");
break;
}
}else{
Serial.println(' ');
Serial.print(bytesread);
Serial.print("=");
Serial.println(val);
code[bytesread]=val;
bytesread++;
Serial.println(RFID.read());
bytesread = 0;
delay(500);
readTag();
if(bytesread == 5) { // if 5 digit read is complete
Serial.print("TAG code is: "); // possibly a good TAG
for(int i=0;i<5;i++){
Serial.print(code[i], HEX);
Serial.print(' ');
}
Serial.println(' ');
bytesread = 0;
delay(500);
}
}
}
}
}
This led us to look at a second BS2 program found at the RobotShop page, and made us think about the possibility that we needed to use RFID_ReadLegacy:
' =========================================================================
'
' File...... rfid_rw_demo.bs2
' Purpose... Demonstration code for the Parallax RFID Read/Write Module
' Author.... Joe Grand, Grand Idea Studio, Inc. [www.grandideastudio.com]
' E-mail.... support@parallax.com
' Updated... 15 Dec 2009
'
' {$STAMP BS2pe}
' {$PBASIC 2.5}
'
' =========================================================================
' -----[ Program Description ]---------------------------------------------
'
' This program demonstrates the capabilities of the Parallax RFID Read/
' Write Module.
'
' Compatible with EM Microelectronic EM4x50 1kbit R/W 125kHz tags.
' These tags can be used in a number of ways:
' 1) Read-only by reading the tag's unique, non-changing serial number
' 2) Read/write up to 116 bytes of user data (publicly accessible)
' 3) Read/write up to 116 bytes of user data (password protected)
' -----[ I/O Definitions ]-------------------------------------------------
RFID_TX PIN 0 ' Connects to RFID R/W Module SIN
RFID_RX PIN 1 ' Connects to RFID R/W Module SOUT
' -----[ Constants ]-------------------------------------------------------
#SELECT $STAMP
#CASE BS2, BS2E, BS2PE
T9600 CON 84
#CASE BS2SX, BS2P
T9600 CON 240
#ENDSELECT
Baud CON T9600
' RFID R/W Module Commands
' Number of bytes returned in ()
RFID_Read CON $01 ' Read data from specified address, valid locations 1 to 33 (5)
RFID_Write CON $02 ' Write data to specified address, valid locations 3 to 31 (1)
RFID_Login CON $03 ' Login to tag with password (1)
RFID_SetPass CON $04 ' Change tag's password from old to new (1)
RFID_Protect CON $05 ' Enable/disable password protection (1)
RFID_Reset CON $06 ' Reset tag (1)
RFID_ReadLegacy CON $0F ' Read unique ID from EM4102 read-only tag (for backwards compatibility with Parallax RFID Card Reader, #28140 and #28340) (12)
' Memory map/address locations for EM4x50 tag
' Each address holds/returns a 32-bit (4 byte) value
ADDR_Password CON 0 ' Password (not readable)
ADDR_Protect CON 1 ' Protection Word
ADDR_Control CON 2 ' Control Word
' ADDR 3-31 are User EEPROM area
ADDR_Serial CON 32 ' Device Serial Number
ADDR_DeviceID CON 33 ' Device Identification
' Status/error return codes
ERR_OK CON $01 ' No errors
ERR_LIW CON $02 ' Did not find a listen window
ERR_NAK CON $03 ' Received a NAK, could be invalid command
ERR_NAK_OLDPW CON $04 ' Received a NAK sending old password (RFID_SetPass), could be incorrect password
ERR_NAK_NEWPW CON $05 ' Received a NAK sending new password (RFID_SetPass)
ERR_LIW_NEWPW CON $06 ' Did not find a listen window after setting new password (RFID_SetPass)
ERR_PARITY CON $07 ' Parity error when reading data
' -----[ Variables ]-------------------------------------------------------
buf VAR Byte(12) ' data buffer
idx VAR Byte ' index
idy VAR Byte
' -----[ EEPROM Data ]-----------------------------------------------------
' -----[ Initialization ]--------------------------------------------------
Initialize:
PAUSE 250 ' let DEBUG open
DEBUG CLS ' clear the screen
DEBUG "Parallax RFID Read/Write Module Demo Application", CR,
"------------------------------------------------", CR, CR
' -----[ Program Code ]----------------------------------------------------
Main:
' Code blocks can be commented/uncommented/rearranged to
' experiment with the available features and operations of the
' Parallax RFID Read/Write Module
DEBUG "Reading tag's unique serial number..."
Read_Tag:
SEROUT RFID_TX, Baud, ["!RW", RFID_Read, ADDR_Serial] ' Read tag's serial number
SERIN RFID_RX, Baud, [STR buf\5] ' Get status byte and data bytes
IF buf(0) <> ERR_OK THEN Read_Tag ' If we get an error, keep trying until the read is successful
FOR idx = 1 TO 4 ' Print data
DEBUG HEX2 buf(idx)
NEXT
DEBUG CR
DEBUG "Reading Legacy tag's unique serial number..." ' Read unique ID from EM4102 read-only tag
Read_Legacy:
SEROUT RFID_TX, Baud, ["!RW", RFID_ReadLegacy]
SERIN RFID_RX, Baud, [STR buf\12] ' Get header and data
IF buf(0) <> $0A THEN Read_Legacy ' If we don't receive the correct header, keep trying until we do
FOR idx = 1 TO 10 ' Display the data (ignore final \r byte sent by the reader)
DEBUG buf(idx)
NEXT
DEBUG CR
DEBUG "Writing and verifying data to tag..."
Write_Tag:
' SEROUT RFID_TX, Baud, ["!RW", RFID_Write, 3, $FE, $ED, $BE, $EF] ' Write $FEEDBEEF into address 3 (user EEPROM area)
SEROUT RFID_TX, Baud, ["!RW", RFID_Write, 3, $FF, $EE, $BB, $EE]
SERIN RFID_RX, Baud, [buf(0)] ' Wait for status byte
IF buf(0) <> ERR_OK THEN Write_Tag ' If we get an error, keep trying until the write is successful
DEBUG "Done!", CR
DEBUG "Reading tag's entire memory contents:", CR
FOR idy = 1 TO 33
Read_Tag2:
SEROUT RFID_TX, Baud, ["!RW", RFID_Read, idy] ' Read data from address location "idy"
SERIN RFID_RX, Baud, [STR buf\5] ' Get status byte and data bytes
IF buf(0) <> ERR_OK THEN Read_Tag2 ' If we get an error, keep trying until the read is successful
DEBUG DEC2 idy, ": "
FOR idx = 1 TO 4 ' Print data
DEBUG HEX2 buf(idx)
NEXT
DEBUG CR ' Repeat for address locations 1 to 33
NEXT
' Login is only required to take advantage of the password protection features
' e.g., set the tag's password, lock/unlock the tag, or read/write the tag (if tag is locked)
DEBUG "Logging into the tag..."
Login:
SEROUT RFID_TX, Baud, ["!RW", RFID_Login, REP $00\4] ' Login to tag with default password of $00000000
SERIN RFID_RX, Baud, [buf(0)] ' Wait for status byte
IF buf(0) <> ERR_OK THEN Login ' If we get an error, keep trying until login is successful
DEBUG "Done!", CR
DEBUG "Changing tag's password..."
Set_Pass:
SEROUT RFID_TX, Baud, ["!RW", RFID_SetPass, REP $00\4, REP $00\4] ' Change password from old ($00000000) to new ($00000000)
SERIN RFID_RX, Baud, [buf(0)] ' Wait for status byte
IF buf(0) <> ERR_OK THEN Set_Pass ' If we get an error, keep trying until the password change is successful
DEBUG "Done!", CR
DEBUG "Locking tag..."
Lock_Tag:
SEROUT RFID_TX, Baud, ["!RW", RFID_Protect, 1] ' Enable read/write password protection of the entire tag
SERIN RFID_RX, Baud, [buf(0)] ' Wait for status byte
IF buf(0) <> ERR_OK THEN Lock_Tag ' If we get an error, keep trying until the function is successful
DEBUG "Done!", CR
DEBUG "Unlocking tag..."
Unlock_Tag:
SEROUT RFID_TX, Baud, ["!RW", RFID_Protect, 0] ' Disable read/write password protection of the entire tag
SERIN RFID_RX, Baud, [buf(0)] ' Wait for status byte
IF buf(0) <> ERR_OK THEN Unlock_Tag ' If we get an error, keep trying until the function is successful
DEBUG "Done!", CR
DEBUG "Resetting the tag..."
Reset_Tag:
SEROUT RFID_TX, Baud, ["!RW", RFID_Reset] ' Log out and reset the tag (will require a re-login if trying to access a locked tag after this point)
SERIN RFID_RX, Baud, [buf(0)] ' Wait for status byte
IF buf(0) <> ERR_OK THEN Reset_Tag ' If we get an error, keep trying until the function is successful
DEBUG "Done!", CR
DEBUG "------------------------------------------------", CR
PAUSE 1000
GOTO Main ' Do it all over again!
END
' -----[ End of File ]----------------------------------------------------
We are creating a random poem lamp box. When a user moves an RFID card in front of a box, a color will be selected and a randomly generated poem reflecting that color will be twittered. The box will also light up that color.
Our Starting Point
Here is how we are constructing our poetry:
Line 1: a color describing word Line 2 : a noun Line 3: a verb Line 4: a statement Blue Lips Chattering Winter is cold! Red flowers quiver. The dream plays out slowly. Yellow mittens fall. Sometimes it is lonely.
/ / Post messages to Twitter (tweet) from Aruduino with Ethernet Shield!
- Get a token to post a message using OAuth.
http://arduino-tweet.appspot.com
The username is saccpc
The password is 5aintann5
- Run a sample sketch to tweet:
#include <SPI.h> #include <Ethernet.h> #include <Udp.h> #include <EthernetDNS.h> #include <Twitter.h> //change the mac address byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // substitute an address on your own network here byte ip[] = { your ip here (separate numbers by commas) }; Twitter twitter("your token here"); char msg[] = "type your message here"; void setup(){ delay(1000); EthernetDHCP.begin(mac); Serial.begin(9600); void setup(){ Ethernet.begin(mac, ip); Serial.begin(9600); delay(1000); Serial.println("connecting ..."); if (twitter.post(msg)) { int status = twitter.wait(); if (status == 200) { Serial.println("OK."); } else { Serial.print("failed : code "); Serial.println(status); } } else { Serial.println("connection failed."); } } void loop(){ }
The first problem encountered with this code was that after the first tweet, an error code 403 was returned. It turns out that you cannot send the te same tweet over and over.
By adding a random number to the string, we could test the Twitter library:
#include <SPI.h>
#include <Ethernet.h>
#include <Udp.h>
#include <EthernetDNS.h>
#include <Twitter.h>
//change the mac address
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
// substitute an address on your own network here
byte ip[] = { your ip here (separate numbers by commas) };
Twitter twitter("your token here");
void setup(){
String myString="Hello, "+ String(random(0,300));
Serial.println(myString);
char filename[140];
myString.toCharArray(filename, 140);
delay(1000);
Ethernet.begin(mac, ip);
Serial.begin(9600);
Serial.println("connecting ...");
if (twitter.post(filename)) {
// Specify &Serial to output received response to Serial.
// If no output is required, you can just omit the argument, e.g.
// int status = twitter.wait();
int status = twitter.wait(&Serial);
if (status == 200) {
Serial.println("OK.");
} else {
Serial.print("failed : code ");
Serial.println(status);
}
} else {
Serial.println("connection failed.");
setup();
}
}
void loop()
{
}Tinker.it created a TrueRandom library that became helpful for testing the twitter connection.code.google.com/p/tinkerit/wiki/TrueRandom
Here was sample code that worked with a button:
#include <Client.h>
#include <Ethernet.h>
#include <Server.h>
#include <Udp.h>
#include <EthernetDNS.h>
#include <Twitter.h>
#include <SPI.h>
#include <TrueRandom.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
This project continues to evolve online at: wwwmakezine.com/kittytwitty
Twitter Library for Arduino V1.0.1 created by NeoCat
http://www.arduino.cc/playground/Code/TwitterLibrary
String (formerly TextString) Library by Tom Igoe
http://www.arduino.cc/en/Tutorial/TextString
*/
//these are libraries that need to be included for the program to work, see links above
// these constants will not change
const int powerPin = 2; // power LED pin
const int statusPin = 3; // status LED pin
const int pushBtn = 6; // the push button
const int red=8;
const int green=9;
const int blue=10;
int color;
// These are variables that will change
int var; // used to store the status of pin (6)
long randNum1;
long randNum2;
long randNum3;
long randNum4;
String dataString;
// defining the network setting for the Ethernet Shield
byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // this can be made up
byte ip[] = {
192,168,1,12 };
byte gateway[] = {
192,168,1,1 }; // the gateway address of your network
byte subnet[] = {
255, 255, 255, 0 }; // the subnet mask of your network
//to get token: http://arduino-tweet.appspot.com/
Twitter twitter("your_token"); // defines your token
char* poet[]={
"-your first name"};
char* words1[] = {
"your first poem color ","your second poem color ", "your third poem color ", "your fourth poem colorow "};
char* words2[] = {
"your first noun", "your second noun", "your third noun", "your fourth noun"};
char* words3[] = {
" your first verb. "," your second verb. "," your third verb. ", " your fourth verb. " };
char* words4[] = {
"your first profound statement.","your second profound statement.","your third profound statement.","your fourth profound statement."};
void setup(){ // run this code once
pinMode(pushBtn, INPUT);//defining the btn as an input so we can read it
pinMode(powerPin, OUTPUT); // sets the pin as output
pinMode(statusPin, OUTPUT); // sets the pin as output
pinMode(red, OUTPUT); // sets the pin as output
pinMode(green, OUTPUT); // sets the pin as output
pinMode(blue, OUTPUT); // sets the pin as output
digitalWrite(powerPin, HIGH); // sets the power LED on
Serial.begin(9600); // starts serial communications so you can debug easier
Ethernet.begin(mac, ip, gateway, subnet); //begins the Ethernet connection from the stored information
delay(2000); // a 2 second delay to let everything settle down!
// let's tweet when you are up and running
String myString="Up and running! "+String(int(TrueRandom.random(1,1000)));
char testFN[140];
myString.toCharArray(testFN, 140);
Serial.println(myString);
Serial.println("Poem Box is up and running!"); // print, used for debugging
Serial.println(); // print a blank line, used for debugging
Serial.println("Connecting to Twitter..."); // print, used for debugging
digitalWrite(statusPin, HIGH); // sets the status LED off
if (twitter.post(testFN)) { // Twitter that we are up and running
// Specify &Serial to output received response to Serial.
// If no output is required, you can just omit the argument, e.g.
// int status = twitter.wait();
int status = twitter.wait(&Serial);
if (status == 200) { // if Twitter responds 200
Serial.println("Tweet OK!"); // print success
Serial.println(); // print a blank line, used for debugging
}
else {
Serial.print("Tweet failed : code ");
Serial.println(status); // print error code
Serial.println(); // print a blank line, used for debugging
}
}
else {
Serial.println("Connection to Twitter failed.");
}
delay (1000); // delay 1 second
digitalWrite(statusPin, LOW); // sets the status LED off
Serial.println("Waiting for someone to play with me!"); // print, used for debugging
}
void loop(){ // run over and over, never stop
checkState(); // check status of wire sensor
}
void getString(){
//concatenates poem
dataString=words1[int(randNum1)];
dataString=dataString+words1[int(randNum1)];
dataString=dataString+words2[int(randNum2)];
dataString=dataString+words3[int(randNum3)];
dataString=dataString+words4[int(randNum4)];
dataString=dataString+poet[0];
}
void tweet(){ // function tweet, this is called if status = 1
char filename[140];
dataString.toCharArray(filename, 140);
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.print(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
}
Serial.println("30 Second timeout started."); // print, used for debugging
Serial.println(); // print a blank line, used for debugging
delay (30000); // this delay of 30 seconds after a tweet ensures we don't over-tweet (150/per hour)
digitalWrite(statusPin, LOW); // sets the status LED off
Serial.println("Waiting for someone to play with me!"); // print, used for debugging
Serial.println(); // print a blank line, used for debugging
}
void changeColor(){
switch(color){
case 0:
digitalWrite(red,HIGH);
digitalWrite(green,LOW);
digitalWrite(blue,LOW);
break;
case 1:
//complete
break;
case 2:
//complete
break;
case 3:
//complete
break;
default:
digitalWrite(red,LOW);
digitalWrite(green,LOW);
digitalWrite(blue,LOW);
}
}
void checkState(){ // check status of wire function
if (digitalRead(pushBtn)){ // if button is pressed
digitalWrite(statusPin, HIGH); // turn on the status LED
tweet(); // go to the Tweet function to send out a tweet
changeColor();
delay (3000); // wait for 3 seconds
digitalWrite(statusPin, LOW); // turn off the status LED
}
else{
digitalWrite(statusPin, LOW); // turn off the status LED
//generate your random numbers and pick the color
randNum1 = random(4); //generate a random number from 0-4
//complete for other random numbers
color=int(randNum1);
getString();
}
}- To configure the network information in the code, find this section of code and replace the ip, gateway, and subnet values with your own values.
To get these settings, 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.
byte ip[] = { 192, 168, 2, 7 }; // a free IP address on your network byte gateway[] = { 192, 168, 2, 1 }; // the gateway address of your network byte subnet[] = { 255, 255, 255, 0 }; // the subnet mask of your network
-
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
-
Next is the gateway address. On a Mac, this is listed as Router and on a PC, it's listed as Default Gateway. Mine is 192.168.1.1. The subnet mask is generally 255.255.255.0, but yours may be different, and it will also be listed in with your computer's network config information.
- Save the revised code, then upload it to your Arduino.
- 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.
Every time the button is pressed, you'll see a new tweet!
Parallax and Twitter
The first problem encountered was resolved by replacing the Duemilanove Atmega168 with the Arduino Uno.
This code randomly picks a color and a poem. For testing purposes, it uses Serial Monitor:
#include <Wire.h>
#include "BlinkM_funcs.h"
String dataString;
int color;
int btn=2;
int blinkm_addr = 0x09;//default address to blinkM
byte r=0,g=0,b=0;
int count=0;
long pt;
boolean written=true;
long randNum1;
long randNum2;
long randNum3;
long randNum4;
char* poet[]={
"-Lukas"};
char* words1[] = {
"Red\n","Green\n", "Blue\n", "Magenta\n","Cyan\n", "Yellow\n", "White\n"};
char* words2[] = {
"your first noun\n", "your second noun\n", "your third noun\n", "your fourth noun\n"};
char* words3[] = {
"your first verb.\n","your second verb.\n","your third verb.\n", "your fourth verb\n" };
char* words4[] = {
"your first profound statement.","your second profound statement.","your third profound statement.","your fourth profound statement."};
void setup() {
//BlinkM_beginWithPower();
BlinkM_begin();
BlinkM_setRGB(blinkm_addr, 0, 0, 0);//call which fades to desired color
pinMode(btn,INPUT);
Serial.begin(9600);
Serial.println("ready");
}
void loop() {
BlinkM_fadeToRGB(blinkm_addr, r, g, b);//call which fades to desired color
checkState();
}
void getString(){
//concatenates poem
dataString=words1[color];
dataString=dataString+words2[int(randNum2)];
dataString=dataString+words3[int(randNum3)];
dataString=dataString+words4[int(randNum4)];
dataString=dataString+poet[0];
}
void checkState(){ // check status of wire function
if (digitalRead(btn)){ // if button is pressed
written=false;
}
else{
if(!written){
randNum2 = random(4);
randNum3 = random(4);
randNum4 = random(4);
color=random(7);
getString();
changeColor();
tweet();
written=true;
}
}
}
void tweet(){
char filename[140];
dataString.toCharArray(filename, 140);
Serial.println(dataString);
}
void changeColor(){
switch (color){
case 0:
r=255;
g=0;
b=0;
break;
case 1:
r=0;
g=255;
b=0;
break;
case 2:
r=0;
g=0;
b=255;
break;
case 3:
r=255;
g=0;
b=255;
break;
case 4:
r=0;
g=255;
b=255;
break;
case 5:
r=255;
g=255;
b=0;
break;
case 6:
r=255;
g=255;
b=255;
break;
default:
r=0;
g=0;
b=0;
}
}
void displayColor(){
BlinkM_fadeToRGB(blinkm_addr, r, g, b);//call which fades to desired color
}
This code Uses the RFID reader to pick the poem
#include <Wire.h>
#include "BlinkM_funcs.h"
#include <NewSoftSerial.h>
#define rxPin 2
#define txPin 3
unsigned long time;
String dataString;
int color=7;
int lastColor=6;
int btn=6;
#define rxPin 2
#define txPin 3
String red="2F00E69DFF";
String blue="2F00E6C2D0";
int blinkm_addr = 0x09;//default address to blinkM
int r=0,g=0,b=0;
String green="2F00E68BC6";
NewSoftSerial RFID = NewSoftSerial(rxPin,txPin);
int count=0;
long pt;
boolean written=false;
long randNum2;
long randNum3;
long randNum4;
char* poet[]={
"\n-Lukas"};
char* words1[] = {
"Red\n","Green\n", "Blue\n", "Magenta\n","Cyan\n", "Yellow\n", "White\n", "Black"};
char* words2[] = {
"your first noun\n", "your second noun\n", "your third noun\n", "your fourth noun\n"};
char* words3[] = {
"your first verb.\n","your second verb.\n","your third verb.\n", "your fourth verb\n" };
char* words4[] = {
"your first profound statement.","your second profound statement.","your third profound statement.","your fourth profound statement."};
void setup() {
pinMode(btn,INPUT);
BlinkM_begin();
BlinkM_setRGB(blinkm_addr,0, 0,0);//call which fades to desired color
//BlinkM_setFadeSpeed(blinkm_addr, 15);//set up fade par
Serial.begin(9600);
RFID.begin(9600);// RFID reader SOUT pin connected to Serial RX pin at 9600bps
lastColor=6;
Serial.println("ready");
RFID.begin(9600);// RFID reader SOUT pin connected to Serial RX pin at 9600bps
}
void loop() {
// BlinkM_fadeToRGB(blinkm_addr, r,g,b);//call which fades to desired color
//checkState();
sendRead();
readTag();
}
void sendRead() {
RFID.flush();
RFID.print("!RW");
RFID.print(0x0F, BYTE);
}
void getString(){
//concatenates poem
dataString=words1[color];
dataString=dataString+words2[int(randNum2)];
dataString=dataString+words3[int(randNum3)];
dataString=dataString+words4[int(randNum4)];
dataString=dataString+poet[0];
}
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];
}
if(count==0){
written=false;
r=0;
b=0;
g=0;
}
if(msg==red) {
r=255;
}
if(msg==green) {
g=255;
}
if(msg==blue) {
b=255;
}
}
}
}
displayColor();
if(millis()-pt>1500){
count++;
pt=millis();
}
}
else{
count=0;
}
}
void getPoem(){
if( !written){
randNum2 = random(4);
randNum3 = random(4);
randNum4 = random(4);
getString();
tweet();
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{
color=7;
}
if(color!=lastColor){
getPoem();
Serial.print("color=");
Serial.println(color);
Serial.print("last=");
Serial.println(lastColor);
BlinkM_fadeToRGB(blinkm_addr, r,g,b);//call which fades to desired color
}
}
void tweet(){
char filename[140];
dataString.toCharArray(filename, 140);
Serial.println(dataString);
written=true;
}
Seeed Studio and Twitter
Before using Twitter this code was created to test the poem generator:
const int powerPin = 2; // power LED pin
const int statusPin = 3; // status LED pin
const int pushBtn = 6; // the push button
const int red=8;
const int green=9;
const int blue=10;
boolean printed=true;
int color;
// These are variables that will change
int var; // used to store the status of pin (6)
long randNum1;
long randNum2;
long randNum3;
long randNum4;
String dataString;
char* poet[]={
"\n-Louis"};
char* words1[] = {
"Red \n","Green \n", "Blue \n", "Yellow \n","Purple \n","Cyan \n","White \n"};
char* words2[] = {
"lights \n", "arts \n", "gases \n", "circles \n","needles \n","doorknobs \n","sirens \n"};
char* words3[] = {
"sleep. \n","walk. \n","live. \n", "exist. \n", "perceive. \n" , "think. \n","see. \n" };
char* words4[] = {
"Cats are awesome.","Quilts taste like gingerbread.","Metal is highly interactive.","Light is radiation.","Sound is the wind.","Clocks make a good bed.","Glass is opaque."};
void setup(){ // run this code once
pinMode(pushBtn, INPUT);//defining the btn as an input so we can read it
pinMode(powerPin, OUTPUT); // sets the pin as output
pinMode(statusPin, OUTPUT); // sets the pin as output
pinMode(red, OUTPUT); // sets the pin as output
pinMode(green, OUTPUT); // sets the pin as output
pinMode(blue, OUTPUT); // sets the pin as output
digitalWrite(powerPin, HIGH); // sets the power LED on
Serial.begin(9600); // starts serial communications so you can debug easier
// let's tweet when you are up and running
Serial.println("Poem Box is up and running!"); // print, used for debugging
Serial.println(); // print a blank line, used for debugging
Serial.println("");
Serial.println("Waiting for someone to play with me!"); // print, used for debugging
}
void loop(){ // run over and over, never stop
checkState(); // check status of wire sensor
}
void getString(){
//concatenates poem
dataString=words1[int(randNum1)];
dataString=dataString+words2[int(randNum2)];
dataString=dataString+words3[int(randNum3)];
dataString=dataString+words4[int(randNum4)];
dataString=dataString+poet[0];
}
void tweet(){ // function tweet, this is called if status = 1
char filename[500];
dataString.toCharArray(filename, 500);
Serial.println(dataString); // print, used for debugging
Serial.println("Waiting for someone to play with me!"); // print, used for debugging
Serial.println(); // print a blank line, used for debugging
}
void checkState(){ // check status of wire function
if (digitalRead(pushBtn)){ // if button is pressed
printed=false;
}else{
//generate your random numbers and pick the color
if(!printed){
// go to the Tweet function to send out a tweet
randNum1 = random(7); //generate a random number from 1-7
randNum2 = random(7);
randNum3 = random(7);
randNum4 = random(7);
//complete for other random numbers
color=int(randNum1);
getString();
tweet();
printed=true;
}
}
}
Stronglink and Twitter
This code randomly picks a color when a button is pressed, it then generates a poem using that color and controls the BlinkM:
#include <Wire.h>
int adr=0x09;
boolean printed=false;
int button=6;
int r=0,g=0,b=0;
#define red 0
#define green 1
#define blue 2
#define yellow 3
#define magenta 4
#define cyan 5
#define black 6
#define white 7
String poem;
String colors[8] = {
"Red",
"Green",
"Blue",
"Yellow",
"Magenta",
"Cyan",
"Black",
"White" };
String nouns[8] = {
"Gloves",
"Hands",
"Blinkms",
"Flowers",
"Clouds",
"Fans",
"Arduinos",
"RFID readers" };
String verbs[8] = {
"Working",
"Breaking",
"Blowing",
"Tweeting",
"Blinking",
"Running",
"Jumping",
"Squeaking" };
String statements[8] = {
"My program finaly works.",
"This is a statement.",
"I love poems.",
"Friends are lonely.",
"A tree in a golden forest.",
"This is a poem.",
"04E7CED1D90280",
"Wire.beginTransmission(adr);" };
void setup(){
pinMode(button,INPUT);
Serial.begin(19200);
Wire.begin();
goBlink();
Serial.println("ready");
}
void loop(){
goBlink();
if(digitalRead(button)){
poem="";
printed=true;
Serial.println("pressed");
}
else{
if(printed){
int col=random(8);
randomColor(col);
makePoem(col);
printed=false;
}
}
}
void makePoem(int color){
poem=colors[color];
poem+="\n";
poem+=nouns[random(8)];
poem+="\n";
poem+=verbs[random(8)];
poem+="\n";
poem+=statements[random(8)];
poem+="\n";
tweet(poem);
randomColor(color);
}
void randomColor(int color){
switch(color){
case red:
Serial.println("red");
goRed(255);
r=255;
break;
case green:
Serial.println("green");
goGreen(255);
g=255;
break;
case blue:
Serial.println("blue");
b=255;
goBlue(255);
break;
case yellow:
Serial.println("yellow");
r=255;
g=255;
goYellow(255);
break;
case magenta:
Serial.println("magenta");
r=255;
b=255;
goMagenta(255);
break;
case cyan:
Serial.println("cyan");
g=255;
b=255;
goCyan(255);
break;
case white:
Serial.println("white");
r=255;
g=255;
b=255;
goWhite();
break;
case black:
Serial.println("black");
goBlack();
r=0;
g=0;
b=0;
break;
}
}
void tweet(String poem){
char filename[500];
poem.toCharArray(filename, 500);
Serial.println("this is my poem:\n");
Serial.print(poem);
Serial.println(" -Gavin\n");
Serial.println("end of poem\n\n");
}
int poemColor(){
if(r>=127){
if(g>=127){
if(b>=127){
return white;
}
else{
return yellow;
}
}
else{
if(b>=127){
return magenta;
}
else{
return red;
}
}
}
else{
if(g>=127){
if(b>=127){
return cyan;
}
else{
return green;
}
}
else{
if(b>=127){
return blue;
}
else{
return black;
}
}
}
}
void goRed(int amount){
r=amount;
g=0;
b=0;
goBlink();
}
void goGreen(int amount){
r=0;
g=amount;
b=0;
goBlink();
}
void goBlue(int amount){
r=0;
g=0;
b=amount;
goBlink();
}
void goYellow(int amount){
r=amount;
g=amount;
b=0;
goBlink();
}
void goMagenta(int amount){
r=amount;
g=0;
b=amount;
goBlink();
}
void goCyan(int amount){
r=0;
g=amount;
b=amount;
goBlink();
}
void goGrey(int amount){
r=amount;
g=amount;
b=amount;
goBlink();
}
void goBlack(){
r=0;
g=0;
b=0;
goBlink();
}
void goWhite(){
r=255;
g=255;
b=255;
goBlink();
}
void goBlink(){
Wire.beginTransmission(adr);
Wire.send('c');
Wire.send(r);
Wire.send(g);
Wire.send(b);
Wire.endTransmission();
}
BlinkM
Our Process
After receiving the BlinkMs and reading over the datasheet, one member of the class worked on controlling the BlinkM through just the wire library. Another member downloaded the blinkm_funcs.h file and explored using functions from this library.
- Read datasheet
- Connected power and ground to BlinkM and it ran through it's routine
- Connected BlinkM to Arduino d-Analog pin 4 (SDA) and c to analog pin 5 (SCL)
- Tried to send commands:
The code fades the BlinkM to red and then to blue
#include <Wire.h> void setup(){ Wire.begin(); } void loop(){ Wire.beginTransmission(0x09); Wire.send('c'); Wire.send(0xff); Wire.send(0x00); Wire.send(0x00); Wire.send('c'); Wire.send(0x00); Wire.send(0x00); Wire.send(0xff); Wire.endTransmission(); } - Ran BlinkMTester from the examples and played around with sending commands. The BlinkM responded as expected
- BlinkM commands consist of a one byte command code and zero or more arguent bytes.
The command code byte's ASCII value is mnemonically related to the action performed.
The default BlinkM address is 0x09, but can be changed at any time with the Set Address("A") command.
You might want to change the address if you had multiple BlinkMs BlinkM_begin(); BlinkM_beginWithPowerPins(byte pwrpin, byte gndpin); BlinkM_beginWithPower(); BlinkM_sendCmd(byte addr, byte* cmd, int cmdlen); BlinkM_setAddress(byte newaddress); BlinkM_setFadeSpeed(byte addr, byte fadespeed); BlinkM_setTimeAdj(byte addr, byte timeadj); BlinkM_fadeToRGB(byte addr, byte red, byte grn, byte blu); BlinkM_fadeToHSB(byte addr, byte hue, byte saturation, byte brightness); BlinkM_setRGB(byte addr, byte red, byte grn, byte blu); BlinkM_fadeToRandomRGB(byte addr, byte rrnd, byte grnd, byte brnd); BlinkM_fadeToRandomHSB(byte addr, byte hrnd, byte srnd, byte brnd); BlinkM_getRGBColor(byte addr, byte* r, byte* g, byte* b); BlinkM_playScript(byte addr, byte script_id, byte reps, byte pos); BlinkM_stopScript(byte addr); BlinkM_setScriptLengthReps(byte addr, byte script_id, byte len, byte reps); BlinkM_writeScriptLine(byte addr, byte script_id, byte pos, byte dur,byte cmd, byte arg1, byte arg2, byte arg3); BlinkM_writeScript(byte addr, byte script_id,byte len, byte reps, blinkm_script_line* lines);
- Here is code using the library commands:
#include <Wire.h> #include "BlinkM_funcs.h" int blinkm_addr = 0x09;//default address to blinkM byte r,g,b; // init BlinkM funcs void setup(){ BlinkM_beginWithPower(); BlinkM_setFadeSpeed(blinkm_addr, 10);//set up fade param for a smooth fade } void loop(){ for(int i=0;i<=2;i++){ displayColor(i); delay(2000); } } void displayColor(int val){ switch(val){ case 0: r = 250; g = 0; b = 0; break; case 1: r = 255; g = 255; b = 0; break; case 2: r = 0; g = 0; b = 255; break; } BlinkM_fadeToRGB(blinkm_addr, r, g, b);//call which fades to desired color }
Stronglink and BlinkM
This code does not use the blinkM library, but sends commands using Wire.
This first test cycled through colors:
#include "Wire.h"
int adr=0x09;
void setup(){
Wire.begin();
Wire.beginTransmission(adr);
Wire.send('c');
Wire.send(0);
Wire.send(0);
Wire.send(0);
//Wire.send('f');
// Wire.send(10);
Wire.endTransmission();
}
void loop(){
red('c',255);
delay(1000);
green('c',255);
delay(1000);
blue('c',255);
delay(1000);
yellow('c',255);
delay(1000);
magenta('c',255);
delay(1000);
cyan('c',255);
delay(1000);
red('c',127);
delay(1000);
green('c',127);
delay(1000);
blue('c',127);
delay(1000);
yellow('c',127);
delay(1000);
magenta('c',127);
delay(1000);
cyan('c',127);
delay(1000);
}
void red(char type,int amount){
Wire.beginTransmission(adr);
Wire.send(type);
Wire.send(amount);
Wire.send(0);
Wire.send(0);
Wire.endTransmission();
}
void green(char type,int amount){
Wire.beginTransmission(adr);
Wire.send(type);
Wire.send(0);
Wire.send(amount);
Wire.send(0);
Wire.endTransmission();
}
void blue(char type,int amount){
Wire.beginTransmission(adr);
Wire.send(type);
Wire.send(0);
Wire.send(0);
Wire.send(amount);
Wire.endTransmission();
}
void yellow(char type,int amount){
Wire.beginTransmission(adr);
Wire.send(type);
Wire.send(amount);
Wire.send(amount);
Wire.send(0);
Wire.endTransmission();
}
void magenta(char type,int amount){
Wire.beginTransmission(adr);
Wire.send(type);
Wire.send(amount);
Wire.send(0);
Wire.send(amount);
Wire.endTransmission();
}
void cyan(char type,int amount){
Wire.beginTransmission(adr);
Wire.send(type);
Wire.send(0);
Wire.send(amount);
Wire.send(amount);
Wire.endTransmission();
}
**
* @title: StrongLink SL018/SL030 RFID reader demo
* @credit: derived from marc@marcboon.com
* @see: http://www.stronglink.cn/english/sl018.htm
* @see: http://www.stronglink.cn/english/sl030.htm
*
* Arduino to SL018/SL030 wiring:
* A4/SDA 2 3
* A5/SCL 3 4
* 5V 4 -
* GND 5 6
* 3V3 - 1
*/
#include <Wire.h>
#include <SL018.h>
SL018 rfid;
int length=100;
int r=0,g=0,b=0;
String tag[3] = {
"04E66CD1D90280", "04E7CED1D90280", "04E7D1D1D90280"};
String color[3] = {
"red", "green", "blue"};
String mytag;
int adr=0x09;
void setup(){
Serial.begin(19200);
Wire.begin();
black('n');
Serial.println("light set to black");
// prompt for tag
Serial.println("Show me your tag");
}
void loop(){
// start seek mode
rfid.seekTag();
// wait until tag detected
int count=0;
while(!rfid.available()){
if(count>3){
Serial.println("waiting for tag");
go('c');
}
count++;
}
// print tag id
//Serial.println("tag found");
mytag=rfid.getTagString();
for(int i=0;i<3;i++){
if(mytag==tag[i]){
Serial.print(mytag);
Serial.print(" is the ");
Serial.print(color[i]);
Serial.println(" tag.");
if(count<50){
switch(i){
case 0:
r=255;
go('c');
break;
case 1:
g=255;
go('c');
break;
case 2:
b=255;
go('c');
break;
default:
white('c');
}
return;
}
switch(i){
case 0:
red('c',255);
break;
case 1:
green('c',255);
break;
case 2:
blue('c',255);
break;
default:
white('c');
}
return;
}
}
Serial.print(mytag);
Serial.println(" is a new tag");
}
void red(char type,int amount){
r=amount;
g=0;
b=0;
Wire.beginTransmission(adr);
Wire.send(type);
Wire.send(amount);
Wire.send(0);
Wire.send(0);
Wire.endTransmission();
}
void green(char type,int amount){
r=0;
g=amount;
b=0;
Wire.beginTransmission(adr);
Wire.send(type);
Wire.send(0);
Wire.send(amount);
Wire.send(0);
Wire.endTransmission();
}
void blue(char type,int amount){
r=0;
g=0;
b=amount;
Wire.beginTransmission(adr);
Wire.send(type);
Wire.send(0);
Wire.send(0);
Wire.send(amount);
Wire.endTransmission();
}
void yellow(char type,int amount){
r=amount;
g=amount;
b=0;
Wire.beginTransmission(adr);
Wire.send(type);
Wire.send(amount);
Wire.send(amount);
Wire.send(0);
Wire.endTransmission();
}
void magenta(char type,int amount){
r=amount;
g=0;
b=amount;
Wire.beginTransmission(adr);
Wire.send(type);
Wire.send(amount);
Wire.send(0);
Wire.send(amount);
Wire.endTransmission();
}
void cyan(char type,int amount){
r=0;
g=amount;
b=amount;
Wire.beginTransmission(adr);
Wire.send(type);
Wire.send(0);
Wire.send(amount);
Wire.send(amount);
Wire.endTransmission();
}
void grey(char type,int amount){
r=amount;
g=amount;
b=amount;
Wire.beginTransmission(adr);
Wire.send(type);
Wire.send(amount);
Wire.send(amount);
Wire.send(amount);
Wire.endTransmission();
}
void black(char type){
r=0;
g=0;
b=0;
Wire.beginTransmission(adr);
Wire.send(type);
Wire.send(0);
Wire.send(0);
Wire.send(0);
Wire.endTransmission();
}
void white(char type){
r=255;
g=255;
b=255;
Wire.beginTransmission(adr);
Wire.send(type);
Wire.send(255);
Wire.send(255);
Wire.send(255);
Wire.endTransmission();
}
void go(char type){
Wire.beginTransmission(adr);
Wire.send(type);
Wire.send(r);
Wire.send(g);
Wire.send(b);
Wire.endTransmission();
}
/**
* @title: StrongLink SL018/SL030 RFID reader demo
* @author: marc@marcboon.com
* @see: http://www.stronglink.cn/english/sl018.htm
* @see: http://www.stronglink.cn/english/sl030.htm
*
* Arduino to SL018/SL030 wiring:
* A4/SDA 2 3
* A5/SCL 3 4
* 5V 4 -
* GND 5 6
* 3V3 - 1
*/
#include <Wire.h>
#include <SL018.h>
#define red 0
#define green 1
#define blue 2
#define yellow 3
#define magenta 4
#define cyan 5
#define black 6
#define white 7
SL018 rfid;
int length=100;
int r=0,g=0,b=0;
String tag[3] = {
"04E66CD1D90280", "04E7CED1D90280", "04E7D1D1D90280"};
String color[3] = {
"red", "green", "blue"};
String mytag;
String colors[8] = {
"Red",
"Green",
"Blue",
"Yellow",
"Magenta",
"Cyan",
"Black",
"White" };
String nouns[8] = {
"Gloves",
"Hands",
"Blinkms",
"Flowers",
"Clouds",
"Fans",
"Arduinos",
"RFID readers" };
String verbs[8] = {
"Working",
"Breaking",
"Blowing",
"Tweeting",
"Blinking",
"Running",
"Jumping",
"Squeaking" };
String statements[8] = {
"My program finaly works.",
"This is a statement.",
"I love poems.",
"Friends are lonely.",
"A tree in a golden forest.",
"This is a poem.",
"04E7CED1D90280",
"Wire.beginTransmission(adr);" };
int adr=0x09;
void setup(){
Serial.begin(19200);
Wire.begin();
// Wire.beginTransmission(adr);
// Wire.send('c');
// Wire.send(0);
// Wire.send(0);
// Wire.send(0);
// //Wire.send('f');
// // Wire.send(10);
// Wire.endTransmission();
goBlack('n');
Serial.println("light set to black");
// prompt for tag
Serial.println("Show me your tag");
}
void loop()
{
// start seek mode
rfid.seekTag();
// wait until tag detected
int count=0;
while(!rfid.available()){
if(count>3){
if(count%10==0){
Serial.println("waiting for tag");
}
go('c');
}
count++;
}
// print tag id
//Serial.println("tag found");
mytag=rfid.getTagString();
for(int i=0;i<3;i++){
if(mytag==tag[i]){
Serial.print(mytag);
Serial.print(" is the ");
Serial.print(color[i]);
Serial.println(" tag.");
if(count<50){
switch(i){
case 0:
r=255;
go('c');
makePoem(poemColor());
break;
case 1:
g=255;
go('c');
makePoem(poemColor());
break;
case 2:
b=255;
go('c');
makePoem(poemColor());
break;
default:
goWhite('c');
makePoem(poemColor());
}
return;
}
switch(i){
case 0:
goRed('c',255);
makePoem(poemColor());
break;
case 1:
goGreen('c',255);
makePoem(poemColor());
break;
case 2:
goBlue('c',255);
makePoem(poemColor());
break;
default:
goWhite('c');
makePoem(poemColor());
}
return;
}
}
Serial.print(mytag);
Serial.println(" is a new tag");
}
void goRed(char type,int amount){
r=amount;
g=0;
b=0;
go(type);
}
void goGreen(char type,int amount){
r=0;
g=amount;
b=0;
go(type);
}
void goBlue(char type,int amount){
r=0;
g=0;
b=amount;
go(type);
}
void goYellow(char type,int amount){
r=amount;
g=amount;
b=0;
go(type);
}
void goMagenta(char type,int amount){
r=amount;
g=0;
b=amount;
go(type);
}
void goCyan(char type,int amount){
r=0;
g=amount;
b=amount;
go(type);
}
void goGrey(char type,int amount){
r=amount;
g=amount;
b=amount;
go(type);
}
void goBlack(char type){
r=0;
g=0;
b=0;
go(type);
}
void goWhite(char type){
r=255;
g=255;
b=255;
go(type);
}
void go(char type){
Wire.beginTransmission(adr);
Wire.send(type);
Wire.send(r);
Wire.send(g);
Wire.send(b);
Wire.endTransmission();
}
int poemColor(){
if(r>=127){
if(g>=127){
if(b>=127){
return white;
}
else{
return yellow;
}
}
else{
if(b>=127){
return magenta;
}
else{
return red;
}
}
}
else{
if(g>=127){
if(b>=127){
return cyan;
}
else{
return green;
}
}
else{
if(b>=127){
return blue;
}
else{
return black;
}
}
}
}
void makePoem(int color){
String poem;
poem=colors[color];
poem+="\n";
poem+=nouns[random(8)];
poem+="\n";
poem+=verbs[random(8)];
poem+="\n";
poem+=statements[random(8)];
poem+="\n";
tweet(poem);
}
void tweet(String poem){
char filename[500];
poem.toCharArray(filename, 500);
Serial.println("this is my poem:\n");
Serial.print(poem);
Serial.println(" -Gavin\n");
Serial.println("end of poem\n\n");
}
Parallax and BlinkM
The first issue that had to be dealt with was controlling the blinkM while the RFID was not available. During this period, the blinkM would cycle through the colors, rather than display the last color selected. Calling fadeToRGB when RFID was not available fixed this issue:
#include "BlinkM_funcs.h"
#include <NewSoftSerial.h>
#define rxPin 2
#define txPin 3
String red="2F00E69DFF";
String blue="2F00E6C2D0";
int blinkm_addr = 0x09;//default address to blinkM
byte r=0,g=0,b=0;
String green="2F00E68BC6";
NewSoftSerial RFID = NewSoftSerial(rxPin,txPin);
void setup() {
//BlinkM_beginWithPower();
BlinkM_begin();
BlinkM_setRGB(blinkm_addr, 0, 0, 0);//call which fades to desired color
BlinkM_setFadeSpeed(blinkm_addr, 15);//set up fade par
Serial.begin(9600);
RFID.begin(9600);// RFID reader SOUT pin connected to Serial RX pin at 9600bps
}
void loop() {
BlinkM_fadeToRGB(blinkm_addr, r, g, b);//call which fades to desired color
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++;
}
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(msg==red) {
displayColor(0);
}
if(msg==blue) {
displayColor(2);
}
if(msg==green) {
displayColor(1);
}
}
}
}
}
void displayColor(int val){
switch(val){
case 0:
Serial.println("red");
r = 255;
g = 0;
b = 0;
break;
case 1:
//green
r = 0;
g = 255;
b = 0;
break;
case 2:
//blue
r = 0;
g = 0;
b = 255;
break;
//these next colors are place holders for when you will be able to add cards together
case 3:
//yellow
r = 255;
g = 255;
b = 0;
case 4:
//teal
r = 0;
g = 255;
b = 255;
case 5:
//purple
r = 255;
g = 0;
b = 255;
}
}
Seeed and BlinkM
This was the first attempt at controlling lights. This assigned each color a number and then used a switch statement to light the BlinkM. The problem with this code is that it did not account for mixing colors:
/* 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 recieved
* Then a string is sent to Serial
*/
#include <Wire.h>
#include "BlinkM_funcs.h"
volatile long reader1 = 0;
volatile int reader1Count = 0;
#define blue 57337134
#define red 23773468
#define green 23805695
int color;
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);
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;
long dec;
Serial.print(" ");
Serial.print("Reader 1 converted to DEC:");
dec = (reader1& 0xfffffff);
Serial.println(dec);
switch(dec){
case red:
color=1;
displayColor();
break;
case green:
color=2;
displayColor();
break;
case blue:
color=3;
displayColor();
break;
default:
color="black";
displayColor();
Serial.print("new tag");
Serial.print(reader1& 0xfffffff);
}
Serial.println(color);
reader1 = 0;
reader1Count = 0;
}
else{//maybe else if(reader1Count == 0) or something like that
color="black";
displayColor();
}
}//void loop()
void displayColor(){
switch(color){
case 1:
BlinkM_fadeToRGB(addr, 0xff,0x00,0x00);
break;
case 2:
BlinkM_fadeToRGB(addr, 0x00,0xff,0x00);
break;
case 3:
BlinkM_fadeToRGB(addr, 0x00,0x00,0xff);
break;
default:
BlinkM_fadeToRGB(addr, 0x00,0x00,0x00);
}
}
/* 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 recieved
* Then a string is sent to Serial
*/
#include <Wire.h>
#include "BlinkM_funcs.h"
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 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);
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() {
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);
}
Putting it all together
We spent the first weeks investigating the 3 different types of RFID readers. Once the readers could detect the tags we moved on to exploring how to control the BlinkM with and without the reader. Our idea was that the tags represented colors, and by flashing two tags, you should be able to mix colors and then control the BlinkM to display that color. The next step was to generate and tweet a poem in response to a button press. The last step was to replace the button press with the RFID tags.
//Stronglink
.
This lamp was inspired by the paper model of a Twisted Decagonal Prism found at http://www.korthalsaltes.com/
Using strings and the various libraries made it difficult to fit the program on the Uno.
This code does integrate the RFID reader, the blinkm and Twitter, but compromises had to be made, The last line of the poem had to be eliminated and the colors were reduced from 8 to 3:
#include <TrueRandom.h>
#include <SL018.h>
#include <Wire.h>
//---------------- for twitter --------------\\
#include <Ethernet.h>
#include <EthernetDNS.h>
#include <Twitter.h>
#include <SPI.h>
//---------------- for twitter --------------\\
//#define button 6
#define adr 0x09
String poem;
boolean printed=true;
boolean twitterConnected=false;
int r=0,g=0,b=0;
char testFN[70];
//---------------- for twitter --------------
byte mac2[] = {
0xC3, 0x99, 0xCF, 0x30, 0xC6, 0xF3 }; // this can be made up
byte ip[] = {your_ip_here_separated_by_commas };
//to get token: http://arduino-tweet.appspot.com/
Twitter twitter("your_token_here"); // defines your token
//---------------- for twitter --------------
#define redTag "04E66CD1D90280"
#define greenTag "04E7CED1D90280"
#define blueTag "04E7D1D1D90280"
#define colorRed "Red"
#define colorGreen "Green"
#define colorBlue "Blue"
#define noun1 " Gloves"
#define noun2 " Hands"
#define noun3 " Blinkms"
#define noun4 " Flowers"
#define noun5 " Clouds"
#define verb1 " Working."
#define verb2 " Breaking."
#define verb3 " Blowing."
#define verb4 " Tweeting."
#define verb5 " Blinking."
SL018 rfid;
String mytag;
String colors[3] = {
colorRed, colorGreen, colorBlue
};
String nouns[5] = {
noun1,noun2,noun3, noun4, noun5
};
String verbs[5] = {
verb1,verb2,verb3,verb4,verb5
};
void setup(){
Serial.begin(19200);
Ethernet.begin(mac2, ip); //begins the Ethernet connection from the stored information
Serial.println("ready");
//---------------- for twitter --------------
connectToTwitter();
delay (1000); // delay 1 second
Serial.println("ready to go");
//---------------- for twitter --------------
}
void connectToTwitter(){
Serial.println("Poem Box is up and running!"); // print, used for debugging
Serial.println(); // print a blank line, used for debugging
Serial.println("Connecting to Twitter...");
// String poem=String(int(TrueRandom.random(1,1000)));
char testFN1[2]={
int(TrueRandom.random(1,100)) };
if (twitter.post(testFN1)) { // Twitter that we are up and running
// Specify &Serial to output received response to Serial.
// If no output is required, you can just omit the argument, e.g.
// int status = twitter.wait();
int status = twitter.wait();
if (status == 200) {
Serial.println("OK.");
Wire.begin();
twitterConnected=true;
}
else {
Serial.print("failed : code ");
Serial.println(status);
connectToTwitter();
}
}
else {
Serial.println("connection failed.");
connectToTwitter();
}
}
void loop(){
rfid.seekTag();
// wait until tag detected
while(!rfid.available()){
go();
printed=false;
}
// print tag id
//Serial.println("tag found");
mytag=rfid.getTagString();
int pc;
if(mytag==redTag){
r=255;
g=0;
b=0;
pc=0;
}else if(mytag==greenTag){
g=255;
r=0;
b=0;
pc=1;
}else if(mytag==blueTag){
b=255;
r=0;
g=0;
pc=2;
}
makePoem(pc);
go();
}
void makePoem(int color){
if(!printed){
poem=colors[color];
poem+=nouns[random(5)];
poem+=verbs[random(5)];
Serial.println(poem);
tweet(poem);
printed=true;
}
}
void tweet(String poem){
poem.toCharArray(testFN, 70);
Serial.print(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 --------------
}
void go(){
Wire.beginTransmission(adr);
Wire.send('c');
Wire.send(r);
Wire.send(g);
Wire.send(b);
Wire.endTransmission();
}
Using PROGMEM solves the space problem. Here is code for
3 colors:
#include <TrueRandom.h>
#include <SL018.h>
#include <Wire.h>
//---------------- for twitter --------------\\
#include <Ethernet.h>
#include <EthernetDNS.h>
#include <Twitter.h>
#include <SPI.h>
//---------------- for twitter --------------\\
#include <avr/pgmspace.h>
#define adr 0x09
prog_char color_0[] PROGMEM = "Red"; // "String 0" etc are strings to store - change to suit.
prog_char color_1[] PROGMEM = "Green";
prog_char color_2[] PROGMEM = "Blue";
prog_char color_3[] PROGMEM = "Yellow";
prog_char color_4[] PROGMEM = "Magenta";
prog_char color_5[] PROGMEM = "Cyan";
prog_char color_6[] PROGMEM = "White";
prog_char noun_0[] PROGMEM = " Gloves"; // "String 0" etc are strings to store - change to suit.
prog_char noun_1[] PROGMEM = " Hands";
prog_char noun_2[] PROGMEM = " Blinkms";
prog_char noun_3[] PROGMEM = " Flowers";
prog_char noun_4[] PROGMEM = " Clouds";
prog_char verb_0[] PROGMEM = " Working."; // "String 0" etc are strings to store - change to suit.
prog_char verb_1[] PROGMEM = " Breaking.";
prog_char verb_2[] PROGMEM = " Blowing.";
prog_char verb_3[] PROGMEM = " Tweeting.";
prog_char verb_4[] PROGMEM = " Blinking.";
prog_char statement_0[] PROGMEM = " My program finaly works."; // "String 0" etc are strings to store - change to suit.
prog_char statement_1[] PROGMEM = " This is a statement.";
prog_char statement_2[] PROGMEM = " I love poems.";
prog_char statement_3[] PROGMEM = " Friends are lonely.";
prog_char statement_4[] PROGMEM = " A tree in a golden forest.";
prog_char statement_5[] PROGMEM = " This is a poem.";
prog_char statement_6[] PROGMEM = " 04E7CED1D90280.";
prog_char tag_0[] PROGMEM = "04E66CD1D90280";
prog_char tag_1[] PROGMEM ="04E7CED1D90280";
prog_char tag_2[] PROGMEM = "04E7D1D1D90280";
PROGMEM const char *tags_table[] ={
tag_0,tag_1,tag_2
};
PROGMEM const char *color_table[] ={
color_0,color_1,color_2,color_3,color_4,color_5, color_6
};
PROGMEM const char *noun_table[] ={
noun_0,noun_1,noun_2,noun_3,noun_4
};
PROGMEM const char *verb_table[] ={
verb_0,verb_1,verb_2,verb_3,verb_4
};
PROGMEM const char *statement_table[] ={
statement_0,statement_1,statement_2,statement_3,statement_4,statement_5,statement_6
};
char t_buffer[16];
char c_buffer[8];
char n_buffer[16];
char v_buffer[16];
char s_buffer[30];
String poem;
boolean printed=true;
boolean twitterConnected=false;
int r=0,g=0,b=0;
char testFN[70];
//---------------- for twitter --------------
byte mac2[] = {
0xC3, 0x99, 0xCF, 0x30, 0xC6, 0xF3 }; // this can be made up
byte ip[] = {your_ip_here_separated_by_commas };
//to get token: http://arduino-tweet.appspot.com/
Twitter twitter("your_token_here"); // defines your token
token
//---------------- for twitter --------------
SL018 rfid;
String mytag;
void setup(){
Serial.begin(19200);
// pinMode(button,INPUT);
Ethernet.begin(mac2, ip); //begins the Ethernet connection from the stored information
Serial.println("ready");
//---------------- for twitter --------------
connectToTwitter();
delay (1000); // delay 1 second
Serial.println("ready to go");
//---------------- for twitter --------------
}
void connectToTwitter(){
Serial.println("Poem Box is up and running!"); // print, used for debugging
Serial.println(); // print a blank line, used for debugging
Serial.println("Connecting to Twitter...");
// String poem=String(int(TrueRandom.random(1,1000)));
char testFN1[3]={
int(TrueRandom.random(1,1000)) };
if (twitter.post(testFN1)) { // Twitter that we are up and running
// Specify &Serial to output received response to Serial.
// If no output is required, you can just omit the argument, e.g.
// int status = twitter.wait();
int status = twitter.wait();
if (status == 200) {
Serial.println("OK.");
Wire.begin();
twitterConnected=true;
}
else {
Serial.print("failed : code ");
Serial.println(status);
connectToTwitter();
}
}
else {
Serial.println("connection failed.");
connectToTwitter();
}
}
void loop(){
rfid.seekTag();
// wait until tag detected
while(!rfid.available()){
go();
printed=false;
}
// print tag id
//Serial.println("tag found");
mytag=rfid.getTagString();
for(int i=0;i<3;i++){
strcpy_P(t_buffer, (char*)pgm_read_word(&(tags_table[i])));
if(mytag==t_buffer){
switch(i){
case 0:
r=255;
g=0;
b=0;
break;
case 1:
g=255;
r=0;
b=0;
break;
case 2:
b=255;
r=0;
g=0;
break;
default:
r=255;
g=255;
b=255;
}
}
}
makePoem(poemColor());
go();
}
void makePoem(int color){
if(!printed){
strcpy_P(c_buffer, (char*)pgm_read_word(&(color_table[color])));
poem=c_buffer;
strcpy_P(n_buffer, (char*)pgm_read_word(&(noun_table[TrueRandom.random(5)])));
poem+=n_buffer;
strcpy_P(v_buffer, (char*)pgm_read_word(&(verb_table[TrueRandom.random(5)])));
poem+=v_buffer;
strcpy_P(s_buffer, (char*)pgm_read_word(&(statement_table[TrueRandom.random(7)])));
poem+=s_buffer;
Serial.println(poem);
tweet(poem);
printed=true;
}
}
void tweet(String poem){
poem.toCharArray(testFN, 70);
Serial.print(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 --------------
}
int poemColor(){
if(r){
if(g){
if(b){
return 6;
}
else{
return 3;
}
}
else{
if(b){
return 4;
}
else{
return 0;
}
}
}
else{
if(g){
if(b){
return 5;
}
else{
return 1;
}
}
else{
if(b){
return 2;
}
}
}
}
void go(){
Wire.beginTransmission(adr);
Wire.send('c');
Wire.send(r);
Wire.send(g);
Wire.send(b);
Wire.endTransmission();
}

Here is code for all colors:
#include <TrueRandom.h>
#include <SL018.h>
#include <Wire.h>
//---------------- for twitter --------------\\
#include <Ethernet.h>
#include <EthernetDNS.h>
#include <Twitter.h>
#include <SPI.h>
//---------------- for twitter --------------\\
#include <avr/pgmspace.h>
#define adr 0x09
prog_char color_0[] PROGMEM = "Red"; // "String 0" etc are strings to store - change to suit.
prog_char color_1[] PROGMEM = "Green";
prog_char color_2[] PROGMEM = "Blue";
prog_char color_3[] PROGMEM = "Yellow";
prog_char color_4[] PROGMEM = "Magenta";
prog_char color_5[] PROGMEM = "Cyan";
prog_char color_6[] PROGMEM = "White";
prog_char noun_0[] PROGMEM = " Gloves"; // "String 0" etc are strings to store - change to suit.
prog_char noun_1[] PROGMEM = " Hands";
prog_char noun_2[] PROGMEM = " Blinkms";
prog_char noun_3[] PROGMEM = " Flowers";
prog_char noun_4[] PROGMEM = " Clouds";
prog_char verb_0[] PROGMEM = " Working."; // "String 0" etc are strings to store - change to suit.
prog_char verb_1[] PROGMEM = " Breaking.";
prog_char verb_2[] PROGMEM = " Blowing.";
prog_char verb_3[] PROGMEM = " Tweeting.";
prog_char verb_4[] PROGMEM = " Blinking.";
prog_char statement_0[] PROGMEM = " My program finaly works."; // "String 0" etc are strings to store - change to suit.
prog_char statement_1[] PROGMEM = " This is a statement.";
prog_char statement_2[] PROGMEM = " I love poems.";
prog_char statement_3[] PROGMEM = " Friends are lonely.";
prog_char statement_4[] PROGMEM = " A tree in a golden forest.";
prog_char statement_5[] PROGMEM = " This is a poem.";
prog_char statement_6[] PROGMEM = " 04E7CED1D90280.";
prog_char tag_0[] PROGMEM = "04E66CD1D90280";
prog_char tag_1[] PROGMEM ="04E7CED1D90280";
prog_char tag_2[] PROGMEM = "04E7D1D1D90280";
PROGMEM const char *tags_table[] ={
tag_0,tag_1,tag_2
};
PROGMEM const char *color_table[] ={
color_0,color_1,color_2,color_3,color_4,color_5, color_6
};
PROGMEM const char *noun_table[] ={
noun_0,noun_1,noun_2,noun_3,noun_4
};
PROGMEM const char *verb_table[] ={
verb_0,verb_1,verb_2,verb_3,verb_4
};
PROGMEM const char *statement_table[] ={
statement_0,statement_1,statement_2,statement_3,statement_4,statement_5,statement_6
};
char t_buffer[16];
char c_buffer[8];
char n_buffer[16];
char v_buffer[16];
char s_buffer[30];
int count=0;
String poem;
boolean printed=true;
boolean twitterConnected=false;
int r=0,g=0,b=0;
char testFN[70];
//---------------- for twitter --------------
byte mac2[] = {
0xC3, 0x99, 0xCF, 0x30, 0xC6, 0xF3 }; // this can be made up
byte ip[] = {your_ip_here_separated_by_commas };
//to get token: http://arduino-tweet.appspot.com/
Twitter twitter("your_token_here"); // defines your token
token
//---------------- for twitter --------------
SL018 rfid;
String mytag;
void setup(){
Serial.begin(19200);
Ethernet.begin(mac2, ip); //begins the Ethernet connection from the stored information
Serial.println("ready");
//---------------- for twitter --------------
connectToTwitter();
delay (1000); // delay 1 second
Serial.println("ready to go");
//---------------- for twitter --------------
}
void connectToTwitter(){
Serial.println("Poem Box is up and running!"); // print, used for debugging
Serial.println(); // print a blank line, used for debugging
Serial.println("Connecting to Twitter...");
// String poem=String(int(TrueRandom.random(1,1000)));
char testFN1[4]={
int(TrueRandom.random(1000,2000)) };
if (twitter.post(testFN1)) { // Twitter that we are up and running
// Specify &Serial to output received response to Serial.
// If no output is required, you can just omit the argument, e.g.
// int status = twitter.wait();
int status = twitter.wait();
if (status == 200) {
Serial.println("OK.");
Wire.begin();
twitterConnected=true;
}
else {
Serial.print("failed : code ");
Serial.println(status);
connectToTwitter();
}
}
else {
Serial.println("connection failed.");
connectToTwitter();
}
}
void loop(){
rfid.seekTag();
// wait until tag detected
count=0;
while(!rfid.available()){
if(count>0){
go();
printed=false;
}
count++;
}
// print tag id
//Serial.println("tag found");
mytag=rfid.getTagString();
for(int i=0;i<3;i++){
strcpy_P(t_buffer, (char*)pgm_read_word(&(tags_table[i])));
if(mytag==t_buffer){
if(count==0){
switch(i){
case 0:
r=255;
b=0;
g=0;
break;
case 1:
g=255;
b=0;
r=0;
break;
case 2:
b=255;
r=0;
g=0;
break;
}
makePoem(poemColor());
go();
return;
}
else if(count<3){
switch(i){
case 0:
r=255;
break;
case 1:
g=255;
break;
case 2:
b=255;
break;
}
makePoem(poemColor());
go();
return;
}
else{
count==0;
}
}
}
}
void makePoem(int color){
if(!printed){
strcpy_P(c_buffer, (char*)pgm_read_word(&(color_table[color])));
poem=c_buffer;
strcpy_P(n_buffer, (char*)pgm_read_word(&(noun_table[TrueRandom.random(5)])));
poem+=n_buffer;
strcpy_P(v_buffer, (char*)pgm_read_word(&(verb_table[TrueRandom.random(5)])));
poem+=v_buffer;
strcpy_P(s_buffer, (char*)pgm_read_word(&(statement_table[TrueRandom.random(7)])));
poem+=s_buffer;
Serial.println(poem);
tweet(poem);
printed=true;
}
}
void tweet(String poem){
poem.toCharArray(testFN, 70);
Serial.print(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 --------------
}
int poemColor(){
if(r){
if(g){
if(b){
return 6;
}
else{
return 3;
}
}
else{
if(b){
return 4;
}
else{
return 0;
}
}
}
else{
if(g){
if(b){
return 5;
}
else{
return 1;
}
}
else{
if(b){
return 2;
}
}
}
}
void go(){
Wire.beginTransmission(adr);
Wire.send('c');
Wire.send(r);
Wire.send(g);
Wire.send(b);
Wire.endTransmission();
}
Seeed Lamp
This is a project that was inspired by Marc de Vinck's Kitty Twitty Cat Toy. 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."



This is a project that was inspired by Marc de Vinck's Kitty Twitty Cat Toy. 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."



#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>
// 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();
}
Parallax Lamp

- First you need to grab a tube
- Next you need to cut off a length from the end of the tube (I cut a 3in portion)
- Drill some holes on the side of the tube
- Cut out a circle of velum that will fit on top of your tube
- Using a hole puncher make some holes in the velum you cut out
- Attach the velum to the top of your tube (tape is good)
- Secure the tube to the box on top over the BlinkM
#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 --------------
}
Sources:http://www.instructables.com/id/I2C-between-Arduinos/step1/I2C-Basics/