Things used in this project

Hardware components:
1586 00
Adafruit NeoPixel Ring: WS2812 5050 RGB LED
NeoPixel tape: https://www.adafruit.com/product/1506
×1
11113 01
SparkFun Arduino Pro Mini 328 - 5V/16MHz
×1
bend sensor
×1
Mfr 25frf52 10k sml
Resistor 10k ohm
×3
Resistor 220 ohm
×1
E switch eg1218 image 75px
Slide Switch
1 for power, 2 for mode-switching
×3
09939 01
Rotary potentiometer (generic)
10k ohm
×1
Panasonic eca 1em102
Capacitor 1000 µF
×1
Software apps and online services:
Ide web
Arduino IDE

Schematics

block diagram
Halloween %e3%83%96%e3%83%ac%e3%83%83%e3%83%89%e3%83%9c%e3%83%bc%e3%83%89

Code

eyeBall.inoArduino
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
  #include <avr/power.h>
#endif

#define PIN 6

Adafruit_NeoPixel led = Adafruit_NeoPixel(68, PIN, NEO_GRB + NEO_KHZ800);

int blackNum = 24;
int pupilNum = 12;

int colorMode1[10] = {7,8,15,18,29,38,49,52,59,60};
int colorMode2[2] = {18,49};
int colorMode3[2] = {7,60};
int colorMode4[2] = {8,59};
int brightMode1[15] = {7,8,9,15,18,26,29,38,39,40,49,52,58,59,60};
int brightMode2[3] = {18,26,49};
int brightMode3[3] = {7,40,60};
int brightMode4[3] = {8,39,59};

//Black eye L&R animation
int blackLED[15][24] = {{12,32,35,55,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68},
                        {12,13,31,36,54,55,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68},
                        {11,13,14,30,37,53,54,56,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68},
                        {10,11,14,15,29,38,52,53,56,57,68,68,68,68,68,68,68,68,68,68,68,68,68,68},
                        { 9,10,11,12,15,16,28,33,34,39,51,52,55,56,57,58,68,68,68,68,68,68,68,68},
                        { 0, 8, 9,10,11,12,13,16,17,27,32,35,40,50,51,54,55,56,57,58,59,67,68,68},
                        { 0, 1, 7, 8, 9,10,13,14,17,18,26,31,36,41,49,50,53,54,57,58,59,60,66,67},
                        { 1, 2, 6, 7, 8, 9,14,15,18,19,25,30,37,42,48,49,52,53,58,59,60,61,65,66},
                        { 2, 3, 5, 6, 7, 8,15,16,19,20,24,29,38,43,47,48,51,52,59,60,61,62,64,65},
                        { 3, 4, 5, 6, 7,16,17,20,21,23,28,39,44,46,47,50,51,60,61,62,63,64,68,68},
                        { 4, 5, 6,17,18,21,22,27,40,45,46,49,50,61,62,63,68,68,68,68,68,68,68,68},
                        { 4, 5,18,19,26,41,48,49,62,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68},
                        { 4,19,20,25,42,47,48,63,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68},
                        {20,21,24,43,46,47,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68},
                        {21,23,44,46,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68}};

//pupil L&R animation
int pupilLED[15][12] = {{33,34,68,68,68,68,68,68,68,68,68,68},
                        {32,33,34,35,68,68,68,68,68,68,68,68},
                        {12,31,32,33,34,35,36,55,68,68,68,68},
                        {12,13,30,31,32,33,34,35,36,37,54,55},
                        {13,14,29,30,31,32,35,36,37,38,53,54},
                        {14,15,28,29,30,31,36,37,38,39,52,53},
                        {15,16,27,28,29,30,37,38,39,40,51,52},
                        {16,17,26,27,28,29,38,39,40,41,50,51},
                        {17,18,25,26,27,28,39,40,41,42,49,50},
                        {18,19,24,25,26,27,40,41,42,43,48,49},
                        {19,20,23,24,25,26,41,42,43,44,47,48},
                        {20,21,22,23,24,25,42,43,44,45,46,47},
                        {21,22,23,24,43,44,45,46,68,68,68,68},
                        {22,23,44,45,68,68,68,68,68,68,68,68},
                        {22,45,68,68,68,68,68,68,68,68,68,68}};

//Blink animation
int eyelidMode = 0;
int eyelidNum[8] = {0,4,8,16,24,34,44,56};
int eyelidLED[56] = {64,65,66,67,58,59,60,61,56,57,62,63,49,50,51,52,47,48,53,54,38,39,40,41,46,55,36,37,42,43,26,27,28,29,35,44,24,25,30,31,15,16,17,18,34,45,23,32,13,14,19,20,6,7,8,9};

//Bending sensor for Blink
int sensorPin = A5;
int sensorValue = 0;

/*
opration mode
10: demo
00: color adjustment
11: brightness adjustment (0-127)
01: normal
*/
uint32_t color;
int brightness = 40;
int modePin[2] = {11, 12};
int modeVal = 3;

//10kohm volume for adjustment and L&R animation
int pinVR = A4;
int valVR = 1;
int valVRMap = 0;

int waitState = 0;
int demoCnt = 0;


void setup() {
  // This is for Trinket 5V 16MHz, you can remove these three lines if you are not using a Trinket
  #if defined (__AVR_ATtiny85__)
    if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
  #endif
  // End of trinket special code

  Serial.begin(115200);

  pinMode(modePin[0], INPUT_PULLUP);
  pinMode(modePin[1], INPUT_PULLUP);

  led.begin();
  led.setBrightness(brightness); // Initial Brightness 40
  led.show(); // Initialize all pixels to 'off'
  color = led.Color(0, 177, 55); // Initial pupil color
}

void loop() {
  modeVal = modeSel();

  //demo mode
  if (modeVal == 2){
    waitState = 0;
    led.clear();
    led.show();
    
    switch (demoCnt) {
      case 0:
        colorWipe(led.Color(127, 0, 0), 50); // Red
        break;
      case 1:
        colorWipe(led.Color(0, 127, 0), 50); // Green
        break;
      case 2:
        colorWipe(led.Color(0, 0, 127), 50); // Blue
        break;
      case 3:
        theaterChase(led.Color(127, 127, 127), 50); // White
        break;
      case 4:
        theaterChase(led.Color(127, 0, 0), 50); // Red
        break;
      case 5:
        theaterChase(led.Color(0, 0, 127), 50); // Blue
        break;
      case 6:
        rainbow(20);
        break;
      case 7:
        rainbowCycle(20);
        break;
      case 8:
        theaterChaseRainbow(50);
        break;
      case 9:
        demoCnt = 0;
        break;
      }
  }

  //color adjustment mode
  if (modeVal == 0){
    if (waitState == 0) {
      led.clear();
      led.show();
      for(uint16_t i=0; i<10; i++) {
        led.setPixelColor(colorMode1[i], color);
      }
      led.show();
      if (modeSel() != 0){return;}
      delay(800);
      for(uint16_t i=0; i<2; i++) {
        led.setPixelColor(colorMode2[i], 0);
      }
      led.show();
      if (modeSel() != 0){return;}
      delay(400);
      for(uint16_t i=0; i<2; i++) {
        led.setPixelColor(colorMode3[i], 0);
      }
      led.show();
      if (modeSel() != 0){return;}
      delay(400);
      for(uint16_t i=0; i<2; i++) {
        led.setPixelColor(colorMode4[i], 0);
      }
      led.show();
      if (modeSel() != 0){return;}
      delay(400);
      led.clear();
      led.show();
      if (modeSel() != 0){return;}
      delay(400);
      waitState = 1;
    }
    if (modeSel() != 0){return;}
    valVR = analogRead(pinVR);
    valVRMap = map(valVR, 0, 512, 0, 255);
    if (valVRMap > 255) {
      valVRMap = 255;
    }
    if (valVRMap < 0) {
      valVRMap = 0;
    }
    
    color = Wheel(valVRMap);
    blink(0, 7);
  }

  //brightness adjustment mode
  if (modeVal == 3){
    if (waitState == 0) {
      led.clear();
      led.show();
      for(uint16_t i=0; i<15; i++) {
        led.setPixelColor(brightMode1[i], color);
      }
      led.show();
      if (modeSel() != 3){return;}
      delay(800);
      for(uint16_t i=0; i<3; i++) {
        led.setPixelColor(brightMode2[i], 0);
      }
      led.show();
      if (modeSel() != 3){return;}
      delay(400);
      for(uint16_t i=0; i<3; i++) {
        led.setPixelColor(brightMode3[i], 0);
      }
      led.show();
      if (modeSel() != 3){return;}
      delay(400);
      for(uint16_t i=0; i<3; i++) {
        led.setPixelColor(brightMode4[i], 0);
      }
      led.show();
      if (modeSel() != 3){return;}
      delay(400);
      led.clear();
      led.show();
      if (modeSel() != 3){return;}
      delay(400);
      waitState = 1;
    }
    if (modeSel() != 3){return;}
    valVR = analogRead(pinVR);
    valVRMap = map(valVR, 0, 512, 3, 70);
    if (valVRMap > 70) {
      valVRMap = 70;
    }
    if (valVRMap < 0) {
      valVRMap = 0;
    }
    
    Serial.print(valVR);
    Serial.print("\t");
    Serial.println(valVRMap);
    
    brightness = valVRMap;
    led.setBrightness(brightness);
    blink(0, 7);
  }

  //normal mode
  if (modeVal == 1) {
    waitState = 0;

    sensorValue = analogRead(sensorPin);
    eyelidMode = map(sensorValue, 770, 815, 0, 8);
    if (eyelidMode > 8) {
      eyelidMode = 8;
    }
    if (eyelidMode < 0) {
      eyelidMode = 0;
    }

    valVR = analogRead(pinVR);
    valVRMap = map(valVR, 314, 456, 14, 0);
    if (valVRMap > 14) {
      valVRMap = 14;
    }
    if (valVRMap < 0) {
      valVRMap = 0;
    }
    
    blink(eyelidMode, valVRMap);
  }
}

byte modeSel(){
  int i,j=0;
  //Get the mode switches state
  for (i=0; i<2; i++) {
    j = (j << 1) | digitalRead(modePin[i]);   // read each input pin
  }
  return j; //return address
}

void blink(int eyelid, int LR) {
  if (eyelid != 8){
    //Pewter
    for(uint16_t i=0; i<led.numPixels(); i++) {
      led.setPixelColor(i, led.Color(66, 66, 66));
    }
    
    //Black eye
    for(uint16_t i=0; i<blackNum; i++) {
      led.setPixelColor(blackLED[LR][i], color);
    }
    
    //pupil
    for(uint16_t i=0; i<pupilNum; i++) {
      led.setPixelColor(pupilLED[LR][i], led.Color(0, 0, 66));
    }

    //eyelid
    for(int i=0; i < eyelidNum[eyelid]; i++) {
      led.setPixelColor(eyelidLED[i], 0);
    }
  } else if (eyelid == 8){
    led.clear();
  }
  led.show();
}

// Fill the dots one after the other with a color
void colorWipe(uint32_t c, uint8_t wait) {
  for(uint16_t i=0; i < led.numPixels(); i++) {
    led.setPixelColor(i, c);
    if (modeSel() != 2){return;}
    led.show();
    delay(wait);
  }
  demoCnt++;
}

//Theatre-style crawling lights.
void theaterChase(uint32_t c, uint8_t wait) {
  for (int j=0; j<10; j++) {  //do 10 cycles of chasing
    for (int q=0; q < 3; q++) {
      for (int i=0; i < led.numPixels(); i=i+3) {
        led.setPixelColor(i+q, c);    //turn every third pixel on
        if (modeSel() != 2){return;}
      }
      led.show();
      delay(wait);
      
      for (int i=0; i < led.numPixels(); i=i+3) {
        led.setPixelColor(i+q, 0);        //turn every third pixel off
      }
    }
  }
  demoCnt++;
}

void rainbow(uint8_t wait) {
  uint16_t i, j;

  for(j=0; j<256; j++) {
    for(i=0; i<led.numPixels(); i++) {
      led.setPixelColor(i, Wheel((i+j) & 255));
      if (modeSel() != 2){return;}
    }
    led.show();
    delay(wait);
  }
  demoCnt++;
}

// Slightly different, this makes the rainbow equally distributed throughout
void rainbowCycle(uint8_t wait) {
  uint16_t i, j;

  for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
    for(i=0; i< led.numPixels(); i++) {
      led.setPixelColor(i, Wheel(((i * 256 / led.numPixels()) + j) & 255));
      if (modeSel() != 2){return;}
    }
    led.show();
    delay(wait);
  }
  demoCnt++;
}

//Theatre-style crawling lights with rainbow effect
void theaterChaseRainbow(uint8_t wait) {
  for (int j=0; j < 256; j++) {     // cycle all 256 colors in the wheel
    for (int q=0; q < 3; q++) {
      for (int i=0; i < led.numPixels(); i=i+3) {
        led.setPixelColor(i+q, Wheel( (i+j) % 255));    //turn every third pixel on
        if (modeSel() != 2){return;}
      }
      led.show();
      delay(wait);

      for (int i=0; i < led.numPixels(); i=i+3) {
        led.setPixelColor(i+q, 0);        //turn every third pixel off
      }
    }
  }
  demoCnt++;
}

// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
  WheelPos = 255 - WheelPos;
  if(WheelPos < 85) {
    return led.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  }
  if(WheelPos < 170) {
    WheelPos -= 85;
    return led.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
  WheelPos -= 170;
  return led.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}

Credits

3eytbp i
HomeMadeGarbage
17 projects • 63 followers
We are family. hobby is D.I.Y!!
Contact

Replications

Did you replicate this project? Share it!

I made one

Love this project? Think it could be improved? Tell us what you think!

Give feedback

Comments

Sign up / LoginProjectsPlatformsTopicsContestsLiveAppsBetaBlog