Vous êtes sur la page 1sur 77

Universit Paris-Sud IUT de Cachan Dpartement Geii-1 Parcours ROBOS Anne 2010

Rapport de projet de semestre S4

Robot Vierzon

Tl-transmission Zigbee
Comment rcuprer les informations du robot lorsqu'il suit la ligne
Alexandre Martins

Date de rception au secrtariat pdagogique : .../.../.... ..h.. Impression : 05/04/10

Table des matires


Rsum du projet.......................................................................................................................................................2 Abstract.....................................................................................................................................................................2 Mots-cls ..................................................................................................................................................................2 Introduction...............................................................................................................................................................2 1. tude de deux protocoles utiliss 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 donne rapide, pratique et robuste...............................................................................3 2. La gestion des protocoles utiliss est prise en charge par deux composants.........................................................5 2.1. Le module Xbee permet de transporter une donne reue en UART via Zigbee...............................................5 2.2. Le microcontrolleur 9S12C128, centre dcisionnel et relai de l'information.....................................................8 3. La carte de tl-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 donnes en UART vers le module Xbee.....................................................................................13 4.1.1. Initialisation du module srie........................................................................................................................13 4.1.2. Programme d'envoi des informations en UART avec utilisation des interruptions.......................................14 4.2. Surveiller et recevoir les donnes provenant du bus CAN...............................................................................15 5. Programme de rception et enregistrement des donnes reues sur le PC..........................................................15 6. Retour sur l'avance du projet.............................................................................................................................18 Conclusion...............................................................................................................................................................18 Annexe.....................................................................................................................................................................19

Rsum du projet
Le but de ce projet est de pouvoir rcuprer en temps rel (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 comptition. Pour cela nous avons raliser une carte sous protel qui sert relayer les informations rcupres sur le bus CAN du robot et les envoi via une carte Xbee (utilisant le protocole Zigbee) sur un PC quip d'un rcepteur o un programme rcuprera et stockera les informations reues du robot. Cela nous permettra ainsi de pouvoir reprer d'ventuels problmes 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-cls

bus CAN Zigbee tl-transmission Dbuggage Liaison sans fil Indpendant

Introduction
Le robot Vierzon est constitu d'une multitude de cartes indpendantes relies pour la plupart par le bus CAN dont la fonction est de permettre au robot de suivre une ligne blanche et raliser diverses actions (tourner sur luimme, laisser une priorit...) de faon 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 dcisionnel est embarqu et qu'il ne communique pas avec l'extrieur durant son parcours) il est difficile de savoir d'o peut provenir cette erreur. Deux manires de rcolter des informations s'offrent alors nous, la transmission distance en temps rel (c'est dire lorsque le robot est encore en activit sur la piste) ou le stockage sur un support interne au robot (mmoire flash, carte SD...). Nous avons ici choisi la transmission distance. La vise du projet de tl-transmission est d'apporter au robot suiveur de ligne du concour Vierzon un moyen d'envoyer vers un terminal extrieur les informations qui transitent dans celui-ci et influent dans le comportement du robot sur la piste. Ceci est fait lorsqu'il est prsent sur la piste et nous permet en suivant en mme temps le ro bot et le terminal o on reoit les informations (un PC distant) de pouvoir trouver immdiatement d'o peut pro venir l'erreur de jugement du robot et pouvoir ainsi ensuite la corriger. Pour la ralisation de cette fonctionnalit nous allons dcouper le projet en trois parties: une partie hardware (la carte qui permettra la liaison) et deux parties software (une sur la carte cre et l'autre sur le terminal de rception). Cependant avant de se plonger dans le sujet nous allons tout d'abord introduire les protocoles utiliss dans ce projet.

Alexandre Martins - (GEII1 - S4 ROBOS) Robot Vierzon : Tl-transmission Zigbee Page 2

1. tude de deux protocoles utiliss dans le projet


Nous utilisons deux protocoles principaux dans ce projet, un protocole sans fil, le Zigbee. Celui-ci a t choisi car il ncessite peu d'nergie afin de fonctionner (comme cela l'ajout de la carte de tl-transmission n'influera que peu sur la puissance disponible pour le robot) ainsi que le bus CAN, bus de terrain qui permet aux diffrentes cartes qui composent le robot suiveur de ligne de dialoguer entre elles (vitant ainsi une multitude de fils).

1.1. Le Zigbee, une liaison efficace et peu gourmande en nergie


Le nom ZigBee signifie Zig Zag like a bee , c'est un protocole de haut niveau (au mme titre que le FTP, HTTP, etc). Il permet de petites radio de communiquer sur de faibles distances. Ce protocole est utilis dans des radio consommation rduite. Il est base sur la norme IEEE 802.15.4 pour les rseaux dimension personnelle ou Wireless Personal Area Networks (WPANs). Les spcifications de ZigBee 1.0 sont disponibles auprs des membres de la communaut industrielle ZigBee Alliance. Bien que le protocole Zigbee soit apparu en 1988, ses spcifications ont t ratifies le 14 dcembre 2004. Les publications officielles du protocole Zigbee ont t diffuses en juin 2005 et sont disponibles en libre tlchargement sur le site de la Zigbee Alliance. On retrouve ce protocole dans des environnements o la consommation est un critre de slection. Il est ainsi trs utilis en domotique mais aussi dans les contrles industriels, les applications mdicales, les dtecteurs de fume et dintrusion... A titre indicatif, certains nuds Zigbee sont conus pour fonctionner plusieurs mois en autonomie complte grce une simple pile alcaline de 1,5 V. Le but du dveloppement de ce protocole est de proposer une liaison sur de courtes distances de faon plus simple que les autres solutions actuelles (principalement le bluetooth et Wifi).
1. Comparatif des caractristiques des trois systmes de transfert de donne sans fil: Protocole IEEE Besoins mmoire Autonomie avec pile Nombre de nuds Vitesse de transfert Porte Zigbee 802.15.4 4-32 Kb Annes 65000+ 250 Kb/s 100 m Bluetooth 802.15.1 250 Kb + Jours 7 1 Mb/s 10-100 m Wi-Fi 802.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, celle-ci permet d'mettre les donnes qu'elle reoit sous format UART en utilisant le protocole Xbee. Pour de plus amples informations merci de vous rfrer la partie 2.1 de ce document.

1.2. Le bus CAN, un bus de donne rapide, 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) dvelopp par Bosch (grand quipementier automobile) durant les annes 80. Il s'agit d'un bus srie (c'est dire que les informations y sont transmises bit par bit). Ce bus est celui utilis dans le robot Alexandre Martins - (GEII1 - S4 ROBOS) Robot Vierzon : Tl-transmission Zigbee Page 3

pour permettre la communication entre les diffrentes cartes composant le robot. La mise en place de ce bus est dsormais peu couteuse du fait de sa large diffusion de plus il s'agit d'un moyen de transporter les donnes robuste, rapide et efficace tout en utilisant un systme de priorit dans les informations y circulant. La dfinition du bus CAN ne comporte pas de support physique prcis, ici nous avons choisi d'utiliser une ligne diffrentielle. Cette ligne est constitue de deux fils termins par une rsistance de 120 ohms qui les relient. Chaque carte du robot reprsente un noeud (node en anglais) sur le bus, chaque noeud tant indpendant et pouvant tre dconnect du rseau sans influencer son fonctionnement.

Figure 1. Implmentation physique du bus CAN


source: http://mk3000.free.fr/ L'information circulant sur chacun le second fil est l'oppos de celle circulant sur le premier fil, 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 mmes interfrences).

Figure 2. Principe de la ligne diffrentielle


source: http://www.oberle.org/ La vitesse de transfert d'information sur le bus CAN est de 1Mbits/sec. On assigne au pralable chaque information un ID, cet ID nous renseigne sur la nature de l'information (et donc Alexandre Martins - (GEII1 - S4 ROBOS) Robot Vierzon : Tl-transmission Zigbee Page 4

souvent sur sa provenance) ainsi que sur sa priorit. Le bus possdant un niveau dominant (0) et un niveau rces sif (1), le plus petit ID aura donc priorit sur un ID numriquement suprieur (du fait du nombre debits rcessifs dont son ID est compos). Voici a titre indicatif la forme d'une trame circulant sur le bus CAN:
2. Constitution d'une trame circulant sur le bus CAN:

2. La gestion des protocoles utiliss est prise en charge par deux composants
Bien que nous utilisons le protocole Zigbee et CAN, leur utilisation est plus ou moins transparente dans le projet tant donn qu'ils sont pris en charge par des composants ddis, nous allons ici vous faire un descriptif des composants utiliss dans ces deux liaisons (Zigbee et bus CAN).

2.1. Le module Xbee permet de transporter une donne reue en UART via Zigbee
Afin de permettre l'envoi via Zigbee des informations receuillies sur le bus CAN nous utilisons le module Xbee dvelopp par Digi.

Alexandre Martins - (GEII1 - S4 ROBOS) Robot Vierzon : Tl-transmission Zigbee Page 5

Figure 3. Carte Xbee dveloppe par Digi


Bien que ce module ne possde de nombreux convertisseurs analogique-numrique ou des entres pour PWM, dans notre cas il ne nous sert qu'au relai de l'information reue via le bus CAN sur le robot jusqu' l'ordinateur en utilisant une liaison sans fil Zigbee. L'avantage de cette carte est sa petite taille (elle pourra donc facilement trouver une place sur le robot) mais elle est aussi totalement indpendante. Nous n'utiliseront ici que 5 de ses pin de sortie, nous y reviendrons plus tard dans cette partie. Le module Xbee envoi automatiquement par Zigbee les informations qu'elle reoit en UART sur son entre Xbee IN. La vitesse de transfert maximale est de 11500 Bauds (le module Xbee sur l'ordinateur dialoguant par liaison s rie, le baud est utilis comme unit de mesure). Nous utilisons une Xbee PRO dont la porte maximale (d'aprs le datasheet) est de 1500m en terrain dgag et 100m en milieu urbain, chose qui est plus que raisonnable pour notre utilisation.Lors des test de porte dans l'IUT le module pu mettre entre les salles HA2 et HC3 avec un niveau de signal maximal ce qui reprsente une distance bien suprieure celle de Vierzon.

Figure 4. Numrotation des pin du module Xbee


source: Datasheet du module Xbee

Alexandre Martins - (GEII1 - S4 ROBOS) Robot Vierzon : Tl-transmission Zigbee Page 6

Figure 5. 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), cela nous permettra d'envoyer au module les informations transmettre RSSI (6), afin d'extrapoler le niveau du signal Xbee entre le rcepteur et notre carte (il s'agit d'une PWM) Associate (15), led d'association Xbee elle nous permettra de savoir si le module est associ un autre ou non. Optionnel DOUT (2), afin de recevoir des informations via Zigbee sur notre carte (en vue d'une utilisation dtourne du projet).

L'envoi des donnes vers la carte Xbee ici se fera via une liaison UART, les informations envoyer par liaison Zigbee sont relayes depuis le microcontrolleur jusqu' la pin DIN (3).

Figure 6. 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, chaque trame doit contenir un bit start (niveau bas), 8 bits de Alexandre Martins - (GEII1 - S4 ROBOS) Robot Vierzon : Tl-transmission Zigbee Page 7

donne, pas de bit de parit et un bit stop (niveau haut) comme indiqu sur ce schma: 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 considration la taille des buffer d'envoi et de rception du module Xbee dans le programme implment sur le microcontrolleur.

Figure 7. Utilisation typique de la liaison UART avec le module Xbee


source: Datasheet du module Xbee

2.2. Le microcontrolleur 9S12C128, centre dcisionnel et relai de l'information


La carte de tl-transmission ncessite un microcontrolleur afin d'assurer le relai entre le module Xbee (voir 2.1) et le bus CAN du robot. Il permettra la rception des donnes nous intressant sur le bus CAN, la mise en forme (suppression des informations inutiles dans la trame, ajout de l'ID de la trame aux donnes pour transmission) et le relai des informa tions vers la carte Xbee via une liaison UART (liaison srie). A cot de cela il nous permettra d'assurer la gestion des LED de statut sur la carte de tl-transmission (voir partie 3.3) en les allumant par programme (L.E.D d'envoi et de rception d'information du module Xbee) ou en transcrivant la PWM de niveau de signal issue du module Xbee. Pour cela le microcontrolleur doit disposer d'au moins un module CAN, un module srie et de 5 sorties logiques (pour les LED). Le microcontrolleur utilis est le freescale (anciennement motorolla) 9S12C128, il prsente toutes les caractris tiques ncessaires et prsente l'avantage de fonctionner comme le 9S12DP256 que j'ai l'habitude d'utiliser l'IUT.

Alexandre Martins - (GEII1 - S4 ROBOS) Robot Vierzon : Tl-transmission Zigbee Page 8

Figure 8. 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), le module Xbee (liaison UART) seront relis aux pins 38 et 39 (pins du module srie). Nous devrons faire attention de bien connecter toutes les alimentations aux tensions d'alimentation correspondantes: Les pins 16,35 et 47 devrons tre connectes VCC soit +5V La pin 6 doit tre connecte Vpll et la pin 18 V1. Ces deux tensions de rfrence sont obtenues grce au montage suivant:

Figure 9. Montage afin d'obtenir les tensions de rfrence du 9S12C128


Alexandre Martins - (GEII1 - S4 ROBOS) Robot Vierzon : Tl-transmission Zigbee Page 9

Une erreur remarque que bien trop tard lors de la conception de la carte est l'emplacement des condensateurs de dcouplage du microcontrolleur. En effet un plan dtaill est fourni par le constructeur concernant la disposition et le nombre de condensateurs de dcouplage recommands 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. La carte de tl-transmission, petite et indicative


Maintenant que nous avons abord les deux points principaux de la carte de tl-transmission savoir le module Xbee et le microcontrolleur, nous allons nous attarder sur des points importants sur cette carte.

Figure 10. la carte de tZigbee

Photographie de l-transmission

Carte Xbee LM2937-3.3 Connecteur CAN

LED Check LEDs 74LS07

Alexandre Martins - (GEII1 - S4 ROBOS) Robot Vierzon : Tl-transmission Zigbee Page 10

de Niveau

LED data out LED data in MCP2551

Figure 11. PCB de la carte de tl-transmission Zigbee


Le schma de cblage complet de la carte est disponible en annexe

3.1. Le bus CAN comme source d'nergie


La carte de tl-transmission prsente l'avantage de ne pas ncessiter de connecteur d'alimentation extrieur. En effet, 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.

Figure 12. Cblage du connecteur micro-match (bus CAN)


La tension d'alimentation du microcontrolleur ainsi que la liaison la masse du robot est donc assure par le biais du bus CAN. Cependant le module Xbee fonctionne avec une tension maximale de 3.3V. Afin de pouvoir alimenter le module Xbee partir de VCC j'avais choisi d'utiliser un LM337, ce composant permettant de choisir le niveau de tension en fixant les rsistances qui lui sont associes. Par soucis de place et de prcision de la tension d'alimentation du module Xbee j'ai finalement choisi un LM2937-3.3 car celui-ci est disponible en CMS et nous permet d'obtenir une tension de sortie stable de 3.3V avec seulement deux condensateurs pour des tensions maximales d'entre bien suprieures celle prsente sur le bus CAN (protection pour des tension d'entre maximale de +60V/-50V d'aprs le datasheet). Ce rgulateur permet d'obtenir un courant de sortie de 400mA maximum, sachant que la consommation maximale du module Xbee est de 215mA en mission, cela laisse une certaine marge.

Figure 13. Cblage du LM2937-3.3


Alexandre Martins - (GEII1 - S4 ROBOS) Robot Vierzon : Tl-transmission Zigbee Page 11

3.2. Une carte deux niveaux de tension implique deux niveaux de signaux
Une carte avec deux tensions d'alimentation pose aussi le problme de niveau des signaux qui transitent entre les composants aliments deux niveaux de tensions diffrents. 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 supporte en entre est de 3.4V d'aprs le datasheet) et le niveau haut en sortie du module Xbee tant dans la zone indtermine du microcontrolleur nous allons devoir adapter les niveaux de tension entre les deux composants. Pour cela plusieurs pistes ont t suivies (montage avec AOP, transistor, pont diviseur de tension...), deux montages ont t retenu. Pour les donnes dans le sens microcontrolleur Xbee nous avons choisi d'utiliser un montage simple avec une diode zener 3.3V afin d'abaisser le niveau de tension du signal (voir figure 14 droite). Aprs mesure des niveaux, cette diode t remplace par une diode zener de 3.9V, la diode de 3.3V n'autorisant un niveau haut en sortie de 2.1V alors que la nouvelle nous permet d'obtenir les 3.3V dsirs.

Figure 14. 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. J'ai donc pris un 74LS07 (porte OUI) qui ne modifie pas le signal en entre et me permet de fixer le niveau de tension en sortie grce des rsistances de pull-up relies VCC=+5V. J'ai au pralable vrifi la compatibilit des niveaux entre le module Xbee, le microcontrolleur et la porte logique. VOH (Xbee) = VCC 0.5 = 2.8V VIH (porte) = 2V VOL (Xbee) = 0.5V VIL (porte) = 0.8V Ces deux systmes simples permettent de rgler le problme d'incompatibilit des niveaux d'entre/sortie des composants.

3.3. Une multitude de L.E.D pour indiquer le statut de la carte


Un point aborder rapidement est l'utilit et le cblage des LED prsentes 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. La carte de tl-transmission prsente au total 7 LED: Alexandre Martins - (GEII1 - S4 ROBOS) Robot Vierzon : Tl-transmission Zigbee Page 12

3 LED de niveau de signal 1 LED indiquant l'envoi de donnes du bus CAN vers le module Xbee 1 LED indiquant la rception de donne 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 cbles de la mme faon et au microcontrolleur, sauf la LED d'association qui est alimente en 3.3V et directement rattache au module Xbee. Les rsistances sont associes une rsistance de pull-up et branches l'entre d'un port du microcontrolleur programm en sortie (voir figure 15), ainsi lorsque le port est au niveau bas, la LED associe s'allume, dans le cas contraire (niveau haut), la diffrence de tension est nulle entre VCC et le port, aucun courant ne circule la LED reste donc en tat bloqu et ne s'allume pas.

Figure 15. Cblage des L.E.D de la carte de tl-transmission


Les LED sont allumes ou teintes dans le programme, l'exception de la LED d'association comme nonc prcdement. 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.1)

4. Programmation du microcontrolleur
Avoir une carte fonctionnelle ne reprsente que la moiti du projet. En effet sans programmation du microcontrolleur la carte de tl-transmission ne serait qu'une carte alimentant le module Xbee avec la LED d'association qui clignoterai mais aucune donne ne serait transmise via Zigbee. On peut dcouper ce programme en deux paties principales, une partie servant envoyer via une liaison srie les donnes vers le module Xbee et une autre qui se chargera de surveiller et rcuprer les trames d'intrt sur le bus CAN.

4.1. Envoyer des donnes en UART vers le module Xbee


Le microcontrolleur 9S12C128 comporte dj un module de liaison srie. Dans le programme il ne nous reste plus donc qu' initialiser ce module et l'utiliser. 4.1.1. Initialisation du module srie Afin d'utiliser la liaison srie du microcontrolleur il njous suffit d'initialiser quelques registres du module srie (afin de fixer le baudrate, les informations sur la trame tel que le nombre de bit de donne...) ainsi que le module timer (puisque nous utilisons les interruptions afin de ne pas utiliser de fonctions bloquantes sur le microcontrol leur). Le Baudrate est fix la valeur maximale (par test rel durant les scances d'E&R) supporte par le module Xbee savoir 115200 Bauds. Alexandre Martins - (GEII1 - S4 ROBOS) Robot Vierzon : Tl-transmission Zigbee Page 13

La valeur de SCIBDL est fix grce la formule prsente dans le datasheet du microcontrolleur:

Dbit =

Fclk (1) Equation de calcul de SCIBDL 16SCIBDx

Nous avons un quartz de 10Mhz adapt sur la carte, le rsultat du calcul est donc SCIBDL=2.71, J'ai donc arrondis 3.
/* FUNCTION NAME: RS232_init * DESCRIPTION * * RETURN * PARAMETER */ void RS232_init (void) { SCIBDH = 0x00; SCIBDL = 0x03; SCICR1 = 0x04; SCICR2 = 0x08; SCISR2 = 0x02; } // Baudrate de 115200: 0x03 (valeur exacte:2.71) // // Module d'emission seulement activ // Broche TXD en mode sortie : Initialise la liaison serie a 115200b/s, 8 bits, parite paire, interruptions activees en emission : void 1 : void

void initialisation_port(void) { asm{__cli;} DDRT = 0xFF; // Port T en sortie TIOS &= ~0x07; //Input capture pour T0 T1 T2 TSCR1 |= 0x80; //Active le bloc de timer TCTL4 |= 0x3F; //Activation chaque fronts montants et fronts descendants TIE |= 0x07; //Activation des interruptions sur les channels 0,1 et 2

TSCR2 |= 0x06; // Rglagle du prescaler 2^6=64 }

4.1.2. Programme d'envoi des informations en UART avec utilisation des interruptions Les fonctions d'envoi de donnes sont au nombre de deux. La fonction RS232_snd_msg est appele dans le programme main ou une sous-fonction. Le message a envoyer est indiqu en paramtre. Dans cette fonction copie le message envoyer dans un tableau (buffer) et active les interruptions sur le microcontrolleur.

/* FUNCTION NAME: RS232_snd_msg * DESCRIPTION * RETURN * PARAMETER */ : Ralise l'mission d'un message termin par le caractre '\0'. : void 1 : INT8U* chaine de caractre a envoyer

Alexandre Martins - (GEII1 - S4 ROBOS) Robot Vierzon : Tl-transmission Zigbee Page 14

void RS232_snd_msg (INT8U* chaine) {

char cpt=0; while (chaine[cpt]!='\0') { buffer[cpt]=chaine[cpt]; cpt++; } buffer [cpt+1] = '\0'; SCICR2 |= 0xC0; //TCIE et TIE =1 (activation des interruptions)

Une fois les interruptions actives, la fonction RS232_sc est appele chaque fin d'envoi d'un caractre de la chaine jusqu' ce qu'on atteigne la fin de la chaine (reprsente par le caractre '\0') o les interruptions sont de nouveau dsactives.
interrupt SCI0_ISR void envoi_de_caractere(void) { RS232_sc (); }

/* FUNCTION NAME: RS232_sc * DESCRIPTION * RETURN * PARAMETER */ void RS232_sc (void) { static char i=0, tmp=0; if ((SCISR1 & MASK_TDRE) == MASK_TDRE) { if (buffer[i]!='\0') { if (i==0) PTT &= ~MASK_LED_OUT; : Ralise l'envoie d'un caractre ASCII sur la liason srie : void : void

SCIDRL=buffer[i]; i++; } else { i=0; PTT |= MASK_LED_OUT; SCICR2 &= ~0xC0; } // Dsactivation des interruptions

Alexandre Martins - (GEII1 - S4 ROBOS) Robot Vierzon : Tl-transmission Zigbee Page 15

} }

4.2. Surveiller et recevoir les donnes provenant du bus CAN


Les fonctions utilises pour surveiller le bus CAN n'ont pas encore t crites l'heure de l'criture de ce rapport. Le module de bus CAN du microcontrolleur sera utilis afin de raliser cette tche.

5. Programme de rception et enregistrement des donnes reues sur le PC


Une fois les donnes envoyes du robot, un rcepteur USB peut-tre branch sur le PC, il s'agit simplement d'une carte Xbee connecte une carte fournie dans le starter kit Zigbee de Digi. La rception des donnes se fait par le biais d'un port COM virtuel (port srie virtuel), il suffit donc de rcuprer les trames circulant sur ce port virtuel et les stocker dans un fichier. J'ai choisi de stocker les informations reues sous deux formes: .txt pour une lecture visuelle et .csv pour l'affichage sous forme de tableau. Lors de la rception d'informations, la date est ajoute avant le message puis cris dans le fichier. Voici un bref descriptif des fonctions du programme, l'intgralit de celui-ci est prsente en annexe.
/*--------------------------------------------------------------------------*/ /* Variables globales */

/*--------------------------------------------------------------------------*/

int comport = 7, baudRate = 115200, parity = NON, dataBits = 8, stopBits = 1, xonXoff = NON, timeout = 10,

// No du port COM // Baudrate // Bits de parits (0 = aucun) // Bits de donne // Nombre de bits stop // Spcifie si le mode Xon Xoff est utilis // Temp de latence (en secondes)

readCount = 499, // Nombre de bits a prendre en compte dans le message (avant de quitter la fonction de lecture) readTerm = 13, riage return CR = 13; ou linefeed LF = 10) portOpen = 0, bytesRead = 0, comStatus = 0, rs232Error, inputQueue = 500, outputQueue = 500; // Dtermine le caractre 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], com_msg[500], deviceName[10]= "COM7", date[10];

// Tableau avec le message recu

// Nom du port COM

FILE *fichier_txt; FILE *fichier_csv; gules) time_t heure;

// Pointeur vers le fichier txt // Pointeur vers le fichier csv (spars par vir// Variable de type time_t qui contiendra l'heure

Alexandre Martins - (GEII1 - S4 ROBOS) Robot Vierzon : Tl-transmission Zigbee Page 16

et la date

Dans la fonction main la liaison avec le port srie est initialise et le programme boucle pour surveiller les changements sur le port COM. Pour viter de probables conflits les anciens fichiers de log prsents dans le dossier sont supprims (par scurit)
void main (void) { printf ("Demarrage du programme RS232... \n"); printf ("Ouverture du port COM %i avec un Baudrate de %i, parite: %i, bits de donnee : %i, bits stop: %i. \n", comport, baudRate, parity, dataBits, stopBits); PortConfig (); RemoveFileIfExists ("E:\\Etudes\\GEII semestre 4\\Projet Zigbee\\Prog_PC\\RS232_perso\\rs232_data.txt"); RemoveFileIfExists ("E:\\Etudes\\GEII semestre 4\\Projet Zigbee\\Prog_PC\\RS232_perso\\rs232_data.csv"); if (portOpen) { printf ("Port COM %i ouvert avec succes \n", comport); printf ("En attente de message... \n"); while (1) ReceiveData (); } else MessagePopup ("Erreur", "Erreur dans l'initialisation du port COM, fermeture du programme"); }

Dans ReceiveData la fonction ComRdTerm est utilise, celle-ci surveille le port et copie les donnes reues dans readData jusqu' ce que le nombre maximum de caractres soit atteind ou qu'un caractre en particulier soit observ.
void ReceiveData (void) { int i; readData[0] = '\0'; bytesRead = ComRdTerm (comport, readData, readCount, readTerm); // ComRdTerm lis les bits sur le port jusqu'au byte de terminaison dfini (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 !!!!"); printf ("\n Message recu de %i caracteres: \n \t %s", bytesRead, readDa ta); // MessagePopup ("Message recu", readData); FillFile (); for (i=0; i<bytesRead; i++) readData[i] = '\0'; bytesRead = 0;

Alexandre Martins - (GEII1 - S4 ROBOS) Robot Vierzon : Tl-transmission Zigbee Page 17

} }

Finalement la fonction FillFile va inscrire les donnes reues dans la fonction prcdente da s un fichier. Pour cela elle vrifie que les fichiers log soient accssibles en criture, puis les ouvre pour les manipuler. S'en suit un appelle la fonction retrieveCurrentTime afin de dterminer la date et l'heure puis utilise fprintf pour crire les donnes dans les fichiers avant de les fermer nouveau (et viter qu'ils ne soient pas accssibles en criture pour un prochain appel).
void FillFile (void) { int write_txt=0, write_csv=0, cpt=0; GetFileWritability ("E:\\Etudes\\GEII semestre 4\\Projet Zigbee\\Prog_PC\\RS232_perso\\rs232_data.txt", &write_txt); dans le fichier GetFileWritability ("E:\\Etudes\\GEII semestre 4\\Projet Zigbee\\Prog_PC\\RS232_perso\\rs232_data.csv", &write_csv); 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.txt", "a"); fichier_csv = fopen ("E:/Etudes/GEII semestre 4/Projet Zigbee/Prog_PC/RS232_perso/rs232_data.csv", "a"); if (fichier_txt == NULL || fichier_csv == NULL) MessagePopup ("Erreur","Erreur d'ouverture de fichier"); // Ouvre le fichier // Ouvre le fichier

RetrieveCurrentTime (); fprintf (fichier_txt, "%s \t %s \n", date, readData); // Ecris les donnes recues dans le fichier txt fprintf (fichier_csv, "%s,%s \n", date, readData); // Ecris les donnes recues dans le fichier csv

fclose(fichier_txt); fclose(fichier_csv); } else MessagePopup ("Erreur", "Impossible de complter le fichier log, fichier prot g en criture"); } void RetrieveCurrentTime (void) { heure = time(NULL); strftime(date, sizeof(date), "%H:%M:%S", localtime(&heure)); }

6. Retour sur l'avance du projet


Maintenant que la prsentation du projet arrive son terme, je me devais de revenir sur son avance. J'ai labor le diagramme de Gantt en dbut de projet (figure 16 en haut) et pensais devoir retravailler une carte de tl-transmission prexistante cependant au final j'ai d compltement recrer cette carte ce qui m'a fait prendre du retard sur le planning initial.Certaines parties du projet on donc t supprimes durant mon avance Alexandre Martins - (GEII1 - S4 ROBOS) Robot Vierzon : Tl-transmission Zigbee Page 18

(tel que la mise en place d'une interface graphique ou l'ajout d'une tche spcialise dans le RTOS dvelopp par Nathan Clerbout) aux vues du retard pris sur la conception de la carte de tl-transmission.

Figure 16. Diagrammes de Gantt du projet Conclusion


A l'heure actuelle (04/04/2010) la majorit du projet t complte, la carte de tl-transmission est fonctionnelle et des donnes ont t envoyes depuis le microcontrolleur vers un ordinateur en utilisant le code indiqu dans ce rapport. Il me reste encore la partie de gestion du bus CAN sur le microcontrolleur crire ou complter, ceci devrait tre (sauf bug majeur) ralisable dans les dlais impartis. Ce projet m'aura permis de dcouvrir le protocole Zigbee ainsi que le bus CAN et son implmentation sur le microcontrolleur que nous avons l'habitude d'utiliser. En esprant que mon projet aidera mes confrres participant la comptition de Vierzon gagner du temps sur la correction des erreurs rencontres durant les parcours du robot.

Alexandre Martins - (GEII1 - S4 ROBOS) Robot Vierzon : Tl-transmission Zigbee Page 19

Annexe

Alexandre Martins - (GEII1 - S4 ROBOS) Robot Vierzon : Tl-transmission Zigbee Page 20

Contenu de l'annexe:

Diagramme de Gantt du projet (ancien et actuel) Schma lectrique de la carte de tl-transmission PCB de la carte de tl-transmission Programme de rception sur PC (perso.c) Programme du microcontrolleur 9S12C128 de la carte de tl-transmission (version du 05/04/10) Extraits du datasheet du module Xbee Extrait du datasheet du LM2937-3.3 Extrait du datasheet du 74LS07

/********************************************************************************** * Perso.c * * Auteur: Alexandre Martins * * Date de rvision: 01/02/2010 * * Version: 0.1 * * Utilit : Ce fichier contient les fonctions permettant la * * rception et le stockage des donnes recues via le RS232 * * du PC * * * **********************************************************************************/ /*--------------------------------------------------------------------------*/ /* Includes */ /*--------------------------------------------------------------------------*/ #include "toolbox.h" #include <ansi_c.h> #include <cvirte.h> #include <userint.h> #include <rs232.h> #include <utility.h> #include <formatio.h> #include <string.h> #include <time.h> /*--------------------------------------------------------------------------*/ /* Defines */ /*--------------------------------------------------------------------------*/ #define OUI 1 #define NON 0 /*--------------------------------------------------------------------------*/ /* Dfinition des fonctions */ /*--------------------------------------------------------------------------*/ void DisplayComStatus (void); void ReceiveData (void); void FillFile (void); void PortConfig (void); void RetrieveCurrentTime (void); /*--------------------------------------------------------------------------*/ /* Variables globales */ /*--------------------------------------------------------------------------*/ int comport = 7, baudRate = 115200, parity = NON, dataBits = 8, stopBits = 1, xonXoff = NON, timeout = 10, readCount = 499, de lecture) readTerm = 13, 10) portOpen = 0, bytesRead = 0, comStatus = 0, rs232Error, inputQueue = 500, outputQueue = 500; char readData[500], com_msg[500], deviceName[10]= "COM7", date[10]; FILE *fichier_txt; FILE *fichier_csv; time_t heure; // // // // // // // // No du port COM Baudrate Bits de parits (0 = aucun) Bits de donne Nombre de bits stop Spcifie 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

// Dtermine le caractre 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 (spars par virgules) // Variable de type time_t qui contiendra l'heure et la date

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

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

//

else MessagePopup ("Erreur", "Impossible de complter le fichier log, fichier protg en criture"); } /*----------------------------------------------------------------------------------------------*/ /* RetrieveCurrentTime */ /* Arguments : Aucun */ /* Sorties : Date sous forme de chaine de caractre */ /* Utilit : Cre une chine de caractre contenant l'heure */ /*----------------------------------------------------------------------------------------------*/ void RetrieveCurrentTime (void) { heure = time(NULL); strftime(date, sizeof(date), "%H:%M:%S", localtime(&heure)); }

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

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

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

/********************************************************************************** * can.c * * Auteur: Alexandre Martins * * Date de rvision: 05/04/2010 * * Version: 2.1 * * Utilit : Fonctions bus CAN pour module Xbee * * * **********************************************************************************/ #include "ERROR.H" #include "STAR12.H" #include "pwm.h" #define NULL (void*)0 void MSCAN0_init(void){ INT8U baud_rate_prescaler; INT8U sjw; INT8U extra_sampling; INT8U time_segment_1; INT8U time_segment_2; INT8U EIGTH_11BIT_ACCEPTANCE_FILTERS = 0x10; baud_rate_prescaler= 1; sjw=2; extra_sampling = FALSE; //quartz 10 Mhz time_segment_1 = 7; // Notes: baud_rate_prescaler*(time_segment_1+time_segment_2+1)=2*sys_clock_per_sec time_segment_2 = 2;

if(CANCTL1_CANE!=1) CANCTL1_CANE=1; while (CANCTL1_CANE!=1); if (CANCTL1_INITAK==0){ // If not in init mode CANCTL0=CANCTL0_INITRQ_MASK ; // then request for init mode while (CANCTL1_INITAK==0); // and wait init mode ack } CANCTL1_LISTEN=0; CANCTL1_CANE=1; //enable CAN module CANCTL1_CLKSRC=0; CANCTL1_LOOPB=0; CANCTL1_LISTEN=0; CANBTR0 = ((3&(sjw-1))<<6) | ((baud_rate_prescaler-1) & 0x3f); CANBTR1 = ((1&extra_sampling)<<7)|((7&(time_segment_2-1))<<4)|(0x0F&(time_segment_1-1)); CANIDAC = EIGTH_11BIT_ACCEPTANCE_FILTERS; CANIDMR0 = 0xFF; // Hit for all ID CANIDAR0 = 0x00; CANIDMR1 = 0xFF; // Hit for all ID CANIDAR1 = 0x00; CANIDMR2 = 0xFF; // Hit for all ID CANIDAR2 = 0x00; CANIDMR3 = 0xFF; // Hit for all ID CANIDAR3 = 0x00; CANIDMR4 = 0xFF; // Hit for all ID CANIDAR4 = 0x00; CANCTL0 &= ~0x01; // initreq=0: exit from init mode while (CANCTL1_INITAK!=0); // wait for ack // Attente de synchronisation du MSCAN while(!(CANCTL0&CANCTL0_SYNCH_MASK)) ; // CANRIER = CANRIER_RXFIE_MASK; // enable RX interrupt // CANTIER = CANTIER_TXEIE_MASK; // enable TX interrupt } INT8U MSCAN0_Tx (T_MSCAN_frame * p_message){ int i; INT8U can_tx_buffer_num; INT8U * CANTXDSR = &CANTXDSR0; ErrorIf(CANCTL0_SYNCH!=1,"CAN: no sychro"); CANTBSEL = CANTFLG; // select the lowest free tx buffer

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

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

Universit Paris-Sud IUT de Cachan Dpartement Geii-1 Parcours [ROBO-OS] Anne 2010

Rapport de projet de semestre S4

Asservissement du suivi de ligne par capteur CCD sur carte FPGA DE0
Klfa SANE

"Le vritable enseignement n'est point de te parler mais de te conduire." St Exupry


Date de rception au secrtariat pdagogique : //. h Impression : 06/04/10

Table des matires


Rsum ................................................................................................................................................................... 3 Abstract .................................................................................................................................................................. 3 Mots-cls ................................................................................................................................................................ 3 Introduction ................................................................................................................ ............................................ 3 1. Etude dun nouveau capteur .............................................................................................................................. 3 1.1. Les raisons de ce choix .................................................................................................................................... 3 1.2. Description du capteur CCD TSL3301LF ..................................................................................................... 4 1.3. Un dialogue via une interface srie .................................................................................................................. 4 1.4. Les commandes principales pour le mettre en uvre ...................................................................................... 5 2. Conception et ralisation de la carte dacquisition CCD .................................................................................... 7 2.1. Une forme particulire ..................................................................................................................................... 7 2.2. Le LVDS pour une communication plus sre .................................................................................................. 7 2.3. Etude des composants LVDS .......................................................................................................................... 8 2.4. Mise en place de la communication LVDS ...................................................................................................... 9 2.5. Choix des diffrents lments constituant la carte ......................................................................................... 10 2.6. Conception sur le logiciel Protel .................................................................................................................... 10 3. Assemblage et test des cartes ............................................................................................................................ 12 3.1. Assemblage de la carte CCD et de la carte LED ............................................................................................ 12 3.2. Test de la carte dacquisition et rsultat des signaux changs ...................................................................... 13 4. Implantation en VHDL ...................................................................................................................................... 14 4.1. Comment activer les entres/sorties LVDS de la DE0 ? ............................................................................... 14 4.2. Choix de la frquence SCLK ......................................................................................................................... 16 4.3. Lautomate dinitialisation et de contrle du capteur CCD ........................................................................... 16 4.4. Lautomate de stockage et de traitement ........................................................................................................ 18 4.5. Traitement ralis sur les valeurs des photodiodes ....................................................................................... 19 5. Conclusion ....................................................................................................................................................... 20 6. Bibliographie et sitographie .............................................................................................................................. 21 7. Annexes ............................................................................................................................................................ 22

Klfa San

Rapport de projet S4

Page 2

Rsum
Pour le concours de robotique runissant les IUT Geii de France chaque anne Vierzon, un groupe dtudiant de lIUT de Cachan doivent concevoir un robot capable de suivre une ligne, le travaille que je devais faire au sein de ce groupe est lasservissement du suivi de ligne par capteur CCD sur une carte FPGA.

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, 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.

Mots-cls
- Asservissement - TSL3301LF - capteur CCD -VHDL -carte FPGA DE0

Introduction
Comme chaque anne durant le semestre 4, les tudiants du parcours ROBOS de lIUT de Cachan participe au concours de robotique inter IUT Geii Vierzon, cette anne 8 tudiants vont devoir concevoir un robot capable de suivre une ligne le plus rapidement possible, le projet t rparti entre ces 8 tudiants. Mon objectif a t de raliser lasservissement du suivi de ligne, pour cela jai du tudier le capteur CCD sur lequel jallai travailler, son principe de fonctionnement, comment le mettre en uvre ensuite je devais raliser la carte dacquisition supportant le capteur et programmer sa mise en uvre en VHDL afin de recueillir les informations ncessaire me permettant de dlivrer les commandes moteurs pour que le robot puisse suivre la ligne.

1. Etude dun nouveau capteur


Il existe diffrents types de capteurs pour raliser le suivi de ligne comme le CNY70, utilis lors de la Gamel trophy une comptition de robotique qui runit les tudiants de premires annes des deux dpartements GEII de lIUT de Cachan, ou encore le OPB704 et le TSL1401RLF un capteur CCD analogique qui a t utilis lanne prcdente pour le coupe de France de robotique. Le capteur retenu cette anne par Monsieur Jacques-Olivier Klein enseignant LIUT, est le TSL3301LF un autre capteur CCD, qui est cependant compltement diffrent du TSL1401RLF car celui ci est numrique. La premire partie du travail que jai eu ralis fut ltude de ce nouveau capteur, avec notamment son principe de fonctionnement et les signaux gnrer pour le mettre en uvre.

1.1. Les raisons de ce choix


Le suivi de ligne tant li un problme dasservissement, il ya donc trois critres prendre en compte : la stabilit, la prcision et la rapidit, le critre majeur tant la stabilit. Pour obtenir une bonne stabilit il faut que la boucle de retour de lasservissement soit la plus courte possible, le calcul de lasservissement ayant t toujours effectuer par un microcontrleur 16 bits le MC9S12DP256B, il sera traiter cette anne par une carte FPGA la DE0 sur architecture cyclone III, cela permettra de diminuer le temps introduit dans la boucle dasservissement et ainsi davoir une stabilit importante, permettant des vitesses beaucoup plus grande pour le robot et une reprsentation plus prcise et fiable de la ligne en mot binaire, ceci explique le choix de ce capteur CCD numrique. Cependant, les dcisions stratgiques comme la prise du raccourci, le stop figure resteront la charge du microcontrleur.

Klfa San

Rapport de projet S4

Page 3

1.2. Description du capteur CCD TSL3301LF


Le TSL3301LF est un capteur CCD (Charge-Coupled Device) (dispositif transfert de charge) fonctionnant sur une tension dalimentation positive Vdd (cf. Figure 1 et Tableau 1), il est muni dun convertisseur analogique numrique et communique laide dune interface srie numrique. Il est constitu de 102 photodiodes arrangs sous forme dun tableau une dimension divise en 3 zones de 34 photodiodes (gauche, centre, droit), chacune delles pouvant tre programme avec un gain et offset diffrent. Lnergie lumineuse reue par une photodiode gnre un photo-courant qui est ensuite intgr par le circuit dintgration associ la photodiode. Pendant la priode dintgration, une capacit dchantillonnage est connecte la sortie de lintgrateur par un commutateur analogue. La quantit de charge accumule par chaque photodiode est directement proportionnelle l'intensit de la lumire sur cette photodiode et au temps d'intgration grce au convertisseur analogique numrique intgr au capteur, on a la valeur dintensit lumineuse reue par les photodiodes sur 8 bit (de 0 255).

Figure 1 Boitier du TSL3301LF 1. Brochage du TSL3301LF Broche SCLK Vdd SDIN SDOUT GND NC Numro 1 2 3 4 6,7 5,8 Entre/Sortie Entre Entre Sortie Description Horloge systme du capteur Tension dalimentation positive (3V 5,5V) Entre de donnes (les donnes sont synchronises sur front montant de SCLK) Sortie de donnes (les donnes sont synchronises sur front descendant de SCLK) Masse Non Connect

Le TSL3301LF est implant dans un boitier de type DIP 8 (cf. Figure 1), il a deux entres une horloge synchronisation SCLK et une de commande SDIN. Il dispose dune seule sortie de donnes SDOUT.

1.3. Un dialogue via une interface srie


La communication tablie entre le capteur CCD et la carte DE0 seffectue laide dune liaison srie, cest la seule que le capteur peut supporter. Cette communication est simple et se fait sur deux fils (SDIN et SDOUT), elle doit suivre un modle dj mis en place (cf. Figure 2 et 3), premirement elle est de type synchrone donc il y a une horloge SCLK commune entre lmetteur et le rcepteur, deuximement on transmet comme donnes des octets c'est--dire des groupes de huit bits la suite en commenant par un bit Start 0 qui nous indique le dbut de la transmission, puis le bit de poids faible B0 jusquau bit de poids fort B7 en terminant par un bit Stop 1 pour la fin de transmission. Cependant il nya pas prsence de bit de parit pour nous informer dune erreur dans la transmission.

Klfa San

Rapport de projet S4

Page 4

Figure 2 Format dune trame dentre de donnes

Figure 3 Format dune trame de sortie de donnes

1.4. Les commandes principales pour le mettre en uvre


Le TSL3301LF est un capteur qui ragit uniquement des commandes prdfinies envoyes par un contrleur numrique dans ce cas la carte FPGA DE0, une fois ces commandes reues cela va provoquer lexcution de fonctions par le capteur comme par exemple IRESET la premire commande qui doit tre utiliser ds la mise sous tension du capteur, elle va permettre initialiser la machine dtat interne du capteur et ainsi lutilisation par la suite des autres commandes. Les commandes que jai utilises (cf. Tableau 2) sont rparties en trois catgories reset (IRESET), actions sur les photodiodes (STARTInt, SAMPLEInt, READPixel) et sur les registres (REGWrite, REGRead), elles sont dfinies par des valeurs en octet et envoyes en suivant le protocole dfinit par la liaison srie sur le signal SDIN (cf. Figure 2), excepter pour la commande IRESET qui elle envoie une succession dau moins 10 bits 0. Il existe bien sur dautres commandes comme ABORTPixel qui stoppe la lecture des valeurs des photodiodes dont je nai pas eu avoir recours.
2. Commandes du TSL3301LF Commande IRESET STARTInt SAMPLEInt READPixel REGWrite REGRead Description Initialise la machine dtat interne du capteur Dbut de la priode dintgration des photo-courants Fin de lintgration et enregistrement des valeurs dintensit lumineuse reu par les photodiodes Lecture des valeurs des 102 photodiodes Ecriture dune valeur dans un registre Lecture de la valeur dun 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 rponse du capteur, qui se fera au bout dun certain temps pour REGRead, il faut attendre un dlai de 4 priodes dhorloge avant le dbut de la rponse qui sera envoye sur SDOUT toujours avec le mme protocole (cf. Figure 4) la commande est dfinie par loctet <011a4_a3a2a1a0> (cf. Tableau 2), les bit a0 a4 reprsentent les 5 bit de poids faible de ladresse du registre dont on veut lire la valeur. Un dlai plus long de 44 priodes dhorloge est requis pour READPixel qui va nous envoyer les valeurs des 102 photodiodes sur cod sur 8 bits en continu les unes aprs les autres spares par des bits Stop et Start.

Klfa San

Rapport de projet S4

Page 5

Figure 4 Temps de rponse pour la commande REGRead

Les 102 photodiodes du TSL3301LF sont rpartis en 3 groupes de 34 pour chaque groupe on peut programmer une valeur de gain et doffset sparment des autres, les valeurs doffset et gain sont dfinir dans des registres que lon identifie grce leur adresse (cf. Tableau 3), on rgle une valeur doffset sur 8 bits les valeurs allant de 0x00 0x7F reprsente un offset positif et de 0x80 0xFF un offset ngatif, le gain quant lui est sur 5 bits et la valeur maximale que lon peut rgler est de 31 en dcimal. Pour mettre une valeur dans un registre on utilise la commande REGWrite, elle est dfinie en envoyant loctet <010a4_a3a2a1a0> (cf. Tableau 2), les bits a0 a4 reprsentent les 5 bit de poids faible de ladresse du registre suivi de loctet <d7d6d5d4_d3d2d1d0> qui reprsente la valeur que lon veut mettre dans le registre.
3. Registres du TSL3301LF 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 TSL3301LF peut tre mis en SLEEP MODE c'est--dire teindre tous les circuits analogique du capteur, pour le mettre en SLEEP MODE il faut crire la valeur 1 sur le bit 4 SLP (cf. Figure 5) du registre ou 0 pour le mode normal de fonctionnement, les autres bits du registre ne nous sont daucune utilit et doivent tre mis 0, donc les uniques valeurs que lon peut mettre dans le registre sont 0x00 et 0x40, il est ncessaire dattendre une 1 milliseconde avant dutiliser une commande pour permettre au capteur de sortir du SLEEP MODE.

Figure 5 Assignement des bits du registre Mode

Klfa San

Rapport de projet S4

Page 6

2. Conception et ralisation de la carte dacquisition CCD


Aprs avoir termin ltude du TSL3301LF, jai commenc la ralisation de la carte dacquisition CCD qui permettra de mettre en uvre le capteur, jai d rflchir sur papier sur la forme de la carte, le type de connecteur, le choix des diffrents composant leur emplacement et sur lalimentation de la carte. Jai ensuite fait le schma lectrique et le routage de la carte laide du logiciel de CAO Protel.

2.1. Une forme particulire


La forme et dimension de la carte mont t impose, car elle devait sintgrer dans un systme dj utilis les annes prcdant et qui avait fait ses preuves, elle devait tre de forme circulaire avec un diamtre de 5cm pour pouvoir tre plac lintrieur dun tube de forme conique et hermtique la lumire extrieure. La carte devait tre assemble une autre carte grce un systme de vis et dcrous, cette autre carte quipe de 12 LED blanche (cf. Figure 6) alimente en 12V permet dclairer la piste que le robot devra parcourir de lintrieur du tube conique, une rsistance 82 est relie en srie avec 3 LED dont la tension de seuil est de 2,4V pour avoir un courant qui circule de 30mA.

Figure 6 Routage de la carte LED

2.2. Le LVDS pour une communication plus sre


Au cours de ma rflexion sur la conception de la carte on ma conseill de mettre en place une communication de type LVDS (Low Voltage Differential Signaling) pour mettre les signaux SCLK, SDIN et SDOUT, le LVDS est une norme de signalisation diffrentielle permettant de protger les signaux haute frquence contre les parasites et bruit lectrique, Jai donc choisi de placer les circuits suivant sur la carte CCD (cf. Figure 7 et 8), le DS90LV017A pour mettre le signal SDOUT et le SN65LVDS9637 pour recevoir les signaux SCLK et SDIN. Le circuit FPGA Cyclone-III de la carte DE0 peut grer directement des signaux LVDS en entre et en sortie.

Figure 7 Boitier du SN65LVDS9637

Figure 8 Boitier du DS90LV017A

Klfa San

Rapport de projet S4

Page 7

2.3. Etude des composants LVDS


Jai choisi ces composants en fonction du nombre de signaux que javais transmettre et de leur tension dalimentation qui est de 3,3V, pour avoir une alimentation commune pour les 2 circuits LVDS et le capteur CCD. Le SN65LVDS9637 reoit en entre les signaux diffrentiels des signaux SCLK et SDIN mis par la carte FPGA DE0 (cf. Figure 9), le circuit va ensuite effectuer une soustraction entre le signal non invers A et le signal invers B, si le rsultat est suprieur ou gal 100mV la sortie Y passe ltat haut en revanche si elle est infrieure ou gale -100mV la sortie passe ltat bas (cf. Tableau 4). Le DS90LV017A va recevoir en entre le signal SDOUT (DI) mis par le capteur CCD, le circuit va ensuite mettre en sortie les 2 signaux diffrentiels, le signal non invers D0+ et le signal invers D0- (cf. Figure 10 et Tableau 5).

Figure 9 Symbole logique du SN65LVDS9637 4. Table de vrit du SN65LVDS9637 Entre diffrentielle A, B A-B >= 100mV -100mV < A-B < 100mV A-B <= -100mV Sortie Y H ? L

Figure 10 Symbole logique du DS90LV017A 5. Table de vrit du DS90LV017A Entre DI H Sortie DO+ H Sortie DOL

Voici un exemple des signaux diffrentiels du signal SDIN mis par la carte FPGA DE0 :

Figure 11 Oscillogramme de signaux diffrentiels

En jaune le signal non invers et en bleu le signal invers.

Klfa San

Rapport de projet S4

Page 8

2.4. Mise en place de la communication LVDS


En examinant la datasheet du Cyclone III, jai remarqu quil fallait mettre en place un schma de cblage de 3 rsistances(Rs et Rp) pour les signaux (SCLK et SDIN) allant de la carte FPGA DE0 au circuit LVDS SN65LVDS9637 pour quil soit bien transmis selon la norme LVDS c'est--dire en trs base tension (de lordre du mV) car les signaux LVDS en sortie de la DE0 ont une gamme de tension allant de 0V ltat bas et de 3,3V ltat haut. Il faut aussi placer une rsistance de 100 entre les entres diffrentielles du SN65LVDS9637 pour quil puisse comparer la diffrence de potentielle ces bornes et dlivrer la sortie qui correspond (cf. Figure 12).

Figure 12 Schma de cblage 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 nest pas ncessaire de cbler les 3 rsistances car les signaux en diffrentiels en sortie du DS90LV017A sont bien dans la gamme de tension de la norme LVDS, mais il faut toujours placer une rsistance de 100 sur les 2 entres diffrentielles de la DE0 (cf. Figure 13).

Figure 13 Schma de cblage de la norme LVDS en entre du Cyclone III Extrait de la datasheet du Cyclone III

Suite a jai dcid de raliser le schma de cblage complet sur une carte Labdec (cf. Figure 14), en plaant les 3 rsistances Rs 120 et Rp 160 pour les signaux SCLK et SDIN et la rsistance de 100 sur les 2 entres diffrentielles de la DE0 pour SDOUT. Cette carte me permettra de faire mes tests sur la chaine dacquisition complte, mais elle sera intgrer dans la carte dinterface ralise par mon collgue Nathan Clerbout qui relie tous les lments du robot camra, carte moteur, carte CCD

Klfa San

Rapport de projet S4

Page 9

Figure 14 Photographie de la carte dadaptation LVDS

2.5. Choix des diffrents lments constituant la carte


Aprs avoir termin la liste de tous les signaux communicants entre le capteur CCD et la carte DE0, jai pu choisir le type de connecteur adapt, sachant quil ya 6 signaux diffrentiels et quil faut mettre une masse entre chaque paire positive et ngative pour annuler les perturbations lies au magntisme, sans oublier le signal dalimentation VCC de 3,3V directement fourni par une broche de la DE0, il me fallait donc un connecteur 10 broches des rsistances de 100 placer sur les entres diffrentielles des circuits LVDS et 3 capacits de dcouplage de 100 nF pour lalimentation des circuits.

2.6. Conception sur le logiciel Protel


Ayant tous les lments en main jai p passer la phase de conception de la carte laide du logiciel de CAO Protel, cette carte tant la premire carte que jai eu raliser sur Protel jai d tout dabord me familiariser avec le logiciel, pour cela jai dabord tudi le tutorial du logiciel fait par Monsieur Hugues Angelis professeur lIUT de Cachan pour les tudiants. Ce tutorial ma permis de comprendre tout ce que je devais faire pour concevoir la carte, jai commenc par raliser le schematic de la carte (cf. Figure 15) c'est--dire le cablage lectrique de tous les composants, ne trouvant pas dans la librairie Protel GEII1 certains des composants comme le capteur CCD TSL3301LF et les circuits LVDS DS90LV017A et SN65LVDS9637 je les ai substitus par dautres composants ayant les mmes boitiers car lobjectif final est de faire un PCB et non de la simulation, 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 15 Schematic de la carte dacquisition CCD

Klfa San

Rapport de projet S4

Page 10

Le Schematic termin je suis pass au routage de la carte (cf. Figure 16) en dessinant les pistes reliant les composants, pour raliser au mieux cette tche jai rflchi sur le placement des composants, le capteur CCD devait tre plac au centre et sur le ct bottom pour tre face la piste, en fonction de cela jessayais de plac le reste des composants de faon avoir des pistes le plus droit possible et faire le moins de strap ce fut un travail long et fastidieux, mais cela en valait la peine car la carte parfaitement bien fonctionn du premier coup, je nai donc pas eu la modifier.

Figure 16 Routage de la carte dacquisition CCD

Jai du raliser une deuxime carte me permettant de commencer mes tests en attendant larriver des composants LVDS qui ont d tre commands (cf. Figure 17).

Figure 17 Routage de la carte dacquisition CCD sans LVDS

Klfa San

Rapport de projet S4

Page 11

3. Assemblage et test des cartes


La phase de conception termine jai d runir les diffrentes cartes, carte CCD, carte LED et carte DE0 (cf. Figure 18), pour commencer la phase de test de la chaine dacquisition et ainsi corriger certains problmes.

Figure 18 Photographie du plan de travail

3.1. Assemblage de la carte CCD et de la carte LED


Les deux cartes tires jai d faire le perage afin de pourvoir placer les composants souder, jai aussi perc 4 trous grands sur les 2 cartes pour les assembler ensemble (cf. Figure 18) grce un systme vis crou, me permettant de rgler la distance entre les 2 cartes, jai aussi mis des rondelles en plastiques entre les cartes et les crous afin disoler. Une lentille mince convergente t mis au centre de la carte LED, elle se trouve donc juste en dessous du capteur, elle permet de polariser les rayons lumineux et ainsi avoir une meilleure vison de la position de la ligne vu par le capteur, ne connaissant pas la distance focal de la lentille jai du raliser plusieurs essais, la distance le plus appropri entre les 2 cartes que jai trouv est de 2,5cm.

Figure 18 Photographie de lassemblage des cartes CCD et LED

Klfa San

Rapport de projet S4

Page 12

3.2. Test de la carte dacquisition et rsultat des signaux changs


Lors de mon premier test jai remarqu que la lecture des pixels se faisait une fois sur deux aprs une commande lecture des valeurs des photodiodes (READPixel) ceux problme sexplique du fait que je demandais la lecture de la prochaine valeur des photodiodes alors que la lecture prcdente ntait pas encore termin, la commande ntait donc pas valid par la machine dtat interne du capteur, jai donc rectifier le problme dans mon automate de contrle pour demander la prochaine lecture une fois la prcdente terminer. Les acquisitions de valeur photodiode se font donc bien les une la suite et on attend bien 44 priodes dhorloges entre la commande READPixel et la lecture des valeurs (cf. Figure 19).

Figure 19 Oscillogramme des signaux chang entre la carte CCD et la DE0

En jaune : SDIN En bleu : SDOUT

Klfa San

Rapport de projet S4

Page 13

4. Implantation en VHDL
La majeure partie de mon projet aura t de faire de la programmation en VHDL sur la carte FPGA DE0, il a fallu que je ralise lautomate dinitialisation et de contrle du capteur CCD et un autre automate en parallle dont le but tait de rcuprer les valeurs des 102 photodiodes et de raliser un traitement dessus pour recueillir les informations ncessaires pour raliser lasservissement du suivi de ligne.

4.1. Comment activer les entres/sorties LVDS de la DE0 ?


Pour activer les entres/sorties LVDS de la DE0 il faut aller dans longlet Assignement du logiciel Quartus puis sur Pins, une nouvelle page va souvrir, dans le tableau on rechercher ses signaux, ici ce sont les miens SCLK, SDIN et SDOUT (cf. Figure 20).

Figure 20

On doit ensuite modifier le I/O Standard en remplaant 3.3-V LVTTL par LVDS_E_3R si le signal est en sorite, si il est en entre on remplace par LVDS (cf. Figure 21).

Figure 21

On remarque par ailleurs que sur la colonne Differential Pair lapparition des signaux diffrentiels inverss SCLK(n), SDIN(n) et SDOUT(n) (cf. Figure 22).

Figure 22

Les signaux diffrentiels inverss sont aussi dfinis la fin du tableau (cf. Figure 23).

Figure 23

Klfa San

Rapport de projet S4

Page 14

Il faut ensuite les assigns sur les broches dun des 2 connecteurs 40 broches de la DE0 qui sont dfinit dans les I/O Bank 3 et 4, dont les noms commencent par GPIO0_D[*] et GPIO1_D[*] avec un numro entre crochet. Je vais assigner SCLK sur la broche GPIO0_D[1] qui dfinit en Location par PIN_AA16, un message derreur apparait, il nous dit que le broche est dj assign (cf. Figure 24).

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. Figure 25).

Figure 25

Une fois les 2 broches supprimes on peut assigner le signal SCLK sur lancienne broche GPIO0_D[1] (cf.Figure 25).

Figure 26

Klfa San

Rapport de projet S4

Page 15

Le signal diffrentiel invers SCLK(n) est quant lui directement assign en mme temps sur lancienne broche GPIO0_D[0] dons le Location tait PIN_AB16 (cf.Figure 27).

Figure 27

Pour les autres signaux il suffit de refaire les mmes manipulations en assignant les signaux diffrentiels non invers SDIN et SDOUT sur des broches dont la Location commence par PIN_AA suivi dun numro les signaux invers SDIN(n) et SDOUT(n) seront directement assign sur les broches dont la Location commence par PIN_AB suivi du mme numro.

4.2. Choix de la frquence SCLK


En regardant le datasheet du TSL3301LF jai vu que la frquence max que lon pouvait appliquer SCLK tait de 10Mhz, utilisant lhorloge a quartz de 50Mhz de la carte DE0, jai dcid de faire un diviseur de frquence par 6 pour ainsi avoir un signal SCLK 8,33Mhz cependant je narrivais pas avoir sur loscilloscope le rsultat de ma programmation pour la dtection de la ligne blanche, on ma donc conseill de prendre une frquence qui me permettre de faire une acquisition de valeur de photodiodes en 1ms, jai donc pris une frquence de 1Mhz pour SCLK. Voir en annexes pour le code source VHDL

4.3. Lautomate dinitialisation et de contrle du capteur CCD


Avant de coder mon automate jai d dabord commencer par raliser son diagramme dtat (cf.Figure 28 et Tableau 4) avec laide de toutes les informations que javais pu extraire de la datasheet du TSL3301LF
4. Description des tats de lautomate de contrle Etat INIT IRESET Wait 30 MODE REG Description Attente de 10 priodes dhorloge avec SDIN 1 ds la mise sous tension du capteur Au moins 10 priodes dhorloges avec SDIN 0, cette tat initialiser la machine dtat interne du capteur. Attente de 30 priodes dhorloge avant lutilisation dune commande pour garantir ltat de la sortie SDOUT. Entrer de ladresse du registre Mode afin dy crire une valeur, la sortie SDIN va prendre successivement les valeurs des bits loctet <0101_1111> chaque priode dhorloge, en commenant par le bit Start suivit bit de poids faible jusquau bit de poids fort et terminer par le Stop. Attente de 5 priodes dhorloge entre chaque commande Ecriture de la valeur <0000_0000> dans le registre Mode en commenant par un Start et en terminant par un Stop. Attente de 1ms, pur permettre au capteur de sortir du SLEEP MODE. Remise 1 du compteur cpt, ltat ne de dure quune priode dhorloge. Entrer de ladresse du registre du Gain. Ecriture dune valeur dans le registre de Gain <0000_0001>. Entrer de ladresse du registre dOffset. Ecriture dune valeur dans le registre dOffset <0000_0000>. Entrer de la commande de dbut dintgration des photodiodes <0000_1000>. Attente minimum de 22 priodes dhorloge pour lintgration de toutes les photodiodes. Entrer de la commande de fin dintgration et denregistrement des valeurs dintensit lumineuse reue par les photodiodes <0001_0000>. Entrer de la commande de lecture des 102 photodiodes <0000_0010>. Attente de 44 priodes avant la lecture de la valeur de la premire photodiode. Attente de la fin de lecture.

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

Klfa San

Rapport de projet S4

Page 16

Figure 28 Diagramme dtat de lautomate dinitialisation et de contrle

Klfa San

Rapport de projet S4

Page 17

Pour le rglage du gain et de loffset lautomate va faire 3 fois le tour de la premire boucle pour entrer les valeurs de gain et doffset des 3 groupes de 34 photodiodes, jai choisi de mettre un gain de 1 et un offset nulle car la carte LED claire suffisamment bien la piste. Aprs avoir initialis le capteur lautomate va rester enferm dans la deuxime boucle ou il va envoyer des commandes intgrations des photodiodes et de lecture.

Figure 29 Oscillogramme du signal de contrle SDIN du capteur CCD

: Entrer de la commande STARTInit : Attente des 22 priodes dhorloges pour lintgration : Entrer de la commande SAMPLEInit : Attente de 5 priodes dhorloge entre chaque commande : Entrer de la commande READPixel Voir en annexes pour le code source VHDL

4.4. Lautomate de stockage et de traitement


Lautomate de stockage tourne en parallle avec lautomate dinitialisation son objectif et de stocker les valeurs des pixels dans un tableau puis de raliser des traitements sur ces valeurs pour pouvoir rcuprer les informations afin de raliser lasservissement du suivi de ligne en dlivrant les commandes moteurs (cf.Figure 30 et Tableau 5).

5. Description des tats de lautomate 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 doffset dans les registres) Entrer des commandes STARTInit, SAMPLEInit et READPixel et attente des 44 priodes dhorloge Stockage des valeurs de 102 photodiodes dans un tableau Traitement des valeurs

Klfa San

Rapport de projet S4

Page 18

Figure 30 Diagramme dtat de lautomate stockage et traitement

Voir en annexes pour le code source VHDL

4.5. Traitement ralis sur les valeurs des photodiodes


Afin de bien dtecter la ligne blanche de la moquette bleue jai ralis diffrent traitement en VHDL comme une binarisation et une rosion.
process(etat_val_pix) --- process de traitement des pixels suppression des pixels isols VARIABLE j : INTEGER RANGE 0 TO 101; VARIABLE k : INTEGER RANGE 0 TO 101; VARIABLE y : INTEGER RANGE 0 TO 101; begin case etat_val_pix is when wait_2 => tab_indice_pixel_noir<=tab_indice_pixel_init; tab_indice_pixel_blanc<=tab_indice_pixel_init; for i in 0 to 101 loop if (to_integer(tab_val_pix(i))>seuil) then tab_pix_binarise(i)<='1'; else tab_pix_binarise(i)<='0'; end if; end loop;

Pour effectuer la binarisation jai fais une boucle for dans laquelle je test la valeur des photodiodes enregistrer dans le tableau tab_val_pix si la valeur est suprieur au seuil que jai choisi laide des boutons de la carte DE0 je mets 1 dans un dans un nouveau tableau tab_pix_bnarise si par contre la valeur est infrieur je mets 0.

Klfa San

Rapport de projet S4

Page 19

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; cpt_indice_pixel_modif<=cpt_indice_pixel_modif+1; 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; cpt_indice_pixel_modif<=cpt_indice_pixel_modif+1; end if; end loop; cpt_indice_pixel_modif<=0; for i in 1 to 100 loop if (tab_indice_pixel_noir(i)/=0) then tab_pix_binarise(tab_indice_pixel_noir(i))<='0'; elsif (tab_indice_pixel_blanc(i)/=0) then tab_pix_binarise(tab_indice_pixel_blanc(i))<='1'; end if; end loop; y:=100; for i in 1 to 100 loop tab_pix_binarise_100(i)<=tab_pix_binarise(y); y:=y-1; end loop; Pour faire lrosion qui permet de supprimer les pixels isol je fais une opration majoritaire trois bits, qui vrifie si les 2 bits des extrmits sont gaux et que celui du milieu est diffrent, si cest le cas jenregistre lindice du tableau dont il faut changer la valeur dans un nouveau tableau. Je fais ensuite un test sur ce nouveau tableau si les valeurs du tableau sont diffrentes de zro alors je change la valeur du tableau. Je dois ensuite placer les nouvelles valeurs dans nouveau tableau sauf la premire et la dernire.

5. Conclusion
Par manque de temps et du retard que jai pris en restant bloqu sur certaines tches je nais pas pu terminer mon projet de S4, cependant le travaille que je ralis permet dobtenir une dtection de ligne net et prcise comme on lesprait (cf.Figure 31). Jai aussi pu mtre en pratique toutes les notions que jai apprise lIUT comme la programmation en VHDL et en dcouvrir dautre la conception de carte sur protel. Jai aussi dcouvert le travaille en autonomie au sein dun groupe et je pense que cette exprience sera une bonne prparation mon stage.

Figure 31 Oscillogramme de la dtection de la ligne

Klfa San

Rapport de projet S4

Page 20

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

Klfa San

Rapport de projet S4

Page 21

7. Annexes Diviseur de frquence


library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity div_de_freq is port( clk: in std_logic; SCLK_OUT: out std_logic); end entity; architecture a1_div_de_freq of div_de_freq is signal cpt1: integer range 0 to 100000:=0; signal sig_SCLK : std_logic := '0'; begin SCLK_OUT<=sig_SCLK; process begin wait until rising_edge(clk); if (cpt1 = 24) then cpt1 <= 0; sig_SCLK <= not sig_SCLK; else cpt1 <= cpt1 + 1; end if; end process; end architecture ;

Klfa San

Rapport de projet S4

Page 22

Automate dinitialisation et de contrle


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

when wait_1ms => if cpt=30080

Klfa San

Rapport de projet S4

Page 23

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

Klfa San

Rapport de projet S4

Page 24

else etat<=wait5_4; end if; when reg_write_O => if cpt=55 or cpt=115 or cpt=175 then etat<=wait5_5; else etat<=reg_write_O; end if; when wait5_5 => if cpt=60 or cpt=120 then etat<=reg_address_G; elsif cpt=180 then etat<=reset_cpt_2; else etat<=wait5_5; end if; when reset_cpt_2 => etat<=start_int; when start_int => if cpt=10 then etat<=wait22; else etat<=start_int; end if; when wait22 => if cpt=32 then etat<=sample_int; else etat<=wait22; end if; when sample_int => if cpt=42 then etat<=wait5_6; else etat<=sample_int; end if; when wait5_6 => if cpt=47 then etat<=read_pix; else etat<=wait5_6; end if; when read_pix => if cpt=57 then etat<=wait44; else etat<=read_pix; end if; when wait44 => if cpt=101 then etat<=wait919; else etat<=wait44; end if; when wait919 => if cpt=1121 then etat<=reset_cpt_2; else etat<=wait919; end if; end case; end process; process (etat,cpt) -- 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=58 then SDIN<=mode_address(1); elsif cpt=59 then SDIN<=mode_address(2); elsif cpt=60 then SDIN<=mode_address(3); elsif cpt=61 then SDIN<=mode_address(4); elsif cpt=62 then SDIN<=mode_address(5); elsif cpt=63 then SDIN<=mode_address(6);

Klfa San

Rapport de projet S4

Page 25

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

Klfa San

Rapport de projet S4

Page 26

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

Klfa San

Rapport de projet S4

Page 27

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

Klfa San

Rapport de projet S4

Page 28

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

Klfa San

Rapport de projet S4

Page 29

elsif cpt=38 then SDIN<=SampleInt(4); elsif cpt=39 then SDIN<=SampleInt(5); elsif cpt=40 then SDIN<=SampleInt(6); elsif cpt=41 then SDIN<=SampleInt(7); elsif cpt=42 then SDIN<=stop; end if; when read_pix => if cpt=48 then SDIN<=start; elsif cpt=49 then SDIN<=ReadPixel(0); elsif cpt=50 then SDIN<=ReadPixel(1); elsif cpt=51 then SDIN<=ReadPixel(2); elsif cpt=52 then SDIN<=ReadPixel(3); elsif cpt=53 then SDIN<=ReadPixel(4); elsif cpt=54 then SDIN<=ReadPixel(5); elsif cpt=55 then SDIN<=ReadPixel(6); elsif cpt=56 then SDIN<=ReadPixel(7); elsif cpt=57 then SDIN<=stop; end if; when wait919 => SDIN<='1'; stock<='1'; when others => SDIN<='1'; stock<='0';

end case; end process; process -- CPT COMPTEUR avec remise zero suivant les tats begin wait until falling_edge (SCLK_OUT); case etat is when wait919 => if(cpt_stock=1020) then cpt_stock<=1; else cpt_stock<=cpt_stock+1; end if; when others => end case; end process; end architecture ; cpt_stock<=1;

Klfa San

Rapport de projet S4

Page 30

Automate de stockage et de traitement


library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity automate_ccd_stokage_pixel is port( SCLK_OUT: in std_logic; SDOUT: in std_logic; SWITCH_SEUIL: in unsigned (7 downto 0); prem_pixel_blanc: inout integer range 0 to 255; der_pixel_blanc: inout integer range 0 to 255; tab_max_pix: out unsigned(7 downto 0); tab_min_pix: out unsigned(7 downto 0); pwm_mot_droit: out unsigned (7 downto 0); pwm_mot_gauche: out unsigned (7 downto 0); sui_ligne: out std_logic; SDOUT_sonde: out std_logic; ligne: out std_logic); end entity; architecture a1_automate_ccd_stokage_pixel of automate_ccd_stokage_pixel is type etat_type_val_pix is (init_2, reset_cpt_pix_1, config, reset_cpt_pix_2, acquisition, stocker_val_pix, reset_cpt_pix_3, wait_2); signal etat_val_pix: etat_type_val_pix:=init_2; type tab is array (0 to 101) of unsigned (7 downto 0); signal tab_val_pix:tab; type tab1 is array (0 to 101) of std_logic; signal tab_pix_binarise:tab1; type tab2 is array (0 to 101) of integer range 0 to 101; signal tab_indice_pixel_noir:tab2; signal tab_indice_pixel_blanc:tab2; signal tab_indice_pixel_init:tab2; type tab3 is array (0 to 101) of std_logic; signal tab_pix_binarise_100:tab3;

signal signal signal signal

cpt_val_pix: integer range 0 to 9000:=0; cpt_indice_ligne_tab_val_pix: integer range 0 to 101:=0; cpt_indice_colonne_tab_val_pix: integer range 0 to 9:=0; cpt_indice_pixel_modif: integer range 0 to 101:=0;

signal SDOUT_unsigned: unsigned(0 downto 0); signal seuil: integer range 0 to 255; signal start : std_logic; signal stop : std_logic; begin SDOUT_sonde<=SDOUT; seuil<=to_integer(SWITCH_SEUIL); start<='0'; stop<='1'; with SDOUT select SDOUT_unsigned<="0" when '0', "1" when others; tab_pix_binarise_100(0)<='0'; tab_pix_binarise_100(101)<='0'; 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; end loop;

Klfa San

Rapport de projet S4

Page 31

when others => null; end case; end process;

process(etat_val_pix)--process qui chercher les valeur min et max des pix variable tab_max_val_pix:unsigned(7 downto 0); variable tab_min_val_pix:unsigned(7 downto 0); begin case etat_val_pix is when wait_2 => tab_max_val_pix:="00000000"; 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; end if; end loop; tab_max_pix<=tab_max_val_pix; tab_min_val_pix:="11111111"; 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); else tab_min_val_pix:=tab_min_val_pix; end if; end loop; tab_min_pix<=tab_min_val_pix; when others => NULL; end case; end process; process (cpt_indice_ligne_tab_val_pix,cpt_indice_colonne_tab_val_pix,etat_val_pix) -- 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); 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); end if; when reset_cpt_pix_3 => ligne<='1'; when others => ligne<='0'; end case; end process; process(etat_val_pix) --- process de traitement des pixels suppression des pixels isols VARIABLE j : INTEGER RANGE 0 TO 101; VARIABLE k : INTEGER RANGE 0 TO 101; VARIABLE y : INTEGER RANGE 0 TO 101; begin case etat_val_pix is when wait_2 => tab_indice_pixel_noir<=tab_indice_pixel_init; tab_indice_pixel_blanc<=tab_indice_pixel_init; for i in 0 to 101 loop if (to_integer(tab_val_pix(i))>seuil) then tab_pix_binarise(i)<='1'; else tab_pix_binarise(i)<='0'; end if; end loop; for i in 1 to 100 loop

Klfa San

Rapport de projet S4

Page 32

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; cpt_indice_pixel_modif<=cpt_indice_pixel_modif+1; 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; cpt_indice_pixel_modif<=cpt_indice_pixel_modif+1; end if; end loop; cpt_indice_pixel_modif<=0; for i in 1 to 100 loop if (tab_indice_pixel_noir(i)/=0) then tab_pix_binarise(tab_indice_pixel_noir(i))<='0'; elsif (tab_indice_pixel_blanc(i)/=0) then tab_pix_binarise(tab_indice_pixel_blanc(i))<='1'; end if; end loop; y:=100; for i in 1 to 100 loop tab_pix_binarise_100(i)<=tab_pix_binarise(y); y:=y-1; end loop; j := 0; loop exit when tab_pix_binarise_100(j)='1' or j=101; j := j + 1; end loop; prem_pixel_blanc<=j; k := 101; loop exit when tab_pix_binarise_100(k)='1' or k=0; k := k - 1; end loop; der_pixel_blanc<=k; if(prem_pixel_blanc=101 and der_pixel_blanc=0) then sui_ligne<='0'; else sui_ligne<='1'; pwm_mot_droit<=to_unsigned(100-prem_pixel_blanc,8); pwm_mot_gauche<=to_unsigned(prem_pixel_blanc,8); end if;

when others => null; end case; end process; process -- process qui stock les valeurs des pixels dans un tableau begin wait until rising_edge (SCLK_OUT); 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;

when others => null; end case; end process;

Klfa San

Rapport de projet S4

Page 33

process --cpt_indice_ligne_tab_val_pix avec remise zero suivant les tats begin wait until falling_edge (SCLK_OUT); 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; elsif cpt_indice_colonne_tab_val_pix=9 then cpt_indice_ligne_tab_val_pix<=cpt_indice_ligne_tab_val_pix+1; else cpt_indice_ligne_tab_val_pix<=cpt_indice_ligne_tab_val_pix; end if; when others => cpt_indice_ligne_tab_val_pix<=0; end case; end process; process --cpt_indice_colonne_tab_val_pix avec remise zero suivant les tats begin wait until falling_edge (SCLK_OUT); 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; else cpt_indice_colonne_tab_val_pix<=cpt_indice_colonne_tab_val_pix+1; end if; when others => cpt_indice_colonne_tab_val_pix<=0; end case; end process; process -- calcul de l'tat futur pour automate qui stocker les valeurs de pixels begin wait until falling_edge (SCLK_OUT); case etat_val_pix is when init_2 => if cpt_val_pix=8415 then etat_val_pix<=reset_cpt_pix_1; else etat_val_pix<=init_2; end if; when reset_cpt_pix_1 => etat_val_pix<=config; when config => if cpt_val_pix=180 then etat_val_pix<=reset_cpt_pix_2; else etat_val_pix<=config; end if; when reset_cpt_pix_2 => etat_val_pix<=acquisition; when acquisition => if cpt_val_pix=100 then etat_val_pix<=reset_cpt_pix_3; else etat_val_pix<=acquisition; end if; when reset_cpt_pix_3 => etat_val_pix<=stocker_val_pix; when stocker_val_pix => if cpt_val_pix=1019 then etat_val_pix<=wait_2; else etat_val_pix<=stocker_val_pix; end if; when wait_2 => if cpt_val_pix=1120 then etat_val_pix<=reset_cpt_pix_3; else etat_val_pix<=wait_2; end if; end case; end process;

Klfa San

Rapport de projet S4

Page 34

process -- CPT COMPTEUR avec remise zero suivant les tats etat_val_pix begin wait until falling_edge (SCLK_OUT); 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_val_pix <= 1; cpt_val_pix <= 0;

when others => cpt_val_pix<=cpt_val_pix+1; end case; end process; end architecture;

Klfa San

Rapport de projet S4

Page 35