We share Valentine's at my office for team building. Everyone decorates a bag or box to collect the Valentines. Mine was a bit over the top. Shows blue eyes at baseline. Uses IR LED and sensor (http://www.radioshack.com/product/index.jsp?productId=2049723) to determine when a card is put through the slot. When that occurs the motor comes on and the card is pulled into the slot by the wheels.

Step 1: Red Eyes

Eyes turn red when card is inserted into slot and motor turns on. The LCD display increments the count of valentines received. 

The bag is the one given to each employee to decorate. I used an Android robot toy from Google. The head comes off. I drilled out the eyes and inserted tri-color LEDs from Radio Shack (http://www.radioshack.com/product/index.jsp?productId=3020765). 

There is a ribbon cable  with  going through a hole in the bag and a hole in the lid to connect to the prototype board connected to the Arduino (see next step). The cable as made using a ribbon cable (https://www.adafruit.com/products/793), and then the LEDs soldered in after stripping one end of the ribbon cables and attaching bare female connectors (http://www.pololu.com/catalog/product/1930), with some shrink tubing used to keep the wires from shorting.

Code is below:

Motor shield

Function pins per Ch. A pins per Ch. B
Direction                D12             D13
PWM                       D3               D11
Brake                      D9               D8
Current Sensing   A0               A1

lcd code from http://www.arduino.cc/playground/Learning/SparkFunSerLCD
LCD is 20x4

for Leonardo need to use Serial1 class

const int IRthreshold = 180;
const int IRPin = 3;    // Read IR value on analog 3
const int SignalPin = A2; // send signal to sound Arduino
const int RedPin = A4;
const int BluePin = A5;
boolean cardsensed = false;
boolean LEDflag = false;
// the following variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long timestamp = 0;  // used to keep track of how long IR sensor blocked
const long MotorDelay = 500;    // keep motor going for half a second after IR sensor clears
const long LEDdelay = 4000;
int val = 0;
int count = 0;

void setup()
  //Setup Channel A
  pinMode(12, OUTPUT); //Initiates Motor Channel A pin
  pinMode(9, OUTPUT); //Initiates Brake Channel A pin
  pinMode(SignalPin, OUTPUT);
  digitalWrite(SignalPin, LOW);
  pinMode(RedPin, OUTPUT);
  pinMode(BluePin, OUTPUT);
  delay(1000); // time to settle in, just in case
  Serial1.print("Happy Valentines Day");
  Serial1.print("        CCE!");
  Serial1.print("I now have:");
  blueLED(); // blue at baseline

void loop()
  val = analogRead(IRPin);
  if (val > IRthreshold)  // path blocked
    cardsensed = true;
    LEDflag = true;
    timestamp = millis();
    //forward @ full speed
    digitalWrite(12, HIGH); //Establishes forward direction of Channel A
    digitalWrite(9, LOW);   //Disengage the Brake for Channel A
    analogWrite(3, 255);   //Spins the motor on Channel A at full speed
    redLED(); // red when it's gotten a card
  if(val < IRthreshold)
      if ((millis()-timestamp) >= MotorDelay)
        cardsensed = false;
        analogWrite(3,0); // turn off motor, but let it coast so no brake
        Serial1.print(" Valentines");
        digitalWrite(SignalPin, HIGH);
        digitalWrite(SignalPin, LOW);
      if ((millis()-timestamp) >= LEDdelay)
        LEDflag = false;
        blueLED(); // back to being sad and blue

///////////////////////////// FUNCTIONS ////////////////////////////////

void selectLineOne(){  //puts the cursor at line 0 char 0.
   Serial1.write(0xFE);   //command flag
   Serial1.write(128);    //position
void selectLineTwo(){  //puts the cursor at line 2 char 0.
   Serial1.write(0xFE);   //command flag
   Serial1.write(192);    //position
void selectLineThree(){  //puts the cursor at line 3 char 0.
   Serial1.write(0xFE);   //command flag
   Serial1.write(148);    //position
void selectLineFour(){  //puts the cursor at line 4 char 0.
   Serial1.write(0xFE);   //command flag
   Serial1.write(212);    //position
void goTo(int position) { //position = line 1: 0-19, line 2: 20-39, etc, 79+ defaults back to 0
if (position<20){ Serial1.write(0xFE);   //command flag
              Serial1.write((position+128));    //position
}else if (position<40){Serial1.write(0xFE);   //command flag
              Serial1.write((position+128+64-20));    //position
}else if (position<60){Serial1.write(0xFE);   //command flag
              Serial1.write((position+128+20-40));    //position
}else if (position<80){Serial1.write(0xFE);   //command flag
              Serial1.write((position+128+84-60));    //position             
} else { goTo(0); }
void clearLCD(){
   Serial1.write(0xFE);   //command flag
   Serial1.write(0x01);   //clear command.
void backlightOn(){  //turns on the backlight
    Serial1.write(0x7C);   //command flag for backlight stuff
    Serial1.write(157);    //light level.
void backlightOff(){  //turns off the backlight
    Serial1.write(0x7C);   //command flag for backlight stuff
    Serial1.write(128);     //light level for off.
void backlight50(){  //sets the backlight at 50% brightness
    Serial1.write(0x7C);   //command flag for backlight stuff
    Serial1.write(143);     //light level for off.
void serCommand(){   //a general function to call the command flag for issuing all other commands  

void blueLED(){
  digitalWrite(BluePin, LOW); // reverse of usual since common
  digitalWrite(RedPin, HIGH); // anode

void redLED(){
  digitalWrite(BluePin, HIGH);
  digitalWrite(RedPin, LOW);

About This Instructable


4 favorites


More by kwoeltje: Arduino Mini breadboard FTDI adapter Robotics Claw Mounting Bracket Valentines Box
Add instructable to: