ROAD RUNNER 1

Transcription

ROAD RUNNER 1
ROAD RUNNER 1
ABSA-NT
Constructeur d’équipements pour la
formation électronique
1
TP N°1 : Capteurs Ultrasoniques
Description :
Le robot Road_Runner1 regroupe plusieurs capteurs, qui constituent la partie commande et le centre
de décision pour contrôler ce robot pour des fins pédagogiques.
But du TP :
Le robot Road_Runner1 dispose de trois capteurs ultrasoniques : droite, centre et gauche. Dans ce
TP, on aura pour but d’apprendre comment fonctionne ce dispositif et comment le programmer pour
déterminer la distance d’un objet par rapport au robot.
Caractéristiques :
Les capteurs Ultrasoniques HC_SR04 :
Le capteur HC-SR04 utilise les ultrasons pour déterminer la
distance d'un objet. Il offre une excellente plage de détection sans
contact, avec des mesures de haute précision et stables.
 Caractéristiques
 Dimensions : 45 mm x 20 mm x 15 mm
 Plage de mesure : 2 cm à 400 cm
 Résolution de la mesure : 0.3 cm
 Angle de mesure efficace : 15 °
 Largeur d'impulsion sur l'entrée de déclenchement : 10 µs (Trigger
Input Pulse width)
 Broches de connections
 Vcc = Alimentation +5 V DC
 Trig = Entrée de déclenchement de la mesure (Trigger input)
 Echo = Sortie de mesure donnée en écho (Echo output)
 GND = Masse de l'alimentation
Travail Demandé :
Question 1 :
Commencer par créer deux fichiers et nommer les ultrasonic_sensor.c et ultrasonic_sensor.h.
Mettez-les dans le dossier /home/pi/Road_Runner1.
Nous allons créer deux fonctions dans le fichier ultrasonic_sensor.h.
void HC_SR04_Init() :
cette fonction va servir à initialiser les capteurs.
void Get_Distance(int) :
cette fonction va servir à calculer la distance.
Nous commençons par le capteur ultrasonique de droite. La broche TRIG du capteur ultrasonique de
droite est connectée au pin 15 de la RPI. La broche ECHO s est reliée au pin 7 de la RPI
ABSA-NT 189 Avenue de Choisy 75013 Paris
SW : www.absa-nt.com @ : [email protected] Tel : 01 45 54 11 07
2

Coder le fichier ultrasonic_sensor.h.
Fonctionnement
Pour déclencher une mesure :
- Il faut présenter une impulsion "high" (5 V) d'au moins 10 µs sur l'entrée "Trig".
-Le capteur émet alors une série de 8 impulsions ultrasoniques à 40 kHz, puis il attend le signal
réfléchi.
-Lorsque celui-ci est détecté, il envoie un signal "high" sur la sortie "Echo", dont la durée est
proportionnelle à la distance mesurée.
Nous allons coder pas à pas la fonction Get_Distance(int), elle prendra comme paramètre la
variable TRIG du capteur ultrasonique de droite.
Question 2 :
Comme indiqué précédemment, il faut envoyer une impulsion "high" (5 V) d'au moins 10 µs sur
l'entrée "Trig".
Ecrire un code pour envoyer une impulsion de 20 Microsecondes sur la broche TRIG du capteur de
droite.
La broche TRIG doit recevoir au début un signal de niveau bas pour une durée qu’on fixe à 30
secondes.
Question 3 :
Pour avoir la distance, il faut calculer la durée de l’impulsion sur la broche ECHO. Donc il faut
récupérer l’instant T1 ou ECHO passe du niveau bas au niveau haut, l’instant T2 où ECHO passe du
niveau haut au niveau bas et calculer la différence entre T2 et T1.
ABSA-NT 189 Avenue de Choisy 75013 Paris
SW : www.absa-nt.com @ : [email protected] Tel : 01 45 54 11 07
3
Pour ce faire utiliser la fonction Micros () qui renvoie le nombre de microsecondes depuis lesquelles
le programme s’est exécuté.
La distance= la durée/ 58, calculer cette distance et afficher la. Modifier dans le main.c en appelant la
fonction Get_Distance(int).
Question 4 :
Dans cette partie nous allons créer une fonction int Print_HC_SR04_Distance() pour afficher les
distances mesurées par les trois capteurs ultrasoniques en même temps. Cette fonction doit appeler la
fonction Get_Distance(int) en lui passant à chaque fois comme paramètre une des variables TRIG
(droite, centre, gauche).
Coder la fonction int Print_HC_SR04_Distance().
Modifier le main.c pour afficher les trois distances.
ABSA-NT 189 Avenue de Choisy 75013 Paris
SW : www.absa-nt.com @ : [email protected] Tel : 01 45 54 11 07
4
TP N°2 : Bus I2C
But du TP :
L’objet de cette manipulation est d’étudier le bus informatique I2C, utilisé dans les applications de
domotique et d’électronique domestique.
Caractéristiques :
Le bus I²C permet de faire communiquer entre eux des composants électroniques très divers grâce à
seulement trois fils : un signal de données (SDA), un signal d'horloge (SCL), et un signal de référence
électrique (masse).
But :
Faire communiquer entre eux des composants électroniques très divers grâce à seulement 3 fils
Signal de donnée : SDA
Signal d’horloge : SCL
Signal de référence électrique : masse
Caractéristiques du bus I2C
Deux lignes uniquement (SDA et SCL) + masse
Une adresse unique pour chaque périphérique
Bus multi-maitre, détection des collisions et arbitrage
Bus série, 8 bits, bidirectionnel à 100 kbps (standard mode), 400 kbps (fast mode) et 32 Mbps (hightspeed mode)
Le protocole I2C :
Le protocole I2C définit la succession des états logiques possibles sur SDA et SCL, et la façon
dont doivent réagir les circuits en cas de conflit.
La prise de contrôle du bus :
Pour prendre le contrôle du bus, il faut que celui-ci soit au repos (SDA et SCL à '1'). Pour
transmettre des données sur le bus, il faut donc surveiller deux conditions particulières :
- La condition de départ. (SDA passe à '0' alors que SCL reste à '1')
- La condition d'arrêt. (SDA passe à '1' alors que SCL reste à '1')
ABSA-NT 189 Avenue de Choisy 75013 Paris
SW : www.absa-nt.com @ : [email protected] Tel : 01 45 54 11 07
5
Lorsqu'un circuit, après avoir vérifié que le bus est libre, prend le contrôle de celui-ci, il en
devient le maître.
C'est toujours le maître qui génère le signal d'horloge.
Exemple de condition de départ et d'arrêt.
La transmission d'un octet :
Après avoir imposé la condition de départ, le maître applique sur SDA le bit de poids fort D7. Il
valide ensuite la donnée en appliquant pendant un instant un niveau '1' sur la ligne SCL. Lorsque SCL
revient à '0', il recommence l'opération jusqu'à ce que l'octet complet soit transmis. Il envoie alors un
bit ACK à '1' tout en scrutant l'état réel de SDA. L'esclave doit alors imposer un niveau '0' pour
signaler au maître que la transmission s'est effectuée correctement. Les sorties de chacun étant à
collecteurs ouverts, le maître voie le '0' et peut alors passer à la suite.
Exemple de transmission réussie.
Dans cet exemple :




SCL : Horloge imposée par le maître.
SDAM : Niveaux de SDA imposés par le maître.
SDAE : Niveaux de SDA imposés par l'esclave.
SDAR : Niveaux de SDA réels résultants.
La transmission d'une adresse :
Le nombre de composants qu'il est possible de connecter sur un bus I2C étant largement supérieur
à deux, il est nécessaire de définir pour chacun une adresse unique. L'adresse d'un circuit, codée sur
sept bits, est défini d'une part par son type et d'autre part par l'état appliqué à un certain nombre de ces
broches. Cette adresse est transmise sous la forme d'un octet au format particulier.
Exemple d'octet d'adresse.
On remarque ici que les bits D7 à D1 représentent les adresse A6 à A0, et que le bit D0 et
remplacé par le bit de R/W qui permet au maître de signaler s'il veut lire ou écrire une donnée. Le bit
d'acquittement ACK fonctionne comme pour une donnée, ceci permet au maître de vérifier si
l'esclave est disponible.
ABSA-NT 189 Avenue de Choisy 75013 Paris
SW : www.absa-nt.com @ : [email protected] Tel : 01 45 54 11 07
6
Note 1: Cas particulier des mémoires :
L'espace adressable d'un circuit de mémoire étant sensiblement plus grand que la plupart des
autres types de circuits, l'adresse d'une information y est codée sur deux octets ou plus. Le premier
représente toujours l'adresse du circuit, et les suivants l'adresse interne de la mémoire.
Note 2: Les adresses réservées.
Les adresses 00000XXX et 111111XX sont réservés à des modes de fonctionnement particuliers.
Ecriture d'une donnée :
L'écriture d'une donnée par le maître ne pose pas de problème particulier :
Exemple d'écriture d'une donnée.
Note : Cas particulier d'utilisation d'ACK :
L'écriture d'un octet dans certains composants (Mémoires, microcontrôleur, ...) peut prendre un
certain temps. Il est donc possible que le maître soit obligé d'attendre l'acquittement ACK avant de
passer à la suite.
Lecture d'une donnée :
La lecture d'une donnée par le maître se caractérise par l'utilisation spéciale qui faite du bit ACK.
Après la lecture d'un octet, le maître positionne ACK à '0' s'il veut lire la donnée suivante (cas d'une
mémoire par exemple) ou à '1' la cas échéant. Il envoie alors la condition d'arrêt.
Exemple de lecture d'une donnée.
Travail Demandé :
Connexion de la RPI à l’Arduino :
La carte Raspberry PI est reliée à la carte Arduino par la liaison I2C, à titre d’information on peut
relier les deux cartes par la liaison USB mais le nombre des ports étant limité nous avons opté pour la
liaison I2C.
Pour connecter les deux cartes il faut relier respectivement les pins SDA et SCL de la RPI aux pins
SDA et SCL de l’Arduino. N’oubliez pas de relier les masses de la RPI et de l’Arduino.
ABSA-NT 189 Avenue de Choisy 75013 Paris
SW : www.absa-nt.com @ : [email protected] Tel : 01 45 54 11 07
7
Configuration de l’I2C sur la RPI :
Il faut commencer par autoriser la communication I2C sur la RPI et faire quelques configurations
nécessaires citées ci-dessous





Par défaut, les cartes RPI désactivent la gestion I2C pour économiser la mémoire utilisée par
le module. Pour la réactiver, il faut mettre en commentaire avec un # la ligne : blacklist i2cbcm2708 dans le fichier /etc/modprobe.d/raspi-blacklist.conf.
Activer le module lors de chaque démarrage. C’est dans le fichier /etc/modules, en y ajoutant
à la fin une nouvelle ligne : i2c-dev.
Installez la suite des outils de gestion I2C : apt-get install i2c-tools
Redémarrer la RPI et taper cette commande ls –l /dev/i2c*, pour apparaitre ce fichier :
Lister les périphériques avec la commande : i2cdetect -y 1
Exemple de programme de communication entre la RPI et l’ARDUINO :
Dans cet exemple la RPI jouera le rôle du MASTER, et l’Arduino sera l’ESCLAVE.
Programme de la RaspBerry :
Appeler les bibliothèques nécessaires
#include <stdio.h>
#include <stdlib.h>
#include <linux/i2c-dev.h>
#include <sys/ioctl.h>
#include <fcntl.h>
// l’adresse de l’esclave i2c ‘Arduino
#define ADDRESS 0x04
ABSA-NT 189 Avenue de Choisy 75013 Paris
SW : www.absa-nt.com @ : [email protected] Tel : 01 45 54 11 07
8
// Le bus I2C
static const char *devName = "/dev/i2c-1";
int main() {
printf("I2C: Connecting\n");
int file;
//Accéder au bus I2c en accédant au fichier "/dev/i2c-1 » en lecture et en
écriture à travers le descripteur du fichier « file »
if ((file = open(devName, O_RDWR)) < 0) {
fprintf(stderr, "I2C: Failed to access %d\n", devName);
exit(1);
}
printf("I2C: acquiring buss to 0x%x\n", ADDRESS);
//Tester la disponibilité du bus I2C pour communiquer avec l’esclave
(adresse 0x04)
if (ioctl(file, I2C_SLAVE, ADDRESS) < 0) {
fprintf(stderr, "I2C: Failed to acquire bus access/talk to slave
0x%x\n", ADDRESS);
exit(1);
}
int val;
unsigned char cmd[16];
printf("Introduce a value :"); //Demander la valeur à envoyer à
l’utilisateur
scanf("%d", &val); //Récupérer la valeur à envoyer par l’I2C
printf("Sending %d\n", val);
cmd[0] = val;
//Mettre la valeur à envoyer dans la table cmd
//On place la valeur à envoyer dans le descripteur du fichier
if (write(file, cmd, 1) == 1) {
usleep(10000);
char buf[1];
//On va lire la réponse envoyé par l’Arduino reçue dans le descripteur
du
fichier déjà ouvert et le mettre dans le buffer buf
if (read(file, buf, 1) == 1) {
int temp = (int) buf[0];
printf("Received %d\n", temp);
}
}
// Là on attend pour ne pas faire crasher l’Arduino en envoyant les
demandes
ABSA-NT 189 Avenue de Choisy 75013 Paris
SW : www.absa-nt.com @ : [email protected] Tel : 01 45 54 11 07
9
//trop vite
usleep(10000);
close(file);
}
Programme de l’Arduino :
#include <Wire.h>
#define SLAVE_ADDRESS 0x04
int number = 0;
void setup() {
pinMode(13, OUTPUT);
// Initialisation de l’i2c comme esclave
Wire.begin(SLAVE_ADDRESS);}
void loop() {
//Fonction à appeler à la réception d’une transmission de la part maitre
Wire.onReceive(receiveData);
// Fonction à appeler à la demande d’une transmission par le maitre
Wire.onRequest(sendData);
delay(100);}
//Fonction pour recevoir les données envoyées par le maitre
void receiveData(int byteCount){
while(Wire.available()) {
number = Wire.read();
}
}
void sendData(){
Wire.write(number+1);
}
ABSA-NT 189 Avenue de Choisy 75013 Paris
SW : www.absa-nt.com @ : [email protected] Tel : 01 45 54 11 07
10
Question 1 :
Compiler et exécuter les programmes ci-dessus.
Question 2 :
Programmer la carte Arduino en modifiant le programme donné pour activer/désactiver les moteurs
en envoyant respectivement 1/0 de la RPI.
Question 3 :
En se référant à la description des capteurs ultrasoniques dans le TP précédent :
Récupérer la distance mesurée par le capteur de droite à travers le bus I2C et afficher la sur le
terminal de la RPI.
Question 4 :
Contrôler le fonctionnement des moteurs (marche/arrêt) en fonction de la distance mesurée par le
capteur ultrasonique de droite (par exemple : si le capteur renvoie =< 20 cm on arrête les moteurs
sinon ils tournent)
ABSA-NT 189 Avenue de Choisy 75013 Paris
SW : www.absa-nt.com @ : [email protected] Tel : 01 45 54 11 07