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
RGB is red green blue, not black. And I'm wondering, Blue must be 0, 0, 255.. Why was taken black with 0,0,0? Thanks for answer
ReplyDeleteThe BLACK, GREEN and RED constants are just there to make the code prettier. BLACK is used for colour keying and clearing. GREEN and RED are used for the display. I'm not using a blue colour anywhere.
ReplyDeleteThis is pretty cool. Obvious enhancement would be to provide audio feedback of some kind, so the driver is not encouraged to be looking solely at the LCD when they should be regularly looking around the car during any reversing manoeuvre. Perhaps some kind of regular pulsed tone where the pulses get closer together as the distance closes, and then become a solid tone at the stop distance?
ReplyDeleteWhat is powering this rig? I'm having a hard time finding a battery pack that will power the Pi with attached 16x2 LCD and an attached iPhone or android device.
ReplyDelete@Genecyber - I get about 12 hours out of one of these with wifi and lcd etc. New Trent iCruiser 11000mAh External Battery Pack
ReplyDeleteThe LCD seems no need. Use the computer screen is fine enough. The main thing we want is sensing distance anyway.
ReplyDelete@Thanh Chung - the purpose of this is to be mounted in a car.
ReplyDeleteWell done on the proof of concept. The audio option mentioned above sounds feasible. The camera needs to be much smaller and lighter (e.g. phone camera) with a field of view as wide as the vehicle. A distance sensor would need to be on each rear corner of vehicle for either side of road parallel parking. I'd like to see activation on engaging reverse (separate white light circuit in Australian vehicles). Screen could be mounted at the rear so that it is only visible when turning around. Any ideas for an extension of the sensors to fit to trailers and caravans? Any problems with the distance of separation of the various components? 12 volt supply?
ReplyDeletemay i connect TFT screen on pic 18f4550???
ReplyDeleteI don't know. Sorry.
DeleteKudos Jeremy, I really like this idea. It would be a _great_ tool for backing a truck up to connect to a trailer. @Terry had a great idea too with attaching to the trailer or caravan. I would also think about using my mobile phone as the video display.
ReplyDelete