LED Eyes

I was inspired by a great Adafruit tutorial by Phillip Burgess Animating Multiple LED backpacks. He was able to make an animated face with a voice changer for a Halloween costume with amazing results. After seeing his success I was interested in creating my own pair of electronic eyes.

LED_EYES_

The hardware

Using an Arduino Uno R3 and two 8×8 LED kits from Adafruit I was able to get up and running very quickly. The soldering was the easy part. Just make sure you get the matrix board aligned correctly with the driver board before you start.

The circuit itself is dead simple. I have to say I really like working with the I2C serial bus and the Adafruit_8x8matrix object. It makes it so simple that all that is required to connect all components is using a common clock and data line. Then you can send or receive data from each component using a unique address on the same line. By default the 8×8’s come with 0x70 as their address. Using some jumper solder you can increment the address to make them unique but in our case we want both eyes to have the same address which makes it even easier. The only feature we lose in this configuration is winking.

LED_EYES_F.png

The driver

The “matrix8x8” example sketch (included with the Adafruit_LEDBackpack library) is written for a single LED matrix and makes the job very simple. Declare a single Adafruit_8x8matrix object:

Adafruit_8x8matrix matrix = Adafruit_8x8matrix();

Like the tutorial, the eyes are drawn using a series of stored bitmaps. We really only define one set of bitmaps and just copy the single eye as they should always look in the same direction anyway.

Bitmap data must be declared with the PROGMEM directive. This will store the data in the Arduino’s flash memory instead of using the limited RAM space where the actual program code is stored.

static uint8_t PROGMEM
eyes_center_large_bmp[] = { 
    B00111100,
    B01101110,
    B11000111,
    B10000011,
    B11000111,
    B11101111,
    B00111100,
    B01111110
  },

I defined a series of different eye positions as named bitmaps. Each bit corresponds to an associated LED. A 0 and the LED is off, a 1 and the LED is on. Each byte corresponds to an associated LED row. Very simple. To keep things neat we could use a simple function look_eyes to accept a bitmap as an argument along with a delay and draw it to the LED grid using the Adafruit_8x8matrix object.

void static look_eyes(uint8_t *bitmap, int d){
  u8p = bitmap;
  matrix.clear();
  matrix.drawBitmap(0, 0, bitmap, 8, 8, LED_ON);
  matrix.writeDisplay(); 
  delay(d);

}

Using this I then added a wrapper function for each bitmap, or combination of them to make the process a single function call for each eye position I want to support.

void static look_center_large(){
 look_eyes(eyes_center_large_bmp, 1000);
}

To animate blinking we just need to systematically turn each LED row off from the top and bottom at the same time. Then reverse this process so each row is turned back on from the center out to the top and bottom. The delay between each state controls how fast the eyes blink.

eyes_shut_1_bmp[] = {
    B00000000,
    B01111110,
    B11111111,
    B11100111,
    B11100111,
    B11111111,
    B01111110,
    B00000000,
},

eyes_shut_2_bmp[] = {
    B00000000,
    B00000000,
    B11111111,
    B11100111,
    B11100111,
    B11111111,
    B00000000,
    B00000000
},
eyes_shut_3_bmp[] = {
    B00000000,
    B00000000,
    B00000000,
    B11100111,
    B11100111,
    B00000000,
    B00000000,
    B00000000
},

eyes_shut_bmp[] = {
    B00000000,
    B00000000,
    B00000000,
    B00000000,
    B00000000,
    B00000000,
    B00000000,
    B00000000
},

One problem with this current solution is restoring each row on the return blink. The pupil returns to center with each blink because of this. My next challenge will be to come up with a better solution that gets around this problem and restores the pupil to the last position before the blink started. I want to be able to use an analog value to direct the eyes so I can use motion tracking and have the eyes follow you. To do this we need the blinking to work with the pupil in any position and maintain that position throughout the blink.

I have an idea I want to try where the center row is where the pupil is most of the time. If I make a discipline to only move left to right then I can make the pupil a separate variable we can pass around and use in the blink function. Something like this:

#define EYE_BALL_CENTER B11100111 
#define EYE_BALL_LEFT_1 B10011111 
#define EYE_BALL_RIGHT_1 B11110011 



eyes_center_small_bmp[] = { 
    B00111100,
    B01111110,
    B11111111,
    EYE_BALL_CENTER,
    EYE_BALL_CENTER,
    B11111111,
    B01111110,
    B00111100
  },

Stay tuned…

Download Git repo or pull from git@github.com:adestefa/arduino_eyes.git

11 thoughts on “LED Eyes

  1. hi
    I tried to use his project by uploading it on my arduino one
    But I have problems
    when I go check it gives me a number of errors is not go to fruition
    you can have the complete code?
    greetings
    alfred

      • Thank you for giving me the code posted
        but any version of code I try I get errors ;-(
        example eye_bitmaps.ino
        eye_bitmaps: 29: error: ‘yes_shut_1_bmp’ was not declared in this scope
        eye_bitmaps: 29: error: expected primary-expression before ‘]’ token
        eye_bitmaps: 29: error: expected primary-expression before ‘{‘ token
        eye_bitmaps: 29: error: expected `} ‘before’ {‘token
        eye_bitmaps: 29: error: expected ‘,’ or ‘;’ before ‘{‘ token
        eye_bitmaps: 38: error: expected unqualified-id before ‘,’ token
        eye_bitmaps: 39: error: expected constructor, destructor, or type conversion before ‘=’ token
        eye_bitmaps: 48: error: expected unqualified-id before ‘,’ token
        eye_bitmaps: 50: error: expected constructor, destructor, or type conversion before ‘=’ token
        eye_bitmaps: 59: error: expected unqualified-id before ‘,’ token
        eye_bitmaps: 61: error: expected constructor, destructor, or type conversion before ‘=’ token
        eye_bitmaps: 70: error: expected unqualified-id before ‘,’ token
        eye_bitmaps: 72: error: expected constructor, destructor, or type conversion before ‘=’ token
        eye_bitmaps: 81: error: expected unqualified-id before ‘,’ token
        eye_bitmaps: 83: error: expected constructor, destructor, or type conversion before ‘=’ token
        eye_bitmaps: 92: error: expected unqualified-id before ‘,’ token
        eye_bitmaps: 94: error: expected constructor, destructor, or type conversion before ‘=’ token
        eye_bitmaps: 103: error: expected unqualified-id before ‘,’ token
        eye_bitmaps: 105: error: expected constructor, destructor, or type conversion before ‘=’ token
        eye_bitmaps: 114: error: expected unqualified-id before ‘,’ token
        eye_bitmaps: 116: error: expected constructor, destructor, or type conversion before ‘=’ token
        eye_bitmaps: 125: error: expected unqualified-id before ‘,’ token
        eye_bitmaps: 127: error: expected constructor, destructor, or type conversion before ‘=’ token
        eye_bitmaps: 136: error: expected unqualified-id before ‘,’ token
        eye_bitmaps: 141: error: expected constructor, destructor, or type conversion before ‘=’ token
        eye_bitmaps: 150: error: expected unqualified-id before ‘,’ token
        eye_bitmaps: 152: error: expected constructor, destructor, or type conversion before ‘=’ token
        eye_bitmaps: 161: error: expected unqualified-id before ‘,’ token
        eye_bitmaps: 164: error: expected constructor, destructor, or type conversion before ‘=’ token
        eye_bitmaps: 173: error: expected unqualified-id before ‘,’ token
        eye_bitmaps: 175: error: expected constructor, destructor, or type conversion before ‘=’ token

      • Remember, once there is a syntax error in the code, the rest of the code below that point is also broken as the compiler can’t parse it correctly.

        It looks like you are missing an ‘e’ in the variable eyes_shut_1_bmp..

        Your error starts here:

        eye_bitmaps: 29: error: ‘yes_shut_1_bmp’ was not declared in this scope

        So the complier is looking for ‘yes_shut_1_bmp‘, which does not exist.
        it should be eyes_shut_1_bmp.

        Let me know what happens after you fix that error.

  2. in your code eyes_bitmaps.ino
    static uint8_t PROGMEM
    eyes_shut_1_bmp [] = {
    B00111100,
    B01111110,
    B01111110,
    B01100110,
    B01100110,
    B01111110,
    B01111110,
    B00111100
    },

    eyes_shut_2_bmp [] = {
    eyes_shut_1_bmp [] = {<—————-

    — eyes_bitmaps: 29: error: expected primary-expression before ']' token
    eyes_bitmaps: 29: error: expected primary-expression before '{' token
    eyes_bitmaps: 29: error: expected `} 'before' {'token
    eyes_bitmaps: 29: error: expected ',' or ';' before '{' token
    eyes_bitmaps: 38: error: expected unqualified-id before ',' token
    eyes_bitmaps: 39: error: expected constructor, destructor, or type conversion before '=' token
    eyes_bitmaps: 48: error: expected unqualified-id before ',' token
    eyes_bitmaps: 50: error: expected constructor, destructor, or type conversion before '=' token

    also correct the problem persists
    Thank you for the help you're giving me
    greetings
    alfred

      • hi
        occurs at the end of the sketch I get this
        core.a(main.cpp.o): In function `main’:
        C:\Documents and Settings\Administrator\Desktop\arduino-1.0.1\hardware\arduino\cores\arduino/main.cpp:5: undefined reference to `setup’
        C:\Documents and Settings\Administrator\Desktop\arduino-1.0.1\hardware\arduino\cores\arduino/main.cpp:15: undefined reference to `loop’

      • I was finally able to get back to my dev system and reconnect to Arduino to test the code. I replicated all your errors. Turns out I was confused and uploaded an older version of code that I had in backup drive I was using for testing. I just replaced with the correct code base and downloaded to my Arduino to test and can confirm this is working 😉

        You can download directly here:

        https://github.com/adestefa/arduino_eyes/archive/master.zip

        Sorry for wasting some of your time, Feel free to ask other Arduino related issues you may be having.

        I will add more API functions with different eye positions and better blinking. Feel free to add your ideas as well, I would be interested in what you add. I was thinking adding sonar to follow user or react to distance.

        Cheers!

  3. I thank you for the availability that you’re giving me … But the problem persists, the code is identical to the one you previously shared.
    I tried to close the uninstall program, but the problem persists.
    It would be nice in a future not too close to your eyes through its sensors follow the person in front of them.

    • I am sorry you are still having a problem. The new code provided has many changes including new comments so I am thinking something is mixed up. if you feel it is exact then you have the wrong copy.

      The best solution is to delete the old files from your system, then download the provided zip again

      https://github.com/adestefa/arduino_eyes/archive/master.zip

      I just downloaded and tested again and working here so something simple we are missing on your side. eyes_api.ino has many new comments, this is a good way to tell if you have the right version

      • I tried it on two computers with different systems (mac / windows) .. but the problem is not cambia.Ho also deleted the previous file and inserted the code.
        ———>eyes_bitmaps.ino
        core.a(main.cpp.o): In function `main’:
        C:\Documents and Settings\Administrator\Desktop\arduino-1.0.1\hardware\arduino\cores\arduino/main.cpp:5: undefined reference to `setup’
        C:\Documents and Settings\Administrator\Desktop\arduino-1.0.1\hardware\arduino\cores\arduino/main.cpp:15: undefined reference to `loop’
        ———>eyes.ino
        Eyes.cpp: In function ‘void loop()’:
        Eyes:28: error: ‘look_center_small’ was not declared in this scope
        Eyes:29: error: ‘look_center_right’ was not declared in this scope
        Eyes:30: error: ‘look_center_left’ was not declared in this scope
        ——>eyes_api.ino
        eyes_api.cpp: In function ‘void look_eyes(uint8_t*, int)’:
        eyes_api:32: error: ‘matrix’ was not declared in this scope
        eyes_api:33: error: ‘LED_ON’ was not declared in this scope
        eyes_api.cpp: In function ‘void blink_eyes(uint8_t*)’:
        eyes_api:41: error: ‘eyes_shut_1_bmp’ was not declared in this scope
        eyes_api:42: error: ‘eyes_shut_2_bmp’ was not declared in this scope
        eyes_api:43: error: ‘eyes_shut_3_bmp’ was not declared in this scope
        eyes_api:44: error: ‘eyes_shut_bmp’ was not declared in this scope
        eyes_api.cpp: In function ‘void look_center_small()’:
        eyes_api:52: error: ‘eyes_center_small_bmp’ was not declared in this scope
        eyes_api.cpp: In function ‘void look_center_right()’:
        eyes_api:58: error: ‘eyes_center_right_bmp’ was not declared in this scope
        eyes_api.cpp: In function ‘void look_center_right_max()’:
        eyes_api:63: error: ‘eyes_center_right_max_bmp’ was not declared in this scope
        eyes_api.cpp: In function ‘void look_center_left()’:
        eyes_api:68: error: ‘eyes_center_left_bmp’ was not declared in this scope
        eyes_api.cpp: In function ‘void look_center_left_ma()’:
        eyes_api:74: error: ‘eyes_center_left_max_bmp’ was not declared in this scope
        eyes_api.cpp: In function ‘void look_center_large()’:
        eyes_api:78: error: ‘eyes_center_large_bmp’ was not declared in this scope
        eyes_api.cpp: In function ‘void square()’:
        eyes_api:86: error: ‘matrix’ was not declared in this scope
        eyes_api:86: error: ‘LED_ON’ was not declared in this scope

Leave a comment