Un radar avec le Raspberry Pi

Le principe

Un capteur à ultrasons SFR04 de Devantech est fixé sur un servomoteur. Le servomoteur permet sa rotation sur angle de 120° environ.
Le capteur à ultrasons balaye l'espace se trouvant devant lui et envoie l'information sur les obstacles rencontrés au Raspberry Pi.

L'information est affichée de 2 façons :
- la distance à l'obstacle en Cm dans une fenêtre
- sous forme d'un graphique
montrant les obstacles rencontrés.

Le câblage

Le schéma de câblage est le suivant et se réalise une plaque perforée et pastillée :


radar_structurel.pdf


Les 2 boutons poussoirs permettent le réglage de la vitesse de rotation du servomoteur.
Le servomoteur nécessite une tension externe (5 à 6 V), car il perturberait le fonctionnement avec une alimentation. directe sur le rail 5V du Raspberry Pi.
Le pont diviseur formé des résistances de 330 et 470 ohms permet d'abaisser la tension de la sortie ECHO du module SFR04 de 5V à 3,3 V, car les entrées du Raspberry Pi ne supportent pas plus de 3,3 V.

Les GPIO utilisées sur le connecteur 2 X 13 broches du Raspberry Pi

Les broches d'entrées/sorties du SFR04 à relier par des fils au connecteur K4


Les brochage classique d'un servomoteur
à relier au connecteur K2

Le programme sous Python

J'utilise le module RPIO.PWM pour générer les impulsions nécessaires à la commande du servomoteur, voir la documentation et la commande d'un servomoteur.


Avec un Raspbery Pi 2 et Pi .., il faut charger la bibliothèque compatible RPi.GPIO.0.7.0, l'archive est disponible sur le site Python. L' installation se fait avec :
$ pip install RPi.GPIO

Il est aussi nécessaire d'installer la bibliothèque graphique Pygame.

Pour l'installation de Pygame, ouvrez un terminal LX et tapez la commande suivante :
$ python3 - m pip install - U pygame -- user

Pour l'installation de Pygame, ouvrez un terminal LX et taper les commandes suivantes :
$ sudo apt-get install python-pygame

Le programme principal envoie une impulsion de 10 µs sur l'entrée TRIGGER du SFR04.
En retour le SFR04 renvoie un signal dont la largeur est proprtionnelle à la distance.
Convertie, cette distance est affichée en Cm et représentée graphiquement par les commandes de la bibliothèque Pygame.
Un Thread gère les déplacements du servomoteur et les boutons poussoirs.

 
# !/usr/bin/python
#JMD February 2015
# Ultrasonic SFR04

import time
import pygame
import RPi.GPIO as GPIO
from RPIO import PWM
import threading

pygame.init()
size = [360,460]
screen = pygame.display.set_mode (size)
pygame.display.set_caption("Radar")

BLACK = (  0,  0,  0)
GREEN = (  0,255,  0)
GREEN_Y = (  120,255,  0)
WHITE = (255, 255, 255)
BLUE = (  0,    0, 255)

screen.fill (WHITE)

GPIO.setmode(GPIO.BCM)

GPIO_SWDOWN  = 23
GPIO_SWUP = 18
GPIO_SERVO =25
GPIO_TRIGGER = 22
GPIO_ECHO = 17

GPIO.setup(GPIO_SERVO,GPIO.OUT)         # Servo
GPIO.setup(GPIO_SWUP,GPIO.IN)           #Switch Up
GPIO.setup(GPIO_SWDOWN,GPIO.IN)         # Switch Down
GPIO.setup(GPIO_TRIGGER,GPIO.OUT)      	# Trigger
GPIO.setup(GPIO_ECHO,GPIO.IN)           # Echo

PWM.setup()
PWM.init_channel(0)

C= 80
C_OLD = C
I= 10
STOP =0
distance_old=0

done= False
clock = pygame.time.Clock()
pygame.draw.rect(screen, BLUE, [50, 0, 260, 440], 3)
pygame.draw.rect(screen, BLACK, [52, 0, 257, 438])

GPIO.output(GPIO_TRIGGER, False)
time.sleep(0.5)

class ServoThread(threading.Thread):
    def run(self) :
        global C
        global I
        global STOP
        while True :
                #Polling switch Down and Up
                if (GPIO.input(GPIO_SWUP) == False ):
                        I = I+1
                        time.sleep(0.1)
                        if (I >10):
                                I = 10
                if(GPIO.input(GPIO_SWDOWN) ==False):
                       I=I - 1
                       time.sleep(0.1)
                       if (I<1):
                                I = 1
                                
                #Pulse 20 ms
                for T in range (0, I):
                        PWM.add_channel_pulse(0, GPIO_SERVO, 0, C)
                        time.sleep(0.03)                                                          
                C=C+1
                if C > 181 :
                        C= 80
                        STOP = 1

myServo= ServoThread()
myServo.start()
        
while not done:
        clock.tick(10)
        for event in pygame.event.get(): # User did something
                if event.type == pygame.QUIT:
                        GPIO.cleanup()
                        pygame.quit()
                        done = True                      

        # Send 10us pulse to trigger
        GPIO.output(GPIO_TRIGGER, True)
        time.sleep(0.00001)
        GPIO.output(GPIO_TRIGGER, False)
        start = time.time()
        while GPIO.input(GPIO_ECHO)==0:
                start = time.time()

        while GPIO.input(GPIO_ECHO)==1:
                stop = time.time()

        # Calculate pulse length
        elapsed = stop-start

        # Distance pulse travelled in that time is time
        # multiplied by the speed of sound (cm/s)
        distance = elapsed * 34000

        # That was the distance there and back so halve the value
        distance = distance / 2

        print "Distance : %.1f" % distance , " Cm"

        # Draw on display
        pygame.draw.line(screen, GREEN, [180,0], [C_OLD*2-90,distance_old],1)
        pygame.draw.line(screen, GREEN_Y, [C_OLD*2-90,distance_old], [C*2-90,distance_old],3)
        C_OLD = C        
        pygame.draw.line(screen, GREEN_Y, [C*2-90,distance_old], [C*2-90,distance],3)
        distance_old = distance
        
        if (STOP == 1):
                pygame.draw.rect(screen, BLACK, [52, 0, 257, 438])
                STOP=0
        pygame.display.flip()

 

 

 

 

 

 

 

 

 

 

Les fichiers (format.zip)

L'affichage

La distance est affichée dans la fenêtre " Shell Python ".
Le traçage s'effectue simultannément dans la fenêtre radar.
Si l'on veut un grand nombre de points de traçage, il faut faire tourner lentement le capteur à ultrasons.
Avec une rotation rapide on obtient que quelques points de mesure sur le graphique, car il faut laisser du temps, comme le montre le diagramme, au SFR04/05 pour renvoyer une mesure.

 

radar