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.

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)
/*
//******************************************************************************************************************************
// 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:  
// note: you cannot understand if you never read the corresponding VHDL code (in io2.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
}

int main() {
   unsigned char data[6];
   while(1) {
     readFIFOandAskForNextData(data);
     if((data[5] & 0x01) ==0) PORTD =0x90; else PORTD=0x00;
     if((data[5] & 0x01) ==0) PORTB =0x90; else PORTB=0x00;
     _delay_ms(500);
  }
}
*/
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[0]>0xC0) tourneDroite(0x55);
      else if (nunchukDATA[0]<0x30) tourneGauche(0x55);
           else if (nunchukDATA[1]>0xC0) enAvant(0x55,0x55);
                else if (nunchukDATA[1]<0x30) enArriere(0x55,0x55);
                   else enAvant(0x00,0x00);
*/ 
      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;
}

/*
int main(int argc, char * argv[])
{
  unsigned char nb;
  while(1){ // boucle de 1/10 s
    nb++;
    // Reset compteur
    DDRB |= 0x80;
    DDRB &= 0x7F; // c'est arti
    if (nb == 9) { // environ 1s
      PORTD = PIND; // affichage compteur sur LEDs
      nb = 0;
    } // if 
    _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;
}