Université Paris-Sud IUT de Cachan Département Geii-1 Parcours ROBOS Année 2010

Rapport de projet de semestre S4

Robot Vierzon

Télé-transmission Zigbee
Comment récupérer les informations du robot lorsqu'il suit la ligne
Alexandre Martins

Date de réception au secrétariat pédagogique : ….../...…/….... à …..h….. Impression : 05/04/10

Table des matières
Résumé du projet.......................................................................................................................................................2 Abstract.....................................................................................................................................................................2 Mots-clés ..................................................................................................................................................................2 Introduction...............................................................................................................................................................2 1. Étude de deux protocoles utilisés dans le projet...................................................................................................2 1.1. Le Zigbee, une liaison efficace et peu gourmande en énergie............................................................................3 1.2. Le bus CAN, un bus de donnée rapide, pratique et robuste...............................................................................3 2. La gestion des protocoles utilisés est prise en charge par deux composants.........................................................5 2.1. Le module Xbee permet de transporter une donnée reçue en UART via Zigbee...............................................5 2.2. Le microcontrolleur 9S12C128, centre décisionnel et relai de l'information.....................................................8 3. La carte de télé-transmission, petite et indicative..................................................................................................9 3.1. Le bus CAN comme source d'énergie..............................................................................................................10 3.2. Une carte à deux niveaux de tension implique deux niveaux de signaux.........................................................11 3.3. Une multitude de L.E.D pour indiquer le statut de la carte..............................................................................12 4. Programmation du microcontrolleur...................................................................................................................12 4.1. Envoyer des données en UART vers le module Xbee.....................................................................................13 4.1.1. Initialisation du module série........................................................................................................................13 4.1.2. Programme d'envoi des informations en UART avec utilisation des interruptions.......................................14 4.2. Surveiller et recevoir les données provenant du bus CAN...............................................................................15 5. Programme de réception et enregistrement des données reçues sur le PC..........................................................15 6. Retour sur l'avancée du projet.............................................................................................................................18 Conclusion...............................................................................................................................................................18 Annexe.....................................................................................................................................................................19

Résumé du projet
Le but de ce projet est de pouvoir récupérer en “temps réel” (c'est à dire alors que le robot est en activité) le maximum d'informations du robot de Vierzon lorsque celui-ci suit la ligne en compétition. Pour cela nous avons réaliser une carte sous protel qui sert à relayer les informations récupérées sur le bus CAN du robot et les envoi via une carte Xbee (utilisant le protocole Zigbee) sur un PC équipé d'un récepteur où un programme récupèrera et stockera les informations reçues du robot. Cela nous permettra ainsi de pouvoir repérer d'éventuels problèmes ou simplement de retracer le trajet et comportement du robot durant son parcours.

Abstract
The goal of this project is to retrieve in « realtime » (bu realtime we mean while the robot is folowing the line) the maximum of informations about the ligne folower robot of the Vierzon competition. In order to achieve this we have to create hardware and software pieces. The hardware part is used to retrieve data from the CAN network and transmit it to the Xbee module (which uses the Zigbee protocol). The software part in the hardware with a MCU and another part is used in the computer to receive and store the data received. This project will allow us to debug potential anomalies or just reproduce the robot's ride.

Mots-clés
– – – – – –

bus CAN Zigbee télé-transmission Débuggage Liaison sans fil Indépendant

Introduction
Le robot Vierzon est constitué d'une multitude de cartes indépendantes reliées pour la plupart par le bus CAN dont la fonction est de permettre au robot de suivre une ligne blanche et réaliser diverses actions (tourner sur luimême, laisser une priorité...) de façon autonome et le plus efficace possible. Cependant des erreurs peuvent sur venir durant le parcours et le robot étant autonome (c'est à dire que son centre décisionnel est embarqué et qu'il ne communique pas avec l'extérieur durant son parcours) il est difficile de savoir d'où peut provenir cette erreur. Deux manières de récolter des informations s'offrent alors à nous, la transmission à distance en « temps réel » (c'est à dire lorsque le robot est encore en activité sur la piste) ou le stockage sur un support interne au robot (mémoire flash, carte SD...). Nous avons ici choisi la transmission à distance. La visée du projet de télé-transmission est d'apporter au robot suiveur de ligne du concour Vierzon un moyen d'envoyer vers un terminal extérieur les informations qui transitent dans celui-ci et influent dans le comportement du robot sur la piste. Ceci est fait lorsqu'il est présent sur la piste et nous permet en suivant en même temps le ro bot et le terminal où on reçoit les informations (un PC distant) de pouvoir trouver immédiatement d'où peut pro venir l'erreur de jugement du robot et pouvoir ainsi ensuite la corriger. Pour la réalisation de cette fonctionnalité nous allons découper le projet en trois parties: une partie hardware (la carte qui permettra la liaison) et deux parties software (une sur la carte crée et l'autre sur le terminal de réception). Cependant avant de se plonger dans le sujet nous allons tout d'abord introduire les protocoles utilisés dans ce projet.

Alexandre Martins - (GEII1 - S4 ROBOS) – Robot Vierzon : Télé-transmission Zigbee — Page 2

1 de ce document. pratique et robuste Le bus CAN (Controller Area Network) est un bus dit de terrain (car son fonctionnement doit être assuré dans des conditions difficiles) développé par Bosch (grand équipementier automobile) durant les années 80. Étude de deux protocoles utilisés dans le projet Nous utilisons deux protocoles principaux dans ce projet. certains nœuds Zigbee sont conçus pour fonctionner plusieurs mois en autonomie complète grâce à une simple pile alcaline de 1.2.S4 ROBOS) – Robot Vierzon : Télé-transmission Zigbee — Page 3 . les applications médicales. etc).(GEII1 . Ce protocole est utilisé dans des radio à consommation réduite. c'est un protocole de haut niveau (au même titre que le FTP. HTTP. Le Zigbee. Il est basée sur la norme IEEE 802. Ce bus est celui utilisé dans le robot Alexandre Martins . une liaison efficace et peu gourmande en énergie Le nom ZigBee signifie « Zig Zag like a bee ».4 4-32 Kb Années 65 000+ 250 Kb/s 100 m Bluetooth 802. 1.1 250 Kb + Jours 7 1 Mb/s 10-100 m Wi-Fi 802. Comparatif des caractéristiques des trois systèmes de transfert de donnée sans fil: Protocole IEEE Besoins mémoire Autonomie avec pile Nombre de nœuds Vitesse de transfert Portée Zigbee 802.15. Il s'agit d'un bus série (c'est à dire que les informations y sont transmises bit par bit). bus de terrain qui permet aux différentes cartes qui composent le robot suiveur de ligne de dialoguer entre elles (évitant ainsi une multitude de fils). le Zigbee.1. un bus de donnée rapide. 1. Les publications officielles du protocole Zigbee ont été diffusées en juin 2005 et sont disponibles en libre téléchargement sur le site de la Zigbee Alliance. Il permet à de petites radio de communiquer sur de faibles distances.4 pour les réseaux à dimension personnelle ou Wireless Personal Area Networks (WPANs). ses spécifications ont été ratifiées le 14 décembre 2004. Les spécifications de ZigBee 1.11a/b/g/n/n-draft 1 Mb + Heures 32 11-54-108-320 Mb/s 300 m Lors de ce projet nous utilisons une carte Xbee.15..0 sont disponibles auprès des membres de la communauté industrielle ZigBee Alliance. Celui-ci a été choisi car il nécessite peu d'énergie afin de fonctionner (comme cela l'ajout de la carte de télé-transmission n'influera que peu sur la puissance disponible pour le robot) ainsi que le bus CAN. Il est ainsi très utilisé en domotique mais aussi dans les contrôles industriels. les détecteurs de fumée et d’intrusion. Le but du développement de ce protocole est de proposer une liaison sur de courtes distances de façon plus simple que les autres solutions actuelles (principalement le bluetooth et Wifi). Bien que le protocole Zigbee soit apparu en 1988. celle-ci permet d'émettre les données qu'elle reçoit sous format UART en utilisant le protocole Xbee. Pour de plus amples informations merci de vous référer à la partie 2.1. 1. A titre indicatif. un protocole sans fil.5 V..15. Le bus CAN. On retrouve ce protocole dans des environnements où la consommation est un critère de sélection.

org/ La vitesse de transfert d'information sur le bus CAN est de 1Mbits/sec. Cette ligne est constituée de deux fils terminés par une résistance de 120 ohms qui les relient.oberle. chaque noeud étant indépendant et pouvant être déconnecté du réseau sans influencer son fonctionnement.pour permettre la communication entre les différentes cartes composant le robot. La mise en place de ce bus est désormais peu couteuse du fait de sa large diffusion de plus il s'agit d'un moyen de transporter les données robuste.(GEII1 . ainsi par sous traction des niveaux entre les deux fils on peut éliminer la majorité des parasites sur la ligne (en supposant que les deux fils sont soumis aux mêmes interférences).S4 ROBOS) – Robot Vierzon : Télé-transmission Zigbee — Page 4 . On assigne au préalable à chaque information un ID. rapide et efficace tout en utilisant un système de priorité dans les informations y circulant. Principe de la ligne différentielle source: http://www.fr/ L'information circulant sur chacun le second fil est l'opposé de celle circulant sur le premier fil. Figure 2.free. Figure 1. cet ID nous renseigne sur la nature de l'information (et donc Alexandre Martins . Implémentation physique du bus CAN source: http://mk3000. Chaque carte du robot représente un noeud (node en anglais) sur le bus. La définition du bus CAN ne comporte pas de support physique précis. ici nous avons choisi d'utiliser une ligne différentielle.

Le module Xbee permet de transporter une donnée reçue en UART via Zigbee Afin de permettre l'envoi via Zigbee des informations receuillies sur le bus CAN nous utilisons le module Xbee développé par Digi. Constitution d'une trame circulant sur le bus CAN: 2.souvent sur sa provenance) ainsi que sur sa priorité. leur utilisation est plus ou moins transparente dans le projet étant donné qu'ils sont pris en charge par des composants dédiés. Le bus possédant un niveau dominant (0) et un niveau réces sif (1). le plus petit ID aura donc priorité sur un ID numériquement supérieur (du fait du nombre debits récessifs dont son ID est composé). Voici a titre indicatif la forme d'une trame circulant sur le bus CAN: 2. 2.(GEII1 . nous allons ici vous faire un descriptif des composants utilisés dans ces deux liaisons (Zigbee et bus CAN).1. Alexandre Martins .S4 ROBOS) – Robot Vierzon : Télé-transmission Zigbee — Page 5 . La gestion des protocoles utilisés est prise en charge par deux composants Bien que nous utilisons le protocole Zigbee et CAN.

le baud est utilisé comme unité de mesure).(GEII1 . Nous n'utiliseront ici que 5 de ses pin de sortie. Nous utilisons une Xbee PRO dont la portée maximale (d'après le datasheet) est de 1500m en terrain dégagé et 100m en milieu urbain.Lors des test de portée dans l'IUT le module à pu émettre entre les salles HA2 et HC3 avec un niveau de signal maximal ce qui représente une distance bien supérieure à celle de Vierzon. Carte Xbee développée par Digi Bien que ce module ne possède de nombreux convertisseurs analogique-numérique ou des entrées pour PWM. La vitesse de transfert maximale est de 11500 Bauds (le module Xbee sur l'ordinateur dialoguant par liaison sé rie. Le module Xbee envoi automatiquement par Zigbee les informations qu'elle reçoit en UART sur son entrée Xbee IN. Numérotation des pin du module Xbee source: Datasheet du module Xbee Alexandre Martins .S4 ROBOS) – Robot Vierzon : Télé-transmission Zigbee — Page 6 . L'avantage de cette carte est sa petite taille (elle pourra donc facilement trouver une place sur le robot) mais elle est aussi totalement indépendante. dans notre cas il ne nous sert qu'au relai de l'information reçue via le bus CAN sur le robot jusqu'à l'ordinateur en utilisant une liaison sans fil Zigbee. Figure 4. chose qui est plus que raisonnable pour notre utilisation. nous y reviendrons plus tard dans cette partie.Figure 3.

led d'association Xbee elle nous permettra de savoir si le module est associé à un autre ou non. Optionnel DOUT (2). Figure 6. Utilisation des pin du module Xbee source: Datasheet du module Xbee Pour notre application nous n'aurons besoin que de quatre (voir cinq) pin: – – – – – – VCC (1) pour alimenter la carte GND (10) pour alimenter la carte DIN (3). 8 bits de Alexandre Martins .(GEII1 . afin d'extrapoler le niveau du signal Xbee entre le récepteur et notre carte (il s'agit d'une PWM) Associate (15).S4 ROBOS) – Robot Vierzon : Télé-transmission Zigbee — Page 7 . Les niveaux de la liaison UART avec le module Xbee source: Datasheet du module Xbee Le niveau au repos de la ligne est le niveau haut. L'envoi des données vers la carte Xbee ici se fera via une liaison UART. afin de recevoir des informations via Zigbee sur notre carte (en vue d'une utilisation détournée du projet).Figure 5. cela nous permettra d'envoyer au module les informations à transmettre RSSI (6). chaque trame doit contenir un bit start (niveau bas). les informations à envoyer par liaison Zigbee sont relayées depuis le microcontrolleur jusqu'à la pin DIN (3).

la mise en forme (suppression des informations inutiles dans la trame. A coté de cela il nous permettra d'assurer la gestion des LED de statut sur la carte de télé-transmission (voir partie 3.donnée.2.(GEII1 . Pour cela le microcontrolleur doit disposer d'au moins un module CAN.D d'envoi et de réception d'information du module Xbee) ou en transcrivant la PWM de niveau de signal issue du module Xbee.1) et le bus CAN du robot. pas de bit de parité et un bit stop (niveau haut) comme indiqué sur ce schéma: J'ai choisi de ne pas utiliser CTS (Clear To Send) et RTS (Request To Send) afin de simplifier le routage au ni veau du microcontrolleur et de prendre en considération la taille des buffer d'envoi et de réception du module Xbee dans le programme implémenté sur le microcontrolleur.3) en les allumant par programme (L. ajout de l'ID de la trame aux données pour transmission) et le relai des informa tions vers la carte Xbee via une liaison UART (liaison série). Alexandre Martins . Utilisation typique de la liaison UART avec le module Xbee source: Datasheet du module Xbee 2. Figure 7.S4 ROBOS) – Robot Vierzon : Télé-transmission Zigbee — Page 8 . Le microcontrolleur 9S12C128. centre décisionnel et relai de l'information La carte de télé-transmission nécessite un microcontrolleur afin d'assurer le relai entre le module Xbee (voir 2. Il permettra la réception des données nous intéressant sur le bus CAN. il présente toutes les caractéris tiques nécessaires et présente l'avantage de fonctionner comme le 9S12DP256 que j'ai l'habitude d'utiliser à l'IUT. un module série et de 5 sorties logiques (pour les LED). Le microcontrolleur utilisé est le freescale (anciennement motorolla) 9S12C128.E.

Pin du microcontrolleur 9S12C128 source: Datasheet du microcontrolleur 9S12 Le bus CAN sera ainsi connecté aux pins 44 et 45 (pins du module CAN du microcontrolleur). Nous devrons faire attention de bien connecter toutes les alimentations aux tensions d'alimentation correspondantes: Les pins 16. le module Xbee (liaison UART) seront reliés aux pins 38 et 39 (pins du module série).Figure 8.35 et 47 devrons être connectées à VCC soit +5V La pin 6 doit être connectée à Vpll et la pin 18 à V1. Montage afin d'obtenir les tensions de référence du 9S12C128 Alexandre Martins .(GEII1 . Ces deux tensions de référence sont obtenues grâce au montage suivant: Figure 9.S4 ROBOS) – Robot Vierzon : Télé-transmission Zigbee — Page 9 .

petite et indicative Maintenant que nous avons abordé les deux points principaux de la carte de télé-transmission à savoir le module Xbee et le microcontrolleur.Une erreur remarquée que bien trop tard lors de la conception de la carte est l'emplacement des condensateurs de découplage du microcontrolleur.(GEII1 . En effet un plan détaillé est fourni par le constructeur concernant la disposition et le nombre de condensateurs de découplage recommandés pour le 9S12C128. Notons que nous devons utiliser un transceiver de ligne afin d'utiliser le bus CAN (celui-ci se charge de la mise à niveau des signaux issus du microcontrolleur pour les adapter au niveau de la ligne). Le composant utilisé pour cela est le MCP2551 3.S4 ROBOS) – Robot Vierzon : Télé-transmission Zigbee — Page 10 . nous allons nous attarder sur des points importants sur cette carte. La carte de télé-transmission.3 Connecteur CAN LED Check LEDs 74LS07 Alexandre Martins . Figure 10. la carte de téZigbee Photographie de lé-transmission Carte Xbee LM2937-3.

ce composant permettant de choisir le niveau de tension en fixant les résistances qui lui sont associées. Par soucis de place et de précision de la tension d'alimentation du module Xbee j'ai finalement choisi un LM2937-3.3V avec seulement deux condensateurs pour des tensions maximales d'entrée bien supérieures à celle présente sur le bus CAN (protection pour des tension d'entrée maximale de +60V/-50V d'après le datasheet).3 Alexandre Martins . sachant que la consommation maximale du module Xbee est de 215mA en émission.de Niveau LED data out LED data in MCP2551 Figure 11. Câblage du LM2937-3. Figure 13. la masse et l'alimentation VCC=+5V proviennent directement du bus CAN cela à été possible car la carte n'utilise que des faibles tensions pour son fonctionnement. Ce régulateur permet d'obtenir un courant de sortie de 400mA maximum.3V.1. Cependant le module Xbee fonctionne avec une tension maximale de 3. Le bus CAN comme source d'énergie La carte de télé-transmission présente l'avantage de ne pas nécessiter de connecteur d'alimentation extérieur.(GEII1 . Figure 12. Afin de pouvoir alimenter le module Xbee à partir de VCC j'avais choisi d'utiliser un LM337. En effet. PCB de la carte de télé-transmission Zigbee Le schéma de câblage complet de la carte est disponible en annexe 3.S4 ROBOS) – Robot Vierzon : Télé-transmission Zigbee — Page 11 . cela laisse une certaine marge. Câblage du connecteur micro-match (bus CAN) La tension d'alimentation du microcontrolleur ainsi que la liaison à la masse du robot est donc assurée par le biais du bus CAN.3 car celui-ci est disponible en CMS et nous permet d'obtenir une tension de sortie stable de 3.

C'est le cas ici entre le microcontrolleur et le module Xbee.. le niveau haut en sortie du microcontrolleur (+5V) n'étant pas supporté par le module Xbee (dont la tension maximale supportée en entrée est de 3.3V n'autorisant un niveau haut en sortie de 2.4V d'après le datasheet) et le niveau haut en sortie du module Xbee étant dans la zone indéterminée du microcontrolleur nous allons devoir adapter les niveaux de tension entre les deux composants. Pour cela plusieurs pistes ont été suivies (montage avec AOP.3.3V afin d'abaisser le niveau de tension du signal (voir figure 14 à droite). transistor. Une carte à deux niveaux de tension implique deux niveaux de signaux Une carte avec deux tensions d'alimentation pose aussi le problème de niveau des signaux qui transitent entre les composants alimentés à deux niveaux de tensions différents.(GEII1 .9V. deux montages ont été retenu. La carte de télé-transmission présente au total 7 LED: Alexandre Martins . pont diviseur de tension.8V Ces deux systèmes simples permettent de régler le problème d'incompatibilité des niveaux d'entrée/sortie des composants. J'ai donc pris un 74LS07 (porte OUI) qui ne modifie pas le signal en entrée et me permet de fixer le niveau de tension en sortie grâce à des résistances de pull-up reliées à VCC=+5V.2.E. Figure 14. J'ai au préalable vérifié la compatibilité des niveaux entre le module Xbee.3V désirés. le microcontrolleur et la porte logique. cette diode à été remplacée par une diode zener de 3. Une multitude de L.8V VIH (porte) = 2V VOL (Xbee) = 0.5 = 2. Montage de changement de tension (avec diode zener et 74LS07) Dans le sens opposé (Xbee → microcontrolleur) j'ai choisi d'utiliser une porte logique à collecteur ouvert.. 3.).5V VIL (porte) = 0. Après mesure des niveaux. Pour les données dans le sens microcontrolleur → Xbee nous avons choisi d'utiliser un montage simple avec une diode zener 3.S4 ROBOS) – Robot Vierzon : Télé-transmission Zigbee — Page 12 .D pour indiquer le statut de la carte Un point à aborder rapidement est l'utilité et le câblage des LED présentes sur la carte car ce sont elles qui per mettrons de voir en jeter un coup d'œil à la carte le statut de celle-ci.1V alors que la nouvelle nous permet d'obtenir les 3. la diode de 3.3. VOH (Xbee) = VCC – 0.

à l'exception de la LED d'association comme énoncé précédement.S4 ROBOS) – Robot Vierzon : Télé-transmission Zigbee — Page 13 . Les LED de niveau de signal sont aussi une exception car leur allumage est conditionné par le rapport cyclique du signal issu du module Xbee (RSSI) indiquant le niveau de signal (voir partie 2. la différence de tension est nulle entre VCC et le port.1) 4. les informations sur la trame tel que le nombre de bit de donnée.(GEII1 . Alexandre Martins .1.1.1.. On peut découper ce programme en deux paties principales.3V et directement rattachée au module Xbee. Dans le programme il ne nous reste plus donc qu'à initialiser ce module et l'utiliser.– – – – – 3 LED de niveau de signal 1 LED indiquant l'envoi de données du bus CAN vers le module Xbee 1 LED indiquant la réception de donnée depuis le module Xbee 1 LED indiquant le fonctionnement du microcontrolleur 1 LED indiquant le statut d'association du module Xbee Toutes les LED de la carte sont câblées de la même façon et au microcontrolleur. Envoyer des données en UART vers le module Xbee Le microcontrolleur 9S12C128 comporte déjà un module de liaison série. 4. la LED associée s'allume.. une partie servant à envoyer via une liaison série les données vers le module Xbee et une autre qui se chargera de surveiller et récupérer les trames d'intérêt sur le bus CAN. Programmation du microcontrolleur Avoir une carte fonctionnelle ne représente que la moitié du projet. aucun courant ne circule la LED reste donc en état bloqué et ne s'allume pas.) ainsi que le module timer (puisque nous utilisons les interruptions afin de ne pas utiliser de fonctions bloquantes sur le microcontrol leur).E. Câblage des L. Initialisation du module série Afin d'utiliser la liaison série du microcontrolleur il njous suffit d'initialiser quelques registres du module série (afin de fixer le baudrate. sauf la LED d'association qui est alimentée en 3. ainsi lorsque le port est au niveau bas.D de la carte de télé-transmission Les LED sont allumées ou éteintes dans le programme. En effet sans programmation du microcontrolleur la carte de télé-transmission ne serait qu'une carte alimentant le module Xbee avec la LED d'association qui clignoterai mais aucune donnée ne serait transmise via Zigbee. 4. Les résistances sont associées à une résistance de pull-up et branchées à l'entrée d'un port du microcontrolleur programmé en sortie (voir figure 15). dans le cas contraire (niveau haut). Le Baudrate est fixé à la valeur maximale (par test réel durant les scéances d'E&R) supportée par le module Xbee à savoir 115200 Bauds. Figure 15.

Le message a envoyer est indiqué en paramètre. le résultat du calcul est donc SCIBDL=2. SCIBDL = 0x03. Programme d'envoi des informations en UART avec utilisation des interruptions Les fonctions d'envoi de données sont au nombre de deux. parite paire. SCICR2 = 0x08. // Port T en sortie TIOS &= ~0x07.} DDRT = 0xFF. SCISR2 = 0x02. } // Baudrate de 115200: 0x03 (valeur exacte:2. 8 bits. /* FUNCTION NAME: RS232_init * DESCRIPTION * * RETURN * PARAMETER */ void RS232_init (void) { SCIBDH = 0x00.S4 ROBOS) – Robot Vierzon : Télé-transmission Zigbee — Page 14 .2.71) // // Module d'emission seulement activé // Broche TXD en mode sortie : Initialise la liaison serie a 115200b/s.1. /* FUNCTION NAME: RS232_snd_msg * DESCRIPTION * RETURN * PARAMETER */ : Réalise l'émission d'un message terminé par le caractère '\0'. //Active le bloc de timer TCTL4 |= 0x3F.(GEII1 . // Réglagle du prescaler à 2^6=64 } 4. //Activation des interruptions sur les channels 0. : void 1 : INT8U* chaine de caractère a envoyer Alexandre Martins . interruptions activees en emission : void 1 : void void initialisation_port(void) { asm{__cli. J'ai donc arrondis à 3.1 et 2 TSCR2 |= 0x06. //Input capture pour T0 T1 T2 TSCR1 |= 0x80.71. La fonction RS232_snd_msg est appelée dans le programme main ou une sous-fonction. Dans cette fonction copie le message à envoyer dans un tableau (buffer) et active les interruptions sur le microcontrolleur. //Activation à chaque fronts montants et fronts descendants TIE |= 0x07.La valeur de SCIBDL est fixé grâce à la formule présente dans le datasheet du microcontrolleur: Débit = Fclk (1) Equation de calcul de SCIBDL 16∗SCIBDx Nous avons un quartz de 10Mhz adapté sur la carte. SCICR1 = 0x04.

cpt++. SCICR2 &= ~0xC0. } // Désactivation des interruptions Alexandre Martins . } buffer [cpt+1] = '\0'. tmp=0. } else { i=0.(GEII1 . if ((SCISR1 & MASK_TDRE) == MASK_TDRE) { if (buffer[i]!='\0') { if (i==0) PTT &= ~MASK_LED_OUT. PTT |= MASK_LED_OUT. la fonction RS232_sc est appelée à chaque fin d'envoi d'un caractère de la chaine jusqu'à ce qu'on atteigne la fin de la chaine (représentée par le caractère '\0') où les interruptions sont de nouveau désactivées. i++.void RS232_snd_msg (INT8U* chaine) { char cpt=0. } /* FUNCTION NAME: RS232_sc * DESCRIPTION * RETURN * PARAMETER */ void RS232_sc (void) { static char i=0. : Réalise l'envoie d'un caractère ASCII sur la liason série : void : void SCIDRL=buffer[i]. interrupt SCI0_ISR void envoi_de_caractere(void) { RS232_sc (). while (chaine[cpt]!='\0') { buffer[cpt]=chaine[cpt].S4 ROBOS) – Robot Vierzon : Télé-transmission Zigbee — Page 15 . SCICR2 |= 0xC0. //TCIE et TIE =1 (activation des interruptions) } Une fois les interruptions activées.

outputQueue = 500. il suffit donc de récupérer les trames circulant sur ce port virtuel et les stocker dans un fichier.txt pour une lecture visuelle et . Programme de réception et enregistrement des données reçues sur le PC Une fois les données envoyées du robot. l'intégralité de celui-ci est présente en annexe. // No du port COM // Baudrate // Bits de parités (0 = aucun) // Bits de donnée // Nombre de bits stop // Spécifie si le mode Xon Xoff est utilisé // Temp de latence (en secondes) readCount = 499. Voici un bref descriptif des fonctions du programme.(GEII1 . un récepteur USB peut-être branché sur le PC. timeout = 10.} } 4. ou linefeed LF = 10) portOpen = 0. la date est ajoutée avant le message puis écris dans le fichier. // Détermine le caractère de fin de trame (car// Port COM ouvert (1) ou non (0) // Nombre de bits lus // Status du port COM // Variable en cas d'erreur // Taille du buffer de reception // Taille du buffer d'émission char readData[500]. 5. // Pointeur vers le fichier txt // Pointeur vers le fichier csv (séparés par vir// Variable de type time_t qui contiendra l'heure Alexandre Martins . stopBits = 1. Surveiller et recevoir les données provenant du bus CAN Les fonctions utilisées pour surveiller le bus CAN n'ont pas encore été écrites à l'heure de l'écriture de ce rapport. La réception des données se fait par le biais d'un port COM virtuel (port série virtuel). FILE *fichier_csv. // Tableau avec le message recu // Nom du port COM FILE *fichier_txt. dataBits = 8. // Nombre de bits a prendre en compte dans le message (avant de quitter la fonction de lecture) readTerm = 13. il s'agit simplement d'une carte Xbee connectée à une carte fournie dans le starter kit Zigbee de Digi. rs232Error. com_msg[500]. date[10]. inputQueue = 500. J'ai choisi de stocker les informations reçues sous deux formes: .2.csv pour l'affichage sous forme de tableau. comStatus = 0. gules) time_t heure. xonXoff = NON. baudRate = 115200.S4 ROBOS) – Robot Vierzon : Télé-transmission Zigbee — Page 16 . Le module de bus CAN du microcontrolleur sera utilisé afin de réaliser cette tâche. bytesRead = 0. riage return CR = 13. parity = NON. deviceName[10]= "COM7". /*--------------------------------------------------------------------------*/ /* Variables globales */ /*--------------------------------------------------------------------------*/ int comport = 7. Lors de la réception d'informations.

\n").txt"). } else MessagePopup ("Erreur".(GEII1 . } Dans ReceiveData la fonction ComRdTerm est utilisée. i++) readData[i] = '\0'.. baudRate. \n").S4 ROBOS) – Robot Vierzon : Télé-transmission Zigbee — Page 17 . comport). fermeture du programme").et la date Dans la fonction main la liaison avec le port série est initialisée et le programme boucle pour surveiller les changements sur le port COM. PortConfig ().. RemoveFileIfExists ("E:\\Etudes\\GEII semestre 4\\Projet Zigbee\\Prog_PC\\RS232_perso\\rs232_data. parite: %i. // MessagePopup ("Message recu". readData[0] = '\0'. if (portOpen) { printf ("Port COM %i ouvert avec succes \n". comport. // ComRdTerm lis les bits sur le port jusqu'au byte de terminaison défini (retourne le nombre de bits la trame) de if (bytesRead != 0) { if (bytesRead == readCount) printf ("\n\n !!!! Attention le message ci-dessous est probable ment incomplet !!!!"). bytesRead = 0. while (1) ReceiveData (). printf ("En attente de message. bits stop: %i. dataBits. void ReceiveData (void) { int i. "Erreur dans l'initialisation du port COM. readDa ta). readData.. \n". stopBits). FillFile (). printf ("\n Message recu de %i caracteres: \n \t %s". Alexandre Martins . bits de donnee : %i.. readData).csv"). Pour éviter de probables conflits les anciens fichiers de log présents dans le dossier sont supprimés (par sécurité) void main (void) { printf ("Demarrage du programme RS232. bytesRead = ComRdTerm (comport. parity. RemoveFileIfExists ("E:\\Etudes\\GEII semestre 4\\Projet Zigbee\\Prog_PC\\RS232_perso\\rs232_data. bytesRead. printf ("Ouverture du port COM %i avec un Baudrate de %i. readCount. i<bytesRead. readTerm). for (i=0. celle-ci surveille le port et copie les données reçues dans readData jusqu'à ce que le nombre maximum de caractères soit atteind ou qu'un caractère en particulier soit observé.

date.csv".csv". "a"). // Ouvre le fichier // Ouvre le fichier RetrieveCurrentTime (). } void RetrieveCurrentTime (void) { heure = time(NULL). "%s. fprintf (fichier_txt. readData).Certaines parties du projet on donc été supprimées durant mon avancée Alexandre Martins . fclose(fichier_csv). dans le fichier GetFileWritability ("E:\\Etudes\\GEII semestre 4\\Projet Zigbee\\Prog_PC\\RS232_perso\\rs232_data. Retour sur l'avancée du projet Maintenant que la présentation du projet arrive à son terme. cpt=0. fichier proté gé en écriture"). } else MessagePopup ("Erreur". void FillFile (void) { int write_txt=0. "%s \t %s \n". localtime(&heure)). "a"). &write_csv).%s \n". strftime(date. // Ecris les données recues dans le fichier txt fprintf (fichier_csv. } 6. "%H:%M:%S". GetFileWritability ("E:\\Etudes\\GEII semestre 4\\Projet Zigbee\\Prog_PC\\RS232_perso\\rs232_data. sizeof(date).txt". Pour cela elle vérifie que les fichiers log soient accéssibles en écriture. write_csv=0. if (fichier_txt == NULL || fichier_csv == NULL) MessagePopup ("Erreur". &write_txt). J'ai élaboré le diagramme de Gantt en début de projet (figure 16 en haut) et pensais devoir retravailler une carte de télé-transmission préexistante cependant au final j'ai dû complètement recréer cette carte ce qui m'a fait prendre du retard sur le planning initial. dans le fichier // Test si on peut c rire // Test si on peut c rire if (write_txt && write_csv) { fichier_txt = fopen ("E:/Etudes/GEII semestre 4/Projet Zigbee/Prog_PC/RS232_perso/rs232_data."Erreur d'ouverture de fichier"). puis les ouvre pour les manipuler.} } Finalement la fonction FillFile va inscrire les données reçues dans la fonction précédente da s un fichier. fichier_csv = fopen ("E:/Etudes/GEII semestre 4/Projet Zigbee/Prog_PC/RS232_perso/rs232_data. date. je me devais de revenir sur son avancée. S'en suit un appelle la fonction retrieveCurrentTime afin de déterminer la date et l'heure puis utilise fprintf pour écrire les données dans les fichiers avant de les fermer à nouveau (et éviter qu'ils ne soient pas accéssibles en écriture pour un prochain appel).S4 ROBOS) – Robot Vierzon : Télé-transmission Zigbee — Page 18 .(GEII1 . "Impossible de compléter le fichier log. // Ecris les données recues dans le fichier csv fclose(fichier_txt).txt". readData).

En espérant que mon projet aidera mes confrères participant à la compétition de Vierzon à gagner du temps sur la correction des erreurs rencontrées durant les parcours du robot.(GEII1 . Ce projet m'aura permis de découvrir le protocole Zigbee ainsi que le bus CAN et son implémentation sur le microcontrolleur que nous avons l'habitude d'utiliser. la carte de télé-transmission est fonctionnelle et des données ont été envoyées depuis le microcontrolleur vers un ordinateur en utilisant le code indiqué dans ce rapport.(tel que la mise en place d'une interface graphique ou l'ajout d'une tâche spécialisée dans le RTOS développé par Nathan Clerbout) aux vues du retard pris sur la conception de la carte de télé-transmission. Figure 16. Diagrammes de Gantt du projet Conclusion A l'heure actuelle (04/04/2010) la majorité du projet à été complétée.S4 ROBOS) – Robot Vierzon : Télé-transmission Zigbee — Page 19 . Alexandre Martins . Il me reste encore la partie de gestion du bus CAN sur le microcontrolleur à écrire ou compléter. ceci devrait être (sauf bug majeur) réalisable dans les délais impartis.

Annexe Alexandre Martins .(GEII1 .S4 ROBOS) – Robot Vierzon : Télé-transmission Zigbee — Page 20 .

Contenu de l'annexe: – – – – – – – – Diagramme de Gantt du projet (ancien et actuel) Schéma électrique de la carte de télé-transmission PCB de la carte de télé-transmission Programme de réception sur PC (perso.c) Programme du microcontrolleur 9S12C128 de la carte de télé-transmission (version du 05/04/10) Extraits du datasheet du module Xbee Extrait du datasheet du LM2937-3.3 Extrait du datasheet du 74LS07 .

.

.

.

h> /*--------------------------------------------------------------------------*/ /* Defines */ /*--------------------------------------------------------------------------*/ #define OUI 1 #define NON 0 /*--------------------------------------------------------------------------*/ /* Définition des fonctions */ /*--------------------------------------------------------------------------*/ void DisplayComStatus (void). time_t heure. char readData[500]. readCount = 499.h> #include <utility. com_msg[500]. 10) portOpen = 0.c * * Auteur: Alexandre Martins * * Date de révision: 01/02/2010 * * Version: 0.h> #include <string. inputQueue = 500. rs232Error. baudRate = 115200. xonXoff = NON. bytesRead = 0. void PortConfig (void). void FillFile (void).h> #include <time.h> #include <userint. stopBits = 1. dataBits = 8. parity = NON. outputQueue = 500. FILE *fichier_csv./********************************************************************************** * Perso.1 * * Utilité : Ce fichier contient les fonctions permettant la * * réception et le stockage des données recues via le RS232 * * du PC * * * **********************************************************************************/ /*--------------------------------------------------------------------------*/ /* Includes */ /*--------------------------------------------------------------------------*/ #include "toolbox.h> #include <rs232. FILE *fichier_txt. void ReceiveData (void).h> #include <formatio. // // // // // // // // No du port COM Baudrate Bits de parités (0 = aucun) Bits de donnée Nombre de bits stop Spécifie si le mode Xon Xoff est utilisé Temp de latence (en secondes) Nombre de bits à prendre en compte dans le message (avant de quitter la fonction // Détermine le caractère de fin de trame (carriage return CR = 13. ou linefeed LF = // // // // // // Port COM ouvert (1) ou non (0) Nombre de bits lus Status du port COM Variable en cas d'erreur Taille du buffer de reception Taille du buffer d'émission // Tableau avec le message recu // Nom du port COM // Pointeur vers le fichier txt // Pointeur vers le fichier csv (séparés par virgules) // Variable de type time_t qui contiendra l'heure et la date . comStatus = 0. /*--------------------------------------------------------------------------*/ /* Variables globales */ /*--------------------------------------------------------------------------*/ int comport = 7.h" #include <ansi_c. deviceName[10]= "COM7". date[10].h> #include <cvirte. void RetrieveCurrentTime (void). timeout = 10. de lecture) readTerm = 13.

// Défini le timeout } else MessagePopup ("Erreur".\n").. if (portOpen) { printf ("Port COM %i ouvert avec succes \n". timeout). stopBits. comport). if (comStatus & 0x0040) strcat (com_msg. if (comStatus & 0x0080) strcat (com_msg. "Break: A break signal was detected. dataBits. RemoveFileIfExists ("E:\\Etudes\\GEII semestre 4\\Projet Zigbee\\Prog_PC\\RS232_perso\\rs232_data. if (comStatus & 0x0020) strcat (com_msg.\n")..\n"). "Remote XOFF: An XOFF character was received.unopened */ rs232Error = OpenComConfig (comport. xonXoff). DisplayComStatus (). if (comStatus & 0x0010) strcat (com_msg. parite: %i. if (comStatus & 0x0002) strcat (com_msg. if (comStatus & 0x0001) strcat (com_msg. } /*----------------------------------------------------------------------------------------------*/ /* DisplayComStatus */ /* Arguments : Aucun */ /* Sorties : Pop-up */ /* Utilité : Affiche par pop-up l'état du port COM */ /*----------------------------------------------------------------------------------------------*/ void DisplayComStatus (void) { com_msg[0] = '\0'. inputQueue. "Parity error. if (comStatus & 0x1000) strcat (com_msg. } else MessagePopup ("Erreur". \n"). bits stop: %i. comport. printf ("Ouverture du port COM %i avec un Baudrate de %i. baudRate. } /*----------------------------------------------------------------------------------------------*/ /* PortConfig */ /* Arguments : Aucun */ /* Sorties : Pop-up */ /* Utilité : Permet l'ouverture et l'init du port COM */ /*----------------------------------------------------------------------------------------------*/ void PortConfig (void) { portOpen = 0. // Active ou non le mode Xon-Xoff SetComTime (comport. while (1) ReceiveData ().\n"). PortConfig (). /* initialize flag to 0 .\n")./*--------------------------------------------------------------------------*/ /* Fonctions */ /*--------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------------------------*/ /* Main */ /* Arguments : Aucun */ /* Sorties : Aucune */ /* Utilité : Fonction main du programme (appel fonctions) */ /*---------------------------------------------------------------------------------------------*/ void main (void) { printf ("Demarrage du programme RS232. outputQueue). if (rs232Error == 0 && comStatus == 0) { portOpen = 1. deviceName. fermeture du programme"). parity. dataBits. bits de donnee : %i." "\nIf XON/XOFF was enabled. SetXMode (comport.. "Input lost: Input queue" " filled and characters were lost.csv"). \n". baudRate. comStatus = GetComStat (comport). "Asynch error: Problem " "determining number of characters in input queue. \n"). "Erreur lors de l'initialisation"). "Overrun error: Received" " characters were lost.txt").\n"). "Framing error: Stop bits were not received" " as expected.. no characters are removed" . RemoveFileIfExists ("E:\\Etudes\\GEII semestre 4\\Projet Zigbee\\Prog_PC\\RS232_perso\\rs232_data. stopBits). printf ("En attente de message. parity. "Erreur dans l'initialisation du port COM.

readData)."Erreur d'ouverture de fichier"). readCount). If XON/XOFF was enabled. "a").txt". // ComRdTerm lis les bits sur le port jusqu'au byte de terminaison défini (retourne le nombre de bits de la trame) if (bytesRead != 0) { if (bytesRead == readCount) printf ("\n\n !!!! Attention le message ci-dessous est probablement incomplet !!!!"). date. "%s.csv". // Ouvre le fichier if (fichier_txt == NULL || fichier_csv == NULL) MessagePopup ("Erreur". fclose(fichier_csv). if (strlen (com_msg) == 0) strcat (com_msg. readData.\n"). // Test si on peut écrire dans le fichier if (write_txt && write_csv) { fichier_txt = fopen ("E:/Etudes/GEII semestre 4/Projet Zigbee/Prog_PC/RS232_perso/rs232_data. &write_txt). fprintf (fichier_txt.\n"). readTerm).%s \n". com_msg). RetrieveCurrentTime (). if (comStatus & 0x2000) strcat (com_msg. readCount. MessagePopup ("RS232 Message". MessagePopup ("Message recu". write_csv=0."). readData[0] = '\0'. bytesRead.\n"). "a"). &write_csv). "%s \t %s \n". "Local XON: An XON character was sent to\n" " the other device. 75%. // Test si on peut écrire dans le fichier GetFileWritability ("E:\\Etudes\\GEII semestre 4\\Projet Zigbee\\Prog_PC\\RS232_perso\\rs232_data. for (i=0. printf ("\n Message recu de %i caracteres: \n \t %s". // Ecris les données recues dans le fichier txt fprintf (fichier_csv." "\nTransmisson can resume. // Ouvre le fichier fichier_csv = fopen ("E:/Etudes/GEII semestre 4/Projet Zigbee/Prog_PC/RS232_perso/rs232_data. XOFF is\n" " transmitted when the input queue is 50%. // bytesRead = ComRd (comport. bytesRead = 0. } // . GetFileWritability ("E:\\Etudes\\GEII semestre 4\\Projet Zigbee\\Prog_PC\\RS232_perso\\rs232_data. If XON/XOFF was enabled. i<bytesRead.txt". readData. readData). // ComRd lis les bits sur le port jusqu'a ce que le compte soit atteint (retourne le nombre de bits de la trame) bytesRead = ComRdTerm (comport.csv"." from the output queue and sent to another device " "until that device sends an XON character. } } /*----------------------------------------------------------------------------------------------*/ /* FillFile */ /* Arguments : Aucun */ /* Sorties : Fichier text */ /* Utilité : Rempli le fichier de sortie (doit être init) */ /*----------------------------------------------------------------------------------------------*/ void FillFile (void) { int write_txt=0. // Ecris les données recues dans le fichier csv fclose(fichier_txt). readData). and 90%\n" " full. XON is\n" " transmitted when the input queue empties after XOFF\n" " was sent. FillFile (). i++) readData[i] = '\0'. if (comStatus & 0x4000) strcat (com_msg. cpt=0. "Local XOFF: An XOFF character was sent to\n" " the other device. "No status bits are set. if (comStatus & 0x8000) strcat (com_msg. } /*----------------------------------------------------------------------------------------------*/ /* ReceiveData */ /* Arguments : Aucun */ /* Sorties : Pop-up ou texte et fichier */ /* Utilité : Lis. affiche et stocke les données recues */ /*----------------------------------------------------------------------------------------------*/ void ReceiveData (void) { int i.\n"). readData). "Remote XON: An XON character was received. date. XON tells the other device that it can \n" " resume sending data.

} . fichier protégé en écriture"). sizeof(date). localtime(&heure)). "Impossible de compléter le fichier log.else MessagePopup ("Erreur". "%H:%M:%S". } /*----------------------------------------------------------------------------------------------*/ /* RetrieveCurrentTime */ /* Arguments : Aucun */ /* Sorties : Date sous forme de chaine de caractère */ /* Utilité : Crée une châine de caractère contenant l'heure */ /*----------------------------------------------------------------------------------------------*/ void RetrieveCurrentTime (void) { heure = time(NULL). strftime(date.

c * * Auteur: Alexandre Martins * * Date de révision: 05/04/2010 * * Version: 2. T_MSCAN_frame rx_message.data).can_tx_ready=0. unsigned char tableau[100] = "Telemetrie Zigbee -"./********************************************************************************** * Main. // Réglagle du prescaler à 2^6=64 } interrupt 11 void TIMER_int(void) { TFLG1 |= 0x08. INT8U can_rx_ready=0.i<200000. PTT = 0xFF.1 et 2 TSCR2 |= 0x06.i<200000. // disable RX interrupt } . // enable RX interrupt while(1) { RS232_snd_trame (rx_message. } interrupt CAN0RX_ISR void CAN_Rx_isr(void) { MSCAN0_Rx (&rx_message).i<200000. // Initialisation de la liaison série RS232_snd_msg (tableau). long i=0. CANRIER_RXFIE = 1. void main(void) { unsigned short cpt=0.h> /* common defines and macros */ #include <MC9S12C128. // Initialisation des registres EnableInterrupts.H" void initialisation_port(void). // Initialisation du bus CAN RS232_init(). // Extinction des LED TIOS &= ~0x07.h> /* derivative information */ #include "STAR12. for(i=0. initialisation_port(). //Activation à chaque fronts montants et fronts descendants TIE |= 0x07. // Initialisation des Timers MSCAN0_init(). CANRIER_RXFIE = 0. //Input capture pour T0 T1 T2 TSCR1 |= 0x80.H" #include "IDENTIFIER. PTT = 0x00. // Port T en sortie for(i=0. // Activation des interruptions TIMER_init(kPRE1). //Active le bloc de timer TCTL4 |= 0x3F. CANRIER_RXFIE = 1.i++). // Remise à zéro du Flag } interrupt SCI0_ISR void envoi_de_caractere(void) { RS232_sc ().i++). // Allumage des LED for(i=0. //Activation des interruptions sur les channels 0. // enable RX interrupt } } void initialisation_port(void) { DDRT = 0xFF.i++).1 * * Utilité : Programme main de la carte pour module Xbee * * * **********************************************************************************/ #include <hidef.

SCICR2 = 0x08. } else { i=0. // Désactivation des interruptions } } } /* * FUNCTION NAME: RS232_snd_msg * DESCRIPTION : Réalise l'émission d'un message terminé par le caractère '\0'. .h> /* common defines and macros */ #include <MC9S12C128.1 * * Utilité : Fonctions RS232 pour module Xbee * * * **********************************************************************************/ #include <hidef. // Broche TXD en mode sortie } /* * FUNCTION NAME: RS232_sc * DESCRIPTION : Réalise l'envoie d'un caractère ASCII sur la liason série * RETURN : void * PARAMETER 1 : INT8U caractère à envoyer */ void RS232_sc (void) { static char i=0. tmp=0. // Module d'emission seulement activé SCISR2 = 0x02. 8 bits. // Baudrate de 115200: 0x03 (valeur exacte:2.H" /******************************************************************************/ /* VARIABLES: */ /******************************************************************************/ void RS232_snd_trame (INT8U* chaine). i++. SCIBDL = 0x03./********************************************************************************** * rs232. * interruptions activées en réception * RETURN : void * PARAMETER 1 : void */ void RS232_init (void) { SCIBDH = 0x00. U8 BUFFERFULL. * l'envoie des caractère utilise le sémaphore BUFFEREMPTY * RETURN : void * PARAMETER 1 : INT8U* chaine de caractère à envoyer */ void RS232_snd_msg (INT8U* chaine) { char cpt=0.H" #include "IDENTIFIER. if ((SCISR1 & MASK_TDRE) == MASK_TDRE) { if (buffer[i]!='\0') { if (i==0) PTT &= ~MASK_LED_OUT. char buffer [512]. SCIDRL=buffer[i]. /******************************************************************************/ /* FUNCTIONS: */ /******************************************************************************/ /* * FUNCTION NAME: RS232_init * DESCRIPTION : Initialise la liaison série à 19200b/s. parité paire.c * * Auteur: Alexandre Martins * * Date de révision: 05/04/2010 * * Version: 2. CARAC.h> /* derivative information */ #include "STAR12. BUFFEREMPTY.71) SCICR1 = 0x04. SCICR2 &= ~0xC0. PTT |= MASK_LED_OUT.

} buffer [cpt+1] = '\0'. SCICR2 |= 0xC0. cpt++.cpt<8. SCICR2 |= 0xC0. //TCIE et TIE =1 (activation des interruptions) } void RS232_snd_trame (INT8U* chaine) { char cpt. //TCIE et TIE =1 (activation des interruptions) } .cpt++) { buffer[cpt]=chaine[cpt]. } buffer [cpt+1] = '\0'. for (cpt=0.while (chaine[cpt]!='\0') { buffer[cpt]=chaine[cpt].

CANBTR0 = ((3&(sjw-1))<<6) | ((baud_rate_prescaler-1) & 0x3f). sjw=2. INT8U time_segment_2. // Hit for all ID CANIDAR2 = 0x00.H" #include "STAR12. //enable CAN module CANCTL1_CLKSRC=0. CANIDAC = EIGTH_11BIT_ACCEPTANCE_FILTERS. // select the lowest free tx buffer ."CAN: no sychro"). CANCTL1_LISTEN=0. // enable RX interrupt // CANTIER = CANTIER_TXEIE_MASK. // and wait init mode ack } CANCTL1_LISTEN=0./********************************************************************************** * can. //quartz 10 Mhz time_segment_1 = 7. while (CANCTL1_CANE!=1). INT8U extra_sampling. INT8U EIGTH_11BIT_ACCEPTANCE_FILTERS = 0x10. INT8U * CANTXDSR = &CANTXDSR0. // Notes: baud_rate_prescaler*(time_segment_1+time_segment_2+1)=2*sys_clock_per_sec time_segment_2 = 2. // wait for ack // Attente de synchronisation du MSCAN while(!(CANCTL0&CANCTL0_SYNCH_MASK)) . // enable TX interrupt } INT8U MSCAN0_Tx (T_MSCAN_frame * p_message){ int i. CANIDMR0 = 0xFF. INT8U sjw. // Hit for all ID CANIDAR0 = 0x00.1 * * Utilité : Fonctions bus CAN pour module Xbee * * * **********************************************************************************/ #include "ERROR. CANIDMR3 = 0xFF. INT8U time_segment_1. // Hit for all ID CANIDAR1 = 0x00.h" #define NULL (void*)0 void MSCAN0_init(void){ INT8U baud_rate_prescaler.H" #include "pwm. if(CANCTL1_CANE!=1) CANCTL1_CANE=1. CANIDMR4 = 0xFF. CANCTL0 &= ~0x01. CANTBSEL = CANTFLG. CANIDMR1 = 0xFF. CANCTL1_CANE=1.c * * Auteur: Alexandre Martins * * Date de révision: 05/04/2010 * * Version: 2. // CANRIER = CANRIER_RXFIE_MASK. // initreq=0: exit from init mode while (CANCTL1_INITAK!=0). // then request for init mode while (CANCTL1_INITAK==0). extra_sampling = FALSE. CANCTL1_LOOPB=0. INT8U can_tx_buffer_num. ErrorIf(CANCTL0_SYNCH!=1. // Hit for all ID CANIDAR3 = 0x00. // Hit for all ID CANIDAR4 = 0x00. CANIDMR2 = 0xFF. CANBTR1 = ((1&extra_sampling)<<7)|((7&(time_segment_2-1))<<4)|(0x0F&(time_segment_1-1)). baud_rate_prescaler= 1. if (CANCTL1_INITAK==0){ // If not in init mode CANCTL0=CANCTL0_INITRQ_MASK .

} // Envoi un "drapeau"(message ne contenant pas de donnée) sur le bus CAN void CAN_EnvoiDrapeau(short int ID){ // NB : Vérifier que c'est bien while(! et non while( while(!MSCAN0_CheckTxBufReady()).unsigned char length.can_tx_buffer_num = CANTBSEL.remote_transmitt_request=0. canmess. for(i=0. i < p_message->length. return TRUE. p_message->length = CANRXDLR.i<length. unsigned char* mess) { INT8U C_R=0.data[i]=mess[i]. CANTFLG = can_tx_buffer_num. if(p_message->remote_transmitt_request) { CANTXIDR1 |= 0x10. // if (CANRXIDR1&0x08) return FALSE. CANTXIDR0 = (p_message->id&0xFC)>>3.i++) { canmess.id=ID. } INT8U MSCAN0_CheckRcvdMsg(void) { return (CANRFLG_RXF==1).} while (!C_R). CAN_EnvoiMess(ID. //ErrorIf (can_tx_buffer_num==0. i++) { p_message->data[i] = CANRXDSR[i]. if (CANRFLG_RXF==0) return FALSE. CANTXTBPR = p_message->priority.i++){ CANTXDSR[i] = p_message->data[i].i<p_message->length. } // Envoi un message sur le bus CAN void CAN_EnvoiMess(short int ID."CAN:No free buffer"). } CANTXDLR = p_message->length. p_message->remote_transmitt_request = (CANRXIDR1_SRR==1).0. // NB : Vérifier que c'est bien while(! et non while( while(!MSCAN0_CheckTxBufReady()).NULL). p_message->id = ((CANRXIDR0<<3)&0x0700) | (INT8U)(CANRXIDR0<<3) | (INT8U)(CANRXIDR1>>5). CANTXIDR1 = p_message->id<<5. unsigned char i. } canmess. T_MSCAN_frame canmess. for(i = 0. } INT8U MSCAN0_CheckTxBufReady(void) { return (CANTFLG_TXE!=0). INT8U i. } for (i=0. return FALSE. if (!can_tx_buffer_num) return TRUE. } CANRFLG &= ~0x01. do { C_R=MSCAN0_Tx(&canmess). canmess. } .length=length. } INT8U MSCAN0_Rx (T_MSCAN_frame * p_message){ INT8U * CANRXDSR = &CANRXDSR0.

} . MSCAN0_Tx(&canmess).id=ID. canmess.// Envoi une requête sur le bus CAN.remote_transmitt_request=1. canmess. void CAN_EnvoiReq(short int ID) { T_MSCAN_frame canmess. // NB : Vérifier que c'est bien while(! et non while( while(!MSCAN0_CheckTxBufReady()).

.

.

.

.

.

Université Paris-Sud IUT de Cachan Département Geii-1 Parcours [ROBO-OS] Année 2010

Rapport de projet de semestre S4

Asservissement du suivi de ligne par capteur CCD sur carte FPGA DE0
Kéléfa SANE

"Le véritable enseignement n'est point de te parler mais de te conduire." St Exupéry
Date de réception au secrétariat pédagogique : …/…/…. à …h… Impression : 06/04/10

............2......................................... 7 2.................................................................................... Comment activer les entrées/sorties LVDS de la DE0 ? ......... 8 2.................................................. Les raisons de ce choix ...............................................................................................................3...3........................................................4............................................................... 14 4.. Choix des différents éléments constituant la carte .2............................................................................................................................................................................................ Conception sur le logiciel Protel ............................................................................... 22 Kéléfa Sané Rapport de projet S4 Page 2 . Les commandes principales pour le mettre en œuvre .............................................................. Annexes ............ Le LVDS pour une communication plus sûre ...............1........ Assemblage de la carte CCD et de la carte LED ......................... 3 Mots-clés .................. 12 3................ 9 2......................................... Etude des composants LVDS ............................................................ Choix de la fréquence SCLK .......... Conception et réalisation de la carte d’acquisition CCD ............................................................................................................. 10 2............................................................2.................................................................................................... 3 Introduction ....................... Test de la carte d’acquisition et résultat des signaux échangés ...................... 3 1..... Traitement réalisé sur les valeurs des photodiodes ..........................................................1........................................ 18 4................................................................................................... 12 3......................................................................... 13 4........................................4.................................................................... 4 1........................................................................................................................................Table des matières Résumé ...........................................................................................................................................................6............................................................................................................ 3 1.............2..4............................................................................... 19 5.......................................... 5 2...... 16 4............................................................................. Conclusion ................................ 3 1............................. Implantation en VHDL .................................. Etude d’un nouveau capteur ........................................ 7 2.............................. 20 6................................................................................................... L’automate d’initialisation et de contrôle du capteur CCD .............................................................. 3 Abstract ............................................................................................................... 14 4........................................................ Mise en place de la communication LVDS .. 4 1.....................5... 16 4............................5.................................. Une forme particulière ... Bibliographie et sitographie ................................1....................................................................................... 7 2.......1. Description du capteur CCD TSL3301−LF ......3....... L’automate de stockage et de traitement ......................... Un dialogue via une interface série .................................................................................................................................... 10 3... 21 7................................................................................................................... Assemblage et test des cartes .......... ..............

est le TSL3301−LF un autre capteur CCD. les étudiants du parcours ROBOS de l’IUT de Cachan participe au concours de robotique inter IUT Geii à Vierzon. Mots-clés . Les raisons de ce choix Le suivi de ligne étant lié à un problème d’asservissement. the work that I have to do in the group is the control of the follow of line by sensor CCD on a FPGA card. son principe de fonctionnement. Le capteur retenu cette année par Monsieur Jacques-Olivier Klein enseignant à L’IUT. Pour obtenir une bonne stabilité il faut que la boucle de retour de l’asservissement soit la plus courte possible. avec notamment son principe de fonctionnement et les signaux à générer pour le mettre en œuvre. La première partie du travail que j’ai eu à réalisé fut l’étude de ce nouveau capteur. il sera traiter cette année par une carte FPGA la DE0 sur architecture cyclone III. 1. ou encore le OPB704 et le TSL1401R−LF un capteur CCD analogique qui a été utilisé l’année précédente pour le coupe de France de robotique. permettant des vitesses beaucoup plus grande pour le robot et une représentation plus précise et fiable de la ligne en mot binaire.TSL3301−LF . Kéléfa Sané Rapport de projet S4 Page 3 . les décisions stratégiques comme la prise du raccourci. la précision et la rapidité. un groupe d’étudiant de l’IUT de Cachan doivent concevoir un robot capable de suivre une ligne. Mon objectif a été de réaliser l’asservissement du suivi de ligne. qui est cependant complètement différent du TSL1401R−LF car celui ci est numérique. le critère majeur étant la stabilité. 1. le projet à été réparti entre ces 8 étudiants.Asservissement . comment le mettre en œuvre ensuite je devais réaliser la carte d’acquisition supportant le capteur et programmer sa mise en œuvre en VHDL afin de recueillir les informations nécessaire me permettant de délivrer les commandes moteurs pour que le robot puisse suivre la ligne. cela permettra de diminuer le temps introduit dans la boucle d’asservissement et ainsi d’avoir une stabilité importante. le travaille que je devais faire au sein de ce groupe est l’asservissement du suivi de ligne par capteur CCD sur une carte FPGA. le calcul de l’asservissement ayant été toujours effectuer par un microcontrôleur 16 bits le MC9S12DP256B. le stop figure resteront à la charge du microcontrôleur.Résumé Pour le concours de robotique réunissant les IUT Geii de France chaque année à Vierzon. Etude d’un nouveau capteur Il existe différents types de capteurs pour réaliser le suivi de ligne comme le CNY70. pour cela j’ai du étudier le capteur CCD sur lequel j’allai travailler. ceci explique le choix de ce capteur CCD numérique.capteur CCD -VHDL -carte FPGA DE0 Introduction Comme chaque année durant le semestre 4. il ya donc trois critères à prendre en compte : la stabilité. Cependant. utilisé lors de la Gamel trophy une compétition de robotique qui réunit les étudiants de premières années des deux départements GEII de l’IUT de Cachan.1. Abstract For the contest of robotics joining together the IUT Geii of France each year at Vierzon . a group of student of the IUT of Cachan must design a robot able to follow a line. cette année 8 étudiants vont devoir concevoir un robot capable de suivre une ligne le plus rapidement possible.

Figure 1 et Tableau 1). il est muni d’un convertisseur analogique numérique et communique à l’aide d’une interface série numérique. Il est constitué de 102 photodiodes arrangés sous forme d’un tableau à une dimension divisée en 3 zones de 34 photodiodes (gauche. deuxièmement on transmet comme données des octets c'est-à-dire des groupes de huit bits à la suite en commençant par un bit Start à 0 qui nous indique le début de la transmission. centre. Figure 2 et 3).2. Figure 1 Boitier du TSL3301−LF 1.1. droit). L’énergie lumineuse reçue par une photodiode génère un photo-courant qui est ensuite intégré par le circuit d’intégration associé à la photodiode. elle doit suivre un modèle déjà mis en place (cf.8 Entrée/Sortie Entrée Entrée Sortie Description Horloge système du capteur Tension d’alimentation positive (3V à 5.7 5. une capacité d’échantillonnage est connectée à la sortie de l’intégrateur par un commutateur analogue. Pendant la période d’intégration. on a la valeur d’intensité lumineuse reçue par les photodiodes sur 8 bit (de 0 à 255). Brochage du TSL3301−LF Broche SCLK Vdd SDIN SDOUT GND NC Numéro 1 2 3 4 6. Kéléfa Sané Rapport de projet S4 Page 4 . Figure 1).3. Cette communication est simple et se fait sur deux fils (SDIN et SDOUT). La quantité de charge accumulée par chaque photodiode est directement proportionnelle à l'intensité de la lumière sur cette photodiode et au temps d'intégration grâce au convertisseur analogique numérique intégré au capteur. puis le bit de poids faible B0 jusqu’au bit de poids fort B7 en terminant par un bit Stop à 1 pour la fin de transmission. Il dispose d’une seule sortie de données SDOUT. premièrement elle est de type synchrone donc il y a une horloge SCLK commune entre l’émetteur et le récepteur. Description du capteur CCD TSL3301−LF Le TSL3301−LF est un capteur CCD (Charge-Coupled Device) (dispositif à transfert de charge) fonctionnant sur une tension d’alimentation positive Vdd (cf. il a deux entrées une horloge synchronisation SCLK et une de commande SDIN. chacune d’elles pouvant être programmée avec un gain et offset différent. c’est la seule que le capteur peut supporter. Un dialogue via une interface série La communication établie entre le capteur CCD et la carte DE0 s’effectue à l’aide d’une liaison série. 1. Cependant il n’ya pas présence de bit de parité pour nous informer d’une erreur dans la transmission.5V) Entrée de données (les données sont synchronisées sur front montant de SCLK) Sortie de données (les données sont synchronisées sur front descendant de SCLK) Masse Non Connecté Le TSL3301−LF est implanté dans un boitier de type DIP 8 (cf.

Tableau 2) sont réparties en trois catégories reset (IRESET). Kéléfa Sané Rapport de projet S4 Page 5 . Il existe bien sur d’autres commandes comme ABORTPixel qui stoppe la lecture des valeurs des photodiodes dont je n’ai pas eu à avoir recours. Tableau 2). actions sur les photodiodes (STARTInt. Les commandes que j’ai utilisées (cf. REGRead). excepter pour la commande IRESET qui elle envoie une succession d’au moins 10 bits à 0. elle va permettre initialiser la machine d’état interne du capteur et ainsi l’utilisation par la suite des autres commandes. une fois ces commandes reçues cela va provoquer l’exécution de fonctions par le capteur comme par exemple IRESET la première commande qui doit être utiliser dès la mise sous tension du capteur. 2. Un délai plus long de 44 périodes d’horloge est requis pour READPixel qui va nous envoyer les valeurs des 102 photodiodes sur codé sur 8 bits en continu les unes après les autres séparées par des bits Stop et Start. SAMPLEInt. qui se fera au bout d’un certain temps pour REGRead. Figure 4) la commande est définie par l’octet <011a4_a3a2a1a0> (cf. il faut attendre un délai de 4 périodes d’horloge avant le début de la réponse qui sera envoyée sur SDOUT toujours avec le même protocole (cf.4.Figure 2 Format d’une trame d’entrée de données Figure 3 Format d’une trame de sortie de données 1. elles sont définies par des valeurs en octet et envoyées en suivant le protocole définit par la liaison série sur le signal SDIN (cf. Les commandes principales pour le mettre en œuvre Le TSL3301−LF est un capteur qui réagit uniquement à des commandes prédéfinies envoyées par un contrôleur numérique dans ce cas la carte FPGA DE0. Commandes du TSL3301−LF Commande IRESET STARTInt SAMPLEInt READPixel REGWrite REGRead Description Initialise la machine d’état interne du capteur Début de la période d’intégration des photo-courants Fin de l’intégration et enregistrement des valeurs d’intensité lumineuse reçu par les photodiodes Lecture des valeurs des 102 photodiodes Ecriture d’une valeur dans un registre Lecture de la valeur d’un registre Code à en entrer en binaire Au moins 10 bits à 0 0x08: <0000_1000> 0x10: <0001_0000> 0x02: <0000_0010> 0x40 <data>: <010a4_a3a2a1a0> <d7d6d5d4_d3d2d1d0> 0x60: <011a4_a3a2a1a0> Certaines commandes comme celle de lecture vont provoquer une réponse du capteur. les bit a0 à a4 représentent les 5 bit de poids faible de l’adresse du registre dont on veut lire la valeur. Figure 2). READPixel) et sur les registres (REGWrite.

donc les uniques valeurs que l’on peut mettre dans le registre sont 0x00 et 0x40. Tableau 2).Figure 4 Temps de réponse pour la commande REGRead Les 102 photodiodes du TSL3301−LF sont répartis en 3 groupes de 34 pour chaque groupe on peut programmer une valeur de gain et d’offset séparément des autres. Pour mettre une valeur dans un registre on utilise la commande REGWrite. 3. les valeurs d’offset et gain sont à définir dans des registres que l’on identifie grâce à leur adresse (cf. Tableau 3). il est nécessaire d’attendre une 1 milliseconde avant d’utiliser une commande pour permettre au capteur de sortir du SLEEP MODE. pour le mettre en SLEEP MODE il faut écrire la valeur 1 sur le bit 4 SLP (cf. Figure 5 Assignement des bits du registre Mode Kéléfa Sané Rapport de projet S4 Page 6 . le gain quant à lui est sur 5 bits et la valeur maximale que l’on peut régler est de 31 en décimal. Registres du TSL3301−LF Adresse du registre 0x00 0x01 0x02 0x03 0x04 0x05 0x1F Description du registre Offset photodiodes (0 à 33) Gain photodiodes (0 à 33) Offset photodiodes (34 à 67) Gain photodiodes (34 à 67) Offset photodiodes (66 à 101) Gain photodiodes (66 à 101) Mode de fonctionnement du capteur Taille du registre en bit 8 5 8 5 8 5 8 Le TSL3301−LF peut être mis en SLEEP MODE c'est-à-dire éteindre tous les circuits analogique du capteur. on règle une valeur d’offset sur 8 bits les valeurs allant de 0x00 à 0x7F représente un offset positif et de 0x80 à 0xFF un offset négatif. elle est définie en envoyant l’octet <010a4_a3a2a1a0> (cf. les autres bits du registre ne nous sont d’aucune utilité et doivent être mis à 0. les bits a0 à a4 représentent les 5 bit de poids faible de l’adresse du registre suivi de l’octet <d7d6d5d4_d3d2d1d0> qui représente la valeur que l’on veut mettre dans le registre. Figure 5) du registre ou 0 pour le mode normal de fonctionnement.

Le circuit FPGA Cyclone-III de la carte DE0 peut gérer directement des signaux LVDS en entrée et en sortie. le type de connecteur.2. j’ai dû réfléchir sur papier sur la forme de la carte. 2. Une forme particulière La forme et dimension de la carte m’ont été imposée. elle devait être de forme circulaire avec un diamètre de 5cm pour pouvoir être placé à l’intérieur d’un tube de forme conique et hermétique à la lumière extérieure. car elle devait s’intégrer dans un système déjà utilisé les années précédant et qui avait fait ses preuves.4V pour avoir un courant qui circule de 30mA. Figure 6 Routage de la carte LED 2. Conception et réalisation de la carte d’acquisition CCD Après avoir terminé l’étude du TSL3301−LF.1. le choix des différents composant leur emplacement et sur l’alimentation de la carte.2. le DS90LV017A pour émettre le signal SDOUT et le SN65LVDS9637 pour recevoir les signaux SCLK et SDIN. J’ai ensuite fait le schéma électrique et le routage de la carte à l’aide du logiciel de CAO Protel. Figure 6) alimentée en 12V permet d’éclairer la piste que le robot devra parcourir de l’intérieur du tube conique. J’ai donc choisi de placer les circuits suivant sur la carte CCD (cf. une résistance 82Ω est reliée en série avec 3 LED dont la tension de seuil est de 2. Le LVDS pour une communication plus sûre Au cours de ma réflexion sur la conception de la carte on m’a conseillé de mettre en place une communication de type LVDS (Low Voltage Differential Signaling) pour émettre les signaux SCLK. Figure 7 et 8). Figure 7 Boitier du SN65LVDS9637 Figure 8 Boitier du DS90LV017A Kéléfa Sané Rapport de projet S4 Page 7 . j’ai commencé la réalisation de la carte d’acquisition CCD qui permettra de mettre en œuvre le capteur. cette autre carte équipée de 12 LED blanche (cf. le LVDS est une norme de signalisation différentielle permettant de protéger les signaux à haute fréquence contre les parasites et bruit électrique. SDIN et SDOUT. La carte devait être assemblée à une autre carte grâce à un système de vis et d’écrous.

3V. Table de vérité du SN65LVDS9637 Entrée différentielle A. le circuit va ensuite effectuer une soustraction entre le signal non inversé A et le signal inversé B. Etude des composants LVDS J’ai choisi ces composants en fonction du nombre de signaux que j’avais à transmettre et de leur tension d’alimentation qui est de 3. Le SN65LVDS9637 reçoit en entrée les signaux différentiels des signaux SCLK et SDIN émis par la carte FPGA DE0 (cf.2.(cf. pour avoir une alimentation commune pour les 2 circuits LVDS et le capteur CCD. le signal non inversé D0+ et le signal inversé D0. Figure 9 Symbole logique du SN65LVDS9637 4. Table de vérité du DS90LV017A Entrée DI H Sortie DO+ H Sortie DOL L L H Voici un exemple des signaux différentiels du signal SDIN émis par la carte FPGA DE0 : Figure 11 Oscillogramme de signaux différentiels En jaune le signal non inversé et en bleu le signal inversé. le circuit va ensuite émettre en sortie les 2 signaux différentiels. B A-B >= 100mV -100mV < A-B < 100mV A-B <= -100mV Sortie Y H ? L Figure 10 Symbole logique du DS90LV017A 5. Figure 9). Kéléfa Sané Rapport de projet S4 Page 8 .3. si le résultat est supérieur ou égal à 100mV la sortie Y passe à l’état haut en revanche si elle est inférieure à ou égale à -100mV la sortie passe à l’état bas (cf. Le DS90LV017A va recevoir en entrée le signal SDOUT (DI) émis par le capteur CCD. Tableau 4). Figure 10 et Tableau 5).

Figure 13).3V à l’état haut. j’ai remarqué qu’il fallait mettre en place un schéma de câblage de 3 résistances(Rs et Rp) pour les signaux (SCLK et SDIN) allant de la carte FPGA DE0 au circuit LVDS SN65LVDS9637 pour qu’il soit bien transmis selon la norme LVDS c'est-à-dire en très base tension (de l’ordre du mV) car les signaux LVDS en sortie de la DE0 ont une gamme de tension allant de 0V à l’état bas et de 3. mais il faut toujours placer une résistance de 100Ω sur les 2 entrées différentielles de la DE0 (cf. mais elle sera intégrer dans la carte d’interface réalisée par mon collègue Nathan Clerbout qui relie tous les éléments du robot caméra. Figure 12 Schéma de câblage de la norme LVDS en sortie du Cyclone III Extrait de la datasheet du Cyclone III Pour le seul signal SDOUT allant de la carte CCD à la DE0 il n’est pas nécessaire de câbler les 3 résistances car les signaux en différentiels en sortie du DS90LV017A sont bien dans la gamme de tension de la norme LVDS. Cette carte me permettra de faire mes tests sur la chaine d’acquisition complète. en plaçant les 3 résistances Rs 120 Ω et Rp 160Ω pour les signaux SCLK et SDIN et la résistance de 100Ω sur les 2 entrées différentielles de la DE0 pour SDOUT. Il faut aussi placer une résistance de 100Ω entre les entrées différentielles du SN65LVDS9637 pour qu’il puisse comparer la différence de potentielle à ces bornes et délivrer la sortie qui correspond (cf. Figure 12).4. carte moteur.2. Figure 14). Mise en place de la communication LVDS En examinant la datasheet du Cyclone III. Figure 13 Schéma de câblage de la norme LVDS en entrée du Cyclone III Extrait de la datasheet du Cyclone III Suite à ça j’ai décidé de réaliser le schéma de câblage complet sur une carte Labdec (cf. carte CCD… Kéléfa Sané Rapport de projet S4 Page 9 .

2. Figure 15) c'est-à-dire le cablage électrique de tous les composants.6. ne trouvant pas dans la librairie Protel GEII1 certains des composants comme le capteur CCD TSL3301−LF et les circuits LVDS DS90LV017A et SN65LVDS9637 je les ai substitués par d’autres composants ayant les mêmes boitiers car l’objectif final est de faire un PCB et non de la simulation. pour cela j’ai d’abord étudié le tutorial du logiciel fait par Monsieur Hugues Angelis professeur à l’IUT de Cachan pour les étudiants. Conception sur le logiciel Protel Ayant tous les éléments en main j’ai pû passer à la phase de conception de la carte à l’aide du logiciel de CAO Protel. j’ai pu choisir le type de connecteur adapté. Choix des différents éléments constituant la carte Après avoir terminé la liste de tous les signaux communicants entre le capteur CCD et la carte DE0. Figure 15 Schematic de la carte d’acquisition CCD Kéléfa Sané Rapport de projet S4 Page 10 . j’ai commencé par réaliser le schematic de la carte (cf. il me fallait donc un connecteur 10 broches des résistances de 100Ω à placer sur les entrées différentielles des circuits LVDS et 3 capacités de découplage de 100 nF pour l’alimentation des circuits. cette carte étant la première carte que j’ai eu à réaliser sur Protel j’ai dû tout d’abord me familiariser avec le logiciel. Ce tutorial m’a permis de comprendre tout ce que je devais faire pour concevoir la carte.3V directement fourni par une broche de la DE0. sans oublier le signal d’alimentation VCC de 3. sachant qu’il ya 6 signaux différentiels et qu’il faut mettre une masse entre chaque paire positive et négative pour annuler les perturbations liées au magnétisme.5. pour le capteur il me fallait un composant avec un boitier DIP 8 et pour les circuits LVDS un boitier CMS 8 broches (SO8).Figure 14 Photographie de la carte d’adaptation LVDS 2.

en fonction de cela j’essayais de placé le reste des composants de façon à avoir des pistes le plus droit possible et faire le moins de strap ce fut un travail long et fastidieux. Figure 17 Routage de la carte d’acquisition CCD sans LVDS Kéléfa Sané Rapport de projet S4 Page 11 . Figure 16 Routage de la carte d’acquisition CCD J’ai du réaliser une deuxième carte me permettant de commencer mes tests en attendant l’arriver des composants LVDS qui ont dû être commandés (cf. le capteur CCD devait être placé au centre et sur le côté bottom pour être face à la piste.Le Schematic terminé je suis passé au routage de la carte (cf. Figure 17). je n’ai donc pas eu à la modifier. Figure 16) en dessinant les pistes reliant les composants. pour réaliser au mieux cette tâche j’ai réfléchi sur le placement des composants. mais cela en valait la peine car la carte à parfaitement bien fonctionné du premier coup.

5cm. Figure 18) grâce à un système vis écrou. j’ai aussi mis des rondelles en plastiques entre les cartes et les écrous afin d’isoler. Assemblage et test des cartes La phase de conception terminée j’ai dû réunir les différentes cartes. Figure 18). Figure 18 Photographie de l’assemblage des cartes CCD et LED Kéléfa Sané Rapport de projet S4 Page 12 .3.1. elle se trouve donc juste en dessous du capteur. Assemblage de la carte CCD et de la carte LED Les deux cartes tirées j’ai dû faire le perçage afin de pourvoir placer les composants à souder. ne connaissant pas la distance focal de la lentille j’ai du réaliser plusieurs essais. Une lentille mince convergente à été mis au centre de la carte LED. carte LED et carte DE0 (cf. j’ai aussi percé 4 trous grands sur les 2 cartes pour les assembler ensemble (cf. carte CCD. elle permet de polariser les rayons lumineux et ainsi avoir une meilleure vison de la position de la ligne vu par le capteur. la distance le plus approprié entre les 2 cartes que j’ai trouvé est de 2. me permettant de régler la distance entre les 2 cartes. pour commencer la phase de test de la chaine d’acquisition et ainsi corriger certains problèmes. Figure 18 Photographie du plan de travail 3.

2. Figure 19 Oscillogramme des signaux échangé entre la carte CCD et la DE0 - En jaune : SDIN En bleu : SDOUT Kéléfa Sané Rapport de projet S4 Page 13 . la commande n’était donc pas validé par la machine d’état interne du capteur. Figure 19). j’ai donc rectifier le problème dans mon automate de contrôle pour demander la prochaine lecture une fois la précédente terminer. Test de la carte d’acquisition et résultat des signaux échangés Lors de mon premier test j’ai remarqué que la lecture des pixels se faisait une fois sur deux après une commande lecture des valeurs des photodiodes (READPixel) ceux problème s’explique du fait que je demandais la lecture de la prochaine valeur des photodiodes alors que la lecture précédente n’était pas encore terminé. Les acquisitions de valeur photodiode se font donc bien les une à la suite et on attend bien 44 périodes d’horloges entre la commande READPixel et la lecture des valeurs (cf.3.

une nouvelle page va s’ouvrir. Figure 21). il a fallu que je réalise l’automate d’initialisation et de contrôle du capteur CCD et un autre automate en parallèle dont le but était de récupérer les valeurs des 102 photodiodes et de réaliser un traitement dessus pour recueillir les informations nécessaires pour réaliser l’asservissement du suivi de ligne.4. SDIN et SDOUT (cf. Figure 23). Comment activer les entrées/sorties LVDS de la DE0 ? Pour activer les entrées/sorties LVDS de la DE0 il faut aller dans l’onglet Assignement du logiciel Quartus puis sur Pins. Figure 23 Kéléfa Sané Rapport de projet S4 Page 14 . 4. ici ce sont les miens SCLK. Figure 22 Les signaux différentiels inversés sont aussi définis à la fin du tableau (cf. SDIN(n) et SDOUT(n) (cf. Implantation en VHDL La majeure partie de mon projet aura été de faire de la programmation en VHDL sur la carte FPGA DE0. Figure 20). Figure 21 On remarque par ailleurs que sur la colonne Differential Pair l’apparition des signaux différentiels inversés SCLK(n). Figure 22). si il est en entrée on remplace par LVDS (cf.3-V LVTTL par LVDS_E_3R si le signal est en sorite. dans le tableau on rechercher ses signaux. Figure 20 On doit ensuite modifier le I/O Standard en remplaçant 3.1.

Figure 24). dont les noms commencent par GPIO0_D[*] et GPIO1_D[*] avec un numéro entre crochet.Il faut ensuite les assignés sur les broches d’un des 2 connecteurs 40 broches de la DE0 qui sont définit dans les I/O Bank 3 et 4. Figure 25 Une fois les 2 broches supprimées on peut assigner le signal SCLK sur l’ancienne broche GPIO0_D[1] (cf. Je vais assigner SCLK sur la broche GPIO0_D[1] qui définit en Location par PIN_AA16. il nous dit que le broche est déjà assigné (cf. Figure 26 Kéléfa Sané Rapport de projet S4 Page 15 . Figure 25).Figure 25). Figure 24 On doit donc trouver dans le tableau la broche GPIO0_D[1] est la supprimer ainsi que la broche dont la Location est PIN_AB16 (GPIO0_D[0]) (cf. un message d’erreur apparait.

Remise à 1 du compteur cpt. Entrer de l’adresse du registre d’Offset. Attente de 30 périodes d’horloge avant l’utilisation d’une commande pour garantir l’état de la sortie SDOUT. on m’a donc conseillé de prendre une fréquence qui me permettre de faire une acquisition de valeur de photodiodes en 1ms. en commençant par le bit Start suivit bit de poids faible jusqu’au bit de poids fort et terminer par le Stop. j’ai donc pris une fréquence de 1Mhz pour SCLK. utilisant l’horloge a quartz de 50Mhz de la carte DE0. la sortie SDIN va prendre successivement les valeurs des bits l’octet <0101_1111> à chaque période d’horloge. Choix de la fréquence SCLK En regardant le datasheet du TSL3301−LF j’ai vu que la fréquence max que l’on pouvait appliquer à SCLK était de 10Mhz. Entrer de la commande de début d’intégration des photodiodes <0000_1000>.3. Attente de 1ms. Attente minimum de 22 périodes d’horloge pour l’intégration de toutes les photodiodes. Entrer de l’adresse du registre du Gain. Attente de 44 périodes avant la lecture de la valeur de la première photodiode. L’automate d’initialisation et de contrôle du capteur CCD Avant de coder mon automate j’ai dû d’abord commencer par réaliser son diagramme d’état (cf. Voir en annexes pour le code source VHDL 4. Attente de la fin de lecture. Attente de 5 périodes d’horloge entre chaque commande Ecriture de la valeur <0000_0000> dans le registre Mode en commençant par un Start et en terminant par un Stop. pur permettre au capteur de sortir du SLEEP MODE.2. Ecriture d’une valeur dans le registre d’Offset <0000_0000>. cette état initialiser la machine d’état interne du capteur. Wait 5 MODE WRITE Wait 1ms Reset cpt Reg Add G Reg Write G Reg Add O Red Write O START Init Wait 22 Sample Init READ Pixel Wait 44 Wait End Read Kéléfa Sané Rapport de projet S4 Page 16 . Entrer de l’adresse du registre Mode afin d’y écrire une valeur.33Mhz cependant je n’arrivais pas avoir sur l’oscilloscope le résultat de ma programmation pour la détection de la ligne blanche.Le signal différentiel inversé SCLK(n) est quant à lui directement assigné en même temps sur l’ancienne broche GPIO0_D[0] dons le Location était PIN_AB16 (cf. Figure 27 Pour les autres signaux il suffit de refaire les mêmes manipulations en assignant les signaux différentiels non inversé SDIN et SDOUT sur des broches dont la Location commence par PIN_AA suivi d’un numéro les signaux inversé SDIN(n) et SDOUT(n) seront directement assigné sur les broches dont la Location commence par PIN_AB suivi du même numéro. Entrer de la commande de fin d’intégration et d’enregistrement des valeurs d’intensité lumineuse reçue par les photodiodes <0001_0000>. Ecriture d’une valeur dans le registre de Gain <0000_0001>.Figure 28 et Tableau 4) avec l’aide de toutes les informations que j’avais pu extraire de la datasheet du TSL3301−LF 4. Entrer de la commande de lecture des 102 photodiodes <0000_0010>. j’ai décidé de faire un diviseur de fréquence par 6 pour ainsi avoir un signal SCLK à 8. Description des états de l’automate de contrôle Etat INIT IRESET Wait 30 MODE REG Description Attente de 10 périodes d’horloge avec SDIN à 1 dès la mise sous tension du capteur Au moins 10 périodes d’horloges avec SDIN à 0. l’état ne de dure qu’une période d’horloge.Figure 27). 4.

Figure 28 Diagramme d’état de l’automate d’initialisation et de contrôle Kéléfa Sané Rapport de projet S4 Page 17 .

Figure 29 Oscillogramme du signal de contrôle SDIN du capteur CCD : Entrer de la commande STARTInit : Attente des 22 périodes d’horloges pour l’intégration : Entrer de la commande SAMPLEInit : Attente de 5 périodes d’horloge entre chaque commande : Entrer de la commande READPixel Voir en annexes pour le code source VHDL 4. 5.4. L’automate de stockage et de traitement L’automate de stockage tourne en parallèle avec l’automate d’initialisation son objectif et de stocker les valeurs des pixels dans un tableau puis de réaliser des traitements sur ces valeurs pour pouvoir récupérer les informations afin de réaliser l’asservissement du suivi de ligne en délivrant les commandes moteurs (cf. j’ai choisi de mettre un gain de 1 et un offset nulle car la carte LED éclaire suffisamment bien la piste. SAMPLEInit et READPixel et attente des 44 périodes d’horloge Stockage des valeurs de 102 photodiodes dans un tableau Traitement des valeurs Kéléfa Sané Rapport de projet S4 Page 18 . Description des états de l’automate de stockage et de traitement Etat INIT 2 Reset cpt pix Config Acquisition Stocker val pix Wait Description Initialisation du capteur Remise à 1 du compteur cpt pix Configuration du capteur (écriture des valeurs de gain et d’offset dans les registres) Entrer des commandes STARTInit.Figure 30 et Tableau 5).Pour le réglage du gain et de l’offset l’automate va faire 3 fois le tour de la première boucle pour entrer les valeurs de gain et d’offset des 3 groupes de 34 photodiodes. Après avoir initialisé le capteur l’automate va rester enfermé dans la deuxième boucle ou il va envoyer des commandes intégrations des photodiodes et de lecture.

end loop. Pour effectuer la binarisation j’ai fais une boucle for dans laquelle je test la valeur des photodiodes enregistrer dans le tableau tab_val_pix si la valeur est supérieur au seuil que j’ai choisi à l’aide des boutons de la carte DE0 je mets 1 dans un dans un nouveau tableau tab_pix_bnarise si par contre la valeur est inférieur je mets 0. else tab_pix_binarise(i)<='0'.Figure 30 Diagramme d’état de l’automate stockage et traitement Voir en annexes pour le code source VHDL 4. Traitement réalisé sur les valeurs des photodiodes Afin de bien détecter la ligne blanche de la moquette bleue j’ai réalisé différent traitement en VHDL comme une binarisation et une érosion. begin case etat_val_pix is when wait_2 => tab_indice_pixel_noir<=tab_indice_pixel_init. VARIABLE y : INTEGER RANGE 0 TO 101. tab_indice_pixel_blanc<=tab_indice_pixel_init. Kéléfa Sané Rapport de projet S4 Page 19 . VARIABLE k : INTEGER RANGE 0 TO 101.process de traitement des pixels suppression des pixels isolés VARIABLE j : INTEGER RANGE 0 TO 101.5. for i in 0 to 101 loop if (to_integer(tab_val_pix(i))>seuil) then tab_pix_binarise(i)<='1'. end if. process(etat_val_pix) --.

cpt_indice_pixel_modif<=0. cpt_indice_pixel_modif<=cpt_indice_pixel_modif+1. 5.Figure 31). end loop. for i in 1 to 100 loop if (tab_indice_pixel_noir(i)/=0) then tab_pix_binarise(tab_indice_pixel_noir(i))<='0'. qui vérifie si les 2 bits des extrémités sont égaux et que celui du milieu est différent. cpt_indice_pixel_modif<=cpt_indice_pixel_modif+1. Figure 31 Oscillogramme de la détection de la ligne Kéléfa Sané Rapport de projet S4 Page 20 . Je fais ensuite un test sur ce nouveau tableau si les valeurs du tableau sont différentes de zéro alors je change la valeur du tableau. elsif (tab_indice_pixel_blanc(i)/=0) then tab_pix_binarise(tab_indice_pixel_blanc(i))<='1'. y:=y-1. Je dois ensuite placer les nouvelles valeurs dans nouveau tableau sauf la première et la dernière. end loop. J’ai aussi pu mètre en pratique toutes les notions que j’ai apprise à l’IUT comme la programmation en VHDL et en découvrir d’autre la conception de carte sur protel. end loop. si c’est le cas j’enregistre l’indice du tableau dont il faut changer la valeur dans un nouveau tableau. end if. for i in 1 to 100 loop tab_pix_binarise_100(i)<=tab_pix_binarise(y). elsif (tab_pix_binarise(i-1)='1' and tab_pix_binarise(i)='0' and tab_pix_binarise(i+1)='1') then tab_indice_pixel_blanc(cpt_indice_pixel_modif)<=i. end if. J’ai aussi découvert le travaille en autonomie au sein d’un groupe et je pense que cette expérience sera une bonne préparation à mon stage. y:=100. Conclusion Par manque de temps et du retard que j’ai pris en restant bloqué sur certaines tâches je n’ais pas pu terminer mon projet de S4. Pour faire l’érosion qui permet de supprimer les pixels isolé je fais une opération majoritaire à trois bits.for i in 1 to 100 loop if (tab_pix_binarise(i-1)='0' and tab_pix_binarise(i)='1' and tab_pix_binarise(i+1)='0') then tab_indice_pixel_noir(cpt_indice_pixel_modif)<=i. cependant le travaille que je réalisé permet d’obtenir une détection de ligne net et précise comme on l’espérait (cf.

6.com/literature/hb/cyc3/cyc3_ciii5v1.com/datasheet-pdf/pdf/203056/TAOS/TSL3301-LF.pdf [4]Documentation technique du Cyclone III: http://www.alldatasheet.chez.com/syntaxe.pdf [5] Syntaxe VHDL: http://amouf.altera.html [2]Documentation technique du SN65LVDS9637: http://www. Bibliographie et sitographie [1]Documentation technique du capteur CCD TSL3301−LF: http://www.national.htm Kéléfa Sané Rapport de projet S4 Page 21 .com/ds/DS/DS90LV017A.datasheetcatalog.pdf [3]Documentation technique du DS90LV017A : http://www.org/datasheet2/e/0ltco5la8l7r3jw47est6103i2ky.

if (cpt1 = 24) then cpt1 <= 0. end architecture . begin SCLK_OUT<=sig_SCLK.all. end entity.7. use ieee. Kéléfa Sané Rapport de projet S4 Page 22 . architecture a1_div_de_freq of div_de_freq is signal cpt1: integer range 0 to 100000:=0. signal sig_SCLK : std_logic := '0'.all. end if. Annexes Diviseur de fréquence library ieee. else cpt1 <= cpt1 + 1.numeric_std. entity div_de_freq is port( clk: in std_logic.std_logic_1164. sig_SCLK <= not sig_SCLK. process begin wait until rising_edge(clk). SCLK_OUT: out std_logic). use ieee. end process.

reset_cpt_1.Automate d’initialisation et de contrôle library ieee. signal etat: etat_type:=init. signal mode_valeur: unsigned(7 downto 0):="00000000". signal ReadPixel: unsigned(7 downto 0):="00000010". reg_address_G. signal reg_address_center_gain: unsigned(7 downto 0):="01000011".reg_address_O. signal reg_address_center_offset: unsigned(7 downto 0):="01000010". use ieee. wait5_6. signal reg_address_right_gain: unsigned(7 downto 0):="01000101". reset_cpt_2. stop<='1'. signal reg_write_right_offset: unsigned(7 downto 0):="00000000". signal StartInt: unsigned(7 downto 0):="00001000". signal reg_write_center_gain: unsigned(7 downto 0):="00000001". signal mode_address: unsigned(7 downto 0):="00011111". signal reg_address_left_gain: unsigned(7 downto 0):="01000001". signal reg_write_left_offset: unsigned(7 downto 0):="00000000". signal reg_address_right_offset: unsigned(7 downto 0):="01000100".numeric_std.all.wait5_5. wait_1ms. SDIN: out std_logic.std_logic_1164. wait22. wait919).wait5_4. reg_write_G. signal reg_write_right_gain: unsigned(7 downto 0):="00000001". stock: out std_logic). wait5_3. mode_write.read_pix. cpt <= 1.reg_write_O.wait5_2. else when wait_1ms => if cpt=30080 Kéléfa Sané Rapport de projet S4 Page 23 .CPT COMPTEUR avec remise à zero suivant les états begin wait until falling_edge (SCLK_OUT). wait44. use ieee. signal stop : std_logic. sample_int. signal cpt: integer range 0 to 9000:=0. then cpt<=0. case etat is when reset_cpt_1 => when reset_cpt_2 => cpt <= 1. end entity. begin start<='0'. wait5_1. entity automate_ccd_initialisation_controle is port( SCLK_OUT: in std_logic.all. signal reg_write_center_offset: unsigned(7 downto 0):="00000000". architecture a1_automate_ccd_initialisation_controle of automate_ccd_initialisation_controle is type etat_type is (init. ireset. start_int. signal SampleInt: unsigned(7 downto 0):="00010000". signal reg_address_left_offset: unsigned(7 downto 0):="01000000". signal start : std_logic. signal reg_write_left_gain: unsigned(7 downto 0):="00000001". signal cpt_stock: integer range 0 to 9000:=1. wait30. mode_reg. process -.

else etat<=ireset. when wait30 => if cpt=55 then etat<=mode_reg.cpt<=cpt+1. else etat<=init. when wait5_1 => if cpt=70 then etat<=mode_write. when wait5_3 => if cpt=30 or cpt=90 or cpt=150 then etat<=reg_address_O. end if. end if. when wait5_4 => if cpt=45 or cpt=105 or cpt=165 then etat<=reg_write_O. end if. else etat<=wait5_2. Kéléfa Sané Rapport de projet S4 Page 24 . when reset_cpt_1 => etat<=reg_address_G. else etat<=wait_1ms. end if. else etat<=mode_write. else etat<=mode_reg. end process. when reg_address_G => if cpt=10 or cpt=70 or cpt=130 then etat<=wait5_2. when reg_write_G => if cpt=25 or cpt=85 or cpt=145 then etat<=wait5_3. when mode_reg => if cpt=65 then etat<=wait5_1.calcul de l'état futur begin wait until falling_edge (SCLK_OUT). else etat<=wait5_3. end if. else etat<=reg_address_G. end if. end if. when others => cpt<=cpt+1. when ireset => if cpt=25 then etat<=wait30. when reg_address_O => if cpt=40 or cpt=100 or cpt=160 then etat<=wait5_4. end if. case etat is when init => if cpt=10 then etat<=ireset. end if. end if. end if. else etat<=reg_address_O. else etat<=reg_write_G. end if. else etat<=wait5_1. when mode_write => if cpt=80 then etat<=wait_1ms. process -. end if. end case. when wait5_2 => if cpt=15 or cpt=75 or cpt=135 then etat<=reg_write_G. else etat<=wait30. when wait_1ms => if cpt=8415 then etat<=reset_cpt_1.

else etat<=wait22. when wait5_5 => if cpt=60 or cpt=120 then etat<=reg_address_G.else etat<=wait5_4. end if. when wait44 => if cpt=101 then etat<=wait919. end if. else etat<=wait5_5. end if.sorties en fontction de l'état begin case etat is when mode_reg => if cpt=56 then SDIN<=start. elsif cpt=57 then SDIN<=mode_address(0). elsif cpt=59 then SDIN<=mode_address(2). when sample_int => if cpt=42 then etat<=wait5_6.cpt) -. else etat<=wait5_6. end if. when reset_cpt_2 => etat<=start_int. Kéléfa Sané Rapport de projet S4 Page 25 . end if. else etat<=wait44. when start_int => if cpt=10 then etat<=wait22. end if. else etat<=start_int. when wait5_6 => if cpt=47 then etat<=read_pix. elsif cpt=60 then SDIN<=mode_address(3). else etat<=sample_int. end if. when wait919 => if cpt=1121 then etat<=reset_cpt_2. else etat<=wait919. elsif cpt=180 then etat<=reset_cpt_2. end case. elsif cpt=62 then SDIN<=mode_address(5). elsif cpt=61 then SDIN<=mode_address(4). else etat<=read_pix. elsif cpt=63 then SDIN<=mode_address(6). when wait22 => if cpt=32 then etat<=sample_int. end process. elsif cpt=58 then SDIN<=mode_address(1). end if. when read_pix => if cpt=57 then etat<=wait44. else etat<=reg_write_O. end if. when reg_write_O => if cpt=55 or cpt=115 or cpt=175 then etat<=wait5_5. end if. process (etat.

elsif cpt=125 Kéléfa Sané Rapport de projet S4 Page 26 . elsif cpt=62 then SDIN<=reg_address_center_gain(0). end if. elsif cpt=76 then SDIN<=mode_valeur(4). elsif cpt=9 then SDIN<=reg_address_left_gain(7). elsif cpt=70 then SDIN<=stop. elsif cpt=72 then SDIN<=mode_valeur(0). elsif cpt=3 then SDIN<=reg_address_left_gain(1). elsif cpt=122 then SDIN<=reg_address_right_gain(0). elsif cpt=75 then SDIN<=mode_valeur(3). end if. elsif cpt=121 then SDIN<=start. elsif cpt=7 then SDIN<=reg_address_left_gain(5). elsif cpt=64 then SDIN<=reg_address_center_gain(2). elsif cpt=4 then SDIN<=reg_address_left_gain(2). elsif cpt=5 then SDIN<=reg_address_left_gain(3). elsif cpt=2 then SDIN<=reg_address_left_gain(0). elsif cpt=77 then SDIN<=mode_valeur(5). elsif cpt=73 then SDIN<=mode_valeur(1). elsif cpt=74 then SDIN<=mode_valeur(2). elsif cpt=66 then SDIN<=reg_address_center_gain(4). elsif cpt=68 then SDIN<=reg_address_center_gain(6). elsif cpt=78 then SDIN<=mode_valeur(6). elsif cpt=67 then SDIN<=reg_address_center_gain(5). when mode_write => if cpt=71 then SDIN<=start. elsif cpt=69 then SDIN<=reg_address_center_gain(7). elsif cpt=124 then SDIN<=reg_address_right_gain(2). elsif cpt=6 then SDIN<=reg_address_left_gain(4).elsif cpt=64 then SDIN<=mode_address(7). elsif cpt=80 then SDIN<=stop. elsif cpt=63 then SDIN<=reg_address_center_gain(1). elsif cpt=65 then SDIN<=stop. elsif cpt=123 then SDIN<=reg_address_right_gain(1). elsif cpt=79 then SDIN<=mode_valeur(7). elsif cpt=8 then SDIN<=reg_address_left_gain(6). elsif cpt=10 then SDIN<=stop. when reg_address_G => if cpt=1 then SDIN<=start. elsif cpt=61 then SDIN<=start. elsif cpt=65 then SDIN<=reg_address_center_gain(3).

elsif cpt=82 then SDIN<=reg_write_center_gain(5). elsif cpt=18 then SDIN<=reg_write_left_gain(1). elsif cpt=143 then SDIN<=reg_write_right_gain(6).then SDIN<=reg_address_right_gain(3). elsif cpt=80 then SDIN<=reg_write_center_gain(3). elsif cpt=83 then SDIN<=reg_write_center_gain(6). elsif cpt=126 then SDIN<=reg_address_right_gain(4). elsif cpt=84 then SDIN<=reg_write_center_gain(7). elsif cpt=79 then SDIN<=reg_write_center_gain(2). end if. elsif cpt=145 then SDIN<=stop. elsif cpt=24 then SDIN<=reg_write_left_gain(7). elsif cpt=78 then SDIN<=reg_write_center_gain(1). elsif cpt=81 then SDIN<=reg_write_center_gain(4). elsif cpt=17 then SDIN<=reg_write_left_gain(0). elsif cpt=76 then SDIN<=start. elsif cpt=77 then SDIN<=reg_write_center_gain(0). elsif cpt=141 then SDIN<=reg_write_right_gain(4). elsif cpt=137 then SDIN<=reg_write_right_gain(0). elsif cpt=136 then SDIN<=start. elsif cpt=129 then SDIN<=reg_address_right_gain(7). elsif cpt=25 then SDIN<=stop. elsif cpt=20 then SDIN<=reg_write_left_gain(3). elsif cpt=139 then SDIN<=reg_write_right_gain(2). elsif cpt=144 then SDIN<=reg_write_right_gain(7). elsif cpt=22 then SDIN<=reg_write_left_gain(5). elsif cpt=140 then SDIN<=reg_write_right_gain(3). when reg_address_O => if cpt=31 then SDIN<=start. elsif cpt=142 then SDIN<=reg_write_right_gain(5). elsif cpt=19 then SDIN<=reg_write_left_gain(2). elsif cpt=138 then SDIN<=reg_write_right_gain(1). end if. elsif cpt=85 then SDIN<=stop. elsif cpt=23 then SDIN<=reg_write_left_gain(6). elsif cpt=21 then SDIN<=reg_write_left_gain(4). Kéléfa Sané Rapport de projet S4 Page 27 . when reg_write_G => if cpt=16 then SDIN<=start. elsif cpt=127 then SDIN<=reg_address_right_gain(5). elsif cpt=128 then SDIN<=reg_address_right_gain(6). elsif cpt=130 then SDIN<=stop.

elsif cpt=98 then SDIN<=reg_address_center_offset(6). elsif cpt=35 then SDIN<=reg_address_left_offset(3). elsif cpt=152 then SDIN<=reg_address_right_offset(0). elsif cpt=33 then SDIN<=reg_address_left_offset(1). elsif cpt=48 then SDIN<=reg_write_left_offset(1). elsif cpt=97 then SDIN<=reg_address_center_offset(5). elsif cpt=53 then SDIN<=reg_write_left_offset(6). elsif cpt=159 then SDIN<=reg_address_right_offset(7). elsif cpt=157 then SDIN<=reg_address_right_offset(5). elsif cpt=49 then SDIN<=reg_write_left_offset(2). elsif cpt=156 then SDIN<=reg_address_right_offset(4). elsif cpt=38 then SDIN<=reg_address_left_offset(6). elsif cpt=100 then SDIN<=stop.elsif cpt=32 then SDIN<=reg_address_left_offset(0). elsif cpt=99 then SDIN<=reg_address_center_offset(7). elsif cpt=93 then SDIN<=reg_address_center_offset(1). elsif cpt=153 then SDIN<=reg_address_right_offset(1). elsif cpt=50 then SDIN<=reg_write_left_offset(3). end if. elsif cpt=40 then SDIN<=stop. elsif cpt=95 then SDIN<=reg_address_center_offset(3). elsif cpt=155 then SDIN<=reg_address_right_offset(3). elsif cpt=96 then SDIN<=reg_address_center_offset(4). elsif cpt=34 then SDIN<=reg_address_left_offset(2). elsif cpt=92 then SDIN<=reg_address_center_offset(0). elsif cpt=154 then SDIN<=reg_address_right_offset(2). elsif cpt=37 then SDIN<=reg_address_left_offset(5). elsif cpt=94 then SDIN<=reg_address_center_offset(2). elsif cpt=47 then SDIN<=reg_write_left_offset(0). elsif cpt=51 then SDIN<=reg_write_left_offset(4). elsif cpt=91 then SDIN<=start. elsif cpt=54 Kéléfa Sané Rapport de projet S4 Page 28 . when reg_write_O => if cpt=46 then SDIN<=start. elsif cpt=36 then SDIN<=reg_address_left_offset(4). elsif cpt=151 then SDIN<=start. elsif cpt=52 then SDIN<=reg_write_left_offset(5). elsif cpt=158 then SDIN<=reg_address_right_offset(6). elsif cpt=160 then SDIN<=stop. elsif cpt=39 then SDIN<=reg_address_left_offset(7).

elsif cpt=174 then SDIN<=reg_write_right_offset(7). elsif cpt=106 then SDIN<=start. when sample_int =>if cpt=33 then SDIN<=start. elsif cpt=171 then SDIN<=reg_write_right_offset(4). elsif cpt=110 then SDIN<=reg_write_center_offset(3). elsif cpt=10 then SDIN<=stop. elsif cpt=2 then SDIN<=StartInt(0). elsif cpt=166 then SDIN<=start. elsif cpt=3 then SDIN<=StartInt(1). elsif cpt=55 then SDIN<=stop. elsif cpt=108 then SDIN<=reg_write_center_offset(1). end if. elsif cpt=7 then SDIN<=StartInt(5). elsif cpt=170 then SDIN<=reg_write_right_offset(3). when start_int => if cpt=1 then SDIN<=start. elsif cpt=111 then SDIN<=reg_write_center_offset(4). elsif cpt=114 then SDIN<=reg_write_center_offset(7). elsif cpt=168 then SDIN<=reg_write_right_offset(1). elsif cpt=167 then SDIN<=reg_write_right_offset(0). elsif cpt=107 then SDIN<=reg_write_center_offset(0). elsif cpt=4 then SDIN<=StartInt(2). elsif cpt=36 then SDIN<=SampleInt(2). elsif cpt=115 then SDIN<=stop. elsif cpt=9 then SDIN<=StartInt(7). elsif cpt=173 then SDIN<=reg_write_right_offset(6).then SDIN<=reg_write_left_offset(7). elsif cpt=35 then SDIN<=SampleInt(1). elsif cpt=6 then SDIN<=StartInt(4). elsif cpt=109 then SDIN<=reg_write_center_offset(2). elsif cpt=113 then SDIN<=reg_write_center_offset(6). elsif cpt=175 then SDIN<=stop. elsif cpt=8 then SDIN<=StartInt(6). elsif cpt=37 then SDIN<=SampleInt(3). elsif cpt=169 then SDIN<=reg_write_right_offset(2). Kéléfa Sané Rapport de projet S4 Page 29 . elsif cpt=5 then SDIN<=StartInt(3). elsif cpt=172 then SDIN<=reg_write_right_offset(5). elsif cpt=34 then SDIN<=SampleInt(0). end if. elsif cpt=112 then SDIN<=reg_write_center_offset(5).

cpt_stock<=1. elsif cpt=42 then SDIN<=stop. Kéléfa Sané Rapport de projet S4 Page 30 . stock<='1'. case etat is when wait919 => if(cpt_stock=1020) then cpt_stock<=1. stock<='0'. elsif cpt=57 then SDIN<=stop.elsif cpt=38 then SDIN<=SampleInt(4).CPT COMPTEUR avec remise à zero suivant les états begin wait until falling_edge (SCLK_OUT). end if. elsif cpt=53 then SDIN<=ReadPixel(4). end architecture . end process. elsif cpt=55 then SDIN<=ReadPixel(6). process -. elsif cpt=49 then SDIN<=ReadPixel(0). elsif cpt=39 then SDIN<=SampleInt(5). end case. else cpt_stock<=cpt_stock+1. when others => end case. elsif cpt=52 then SDIN<=ReadPixel(3). elsif cpt=40 then SDIN<=SampleInt(6). elsif cpt=51 then SDIN<=ReadPixel(2). when wait919 => SDIN<='1'. end process. when read_pix => if cpt=48 then SDIN<=start. elsif cpt=56 then SDIN<=ReadPixel(7). elsif cpt=50 then SDIN<=ReadPixel(1). end if. when others => SDIN<='1'. end if. elsif cpt=41 then SDIN<=SampleInt(7). elsif cpt=54 then SDIN<=ReadPixel(5).

signal tab_indice_pixel_blanc:tab2. SDOUT_sonde: out std_logic. prem_pixel_blanc: inout integer range 0 to 255. signal stop : std_logic. signal tab_pix_binarise_100:tab3. signal tab_val_pix:tab. end entity.all. signal etat_val_pix: etat_type_val_pix:=init_2. ligne: out std_logic). reset_cpt_pix_2. pwm_mot_droit: out unsigned (7 downto 0).std_logic_1164. type tab is array (0 to 101) of unsigned (7 downto 0). use ieee. Kéléfa Sané Rapport de projet S4 Page 31 . architecture a1_automate_ccd_stokage_pixel of automate_ccd_stokage_pixel is type etat_type_val_pix is (init_2. seuil<=to_integer(SWITCH_SEUIL). with SDOUT select SDOUT_unsigned<="0" when '0'. type tab2 is array (0 to 101) of integer range 0 to 101. signal seuil: integer range 0 to 255. acquisition. pwm_mot_gauche: out unsigned (7 downto 0). signal tab_pix_binarise:tab1. config. process(etat_val_pix) begin case etat_val_pix is when init_2 => for i in 0 to 101 loop tab_indice_pixel_init(i)<=0. signal SDOUT_unsigned: unsigned(0 downto 0). SDOUT: in std_logic. reset_cpt_pix_1. entity automate_ccd_stokage_pixel is port( SCLK_OUT: in std_logic. stocker_val_pix. tab_pix_binarise_100(101)<='0'. cpt_indice_colonne_tab_val_pix: integer range 0 to 9:=0. start<='0'. der_pixel_blanc: inout integer range 0 to 255.numeric_std. wait_2). signal tab_indice_pixel_noir:tab2. cpt_indice_pixel_modif: integer range 0 to 101:=0. reset_cpt_pix_3. signal start : std_logic. "1" when others. use ieee. sui_ligne: out std_logic. type tab3 is array (0 to 101) of std_logic. stop<='1'. tab_max_pix: out unsigned(7 downto 0). begin SDOUT_sonde<=SDOUT. signal signal signal signal cpt_val_pix: integer range 0 to 9000:=0. type tab1 is array (0 to 101) of std_logic. tab_min_pix: out unsigned(7 downto 0). tab_pix_binarise_100(0)<='0'.Automate de stockage et de traitement library ieee. end loop. cpt_indice_ligne_tab_val_pix: integer range 0 to 101:=0. signal tab_indice_pixel_init:tab2.all. SWITCH_SEUIL: in unsigned (7 downto 0).

begin case etat_val_pix is when wait_2 => tab_max_val_pix:="00000000". end loop. end loop. end if. end if. for i in 0 to 101 loop if (to_integer(tab_val_pix(i))>seuil) then tab_pix_binarise(i)<='1'. process(etat_val_pix)--process qui chercher les valeur min et max des pix variable tab_max_val_pix:unsigned(7 downto 0). tab_max_pix<=tab_max_val_pix.etat_val_pix) -. tab_min_val_pix:="11111111". when others => NULL.cpt_indice_colonne_tab_val_pix. for i in 1 to 100 loop Kéléfa Sané Rapport de projet S4 Page 32 . end process. for i in 0 to 101 loop if(to_integer(tab_min_val_pix)>to_integer(tab_val_pix(i))) then tab_min_val_pix:=tab_val_pix(i). tab_min_pix<=tab_min_val_pix. end case. end process.when others => null. end loop. end process. end case. VARIABLE y : INTEGER RANGE 0 TO 101. when reset_cpt_pix_3 => ligne<='1'. end if.process qui affiche la ligne begin case etat_val_pix is when stocker_val_pix => if (cpt_indice_ligne_tab_val_pix=0 and cpt_indice_colonne_tab_val_pix=0) then ligne<=tab_pix_binarise_100(0). end if. variable tab_min_val_pix:unsigned(7 downto 0). else tab_min_val_pix:=tab_min_val_pix. tab_indice_pixel_blanc<=tab_indice_pixel_init. elsif (cpt_indice_ligne_tab_val_pix/=0 and cpt_indice_colonne_tab_val_pix=0) then ligne<=tab_pix_binarise_100(cpt_indice_ligne_tab_val_pix). begin case etat_val_pix is when wait_2 => tab_indice_pixel_noir<=tab_indice_pixel_init. process (cpt_indice_ligne_tab_val_pix. end case. else tab_pix_binarise(i)<='0'. when others => ligne<='0'. for i in 0 to 101 loop if(to_integer(tab_val_pix(i)) > to_integer(tab_max_val_pix)) then tab_max_val_pix:=tab_val_pix(i). else tab_max_val_pix:=tab_max_val_pix.process de traitement des pixels suppression des pixels isolés VARIABLE j : INTEGER RANGE 0 TO 101. process(etat_val_pix) --. VARIABLE k : INTEGER RANGE 0 TO 101.

pwm_mot_gauche<=to_unsigned(prem_pixel_blanc. loop exit when tab_pix_binarise_100(j)='1' or j=101. k := 101. end if. end loop. pwm_mot_droit<=to_unsigned(100-prem_pixel_blanc. y:=y-1. der_pixel_blanc<=k. cpt_indice_pixel_modif<=0. end loop. end if. if(prem_pixel_blanc=101 and der_pixel_blanc=0) then sui_ligne<='0'. j := 0.process qui stock les valeurs des pixels dans un tableau begin wait until rising_edge (SCLK_OUT). end case. when others => null. process -. cpt_indice_pixel_modif<=cpt_indice_pixel_modif+1. j := j + 1. end loop.if (tab_pix_binarise(i-1)='0' and tab_pix_binarise(i)='1' and tab_pix_binarise(i+1)='0') then tab_indice_pixel_noir(cpt_indice_pixel_modif)<=i.1. else sui_ligne<='1'. end case. end if.8).8). case etat_val_pix is when stocker_val_pix => if (cpt_indice_colonne_tab_val_pix/=0 and cpt_indice_colonne_tab_val_pix/=9) then tab_val_pix(cpt_indice_ligne_tab_val_pix)(cpt_indice_colonne_tab_val_pix1)<=SDOUT_unsigned(0). end if. prem_pixel_blanc<=j. when others => null. end process. end loop. for i in 1 to 100 loop tab_pix_binarise_100(i)<=tab_pix_binarise(y). cpt_indice_pixel_modif<=cpt_indice_pixel_modif+1. y:=100. elsif (tab_pix_binarise(i-1)='1' and tab_pix_binarise(i)='0' and tab_pix_binarise(i+1)='1') then tab_indice_pixel_blanc(cpt_indice_pixel_modif)<=i. end process. loop exit when tab_pix_binarise_100(k)='1' or k=0. Kéléfa Sané Rapport de projet S4 Page 33 . for i in 1 to 100 loop if (tab_indice_pixel_noir(i)/=0) then tab_pix_binarise(tab_indice_pixel_noir(i))<='0'. end loop. k := k . elsif (tab_indice_pixel_blanc(i)/=0) then tab_pix_binarise(tab_indice_pixel_blanc(i))<='1'.

process -. else etat_val_pix<=acquisition. case etat_val_pix is when stocker_val_pix => if (cpt_indice_colonne_tab_val_pix=9) then cpt_indice_colonne_tab_val_pix<=0. when others => cpt_indice_colonne_tab_val_pix<=0. when wait_2 => if cpt_val_pix=1120 then etat_val_pix<=reset_cpt_pix_3. end case. case etat_val_pix is when init_2 => if cpt_val_pix=8415 then etat_val_pix<=reset_cpt_pix_1. when reset_cpt_pix_1 => etat_val_pix<=config. when acquisition => if cpt_val_pix=100 then etat_val_pix<=reset_cpt_pix_3. when reset_cpt_pix_2 => etat_val_pix<=acquisition. else etat_val_pix<=init_2.calcul de l'état futur pour automate qui stocker les valeurs de pixels begin wait until falling_edge (SCLK_OUT). else etat_val_pix<=stocker_val_pix. process --cpt_indice_colonne_tab_val_pix avec remise à zero suivant les états begin wait until falling_edge (SCLK_OUT). Kéléfa Sané Rapport de projet S4 Page 34 . end if. when config => if cpt_val_pix=180 then etat_val_pix<=reset_cpt_pix_2. end case. end process. when reset_cpt_pix_3 => etat_val_pix<=stocker_val_pix. end if. case etat_val_pix is when stocker_val_pix => if (cpt_indice_colonne_tab_val_pix=9 and cpt_indice_ligne_tab_val_pix=101) then cpt_indice_ligne_tab_val_pix<=0. end if. end if. elsif cpt_indice_colonne_tab_val_pix=9 then cpt_indice_ligne_tab_val_pix<=cpt_indice_ligne_tab_val_pix+1. else etat_val_pix<=config.process --cpt_indice_ligne_tab_val_pix avec remise à zero suivant les états begin wait until falling_edge (SCLK_OUT). end process. end case. when others => cpt_indice_ligne_tab_val_pix<=0. else etat_val_pix<=wait_2. else cpt_indice_ligne_tab_val_pix<=cpt_indice_ligne_tab_val_pix. when stocker_val_pix => if cpt_val_pix=1019 then etat_val_pix<=wait_2. end process. end if. end if. end if. else cpt_indice_colonne_tab_val_pix<=cpt_indice_colonne_tab_val_pix+1.

end process.process -. cpt_val_pix <= 0. end case. when others => cpt_val_pix<=cpt_val_pix+1. cpt_val_pix <= 1. Kéléfa Sané Rapport de projet S4 Page 35 . end architecture. case etat_val_pix is when reset_cpt_pix_1 => when reset_cpt_pix_2 => when reset_cpt_pix_3 => cpt_val_pix <= 1.CPT COMPTEUR avec remise à zero suivant les états etat_val_pix begin wait until falling_edge (SCLK_OUT).

Sign up to vote on this title
UsefulNot useful