Here it is in action:
And a close-up of the screen:
LCD: Adafruit 2.2" 18-bit color TFT LCD display - from my blog article Raspberry Pi playing video on 2.2" LCD
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