Commande de robot par FPGA

De troyesGEII
Aller à : navigation, rechercher

Présentation du robot arexx

Fichier:Robot arexx.mkv

Information sur la Basys 2

Basys2
Basys2


La Basys2 est une carte FPGA conçue par Digilent. Elle permet la simulation de vrais circuits numériques. La programmation de circuits numériques se fait à l'aide du logiciel XilinX. Grâce à sa grande collection de périphériques d'entrées et de sorties, on peut simuler une grande gamme de circuits numériques.




Caractéristiques :

    -Xilinx Spartan 3-E FPGA 100k ou 250k portes;
    -72Kbits de RAM et fréquence de transfert de 500MHz;
    -2 ports USB 2.0 pour les transferts de configurations et de données;
    -Fréquence de l'oscillateur (25,50 et 100MHz) réglable par l'utilisateur; 
    -Trois régulateurs de tension intégrés (1,2V, 2,5V, 3,3V) permettent l'utilisation 
     des sources d'alimentations externes 3.5V-5.5V;
    -8 LED, 4 Afficheurs sept segments, 4 boutons poussoirs,
     8 interrupteurs à glissière, 1 ports PS/2 et 1 port VGA-8bits;
    

Lien : User Guide Basys2

Carte capteur à photo-transistors

Le CNY70 est un capteur à réflexion optique c'est à dire qu'il est composé d'un photo-transistor filtrant la lumière visible et d'une diode infrarouge. Il permet de détecter un contraste noir-blanc à faible distance (inférieur à 5mm).

capteur à photo-transistor












On envisage l'implantation de 4 capteurs CNY70 au lieu de 2 vu précédemment dans le projet inter-semestre de 1ere année.


II-Montage et programmation du robot

Présentation de notre robot

Le robot est composé d'une plate-forme métallique sur laquelle est posée la carte Basys2, de 2roues de 3pouces, de 2moteurs contrôlés chacun une carte PmodHB5, d'un support de 4piles et d'une bille porteuse permettant de maintenir le robot à plat.


Programmation des moteurs PmodHB5

Programmation de la manette Nunchuk

Programme C

//#include "stdint.h"
#include "avr/io.h"
//#include "avr/pgmspace.h"
#undef F_CPU
#define F_CPU 25000000UL
#include "util/delay.h"
#define DATAPRESENT 2
#define PORTA _SFR_IO8(0x1B)


void readFIFOandAskForNextData(unsigned char nunchukDATA[]);
void enAvant(unsigned char droite, unsigned char gauche);
void enArriere(unsigned char droite, unsigned char gauche); 
void tourneDroite(unsigned char gauche);
void tourneGauche(unsigned char gauche);

int main(int argc, char * argv[])
{ 
  unsigned char nunchukDATA[6],vitesseDroite,vitesseGauche,avant;
  while(1){
    readFIFOandAskForNextData(nunchukDATA);
    if (!(nunchukDATA[5] & 1)) {// Z button
      if (nunchukDATA[1]>0xA0) {vitesseDroite=vitesseGauche=nunchukDATA[1]-0x80; avant=1;}
        else  if (nunchukDATA[1]<0x60) {vitesseDroite=vitesseGauche=0x80-nunchukDATA[1];avant=0; }
          else {vitesseGauche=vitesseDroite=0x00;}
      if (nunchukDATA[0]>0xA0) vitesseDroite = vitesseDroite -nunchukDATA[0]+0x80;
      else  if (nunchukDATA[0]<0x60) vitesseGauche = vitesseGauche + nunchukDATA[0]-0x80;
      if (avant) enAvant(vitesseGauche,vitesseDroite); else enArriere(vitesseGauche,vitesseDroite);
    } else if (!(nunchukDATA[5] & 2)) {// C button
      if (nunchukDATA[2]>0xB0) tourneDroite(0x55);
      else if (nunchukDATA[2]<0x55) tourneGauche(0x55);
           else if (nunchukDATA[3]>0x90) enAvant(0x55,0x55);
                else if (nunchukDATA[3]<0x80) enArriere(0x55,0x55);  
		   else enAvant(0x00,0x00);	
	}
	else enAvant(0x00,0x00);
    PORTA = vitesseGauche;
    _delay_ms(100);
    



}
  return 0;
}


//******************************************************************************************************************************
// function readFIFOandAskForNextData()
// purpose: read FIFO and put data in array and start the request of next data
// arguments: array of unsigned char to store FIFO data
//   
// return: nothing 
// note: you cannot understand if you never read the corresponding VHDL code (in iotimer.vhd)
//******************************************************************************************************************************
void readFIFOandAskForNextData(unsigned char nunchukDATA[]){
  unsigned char i;
  while(!(TWCR & (1<<DATAPRESENT))); // attente données dans le FIFO 	
  for (i=0;i<6;i++) {//lecture du Nunchuk du FIFO dans tableau
     nunchukDATA[i]=TWDR;
     //PORTA=TWDR;
  }
  // on demande une nouvelle lecture par le pérphérique : toutes données seront pour la prochaine fois
  TWCR |= (1<<0); //depart
  TWCR &= ~(1<<0);// arret pour attendre la prochaine fois : voir machine d'états pour comprendre
}

//******************************************************************************************************************************
// function enAvant()
// purpose: goAhead
// arguments: left and right speed
//   
// return: nothing 
// note: you cannot understand if you never read the corresponding VHDL code (in iotimer.vhd)
//******************************************************************************************************************************
void enAvant(unsigned char droite, unsigned char gauche) {
// par sécurité toute fonction commence par l'arrêt des moteurs
    PORTD = 0x00;
    PORTB = 0x00;
    _delay_ms(10);
// les deux moteurs en marche avant
// choix de la direction : en avant : voir code iotimer.vhd
    PORTC = 0x02;
    PORTD = droite;
    PORTB = gauche;
}

//******************************************************************************************************************************
// function enArriere()
// purpose: goBack
// arguments: left and right speed
//   
// return: nothing 
// note: you cannot understand if you never read the corresponding VHDL code (in iotimer.vhd)
//******************************************************************************************************************************
void enArriere(unsigned char droite, unsigned char gauche) {
// par sécurité toute fonction commence par l'arrêt des moteurs
    PORTD = 0x00;
    PORTB = 0x00;
    _delay_ms(10);
// les deux moteurs en marche arriere
// choix de la direction : en avant : voir code iotimer.vhd
   PORTC = 0x01;
    PORTD = droite;
    PORTB = gauche;
}

//******************************************************************************************************************************
// function TourneDroite()
// purpose: turn on the right
// arguments: left speed (right speed is zero)
//   
// return: nothing 
// note: you cannot understand if you never read the corresponding VHDL code (in iotimer.vhd)
//******************************************************************************************************************************
void tourneDroite(unsigned char gauche) {
// par sécurité toute fonction commence par l'arrêt des moteurs
    PORTD = 0x00;
    PORTB = 0x00;
    _delay_ms(10);
// les deux moteurs en marche avant
// choix de la direction : en avant : voir code iotimer.vhd
    PORTC = 0x02;
    PORTB = gauche;
}

//******************************************************************************************************************************
// function tourneGauche()
// purpose: turn on the left
// arguments: right speed (left speed is zero)
//   
// return: nothing 
// note: you cannot understand if you never read the corresponding VHDL code (in iotimer.vhd)
//******************************************************************************************************************************
void tourneGauche(unsigned char droite) {
// par sécurité toute fonction commence par l'arrêt des moteurs
    PORTD = 0x00;
    PORTB = 0x00;
    _delay_ms(10);
// les deux moteurs en marche avant
// choix de la direction : en avant : voir code iotimer.vhd
    PORTC = 0x02;
    PORTD = droite;
}