Here it is in action:
And a close-up of the screen:
Camera: Microsoft Lifecam Cinema - I've used this with lots of Raspberry Pi projects - it works nicely and has a good microphone too.
Distance sensor: Sharp GP2Y0A02YK0F - my article Raspberry Pi distance measuring sensor with LCD output explains how to put this together.
I'm also using an Adafruit Pi Cobbler to breakout the header onto the breadboard.


For the software I'm using Pygame. Thankfully the camera supports a 176x144 resolution and since my screen is 176x220 this fits perfectly. So, after some initializing there is a main loop which simply: blits the image from the camera, reads from the distance sensor, draws the circle and text. Finally update() is called to send this to the framebuffer.
For the software I'm using Pygame. Thankfully the camera supports a 176x144 resolution and since my screen is 176x220 this fits perfectly. So, after some initializing there is a main loop which simply: blits the image from the camera, reads from the distance sensor, draws the circle and text. Finally update() is called to send this to the framebuffer.
import pygame
import pygame.camera
import os
import mcp3008
BLACK = 0,0,0
GREEN = 0,255,0
RED = 255,0,0
if not os.getenv('SDL_FBDEV'):
os.putenv('SDL_FBDEV', '/dev/fb1')
if not os.getenv('SDL_VIDEODRIVER'):
os.putenv('SDL_VIDEODRIVER', 'fbcon')
pygame.init()
lcd = pygame.display.set_mode((176, 220))
pygame.mouse.set_visible(False)
lcd.fill(BLACK)
pygame.display.update()
pygame.camera.init()
size = (176,144)
cam = pygame.camera.Camera('/dev/video0', size, 'RGB')
cam.start()
font_big = pygame.font.Font(None, 50)
surf = pygame.Surface(size)
while True:
lcd.fill(BLACK)
cam.get_image(surf)
lcd.blit(surf, (0,0))
cm = mcp3008.read_2Y0A02_sensor(7)
colour = GREEN
if cm < 30:
colour = RED
text_surface = font_big.render('STOP', True, colour)
rect = text_surface.get_rect(center=(88,72))
lcd.blit(text_surface, rect)
if cm < 140:
pygame.draw.circle(lcd, colour, (88,72), (150-cm)/2, 3)
text_surface = font_big.render('%dcm'%cm, True, colour)
rect = text_surface.get_rect(center=(88,180))
lcd.blit(text_surface, rect)
pygame.display.update()
Finally here's the mcp3008 module which is imported above. NOTE: Since the LCD is using SPI 0.0 I have used SPI 0.1 for the mcp3008. You'll see this in the code below:
import spidev
spi = spidev.SpiDev()
spi.open(0,1)
# read SPI data from MCP3008 chip, 8 possible adc's (0 thru 7)
def readadc(adcnum):
if ((adcnum > 7) or (adcnum < 0)):
return -1
r = spi.xfer2([1,(8+adcnum)<<4,0])
adcout = ((r[1]&3) << 8) + r[2]
return adcout
def read_3v3(adcnum):
r = readadc(adcnum)
v = (r/1023.0)*3.3
return v
def read_2Y0A02_sensor(adcnum):
r = []
for i in range (0,10):
r.append(readadc(adcnum))
a = sum(r)/10.0
v = (a/1023.0)*3.3
d = 16.2537 * v**4 - 129.893 * v**3 + 382.268 * v**2 - 512.611 * v + 306.439
cm = int(round(d))
return cm
