Craig Gibson
Published

Halloween Pumpkin Eyes

Simple project that flashes LED eyes in your Halloween pumpkin. Non-blocking so they eyes can flash out of synch.

BeginnerFull instructions provided1 hour378

Things used in this project

Hardware components

Resistor 220 ohm
Resistor 220 ohm
×4
5 mm LED: Red
5 mm LED: Red
×2
5 mm LED: Green
5 mm LED: Green
Used blue, but same thing
×2
Jumper wires (generic)
Jumper wires (generic)
×1
Arduino UNO
Arduino UNO
×1

Software apps and online services

Arduino IDE
Arduino IDE

Story

Read more

Code

Pumpkin Eyes using OOP

Arduino
// different State Types for the eyes
#define STATE_BLINK 0
#define STATE_WINK 1

// the maximum number of states (arbitrary)
#define MAX_STATES 5

/*
 * PumpkinEyes Class
 * Need 2 LED's, one for each eye
 */
class PumpkinEyes {
  private:
    int pinRight; // right eye led pin
    int pinLeft;  // left eye led pin
    // number of milliseconds until the next change
    unsigned long nextChangeTime = 0;
    
    int numStates = 0;    // the total number of states
    int currentState = 0; // what state are we in
    int counterState = 0; // number of times in the current state

    bool winkEye = false; // used to alternate eyes when winking

    // structure for state variables
    typedef struct {
      int stateType;
      unsigned long ledOn=0;
      unsigned long ledOff=0;
      int maxTimes=0;
    } eye_State;
    eye_State arrayStates[5];
    
  public:
    PumpkinEyes(int pinRightEye, int pinLeftEye) {
      this->pinRight = pinRightEye;
      this->pinLeft = pinLeftEye;
      pinMode(pinRight, OUTPUT);
      pinMode(pinLeft, OUTPUT);
      digitalWrite(pinRight, LOW);
      digitalWrite(pinLeft, LOW);
    }

    // Use only in Setup
    // set a blink state
    setupBlink(unsigned long timeOn, unsigned long timeOff, int numBlinks) {
      if (numStates < MAX_STATES) {
        arrayStates[numStates].stateType = STATE_BLINK;
        arrayStates[numStates].ledOn = timeOn;
        arrayStates[numStates].ledOff = timeOff;
        arrayStates[numStates].maxTimes = numBlinks;
        numStates++;
      }
    }

    // Use only in Setup
    // set a wink state
    setupWink(unsigned long timeOn, unsigned long timeOff, int numWinks) {
      if (numStates < MAX_STATES) {
        arrayStates[numStates].stateType = STATE_WINK;
        arrayStates[numStates].ledOn = timeOn;
        arrayStates[numStates].ledOff = timeOff;
        arrayStates[numStates].maxTimes = numWinks;
        numStates++;
      }
    }

    // Use in Loop
    // controls the led's based on their state
    run() {
      unsigned long currentTime = millis();
      if(currentTime >= nextChangeTime) {
        // check if we've done the maxTime of blinks/winks in the current state
        if (counterState < (arrayStates[currentState].maxTimes*2)) {
          
          if (counterState % 2) { // lights are on, so turn them off
            if (arrayStates[currentState].stateType == STATE_WINK) {
              if (winkEye) {
                digitalWrite(pinRight, LOW);
              } else {
                digitalWrite(pinLeft, LOW);
              }
              winkEye = !winkEye;
            } else {  // we're in STATE_BLINK
              digitalWrite(pinRight, LOW);
              digitalWrite(pinLeft, LOW);
            }
            nextChangeTime = currentTime + arrayStates[currentState].ledOff;
          } else { // eyes are off, so turn them on
            digitalWrite(pinRight, HIGH);
            digitalWrite(pinLeft, HIGH);
            nextChangeTime = currentTime + arrayStates[currentState].ledOn;
          }
          
          counterState++;
        } else {  // we've done the correct iteration of blinks/winks
          counterState = 0;
          currentState++;
        }

        // if we've reached the last state, start again
        if (currentState == numStates) {
          currentState = 0;
        }
      }   // end millisecond comparison
    }     // end run()
};


/*
 * Run the code
 */
 
// initialize each object
PumpkinEyes redEyes(4, 6);
PumpkinEyes blueEyes(8, 10);

// Setup code
void setup() {
  // Setup the states for each set of eyes
  redEyes.setupBlink(1800, 600, 3);
  redEyes.setupBlink(125, 60, 20);
  redEyes.setupWink(1000, 400, 4);

  blueEyes.setupBlink(1500, 400, 2);
  blueEyes.setupWink(800, 500, 3);
}

void loop() {
  // Make the objects do their stuff
  redEyes.run();
  blueEyes.run();
}

Pumpkin Eyes using SimpleTimer.h Library

Arduino
/* Halloween Pumpkin Eyes
 * Board: Arduino Uno
 * Parts: 4 LED's (two sets of eyes)
 *        4 220 ohm resistors
 *        Bunch of connector wires
 */

#include <SimpleTimer.h>

// create a timer object
SimpleTimer myTimer;

// Arduino Pins for each eye
const int eyesRed[] = {4, 6};
const int eyesBlue[] = {8, 10};

// States for the eyes
const int sBlinkSlow = 0;
const int sBlinkFast = 1;
const int sWink = 2;

// Number of blinks/winks
const int maxSlowBlinks = 2;
const int maxFastBlinks = 15;
const int maxWinks = 3;

// State variable for each set of eyes
int stateRed = sBlinkSlow;
int stateBlue = sBlinkFast;

// Count the number of times in a state
int countRed = 0;
int countBlue = 0;

// bool to alternate eyes when winking
bool winkRed = true;
bool winkBlue = true;

/**************************************************************
/* SETUP - run once initialization code
/*************************************************************/
void setup() {
  pinMode(eyesRed[0], OUTPUT);
  pinMode(eyesRed[1], OUTPUT);
  pinMode(eyesBlue[0], OUTPUT);
  pinMode(eyesBlue[1], OUTPUT);
  // turn off all the LED's
  digitalWrite(eyesRed[0], LOW);
  digitalWrite(eyesRed[1], LOW);
  digitalWrite(eyesBlue[0], LOW);
  digitalWrite(eyesBlue[1], LOW);

  // set timers for each set of eyes
  myTimer.setTimeout(100, CheckStateRed);
  myTimer.setTimeout(125, CheckStateBlue);
}

/**************************************************************
/* LOOP - Just used to run the timer
/*************************************************************/
void loop() {
  myTimer.run();
}


/**************************************************************
/* RED EYES
 *  Do actions based on the current state
 *  Count the number of times in each state,
 *  and compare to the max times in the state x2
 *  (each blink has 2 counts, 1 for ON and 1 for OFF)
 */
/*************************************************************/
void CheckStateRed() {
  // Check the current state
  switch(stateRed) {
    case sBlinkSlow:
      // check # times in the state
      if (countRed < (maxSlowBlinks*2)) {
        ToggleEyes(eyesRed);
        if (countRed % 2) { // odd means light was on, so turn it off
          myTimer.setTimeout(600, CheckStateRed);
        } else { // even means light was off, so turn it on
          myTimer.setTimeout(2000, CheckStateRed);
        }
        countRed++;
        break;
      } else {
        countRed = 0;
        stateRed++;
      }
    case sBlinkFast:
      if (countRed < (maxFastBlinks*2)) {
        ToggleEyes(eyesRed);
        if (countRed % 2) { // odd means light was on, time OFF
          myTimer.setTimeout(60, CheckStateRed);
        } else { // even means light was off, time ON
          myTimer.setTimeout(125, CheckStateRed);
        }
        countRed++;
        break;
      } else {
        countRed = 0;
        stateRed++;
        ToggleEyes(eyesRed);;
      }
    case sWink:
      if (countRed < (maxWinks*2)) {
        if (countRed % 2) { // odd means light was on, time OFF
          WinkRed();
          myTimer.setTimeout(400, CheckStateRed);
        } else { // even means light was off, time ON
          digitalWrite(eyesRed[0], HIGH);
          digitalWrite(eyesRed[1], HIGH);
          myTimer.setTimeout(1000, CheckStateRed);
        }
        countRed++;
        break;
      } else {
        countRed = 0;
        stateRed = 0;
        digitalWrite(eyesRed[0], LOW);
        digitalWrite(eyesRed[1], LOW);
        myTimer.setTimeout(10, CheckStateRed);
      }
      break;
  }
}

void WinkRed() {
  if (winkRed) {
    digitalWrite(eyesRed[0], LOW);
  } else {
    digitalWrite(eyesRed[1], LOW); 
  }
  winkRed = !winkRed;
}

/**************************************************************
/* BLUE EYES
/*************************************************************/
void CheckStateBlue() {
  switch(stateBlue) {
    case sBlinkSlow:
      if (countBlue < (maxSlowBlinks*2)) {
        ToggleEyes(eyesBlue);
        if (countBlue % 2) { // odd means light was on, so turn it off
          myTimer.setTimeout(300, CheckStateBlue);
        } else { // even means light was off, so turn it on
          myTimer.setTimeout(1500, CheckStateBlue);
        }
        countBlue++;
        break;
      } else {
        countBlue = 0;
        stateBlue++;
      }
    case sBlinkFast:
      if (countBlue < (maxFastBlinks*2)) {
        ToggleEyes(eyesBlue);
        if (countBlue % 2) { // odd means light was on, time OFF
          myTimer.setTimeout(50, CheckStateBlue);
        } else { // even means light was off, time ON
          myTimer.setTimeout(100, CheckStateBlue);
        }
        countBlue++;
        break;
      } else {
        countBlue = 0;
        stateBlue++;
        ToggleEyes(eyesBlue);
      }
    case sWink:
      if (countBlue < (maxWinks*2)) {
        if (countBlue % 2) { // odd means light was on, time OFF
          WinkBlue();
          myTimer.setTimeout(500, CheckStateBlue);
        } else { // even means light was off, time ON
          digitalWrite(eyesBlue[0], HIGH);
          digitalWrite(eyesBlue[1], HIGH);
          myTimer.setTimeout(1000, CheckStateBlue);
        }
        countBlue++;
        break;
      } else {
        countBlue = 0;
        stateBlue = 0;
        digitalWrite(eyesBlue[0], LOW);
        digitalWrite(eyesBlue[1], LOW);
        myTimer.setTimeout(10, CheckStateBlue);
      }
      break;
  }
}

void WinkBlue() {
  if (winkBlue) {
    digitalWrite(eyesBlue[0], LOW);
  } else {
    digitalWrite(eyesBlue[1], LOW); 
  }
  winkBlue = !winkBlue;
}


/**************************************************************
/* General for both eyes
/*************************************************************/
void ToggleEyes(int eyes[]) {
  digitalWrite(eyes[0], !digitalRead(eyes[0]));
  digitalWrite(eyes[1], !digitalRead(eyes[1]));
}

Credits

Craig Gibson
2 projects • 1 follower
Contact

Comments

Please log in or sign up to comment.