Projet IMA3 P7, 2015/2016, TD2

De Wiki d'activités IMA

Projet IMA3-SC 2015/2016 : Détection de présence

Cahier des charges

Portique d'un magasin où la détection de présence à la porte informe le caissier l'arrivée d'un nouveau client pour décider de lui ouvrir la porte ou pas.

On se servira alors d'un sonar pour détecter l'arrivée du client ,afficher sur l'ordinateur du caissier le message suivant " Client à la porte" ensuite attendre la réponse du caissier pour pouvoir tourner le servomoteur qui servira à ouvrir la porte .

Matériel

  • Un servomoteur;
  • 2 sonars
  • NanoBoard
  • Une carte Rasberry Pi

Séance 1

Partie électronique

Le servomoteur fourni dans le projet est piloté grâce à une MLI( ou PWM en anglais). Cet MLI nous permettra de controler la position angulaire du servomoteur, qui est régi de la manière suivante, d'après sa datasheet

Pour initialiser à 0°, il faut fournir un signal de 50Hz avec 1,5 ms à l'état haut

0.PNG

Et pour avoir un angle de 90°, on fournit toujours un signal de 50 Hz mais avec un état haut de 2.5 ms cette fois-ci

100.PNG

Nous nous devons alors d'utiliser un PWM . Ce PWM qu'on implémentera sur Altium, aura la structure suivante:

Projet SC.png


Nous avons alors entamé la prise en main du complexe Nanoboard-Altium à travers un tutoriel qui nous a permis de réaliser l'affichage d'un compteur 4 bits sur des leds

Figure 1.PNG

Partie informatique

Partie informatique

Configuration, via connexion série, de la raspberry accessible via ssh (pi@172.26.79.7).

Installation de la bibliothèque libwebsockets.

Installation d'apache2 pour avoir un serveur web.

Partie Arduino

Montage effectué


Test du matériels fournis avec des fonctions simple sous le logiciels Arduino

Séance 2

Partie électronique

Lors de cette deuxième séance, nous avoir réaliser sur Altium la MLI pensée lors de la première séance et qui va ainsi nous permettre de piloter notre servomoteur

MLI.PNG

CLKBRD:Horloge interne

CLKGEN:Générateur de fréquence

CB8CEB: Compteur 8 bits

COMPM8B:Comparateur 8 bits

SW_USER0:Bouton poussoir

Montage expérimental

Notre PWM ainsi implémenté sur Altium, on refait le même protocole qu'au tutoriel fait à la séance n° 1 pour compiler notre montage et l'envoyer sur la nanobaord.

A travers nos expérimentations, on trouve que pour avoir 1.5ms d'état haut( position 0 donc), il faut envoyer le mot 0b00001111

Pour 90°: 0b00100000

On branche la sortie sur un oscilloscope et on obtient le graphe ci-dessous, relatif à un PWM

Oscillo1.PNG

On réalise alors le montage ci-dessous à l'aide d'un servomoteur, d'une plaque d'essai, d'un générateur et notre nanoboard.


Montage.PNG


Pour avoir une fréquence de 50 Hz à la sortie du PWM on doit régler la fréquence du générateur de fréquence à 12,698 KHz

Frequence.PNG

Partie informatique

Réalisation de Programme Arduino

Arduino.png

Séance 3

Partie électronique

Lors de cette troisième séance, on s'est intéressé à la partie détection de notre système. Pour cela, nous avons essayer d'intégrer le sonar. Le fonctionnement de celui- ci est le suivant: Il faut envoyer une impulsion niveau haut (à + 5v) pendant au moins 10 µs sur la broche ‘Trig Input’; cela déclenche la mesure. En retour la sortie ‘Output’ ou ‘Echo’, va fournir une impulsion + 5v dont la durée est proportionnelle à la distance si le module détecte un objet. Voici une représentation graphique de la séquence de fonctionnement du module :

Sonar.PNG

Etant donné que nous voulons seulement détecter la présence d'une personne, la distance nous importe peu. Ainsi j'ai décidé d'utiliser deux sonars : un n'ayant pas d'obstacle, qu'on nommera sonar étalon et un deuxième positionné sur la porte. Ces deux sonars seront piloté grâce à un montage PWM similaire à celui créé lors de la première séance.On comparera les Echo des deux sonars grâce à un comparateur de 8 bits renvoyant 1 si tout les bits sont égaux, 0 sinon.

Au départ, n'ayant personne devant la porte, l' Echo du sonar aura la même valeur que celle de l'étalon. Mes collègues de la partie informatique ayant choisit une transmission sur 2 bits. Le poste de contrôle recevra 0b11 s'il y a une personne, 0b00 sinon.

A ce moment l'utilisateur pourra choisir d'ouvrir la porte en envoyant le mot 0b11 qu'on comparera avec 0b11 grâce à un comparateur 2 bits. Ainsi on aura 1 à la sortie du comparateur, si l'on souhaite ouvrir la porte, 0 sinon

Cette démarche est représenté ci-dessous

Système 1.png

On connecte alors la sortie de système à la broche CLR du compteur du système réaliser lors de la première séance. On obtient alors le schéma suivant


Projet SC3.png

Ainsi si l'utilisateur ne souhaite pas ouvrir la porte, il doit envoyer n'importe quel de deux bits différents de 0b11. On aura alors 0 à la sortie du système 1 qu'on inverse pour avoir 1 à l'entrée du CLR et du coup toute les sorties du compteur seront mises à zéros et le servomoteur qui actionnera la porte ne se mettra pas en marche pas.

Partie informatique

Programmes de la configuration et la mise en marche de la liaison série
Serial.c 

/*

* Serial library
*/

//// // Include files ////

  1. include <stdio.h>
  2. include <stdlib.h>
  3. include <unistd.h>
  4. include <fcntl.h>
  5. include <termios.h>
  6. include <strings.h>
  7. include <sys/types.h>
  8. include <sys/ioctl.h>
  9. include <sys/file.h>
  10. include <linux/serial.h>
  1. include "serial.h"

//// // Functions //// // // Open serial port device // int serialOpen(char *device,int mode){ int flags=(mode==SERIAL_READ?O_RDONLY:(mode==SERIAL_WRITE?O_WRONLY:O_RDWR)); int fd=open(device,flags|O_NOCTTY|O_NONBLOCK); if(fd<0){ perror(device); exit(-1); } return fd; }

// // Serial port configuration // void serialConfig(int fd,int speed){ struct termios new; bzero(&new,sizeof(new)); new.c_cflag=CLOCAL|CREAD|speed|CS8; new.c_iflag=0; new.c_oflag=0; new.c_lflag=0; /* set input mode (non-canonical, no echo,...) */ new.c_cc[VTIME]=0; /* inter-character timer unused */ new.c_cc[VMIN]=1; /* blocking read until 1 char received */ if(tcsetattr(fd,TCSANOW,&new)<0){ perror("serialInit.tcsetattr"); exit(-1); } }

// // Serial port termination // void serialClose(int fd){ close(fd); }



Serial.h

/*

* Public definitions for serial library
*/

//// // Constants ////

  1. define SERIAL_READ 0
  2. define SERIAL_WRITE 1
  3. define SERIAL_BOTH 2

//// // Public prototypes //// int serialOpen(char *device,int mode); void serialConfig(int fd,int speed); void serialClose(int fd);

Programme du WEBSOCKETS

(

  1. include <string.h>
  2. include <libwebsockets.h>
  3. include <stdio.h>
  4. include <stdlib.h>
  5. include <unistd.h>
  6. include <fcntl.h>
  7. include <termios.h>
  8. include <sys/types.h>
  9. include <sys/ioctl.h>
  10. include <sys/file.h>
  11. include <linux/serial.h>
  12. include "serial.h"


  1. define MAX_FRAME_SIZE 1024
  2. define WAIT_DELAY 50
  3. define TAILLE_MESS 2
  4. define SERIAL_DEVICE "/dev/ttyACM0"

int serie;

static int callback_http(

 struct libwebsocket_context *this,
 struct libwebsocket *wsi,enum libwebsocket_callback_reasons reason,
 void *user,void *in,size_t len)

{ return 0; }

static int callback_my(

 struct libwebsocket_context * this,
 struct libwebsocket *wsi,enum libwebsocket_callback_reasons reason,
 void *user,void *in,size_t len)

{ static char message[TAILLE_MESS+LWS_SEND_BUFFER_PRE_PADDING+LWS_SEND_BUFFER_POST_PADDING]; unsigned char valeur;

switch(reason){

 case LWS_CALLBACK_ESTABLISHED:
   printf("connection established\n");
               // Declenchement d'un prochain envoi au navigateur
   libwebsocket_callback_on_writable(this,wsi);
   break;
 case LWS_CALLBACK_RECEIVE:
               // Ici sont traites les messages envoyes par le navigateur
   printf("received data: %s\n",(char *)in);
  
   break;
 case LWS_CALLBACK_SERVER_WRITEABLE:
               // Ici sont envoyes les messages au navigateur
   if(read(serie,&valeur,1)==1){

char *out=message+LWS_SEND_BUFFER_PRE_PADDING; sprintf(out,"%02d",valeur);

     libwebsocket_write(wsi,(unsigned char *)out,TAILLE_MESS,LWS_WRITE_TEXT);
     }

libwebsocket_callback_on_writable(this,wsi);

   break;
 default:
   break;
 }

return 0; }

static struct libwebsocket_protocols protocols[] = {

 {
   "http-only",   // name
   callback_http, // callback
   0,             // data size
   0              // maximum frame size
 },
 {"myprotocol",callback_my,0,MAX_FRAME_SIZE},
 {NULL,NULL,0,0}
 };


int main(void) { int port=9000; struct lws_context_creation_info info; memset(&info,0,sizeof info); info.port=port; info.protocols=protocols; info.gid=-1; info.uid=-1; struct libwebsocket_context *context=libwebsocket_create_context(&info); if(context==NULL){

 fprintf(stderr, "libwebsocket init failed\n");
 return -1;
 }

printf("starting server...\n");

int c=0; int serie=serialOpen(SERIAL_DEVICE,SERIAL_BOTH); serialConfig(serie,B9600); if(write(serie,&c,sizeof(char))!=1){ perror("main.write"); exit(-1); } int i; for(i=0;i<3;i++){

 if(read(serie,&c,sizeof(char))!=1){ perror("main.read"); exit(-1); }
 printf("%02x\n",c);
 }

serialClose(serie); exit(0);


while(1){

 libwebsocket_service(context,WAIT_DELAY);
 }

libwebsocket_context_destroy(context); return 0; }

Démonstration

Conclusion

Nous venons de réaliser un système de détection pour magasin. Mais, faute de temps, nous n'avons pas pu le tester totalement. Ce qui nous aurait peut-être permis de le peaufiner( utiliser seulement un sonar au lieu de deux par exemple).