element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet & Tria Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • About Us
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      • Japan
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Vietnam
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Raspberry Pi Projects
  • Products
  • Raspberry Pi
  • Raspberry Pi Projects
  • More
  • Cancel
Raspberry Pi Projects
Blog Pi in the Face Pumpkin:  The Blinking Eye
  • Blog
  • Documents
  • Events
  • Polls
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Raspberry Pi Projects to participate - click to join for free!
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: screamingtiger
  • Date Created: 18 Oct 2015 6:32 PM Date Created
  • Views 1098 views
  • Likes 3 likes
  • Comments 3 comments
  • rpiintermediate
  • pieintheface
  • raspberrypi
  • raspberry_pi_projects
  • pumpkinpi2015
Related
Recommended

Pi in the Face Pumpkin:  The Blinking Eye

screamingtiger
screamingtiger
18 Oct 2015

Previous posts for this project here:

http://www.element14.com/community/community/raspberry-pi/raspberrypi_projects/blog/tags#/?tags=pieintheface

 

Got my kit, and assembled the Pi screen.  I did a few things that will help with development and deployment.  Follow the steps on this page:

http://opentechguides.com/how-to/article/raspberry-pi/5/raspberry-pi-auto-start.html

 

This will allow auto login, as well as automatic starting of the GUI on boot.  This is better for a project that will use the GUI and wont have a keyboard and/or mouse attached.

 

Edit your /boot/boot.config file to have these lines.  The lines probably already exist so just edit them.

framebuffer_width=800
framebuffer_height=480

 

I found this to be a perfect resolution for the Raspberry pi Screen as well as the command line interface.

 

I have been working on the code to animate the eyes.  I have one eye working that blinks at random.  I have it enlarged for development and here is a video demonstration:

 

 

 

You don't have permission to edit metadata of this video.
Edit media
x
image
Upload Preview
image

 

 

 

The blinking is a simple algorithm that ensures it does not blink too fast or blink too slow.  The actual blink animation is a fixed time, but the time between blinks is based on the interval between the last blink.

if(self.blinking == 0):  #determine when to blink again
   display.blit(self.leftEye,(0,0))
   if (time.time() - self.lastBlink >= self.blinkDelay):
    print("Blink!" + "(" + str(self.blinkDelay) + ")")
    self.blinking = 1
    self.blinkIndex = 0
    self.blinkDirection = 1
    lastBlinkSwap = time.time()
    if(self.blinkDelay <= 2):
     self.blinkMin = 4
    else:
     self.blinkMin = 1
    if(self.blinkDelay >= 4):
     self.blinkMax = 3
    else:
     self.blinkMax = 6
    self.blinkDelay = random.randint(self.blinkMin,self.blinkMax)
    self.lastBlink = time.time()
 

 

 

 

I have added a Eye subclass to the Face class.  Each part of the face will be a class that encapsulates and draws its own images on the screen.  The completed code thus far:

 

import os
import pygame,sys, time, random
from pygame.locals import *

#a generic function for loading a set of images from a given directory
def LoadImages(imagesPath):
 imageList = list()
 for dirname, dirnames, filenames in os.walk(imagesPath):
  for filename in sorted(filenames):
   try:
    imageList.append( pygame.image.load(os.path.join(dirname, filename)))
   except:
    pass
 return imageList
 
#a generic function for loading a set of sounds from a given directory
def LoadSounds(imagesPath):
 soundList = list()
 for dirname, dirnames, filenames in os.walk(imagesPath):
  for filename in sorted(filenames):
   try:
    soundList.append( pygame.mixer.Sound(os.path.join(dirname, filename)))
   except:
    pass
 return soundList

#define the face and sub classes, which is just used to keep all the images together that go together
class Eyes:
 def __init__(self,path):
  self.leftEyeSquint = LoadImages(os.path.join(path, 'eye/left/squint/'))
  self.leftEye = pygame.image.load(os.path.join(path, 'eye/left/eye.png'))
  self.leftEyeBlink  = LoadImages(os.path.join(path , 'eye/left/blink/'))
  self.rightEyeSquint  = LoadImages(os.path.join(path , 'eye/right/squint/'))
  self.rightEyeBlink  = LoadImages(os.path.join(path , 'eye/right/blink/'))
  self.leftEyeX = 20
  self.leftEyeY = 20
  self.leftEyeW = 20
  self.leftEyeH = 20
  self.rightEyeX = 70
  self.rightEyeY = 70
  self.rightEyeW = 20
  self.rightEyeH = 20
  self.lastBlink = time.time()
  self.lastBlinkSwap = time.time()
  self.blinkMin = 1
  self.blinkMax = 6
  self.blinkDelay = random.randint(self.blinkMin,self.blinkMax)
  self.blinking = 0 
  self.blinkIndex = 0
  self.blinkDirection = 1
 
 def getBlink(self):
  if(self.blinking == 0):  #determine when to blink again
   display.blit(self.leftEye,(0,0))
   if (time.time() - self.lastBlink >= self.blinkDelay):
    print("Blink!" + "(" + str(self.blinkDelay) + ")")
    self.blinking = 1
    self.blinkIndex = 0
    self.blinkDirection = 1
    lastBlinkSwap = time.time()
    if(self.blinkDelay <= 2):
     self.blinkMin = 4
    else:
     self.blinkMin = 1
    if(self.blinkDelay >= 4):
     self.blinkMax = 3
    else:
     self.blinkMax = 6
    self.blinkDelay = random.randint(self.blinkMin,self.blinkMax)
    self.lastBlink = time.time()
  else:  #animate blinking
   if(time.time() - self.lastBlinkSwap >= .3):
    self.blinkIndex = self.blinkIndex + self.blinkDirection
    if(self.blinkIndex >= len(self.leftEyeBlink)):
     self.blinkIndex = len(self.leftEyeBlink)-1
     self.blinkDirection = -1
    if(self.blinkIndex == 0 and self.blinkDirection == -1):
##     print("reset")
     self.blinking = 0
     self.blinkDirection = 1
     self.lastBlink = time.time()
##    print("blink index:" + str(self.blinkIndex))
    display.blit(self.leftEyeBlink[self.blinkIndex],(0,0))
     
    
  
 
class Face:
 def __init__(self,path):
  #load each component of the eyes using the generic image loading function
  
  self.mouthTalk = LoadImages(os.path.join(path , 'mouth/talk/'))
  self.talkSounds = LoadSounds(os.path.join(path , 'sounds/talk'))
  self.singSounds = LoadSounds(os.path.join(path , 'sounds/sing'))
  self.scareSounds = LoadSounds(os.path.join(path , 'sounds/scare'))
  
  #create the eyes class
  self.eyes = Eyes(path)
  #define vars for face
  
  #emperically  determined coordinates
  
  self.mouthX = 20
  self.mouthY = 150
  self.mouthW = 200
  self.mouthH = 200
  
 def PrintInfo(self):
  print str(len(self.eyes.leftEyeSquint)) + ' left squint images loaded'
  print str(len(self.eyes.leftEyeBlink )) + ' left blink images loaded'
  print str(len(self.eyes.rightEyeSquint  )) + ' right squint images loaded'
  print str(len(self.eyes.rightEyeBlink  )) + ' right blink images loaded'
  print str(len(self.mouthTalk )) + ' talk images loaded'
  print str(len(self.talkSounds )) + ' talk sounds loaded'
  print str(len(self.singSounds )) + ' sing sounds loaded'
  print str(len(self.scareSounds )) + ' scare sounds loaded'


  
#main code here
pygame.init()
display = pygame.display.set_mode((800, 320))
pygame.display.set_caption('Funny Pumpkin')

#Create a list of faces classes, this example only has 1 face, but multiple faces can be used
faces = list()
#load the default face 
faces.append(Face('./faces/default/'))

#test the class
faces[0].PrintInfo()





#global vars
FPS = 30



#main game loop
i = 0

while(1):
 faces[0].eyes.getBlink()
 for event in pygame.event.get(): 
  if event.type == QUIT:
   pygame.quit()
   sys.exit()

 pygame.display.update()





 

  • Sign in to reply

Top Comments

  • DAB
    DAB over 10 years ago +1
    I like it, just ominous to be scary without being too obvious. DAB
  • balearicdynamics
    balearicdynamics over 10 years ago

    Hi Joey,

     

    I am figuring it with the other eye inside a pumpking... It sounds really scary!

    Nice work.

     

    Enrico

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • screamingtiger
    screamingtiger over 10 years ago in reply to DAB

    Thanks DAB.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • DAB
    DAB over 10 years ago

    I like it, just ominous to be scary without  being too obvious.

     

    DAB

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • More
    • Cancel
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube