Raspberry Pi parking camera with distance sensor
This build brings together a few other projects to make something potentially quite useful for a change - a parking camera with distance sensor. The feed from the webcam is shown on the LCD with a distance read-out underneath. As you get closer to the object (my hand in the videos) a circle is overlaid on the video which gets larger as you move closer. Once you get to within 30cm of the object the word "STOP" is overlaid and everything turns red.
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
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:
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.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
| 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:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
| 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 |
No comments:
Post a Comment