De2115Extension

De troyesGEII
Aller à : navigation, rechercher


Étude et conception

Présentation projet

On cherche à contrôler une tourelle pan-tilt à l'aide de 2 servomoteurs, d'un joystick ou d'un nunchuk, et d'un radar ultra-son.

Contraintes

Dimensionnement des écarts entre les connecteurs

1) Ecart entre les connecteurs MSP
C'est l'écart qui compte le plus : s'il n'y a qu'un mm de trop, la carte extension ne sert à rien. Une mesure précise de l'écart entre les broches extérieures de la MSP432, puisque celle-ci possède 2 broches doubles, donne 46mm.

2) Ecart entre les connecteurs MSP et le connecteur Altera
Une distance minimale est également nécessaire entre le connecteur Altera et les connecteurs MSP : 21mm.

3) Ecart entre les autres composants et les connecteurs MSP ou Altera
Comme le connecteur Altera a une certaine largeur, on ne peut pas placer des straps en-deçà d'une certaine distance avec l'élément. Or, comme, pour des raisons de commodité, il est très conseillé de placer toutes les pistes connectées à l'élément sur le côté inférieur de la carte, on se retrouve donc avec plusieurs straps, et il ne faut pas oublier cet élément.
De la même manière, une certaine distance est obligatoire entre les connecteurs MSP et les autres, car la carte n'a même pas exactement la largeur existante entre ses deux connecteurs, elle empatte. Cet empattement est de 5mm. Pour d'autres composants, cette distance doit être encore plus grande, car ceux-ci ont également une certaine largeur. Ainsi, la prise de la nunchuk ayant une largeur respectable, il faut une distance de 15mm entre les deux connecteurs.

Espace nécessaire à la fixation de la tourelle

La carte doit également nécessiter un espace suffisant pour fixer la tourelle pan-tilt.

Surface de la tourelle (en mm) : 33 x 37

Distances maximales entre les connecteurs et les composants

Comme les fils des composants n'ont pas une distance infinie, il y a une distance maximale entre ceux-ci et les connecteurs. Sur les 3 composants,l'un d'entre eux ne pose pas de problèmes : le nunchuk est tenu en main. Les deux restants se trouvent au même endroit : le sonar est imbriqué dans la tourelle. Cela implique donc que la tourelle doit se trouver à proximité des connecteurs des servomoteurs et du sonar.


Longueur des fils (en cm) :

- du sonar : 30

- de la tourelle pan-tilt : 24


Surface de la carte : 17 x 9


Etant donné que la surface de la carte est inférieure à la longueur des fils, la contrainte peut donc être négligée.

Cependant, dans l'optique de rendre la carte plus simple, il vaut mieux diminuer autant que possible la distance entre les composants et les connecteurs, afin de pouvoir raccourcir la longueur des fils.

Conception

Conception de la carte du binôme Baczkowski/To

Nous avons conçu notre carte en prenant en compte plusieurs paramètres.

Tout d'abord, afin de diminuer le flux entre les pistes, nous avons essayé d'éviter que celles-ci soient parallèles.
Dans un deuxième temps, pour éviter les vias, nous avons fait une carte en double face.

Nous avons eu un choix à faire au sujet des barrettes : celles-ci agissent en quelque sorte comme un interrupteur, sauf qu'il n'y a pas un état 0 et un état 1 mais, comme dans les deux cas il y a une liaison, une connexion A et une connexion B.

Comme un barrettes possède 4 pattes, on a une alternative :
- solution 1 : il y a une entrée et 2 sorties. Pour que les 4 pattes soient utilisées, on peut dupliquer l'entrée, et dans ce cas-là, il faut décaler le cavalier pour passer de la connexion A à la connexion B.
- solution 2 : on peut également se contenter d'une entrée. Mais comme le cavalier a une taille fixe, il ne peut pas être disposé sur la diagonale de la bar. On est donc obligé de disposer les sorties du cavalier de part et d'autre de l'entrée.

Dans un premier temps, nous avons retenu la première solution. Mais après la réalisation du premier prototype, nous avons préféré nous reporter sur la deuxième solution, afin de rendre l'utilisation de la carte plus simple. Mieux encore, nous avons décidé que sur chaque barrette, les positions des cavaliers auraient la même signification. Premièrement, les cavaliers sont toujours disposés de manière horizontale. Ensuite, la première position, celle du haut, relie l'élément au microcontrôleur de la carte MSP432, et celle du bas relie l'élément à la carte Altera.

Schéma du prototype
Typon du prototype















Un autre défi s'est présenté à nous lorsqu'il nous a fallu dimensionner, puis stabiliser la plaque soutenant le sonar sur la tourelle. Plusieurs solutions se présentaient à nous, mais dans tous les cas il nous fallait viser les deux plaques. Les 3 dimensions sont à prendre en compte :
- pour la largeur, des bordures en plastique permettent de la limiter, mais encore faut-il que la largeur du support du sonar corresponde avec l'écart entre les deux bordures ;
- pour la longueur, une bordure en plastique est placée à l'avant, mais il n'y a rien à l'arrière, il y a donc un risque que la carte s'échappe.
- pour la hauteur, elle est encore une fois limitée, en haut, par deux morceaux de plastique. Cependant, comme le mouvement de la tourelle est vertical, le sonar et sa plaque bougent beaucoup. C'est donc sur la hauteur que la stabilisation importe vraiment, même s'il n'y a pas pour autant de risques que le sonar s'échappe.

Schéma de la carte
Typon de la carte














Conception de la carte du binôme Gaya/Gnagne

Nous avons conçu notre carte de la manière suivante :
Afin de pouvoir optimiser la carte et qu'elle soit la plus petite possible donc la moins chère possible à fabriquer, tout en restant fonctionnelle :

  • Nous avons décidé de mettre les 2 deux connecteurs 3 broches mâle-mâle, servant aux 2

servomoteurs de la tourelle côte-à- côte afin de limiter des étalements de fils.

  • Nous avons bien pris les précautions nécessaires vis-à- vis des espacements entre chaque

composant.

  • Afin de pouvoir souder que d’un seul côté le plus gros composant de notre carte « le

connecteur 40 broches », qui sert à la connexion avec l’Altera, nous l’avons routé que du côté « Bottom ».

Nous avions donc le même schéma, mais nos typons étaient différents :

Board eagle

Programmation

Travail S3

Une fois la carte réalisée, nous avons voulu vérifier si celle-ci fonctionnait en commençant directement avec un programme complexe. Mais comme les résultats que nous a donnés celui-ci se sont avérés surréalistes, nous avons dans un second temps préféré créer 3 programmes séparés, pour chacune des 3 parties du montage :
- le premier destiné à contrôler le fonctionnement des servomoteurs, et donc la rotation de la tourelle ;
- le second destiné à soumettre cette tourelle au mouvement de la nunchuk ;
- et dans un troisième temps, faire fonctionner le sonar, c'est-à-dire émettre et récupérer un signal pour pouvoir déterminer la distance à laquelle se trouvent les obstacles les plus proches.

Programme relatif au contrôle des servomoteurs

Pour contrôler les servomoteurs, nous avons d'abord trouvé un programme test, pour vérifier le fonctionnement du servomoteur sur une plaque à essai avant la réalisation.
Pour cela, nous avons trouvé dans Energia, une plateforme de prototypage électronique permettant de rendre compatible la structure Arduino, avec les composants Texas Instruments, le programme Knob dans la bibliothèque Servo. Ce programme ne fonctionne pas avec la nunchuk, mais avec un potentiomètre.

  #include <Servo.h> 
  
  Servo myservo;  // create servo object to control a servo 
  
  int potpin = PE_4;  // analog pin used to connect the potentiometer
  int val;    // variable to read the value from the analog pin 
  
  void setup() 
  { 
   myservo.attach(PF_1);  // attaches the servo on Port F, pin 1 (Red LED pin) to the servo object 
  } 
   
  void loop() 
  { 
   val = analogRead(potpin);            // reads the value of the potentiometer (value between 0 and 4095) 
   val = map(val, 0, 4095, 0, 179);     // scale it to use it with the servo (value between 0 and 180) 
   myservo.write(val);                  // sets the servo position according to the scaled value 
   delay(15);                           // waits for the servo to get there 
  }

De cette manière, nous avons pu nous assurer que le montage que nous nous proposions de faire ne comportait pas d'erreur de routage.

Par la suite, avec l'aide de l'enseignant, nous avons fait un deuxième programme, servant uniquement à vérifier que la tourelle n'ait pas de problèmes.

  #include <Servo.h>
  
  Servo h_servo, v_servo;;
  
  uint8_t horizontal,vertical;
  void setup() {
    //définir patte Data des servomoteurs
    h_servo.attach(A15); // servomoteur horizontal
    v_servo.attach(3); // servomoteur vertical
   
    // iniatialisation de la valeur de départ
    horizontal=0; 
    vertical=20;
  }
  
  void loop() {
    // Incrémentation de la variable horizontale
    horizontal += 10;
    
    // Condition 
    if (horizontal > 180) // si la variable horizontale est maximale
    {
      vertical += 10; // Incrémentation la variable verticale
      horizontal=0; // remise à zéro de la valeur horizontale
    }
   if (vertical > 105) vertical=20; // si la variable vertical est maximale, retour à la valeur initiale
  
   // donne une valeur aux servomoteurs
   h_servo.write(horizontal);
   v_servo.write(vertical);
   delay(1000);
   h_servo.write(horizontal);
   v_servo.write(vertical);
   delay(333);
  
  }

Nous avons toutefois rencontré des problèmes. L'un d'entre eux ne nous a pas posé de vrais problèmes, étant aisément contournable, mais il nous a agacé, car nous n'en comprenons pas la cause : la temporisation que l'on trouve dans la boucle ne pouvait pas être une autre valeur que 100 ou 333.
Comme nous cherchions une temporisation de 1000, nous avons d'abord pensé que les servomoteurs ne gardaient pas en mémoire leur valeur suffisamment longtemps, mais comme nous avons essayé également une temporisation de 250, nous avons dû admettre que ce n'était pas ça. Finalement, afin de pouvoir conserver une temporisation assez grande, nous avons compris que c'était le fait que ce soit la dernière temporisation qui posait problème, et nous avons donc rajouté une deuxième temporisation, avec cette fois-ci une valeur "admise".
Comme la rotation de la tourelle est soumise à la nunchuk, cette temporisation n'est pas si importante, même si on en aura quand même besoin pour la réception du signal par le sonar.

Programme relatif au contrôle du sonar

unsigned char trig = 17; // Définit la patte du transmetteur
unsigned char echo = 19; // Définit la patte du récepteur
float aff; 
float diviseur = 64.1; // Convertit la valeur reçue en cm 

void setup() {
  // Déclare les pins
  pinMode(trig, OUTPUT);
  pinMode(echo, INPUT);
  Serial.begin(9600);
}

void loop()
{
  delay(500);
  digitalWrite(trig, 1);
  delayMicroseconds(10);
  digitalWrite(trig, 0);
  aff = (pulseIn(echo, 1) / diviseur);
  Serial.print(aff);
  Serial.println("cm");

}

Programme relatif au contrôle de la manette nunchuk

Nous avons perdu beaucoup de temps avec une erreur bête : sur Arduino, il ne faut pas mettre de pull-up, puisque le logiciel le fait automatiquement. Mais Energia ne le fait pas, il faut donc mettre une pull-up, et cet oubli nous a fait perdre un temps précieux.



Programme Test

#include <Wire.h>
 // adresse I2C du nunchuck
#define WII_NUNCHUK_I2C_ADDRESS 0x52
 
// définition d'une variable counter
uint8_t counter;
 
// définition d'un tableau de données
uint8_t data[6];
 
void setup() {
  pinMode(10,INPUT_PULLUP); // SDA
  pinMode(BLUE_LED, OUTPUT); // Déclaration de la LED

  // initialisation du nunchuck
  Wire.begin();
  Wire.beginTransmission(WII_NUNCHUK_I2C_ADDRESS);
  Wire.write(0xF0);
  Wire.write(0x55);
  Wire.endTransmission();
 
  Wire.beginTransmission(WII_NUNCHUK_I2C_ADDRESS);
  Wire.write(0xFB);
  Wire.write(0x00);
  Wire.endTransmission();
}
 
 
void loop() { 
  // on réinitialise le nunchuck pour la prochaine demande
  Wire.beginTransmission(WII_NUNCHUK_I2C_ADDRESS);
  Wire.write(0x00);
  Wire.endTransmission();
  delay(1);

  // on demande 6 octets au nunchuck
  Wire.requestFrom(WII_NUNCHUK_I2C_ADDRESS, 6);
  counter = 0;  // tant qu’il y a des données
  while(Wire.available()) {
    // on récupère les données
    data[counter++] = Wire.read();
  }
   //allumer la LED bleu dont la valeur est donnée par l'axe X du joystick
   analogWrite(BLUE_LED, data[0]);  
   // un petit delai  pour pas saturer la liaison série.
   delay(30);
}

Programme reliant le nunchuck au servomoteurs

#include <Servo.h>
#include <Wire.h>

// adresse I2C du nunchuck
#define WII_NUNCHUK_I2C_ADDRESS 0x52

Servo h_servo, v_servo;

// iniatialisation de la valeur de départ
uint8_t horizontal = 90;
uint8_t vertical = 20;;

// définition d'une variable counter
uint8_t counter;

// définition d'un tableau de données
uint8_t data[6];

uint8_t joyX;
uint8_t joyY;
int16_t accelX;
int16_t accelY;
int16_t accelZ;



void setup() {
  pinMode(10, INPUT_PULLUP); // SDA

  //définir patte Data des servomoteurs
  h_servo.attach(A15); // servomoteur horizontal
  v_servo.attach(3); // servomoteur vertical

  Serial.begin(9600);

  // initialisation du nunchuck

  Wire.begin();
  Wire.beginTransmission(WII_NUNCHUK_I2C_ADDRESS);
  Wire.write(0xF0);
  Wire.write(0x55);
  Wire.endTransmission();

  Wire.beginTransmission(WII_NUNCHUK_I2C_ADDRESS);
  Wire.write(0xFB);
  Wire.write(0x00);
  Wire.endTransmission();
}


void loop() {
  // on réinitialise le nunchuck pour la prochaine demande
  Wire.beginTransmission(WII_NUNCHUK_I2C_ADDRESS);
  Wire.write(0x00);
  Wire.endTransmission();
  delay(1);

  // on demande 6 octets au nunchuck
  Wire.requestFrom(WII_NUNCHUK_I2C_ADDRESS, 6);
  counter = 0;  // tant qu’il y a des données
  while (Wire.available()) {
    // on récupère les données
    data[counter++] = Wire.read();
  }



  if (counter >= 5)
  {
    // on extrait les données
    joyX = data[0];
    joyY = data[1];
    // dans mon exemple j'utilise uniquement les données d'accélération sur l'axe Y
    accelX = ((data[2] << 2) + ((data[5] >> 2) & 0x03));
    accelY = ((data[3] << 2) + ((data[5] >> 4) & 0x03));
    accelZ = ((data[4] << 2) + ((data[5] >> 6) & 0x03));
  }

  // Si joyX est inférieur à 110
  if (joyX < 110)
  {
    horizontal += 10; // on incrémente
  }
  else if (joyX > 140) // Ou si joyX est supérieur à 140
  {
    horizontal -= 10; // on décrémente
  }

  //seuil limite h_servo
  if (horizontal > 190)
  {
    horizontal = 190;
  }
  else if (horizontal < 10)
  {
    horizontal = 10;
  }

  // Si joyY est inférieur à 120
  if (joyY < 120)
  {
    vertical -= 10; // on décrémente
  }
  else if (joyY > 140) // Ou si joyY est supérieur à 140
  {
    vertical += 10; // on incrémente
  }

  //seuil limite v_servo
  if (vertical > 160)
  {
    vertical = 160;
  }
  else if (vertical < 30)
  {
    vertical = 30;
  }
  //Serial.print("vtc = ");
  //Serial.println(vertical);

  // donne une valeur aux servomoteurs
  h_servo.write(horizontal);
  v_servo.write(vertical);
  delay(100);

  // un petit delai  pour pas saturer la liaison série.
  delay(30);
}

Programme complet

#include <Servo.h>
#include <Wire.h>

// adresse I2C du nunchuck
#define WII_NUNCHUK_I2C_ADDRESS 0x52

Servo h_servo, v_servo;
//servomteur
// iniatialisation de la valeur de départ
uint8_t horizontal = 90;
uint8_t vertical = 20;;

//nunchuck
// définition d'une variable counter
uint8_t counter;

// définition d'un tableau de données
uint8_t data[6];

uint8_t joyX;
uint8_t joyY;
int16_t accelX;
int16_t accelY;
int16_t accelZ;

//sonar
unsigned char trig = 17;
unsigned char echo = 19;
float aff;
float diviseur = 64.1;

void setup() {
  pinMode(10, INPUT_PULLUP); // SDA

  //sonar
  pinMode(trig, OUTPUT);
  pinMode(echo, INPUT);

  //servomoteur
  //définir patte Data des servomoteurs
  h_servo.attach(A15); // servomoteur horizontal
  v_servo.attach(3); // servomoteur vertical

  Serial.begin(9600);

  // initialisation du nunchuck

  Wire.begin();
  Wire.beginTransmission(WII_NUNCHUK_I2C_ADDRESS);
  Wire.write(0xF0);
  Wire.write(0x55);
  Wire.endTransmission();

  Wire.beginTransmission(WII_NUNCHUK_I2C_ADDRESS);
  Wire.write(0xFB);
  Wire.write(0x00);
  Wire.endTransmission();
}


void loop() {
  // on réinitialise le nunchuck pour la prochaine demande
  Wire.beginTransmission(WII_NUNCHUK_I2C_ADDRESS);
  Wire.write(0x00);
  Wire.endTransmission();
  delay(1);

  // on demande 6 octets au nunchuck
  Wire.requestFrom(WII_NUNCHUK_I2C_ADDRESS, 6);
  counter = 0;  // tant qu’il y a des données
  while (Wire.available()) {
    // on récupère les données
    data[counter++] = Wire.read();
  }



  if (counter >= 5)
  {
    // on extrait les données
    joyX = data[0];
    joyY = data[1];
    // dans mon exemple j'utilise uniquement les données d'accélération sur l'axe Y
    accelX = ((data[2] << 2) + ((data[5] >> 2) & 0x03));
    accelY = ((data[3] << 2) + ((data[5] >> 4) & 0x03));
    accelZ = ((data[4] << 2) + ((data[5] >> 6) & 0x03));
  }

  // Si joyX est inférieur à 110
  if (joyX < 110)
  {
    horizontal += 10; // on incrémente
  }
  else if (joyX > 140) // Ou si joyX est supérieur à 140
  {
    horizontal -= 10; // on décrémente
  }

  //seuil limite h_servo
  if (horizontal > 190)
  {
    horizontal = 190;
  }
  else if (horizontal < 10)
  {
    horizontal = 10;
  }

  // Si joyY est inférieur à 120
  if (joyY < 120)
  {
    vertical -= 10; // on décrémente
  }
  else if (joyY > 140) // Ou si joyY est supérieur à 140
  {
    vertical += 10; // on incrémente
  }

  //seuil limite v_servo
  if (vertical > 160)
  {
    vertical = 160;
  }
  else if (vertical < 30)
  {
    vertical = 30;
  }

  // donne une valeur aux servomoteurs
  h_servo.write(horizontal);
  v_servo.write(vertical);
  delay(100);

  // un petit delai  pour pas saturer la liaison série.
  delay(30);

  //sonar
  delay(500);
  digitalWrite(trig, 1);
  delayMicroseconds(5);
  digitalWrite(trig, 0);
  aff = (pulseIn(echo, 1) / diviseur);
  Serial.print(aff);
  Serial.println("cm");
}

Travail S4 du binôme Baczkowski/To

Dans la continuité de notre projet en Etude et Réalisation du S3, nous devions programmer notre carte de tels sorte que les servomoteurs et le sonar soient contrôlés par la carte Altera, c'est-à-dire en VHDL, et la nunchuk par la carte MSP432. Pour cela, nous avons suivi la même logique que nous avons utilisé lors du S3. Nous avons divisé les tâches en plusieurs partie pour résoudre petit problème par petit problème. Nous avons :
- tout d'abord commencé par mouvoir les servomoteurs et définir leurs plages de déplacement,
- ensuite programmé le sonar et faire afficher la distance en cm avec les afficheurs 7 segments,
- puis mélangé les 2 programmes précédents,
- Enfin programmé le sonar pour qu'il affiche la distance sous forme d'un barregraphe sur l'écran LCD

Programme relatif au contrôle des servomoteurs

Nous avons commencé par faire bouger le servomoteur horizontal en définissant des valeurs en dur pour encadrer la plage de déplacement du servomoteur, puis nous avons exécuté la même manipulation pour le servomoteur vertical. Ensuite, nous avons programmé les servomoteurs de tels sorte qu'il balaye une plage pour se déplacer.

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

entity ER_Project is port (
  clk : in std_logic;
  pwm : out std_logic_vector(1 downto 0)
    );
end entity;

architecture Movemotor of ER_Project is

component diviseur is port (
	clk : in std_logic;
	eno : out std_logic
--	q : out std_logic_vector(23 downto 0)
	);
end component;

component cmpt_hzt is port (
	clk, en : in std_logic;
	eno : out std_logic;
	s_hzt : out std_logic_vector(7 downto 0)
	);
end component;

component cmpt_vtc is port (
	clk, en : in std_logic;
	s_vtc : out std_logic_vector(7 downto 0)
	);
end component;

 signal timer : natural range 0 to 3900 := 0;
 signal eno : std_logic;
 signal s_cmpt8 : std_logic_vector(7 downto 0);
 signal s_eno, s_eno1 : std_logic;
 signal ref1 : std_logic_vector(7 downto 0);
 signal ref2 : std_logic_vector(7 downto 0);
begin 

div : diviseur port map (
	clk => clk, eno => s_eno
	);
cmpt1 : cmpt_hzt port map (
	clk => clk, en => s_eno, eno => s_eno1, s_hzt => ref1
	);
cmpt2 : cmpt_vtc port map (
	clk => clk, en => s_eno1, s_vtc => ref2
	);

 -- realisation 78 us
 process(clk)
  begin
    if rising_edge(clk) then
      if timer = 0 then
        timer <= 3900;
        eno <= '1';
      else
        timer <= timer - 1;
		  eno <='0';
      end if;
    end if;
  end process;
 
  cmpt8:process(clk) begin
     if rising_edge(clk) then
	    if eno = '1' then
		   s_cmpt8 <= s_cmpt8 + 1;
		 end if;
	  end if;
	end process; 

--comparaison svm hrz
 process(s_cmpt8)
  begin	
	if (s_cmpt8 < ref1) then
		pwm(0) <= '1';
	else
		pwm(0) <= '0';
	end if;
  end process;
  
  
  --comparaison svm vtc
 process(s_cmpt8)
  begin	
	if (s_cmpt8 < ref2) then
		pwm(1) <= '1';
	else
		pwm(1) <= '0';
	end if;
  end process;
  
end Movemotor;

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity diviseur is port (
	clk : in std_logic;
	eno : out std_logic
--	q : out std_logic_vector(23 downto 0)
	);
end entity diviseur;

architecture arch of diviseur is
signal cmpt : std_logic_vector(23 downto 0);
begin
  process (clk) begin
    if rising_edge(clk) then
	   cmpt <= cmpt+1;
	 end if;
  end process;
  eno <= '1' when cmpt = x"FFFFFF" else
         '0';
end arch;

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity cmpt_hzt is port (
	clk, en : in std_logic;
	eno : out std_logic;
	s_hzt : out std_logic_vector(7 downto 0)
	);
end entity cmpt_hzt;

architecture arch of cmpt_hzt is
  signal cmpt : std_logic_vector(7 downto 0) := x"0A";
begin
  process (clk) begin
    if rising_edge(clk) then
	   if en='1' then
	     if cmpt < x"1F" then
		    cmpt <= cmpt+1;
		  else
		    cmpt <= x"08";
		  end if;
		end if;
	 end if;
  end process;
  eno <= '1' when cmpt = x"1F" else
         '0';
  s_hzt <= cmpt;
end arch;

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity cmpt_vtc is port (
	clk, en : in std_logic;
	s_vtc : out std_logic_vector(7 downto 0)
	);
end entity;

architecture arch of cmpt_vtc is
  signal cmpt : std_logic_vector(7 downto 0) := x"0A";
begin
  process (clk) begin
    if rising_edge(clk) then
	   if en='1' then
	     if cmpt < x"14" then
		    cmpt <= cmpt+1;
		  else
		    cmpt <= x"0A";
		  end if;
		end if;
	 end if;
  end process;
  s_vtc <= cmpt;
end arch;


Et voici le fichier de contrainte :


To,Direction,Location,I/O Bank,VREF Group,I/O Standard,Reserved
CLK,Input,PIN_Y2,2,B2_N0,3.3-V LVTTL,
pwm[0],Output,PIN_AC15,4,B4_N2,3.3-V LVTTL,
pwm[1],Output,PIN_Y17,4,B4_N0,3.3-V LVTTL,

Fichier:Test Servo.zip

Programme relatif au sonar

A partir d'un programme de base donné, nous avons ajouté au programme l'affichage de la distance pour qu'il affiche la distance sur 2 digit.

----------------------------------------------
-- Interfacing a low-cost sonar module with
-- an FPGA 
-- Author: Mike Field <hamster@snap.net.nz>
----------------------------------------------

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
--use IEEE.NUMERIC_STD.ALL;

entity sonar is
    Port ( clk        : in  STD_LOGIC;
           sonar_trig : out STD_LOGIC;
           sonar_echo : in  STD_LOGIC;
--           anodes     : out STD_LOGIC_VECTOR (3 downto 0);
--           segments   : out STD_LOGIC_VECTOR (6 downto 0));
           Diz7segs   : out std_logic_vector(6 downto 0);
           Unit7segs  : out std_logic_vector(6 downto 0));
end sonar;

architecture Behavioral of sonar is

  component affichage2digits is
    port (  
            I_in8    : in  std_logic_vector(7 downto 0);
				-- Ordre : gfedcba
            Diz7segs,Unit7segs  : out std_logic_vector(6 downto 0)
    );
  end component affichage2digits;
  
    signal count            : std_logic_vector(16 downto 0) := (others => '0');
    signal centimeters      : std_logic_vector(15 downto 0) := (others => '0');
    signal centimeters_ones : std_logic_vector(3 downto 0)  := (others => '0');
    signal centimeters_tens : std_logic_vector(3 downto 0)  := (others => '0');
    signal output_ones      : std_logic_vector(3 downto 0)  := (others => '0');
    signal output_tens      : std_logic_vector(3 downto 0)  := (others => '0');
    signal digit            : std_logic_vector(3 downto 0)  := (others => '0');
    signal echo_last        : std_logic := '0';
    signal echo_synced      : std_logic := '0';
    signal echo_unsynced    : std_logic := '0';
    signal waiting          : std_logic := '0'; 
    signal seven_seg_count  : std_logic_vector(15 downto 0) := (others => '0');
begin

  affichage : affichage2digits port map(
       I_in8(3 downto 0) =>  output_ones,
		 I_in8(7 downto 4) =>  output_tens,
       Diz7segs => Diz7segs,
		 Unit7segs => Unit7segs 
  );
    
process(clk)
    begin
        if rising_edge(clk) then
            if waiting = '0' then
            --    if count = 1000 then -- Assumes 100MHz
				   if count = 500 then -- Assumes 50MHz
                   -- After 10us then go into waiting mode
                   sonar_trig <= '0';
                   waiting    <= '1';
                   count       <= (others => '0');
                else
                   sonar_trig <= '1';
                   count <= count+1;
                end if;
            elsif echo_last = '0' and echo_synced = '1' then
                -- Seen rising edge - start count
                count       <= (others => '0');
                centimeters <= (others => '0');
                centimeters_ones <= (others => '0');
                centimeters_tens <= (others => '0');
            elsif echo_last = '1' and echo_synced = '0' then
                -- Seen falling edge, so capture count
                output_ones <= centimeters_ones; 
                output_tens <= centimeters_tens; 
 --           elsif count = 2900*2 -1 then
             elsif count = 1450*2 -1 then
                -- advance the counter
                if centimeters_ones = 9 then
                    centimeters_ones <= (others => '0');
                    centimeters_tens <= centimeters_tens + 1;
                else
                    centimeters_ones <= centimeters_ones + 1;
                end if;
                centimeters <= centimeters + 1;
                count <= (others => '0');
                if centimeters = 3448 then
                    -- time out - send another pulse
                    waiting <= '0';
                end if;
            else
                count <= count + 1;                
            end if;

            echo_last     <= echo_synced;
            echo_synced   <= echo_unsynced;
            echo_unsynced <= sonar_echo;
        end if;
        
    end process;
end Behavioral;

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- zero pour allumer les LEDs
entity transcod7segs is
    port (  
            I_in4    : in  std_logic_vector(3 downto 0);
				-- Ordre : gfedcba
            Q_7segs  : out std_logic_vector(6 downto 0)
    );
end transcod7segs;

architecture arch of transcod7segs is begin
  with I_in4 select
    Q_7SEGS <= "1000000" when "0000",
               "1111001" when "0001",
               "0100100" when "0010",
               "0110000" when "0011",
               "0011001" when X"4",
               "0010010" when X"5",
               "0000010" when X"6",
               "1111000" when X"7",
               "0000000" when X"8",
               "0010000" when X"9",
               "0001000" when X"A",
               "0000011" when X"B",
               "1000110" when X"C",
               "0100001" when X"D",
               "0000110" when X"E",
               "0001110" when others; --X"F"
end arch;

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- zero pour allumer les segments
entity affichage2digits is
    port (  
            I_in8    : in  std_logic_vector(7 downto 0);
				-- Ordre : gfedcba
            Diz7segs,Unit7segs  : out std_logic_vector(6 downto 0)
    );
end affichage2digits;

architecture arch_affichage2digits of affichage2digits is
component transcod7segs is
    port (  
            I_in4    : in  std_logic_vector(3 downto 0);
				-- Ordre : gfedcba
            Q_7segs  : out std_logic_vector(6 downto 0)
    );
end component transcod7segs;
 
begin
  unite : transcod7segs port map (
     I_in4 => I_in8(3 downto 0),
	  Q_7segs => Unit7segs
	  );
  dizaine : transcod7segs port map (
     I_in4 => I_in8(7 downto 4),
	  Q_7segs => Diz7segs
	  );
end arch_affichage2digits;

Et voici le ficher de contrainte :


To,Direction,Location,I/O Bank,VREF Group,I/O Standard,Reserved
clk,Input,PIN_Y2,2,B2_N0,3.3-V LVTTL,
Unit7segs[6],Output,PIN_H22,6,B6_N0,2.5 V,
Unit7segs[5],Output,PIN_J22,6,B6_N0,2.5 V,
Unit7segs[4],Output,PIN_L25,6,B6_N1,2.5 V,
Unit7segs[3],Output,PIN_L26,6,B6_N1,2.5 V,
Unit7segs[2],Output,PIN_E17,7,B7_N2,2.5 V,
Unit7segs[1],Output,PIN_F22,7,B7_N0,2.5 V,
Unit7segs[0],Output,PIN_G18,7,B7_N2,2.5 V,
Diz7segs[6],Output,PIN_U24,5,B5_N0,2.5 V,
Diz7segs[5],Output,PIN_U23,5,B5_N1,2.5 V,
Diz7segs[4],Output,PIN_W25,5,B5_N1,2.5 V,
Diz7segs[3],Output,PIN_W22,5,B5_N0,2.5 V,
Diz7segs[2],Output,PIN_W21,5,B5_N1,2.5 V,
Diz7segs[1],Output,PIN_Y22,5,B5_N0,2.5 V,
Diz7segs[0],Output,PIN_M24,6,B6_N2,2.5 V,
sonar_trig,Output,PIN_AE16,4,B4_N2,3.3-V LVTTL,
sonar_echo,Input,PIN_Y16,4,B4_N0,3.3-V LVTTL,

2 Digits - Mesure distance = 26 cm
2 Digits - Mesure distance = 50 cm














2 Digits - Mesure distance = ERROR



Fichier:Sonar 2 digit.zip


Mais nous avons remarqué que ce type d'affichage ne suffisait pas pour afficher les longues distances, donc nous avons ajouté un 3e digit.

----------------------------------------------
-- Interfacing a low-cost sonar module with
-- an FPGA 
-- Author: Mike Field <hamster@snap.net.nz>
----------------------------------------------

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
--use IEEE.NUMERIC_STD.ALL;

entity sonar is
    Port ( clk        : in  STD_LOGIC;
           sonar_trig : out STD_LOGIC;
           sonar_echo : in  STD_LOGIC;
--           anodes     : out STD_LOGIC_VECTOR (3 downto 0);
--           segments   : out STD_LOGIC_VECTOR (6 downto 0));
			  Cent7segs   : out std_logic_vector(6 downto 0);
           Diz7segs   : out std_logic_vector(6 downto 0);
           Unit7segs  : out std_logic_vector(6 downto 0));
end sonar;

architecture Behavioral of sonar is

  component affichage2digits is
    port (  
            I_in12    : in  std_logic_vector(11 downto 0);
				-- Ordre : gfedcba
            Cent7segs, Diz7segs,Unit7segs  : out std_logic_vector(6 downto 0)
    ); 
  end component affichage2digits;
  
    signal count            : std_logic_vector(16 downto 0) := (others => '0');
    signal centimeters      : std_logic_vector(15 downto 0) := (others => '0');
    signal centimeters_ones : std_logic_vector(3 downto 0)  := (others => '0');
    signal centimeters_tens : std_logic_vector(3 downto 0)  := (others => '0');
	 signal centimeters_hundreds : std_logic_vector(3 downto 0)  := (others => '0');
    signal output_ones      : std_logic_vector(3 downto 0)  := (others => '0');
    signal output_tens      : std_logic_vector(3 downto 0)  := (others => '0');
	 signal output_hundreds      : std_logic_vector(3 downto 0)  := (others => '0');
    signal digit            : std_logic_vector(3 downto 0)  := (others => '0');
    signal echo_last        : std_logic := '0';
    signal echo_synced      : std_logic := '0';
    signal echo_unsynced    : std_logic := '0';
    signal waiting          : std_logic := '0'; 
    signal seven_seg_count  : std_logic_vector(15 downto 0) := (others => '0');
begin

  affichage : affichage2digits port map(
       I_in12(3 downto 0) =>  output_ones,
		 I_in12(7 downto 4) =>  output_tens,
		 I_in12(11 downto 8) =>  Output_hundreds,
		 Cent7segs => Cent7segs,
       Diz7segs => Diz7segs,
		 Unit7segs => Unit7segs 
  );
    
process(clk)
    begin
        if rising_edge(clk) then
            if waiting = '0' then
            --    if count = 1000 then -- Assumes 100MHz
				   if count = 500 then -- Assumes 50MHz
                   -- After 10us then go into waiting mode
                   sonar_trig <= '0';
                   waiting    <= '1';
                   count       <= (others => '0');
                else
                   sonar_trig <= '1';
                   count <= count+1;
                end if;
            elsif echo_last = '0' and echo_synced = '1' then
                -- Seen rising edge - start count
                count       <= (others => '0');
                centimeters <= (others => '0');
                centimeters_ones <= (others => '0');
                centimeters_tens <= (others => '0');
					 centimeters_hundreds <= (others => '0');
            elsif echo_last = '1' and echo_synced = '0' then
                -- Seen falling edge, so capture count
                output_ones <= centimeters_ones; 
                output_tens <= centimeters_tens; 
					 output_hundreds <= centimeters_hundreds;
 --           elsif count = 2900*2 -1 then
             elsif count = 1450*2 -1 then
                -- advance the counter
                if centimeters_ones = 9 then
                    centimeters_ones <= (others => '0');
                    centimeters_tens <= centimeters_tens + 1;
						  if centimeters_tens = 9 then
                      centimeters_tens <= (others => '0');
                      centimeters_hundreds <= centimeters_hundreds + 1;
						  else
                      centimeters_tens <= centimeters_tens + 1;
						  end if;
                else
                    centimeters_ones <= centimeters_ones + 1;
                end if;
                centimeters <= centimeters + 1;
                count <= (others => '0');
                if centimeters = 3448 then
                    -- time out - send another pulse
                    waiting <= '0';
                end if;
            else
                count <= count + 1;                
            end if;

            echo_last     <= echo_synced;
            echo_synced   <= echo_unsynced;
            echo_unsynced <= sonar_echo;
        end if;
        
    end process;
end Behavioral;

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- zero pour allumer les LEDs
entity transcod7segs is
    port (  
            I_in4    : in  std_logic_vector(3 downto 0);
				-- Ordre : gfedcba
            Q_7segs  : out std_logic_vector(6 downto 0)
    );
end transcod7segs;

architecture arch of transcod7segs is begin
  with I_in4 select
    Q_7SEGS <= "1000000" when "0000",
               "1111001" when "0001",
               "0100100" when "0010",
               "0110000" when "0011",
               "0011001" when X"4",
               "0010010" when X"5",
               "0000010" when X"6",
               "1111000" when X"7",
               "0000000" when X"8",
               "0010000" when X"9",
               "0001000" when X"A",
               "0000011" when X"B",
               "1000110" when X"C",
               "0100001" when X"D",
               "0000110" when X"E",
               "0001110" when others; --X"F"
end arch;

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- zero pour allumer les segments
entity affichage2digits is
    port (  
            I_in12    : in  std_logic_vector(11 downto 0);
				-- Ordre : gfedcba
            Cent7segs, Diz7segs,Unit7segs  : out std_logic_vector(6 downto 0)
    );
end affichage2digits;

architecture arch_affichage2digits of affichage2digits is
component transcod7segs is
    port (  
            I_in4    : in  std_logic_vector(3 downto 0);
				-- Ordre : gfedcba
            Q_7segs  : out std_logic_vector(6 downto 0)
    );
end component transcod7segs;
 
begin
  unite : transcod7segs port map (
     I_in4 => I_in12(3 downto 0),
	  Q_7segs => Unit7segs
	  );
  dizaine : transcod7segs port map (
     I_in4 => I_in12(7 downto 4),
	  Q_7segs => Diz7segs
	  );
  centaine : transcod7segs port map (
     I_in4 => I_in12(11 downto 8),
	  Q_7segs => Cent7segs
	  );
end arch_affichage2digits;

Et donc utiliser ce ficher de contrainte :


To,Direction,Location,I/O Bank,VREF Group,I/O Standard,Reserved
clk,Input,PIN_Y2,2,B2_N0,3.3-V LVTTL,
Unit7segs[6],Output,PIN_H22,6,B6_N0,2.5 V,
Unit7segs[5],Output,PIN_J22,6,B6_N0,2.5 V,
Unit7segs[4],Output,PIN_L25,6,B6_N1,2.5 V,
Unit7segs[3],Output,PIN_L26,6,B6_N1,2.5 V,
Unit7segs[2],Output,PIN_E17,7,B7_N2,2.5 V,
Unit7segs[1],Output,PIN_F22,7,B7_N0,2.5 V,
Unit7segs[0],Output,PIN_G18,7,B7_N2,2.5 V,
Diz7segs[6],Output,PIN_U24,5,B5_N0,2.5 V,
Diz7segs[5],Output,PIN_U23,5,B5_N1,2.5 V,
Diz7segs[4],Output,PIN_W25,5,B5_N1,2.5 V,
Diz7segs[3],Output,PIN_W22,5,B5_N0,2.5 V,
Diz7segs[2],Output,PIN_W21,5,B5_N1,2.5 V,
Diz7segs[1],Output,PIN_Y22,5,B5_N0,2.5 V,
Diz7segs[0],Output,PIN_M24,6,B6_N2,2.5 V,
Cent7segs[6],Output,PIN_W28,5,B5_N1,2.5 V,
Cent7segs[5],Output,PIN_W27,5,B5_N1,2.5 V,
Cent7segs[4],Output,PIN_Y26,5,B5_N1,2.5 V,
Cent7segs[3],Output,PIN_W26,5,B5_N1,2.5 V,
Cent7segs[2],Output,PIN_Y25,5,B5_N1,2.5 V,
Cent7segs[1],Output,PIN_AA26,5,B5_N1,2.5 V,
Cent7segs[0],Output,PIN_AA25,5,B5_N1,2.5 V,
sonar_trig,Output,PIN_AE16,4,B4_N2,3.3-V LVTTL,
sonar_echo,Input,PIN_Y16,4,B4_N0,3.3-V LVTTL,


3 Digits - Mesure distance = 50 cm
3 Digits - Mesure distance = 114 cm














3 Digits - Mesure distance = 180 cm




Fichier:Sonar 3 digit.zip

Programme mélangé

Suite au 2 précédentes résolutions, nous avons essayé de calculer et afficher la distance sur 2 digits tout en bougeant les servomoteurs.

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

entity ER_Project is port (
  clk : in std_logic;
  pwm : out std_logic_vector(1 downto 0);
  sonar_trig : out STD_LOGIC;
  sonar_echo : in  STD_LOGIC;
  Diz7segs   : out std_logic_vector(6 downto 0);
  Unit7segs  : out std_logic_vector(6 downto 0)
    );
end entity;

architecture Movemotor of ER_Project is

component diviseur is port (
	clk : in std_logic;
	eno : out std_logic
--	q : out std_logic_vector(23 downto 0)
	);
end component;

component cmpt_hzt is port (
	clk, en : in std_logic;
	eno : out std_logic;
	s_hzt : out std_logic_vector(7 downto 0)
	);
end component;

component cmpt_vtc is port (
	clk, en : in std_logic;
	s_vtc : out std_logic_vector(7 downto 0)
	);
end component;

-- component of sonar
component affichage2digits is
    port (  
            I_in8    : in  std_logic_vector(7 downto 0);
				-- Ordre : gfedcba
            Diz7segs,Unit7segs  : out std_logic_vector(6 downto 0)
    );
  end component affichage2digits;

 signal timer : natural range 0 to 3900 := 0;
 signal eno : std_logic;
 signal s_cmpt8 : std_logic_vector(7 downto 0);
 signal s_eno, s_eno1 : std_logic;
 signal ref1 : std_logic_vector(7 downto 0);
 signal ref2 : std_logic_vector(7 downto 0);
 
 -- signal of sonar
    signal count            : std_logic_vector(16 downto 0) := (others => '0');
    signal centimeters      : std_logic_vector(15 downto 0) := (others => '0');
    signal centimeters_ones : std_logic_vector(3 downto 0)  := (others => '0');
    signal centimeters_tens : std_logic_vector(3 downto 0)  := (others => '0');
    signal output_ones      : std_logic_vector(3 downto 0)  := (others => '0');
    signal output_tens      : std_logic_vector(3 downto 0)  := (others => '0');
    signal digit            : std_logic_vector(3 downto 0)  := (others => '0');
    signal echo_last        : std_logic := '0';
    signal echo_synced      : std_logic := '0';
    signal echo_unsynced    : std_logic := '0';
    signal waiting          : std_logic := '0'; 
    signal seven_seg_count  : std_logic_vector(15 downto 0) := (others => '0');
	 
begin 

div : diviseur port map (
	clk => clk, eno => s_eno
	);
cmpt1 : cmpt_hzt port map (
	clk => clk, en => s_eno, eno => s_eno1, s_hzt => ref1
	);
cmpt2 : cmpt_vtc port map (
	clk => clk, en => s_eno1, s_vtc => ref2
	);

-- sonar
  affichage : affichage2digits port map(
       I_in8(3 downto 0) =>  output_ones,
		 I_in8(7 downto 4) =>  output_tens,
       Diz7segs => Diz7segs,
		 Unit7segs => Unit7segs 
  );

 -- realisation 78 us
 -- process of Servo
 process(clk)
  begin
    if rising_edge(clk) then
      if timer = 0 then
        timer <= 3900;
        eno <= '1';
      else
        timer <= timer - 1;
		  eno <='0';
      end if;
    end if;
  end process;
 
  cmpt8:process(clk) begin
     if rising_edge(clk) then
	    if eno = '1' then
		   s_cmpt8 <= s_cmpt8 + 1;
		 end if;
	  end if;
	end process; 
	
-- process of sonar
process(clk)
    begin
        if rising_edge(clk) then
            if waiting = '0' then
            --    if count = 1000 then -- Assumes 100MHz
				   if count = 500 then -- Assumes 50MHz
                   -- After 10us then go into waiting mode
                   sonar_trig <= '0';
                   waiting    <= '1';
                   count       <= (others => '0');
                else
                   sonar_trig <= '1';
                   count <= count+1;
                end if;
            elsif echo_last = '0' and echo_synced = '1' then
                -- Seen rising edge - start count
                count       <= (others => '0');
                centimeters <= (others => '0');
                centimeters_ones <= (others => '0');
                centimeters_tens <= (others => '0');
            elsif echo_last = '1' and echo_synced = '0' then
                -- Seen falling edge, so capture count
                output_ones <= centimeters_ones; 
                output_tens <= centimeters_tens; 
 --           elsif count = 2900*2 -1 then
             elsif count = 1450*2 -1 then
                -- advance the counter
                if centimeters_ones = 9 then
                    centimeters_ones <= (others => '0');
                    centimeters_tens <= centimeters_tens + 1;
                else
                    centimeters_ones <= centimeters_ones + 1;
                end if;
                centimeters <= centimeters + 1;
                count <= (others => '0');
                if centimeters = 3448 then
                    -- time out - send another pulse
                    waiting <= '0';
                end if;
            else
                count <= count + 1;                
            end if;

            echo_last     <= echo_synced;
            echo_synced   <= echo_unsynced;
            echo_unsynced <= sonar_echo;
        end if;
        
    end process;

--comparaison svm hrz
 process(s_cmpt8)
  begin	
	if (s_cmpt8 < ref1) then
		pwm(0) <= '1';
	else
		pwm(0) <= '0';
	end if;
  end process;
  
  
  --comparaison svm vtc
 process(s_cmpt8)
  begin	
	if (s_cmpt8 < ref2) then
		pwm(1) <= '1';
	else
		pwm(1) <= '0';
	end if;
  end process;
  
end Movemotor;











-- library for servo
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity diviseur is port (
	clk : in std_logic;
	eno : out std_logic
--	q : out std_logic_vector(23 downto 0)
	);
end entity diviseur;

architecture arch of diviseur is
signal cmpt : std_logic_vector(23 downto 0);
begin
  process (clk) begin
    if rising_edge(clk) then
	   cmpt <= cmpt+1;
	 end if;
  end process;
  eno <= '1' when cmpt = x"FFFFFF" else
         '0';
end arch;

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity cmpt_hzt is port (
	clk, en : in std_logic;
	eno : out std_logic;
	s_hzt : out std_logic_vector(7 downto 0)
	);
end entity cmpt_hzt;

architecture arch of cmpt_hzt is
  signal cmpt : std_logic_vector(7 downto 0) := x"0A";
begin
  process (clk) begin
    if rising_edge(clk) then
	   if en='1' then
	     if cmpt < x"1F" then
		    cmpt <= cmpt+1;
		  else
		    cmpt <= x"08";
		  end if;
		end if;
	 end if;
  end process;
  eno <= '1' when cmpt = x"1F" else
         '0';
  s_hzt <= cmpt;
end arch;

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity cmpt_vtc is port (
	clk, en : in std_logic;
	s_vtc : out std_logic_vector(7 downto 0)
	);
end entity;

architecture arch of cmpt_vtc is
  signal cmpt : std_logic_vector(7 downto 0) := x"0A";
begin
  process (clk) begin
    if rising_edge(clk) then
	   if en='1' then
	     if cmpt < x"14" then
		    cmpt <= cmpt+1;
		  else
		    cmpt <= x"0A";
		  end if;
		end if;
	 end if;
  end process;
  s_vtc <= cmpt;
end arch;












-- library for sonar
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- zero pour allumer les LEDs
entity transcod7segs is
    port (  
            I_in4    : in  std_logic_vector(3 downto 0);
				-- Ordre : gfedcba
            Q_7segs  : out std_logic_vector(6 downto 0)
    );
end transcod7segs;

architecture arch of transcod7segs is begin
  with I_in4 select
    Q_7SEGS <= "1000000" when "0000",
               "1111001" when "0001",
               "0100100" when "0010",
               "0110000" when "0011",
               "0011001" when X"4",
               "0010010" when X"5",
               "0000010" when X"6",
               "1111000" when X"7",
               "0000000" when X"8",
               "0010000" when X"9",
               "0001000" when X"A",
               "0000011" when X"B",
               "1000110" when X"C",
               "0100001" when X"D",
               "0000110" when X"E",
               "0001110" when others; --X"F"
end arch;

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- zero pour allumer les segments
entity affichage2digits is
    port (  
            I_in8    : in  std_logic_vector(7 downto 0);
				-- Ordre : gfedcba
            Diz7segs,Unit7segs  : out std_logic_vector(6 downto 0)
    );
end affichage2digits;

architecture arch_affichage2digits of affichage2digits is
component transcod7segs is
    port (  
            I_in4    : in  std_logic_vector(3 downto 0);
				-- Ordre : gfedcba
            Q_7segs  : out std_logic_vector(6 downto 0)
    );
end component transcod7segs;
 
begin
  unite : transcod7segs port map (
     I_in4 => I_in8(3 downto 0),
	  Q_7segs => Unit7segs
	  );
  dizaine : transcod7segs port map (
     I_in4 => I_in8(7 downto 4),
	  Q_7segs => Diz7segs
	  );
end arch_affichage2digits;

Fichier de contrainte:


To,Direction,Location,I/O Bank,VREF Group,I/O Standard,Reserved
CLK,Input,PIN_Y2,2,B2_N0,3.3-V LVTTL,
pwm[0],Output,PIN_AC15,4,B4_N2,3.3-V LVTTL,
pwm[1],Output,PIN_Y17,4,B4_N0,3.3-V LVTTL,
Unit7segs[6],Output,PIN_H22,6,B6_N0,2.5 V,
Unit7segs[5],Output,PIN_J22,6,B6_N0,2.5 V,
Unit7segs[4],Output,PIN_L25,6,B6_N1,2.5 V,
Unit7segs[3],Output,PIN_L26,6,B6_N1,2.5 V,
Unit7segs[2],Output,PIN_E17,7,B7_N2,2.5 V,
Unit7segs[1],Output,PIN_F22,7,B7_N0,2.5 V,
Unit7segs[0],Output,PIN_G18,7,B7_N2,2.5 V,
Diz7segs[6],Output,PIN_U24,5,B5_N0,2.5 V,
Diz7segs[5],Output,PIN_U23,5,B5_N1,2.5 V,
Diz7segs[4],Output,PIN_W25,5,B5_N1,2.5 V,
Diz7segs[3],Output,PIN_W22,5,B5_N0,2.5 V,
Diz7segs[2],Output,PIN_W21,5,B5_N1,2.5 V,
Diz7segs[1],Output,PIN_Y22,5,B5_N0,2.5 V,
Diz7segs[0],Output,PIN_M24,6,B6_N2,2.5 V,
sonar_trig,Output,PIN_AE16,4,B4_N2,3.3-V LVTTL,
sonar_echo,Input,PIN_Y16,4,B4_N0,3.3-V LVTTL,

Fichier:Progmelanger.zip

Programme relatif à l'écran LCD

Le But de ce projet était d'afficher sur un écran les distance sous forme de barregraphe tout en contrôlant la tourelle pan tilt avec une télécommande nunchuk mais suite au manque du logiciel Energia nous ne pouvions pas finir le contrôle de la direction de la tourelle mais nous avons réussi à afficher un bargraphe sur l'écran LCD.

----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date:    08:57:48 08/26/2014 
-- Design Name: 
-- Module Name:    microcontroleur - microcontroleur_architecture 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity micrcontroleur is
    Port ( clk : in  STD_LOGIC;
           Rst : in  STD_LOGIC;
           sw : in STD_LOGIC_VECTOR (7 downto 0);
			  HServo,VServo : out std_logic;
			  sonar_trig : out STD_LOGIC;
           sonar_echo : in  STD_LOGIC;
           lcd_e  : out std_logic;
           lcd_rs : out std_logic;
           lcd_rw : out std_logic;
           lcd_db : out std_logic_vector(7 downto 4);
           Q_PORTA : out STD_LOGIC_VECTOR (7 downto 0)
           );
end micrcontroleur;

architecture microcontroleur_architecture of micrcontroleur is
--Registres et PORTs de l'ATTiny861
constant OCR1A : std_logic_vector(5 downto 0) := "101101";
constant OCR1B : std_logic_vector(5 downto 0) := "101100";
constant PORTA : std_logic_vector(5 downto 0) := "011011";
constant DDRA : std_logic_vector(5 downto 0) := "011010";
constant PINA : std_logic_vector(5 downto 0) := "011001";
constant PORTB : std_logic_vector(5 downto 0) := "011000";
constant DDRB : std_logic_vector(5 downto 0) := "010111";
constant PINB : std_logic_vector(5 downto 0) := "010110";
constant ADCH : std_logic_vector(5 downto 0) := "000101";
constant ADCL : std_logic_vector(5 downto 0) := "000100";
--Registres non présents dans l'ATTiny861
constant UDR : std_logic_vector(5 downto 0) := "000011";
constant UCSRA : std_logic_vector(5 downto 0) := "000010";
constant UCSRB : std_logic_vector(5 downto 0) := "000001";
component mcu_core is
		Port (
			Clk	: in std_logic;
			Rst	: in std_logic; -- Reset core when Rst='1'
			En		: in std_logic; -- CPU stops when En='0', could be used to slow down cpu to save power
			-- PM
			PM_A		: out std_logic_vector(15 downto 0);
			PM_Drd	: in std_logic_vector(15 downto 0);
			-- DM
			DM_A		: out std_logic_vector(15 downto 0); -- 0x00 - xxxx
			DM_Areal	: out std_logic_vector(15 downto 0); -- 0x60 - xxxx (same as above + io-adr offset)
			DM_Drd	: in std_logic_vector(7 downto 0);
			DM_Dwr	: out std_logic_vector(7 downto 0);
			DM_rd		: out std_logic;
			DM_wr		: out std_logic;
			-- IO
			IO_A		: out std_logic_vector(5 downto 0); -- 0x00 - 0x3F
			IO_Drd	: in std_logic_vector(7 downto 0);
			IO_Dwr	: out std_logic_vector(7 downto 0);
			IO_rd		: out std_logic;
			IO_wr		: out std_logic;
			-- OTHER
		   OT_FeatErr	: out std_logic; -- Feature error! (Unhandled part of instruction)
		   OT_InstrErr	: out std_logic -- Instruction error! (Unknown instruction)
		);
	end component mcu_core;
	--PM
	component pm  is
		Port (
				Clk	: in std_logic;
				rst	: in std_logic; -- Reset when Rst='1'
				-- PM
				PM_A		: in std_logic_vector(15 downto 0);
				PM_Drd	: out std_logic_vector(15 downto 0)
		);
	end component pm;	

  component dm is
    Port ( clk : in  STD_LOGIC;
           addr : in  STD_LOGIC_VECTOR (15 downto 0);
           dataread : out  STD_LOGIC_VECTOR (7 downto 0);
           datawrite : in  STD_LOGIC_VECTOR (7 downto 0);
           rd : in  STD_LOGIC;
           wr : in  STD_LOGIC);
  end component dm;
  
  component SERVO is
	port(
		MCLK		: in	std_logic;
		nRST		: in	std_logic;
		DATA		: in	std_logic_vector(7 downto 0);
		SERVO		: out	std_logic
	);
  end component SERVO;
  
  component sonar is
    Port ( clk        : in  STD_LOGIC;
           sonar_trig : out STD_LOGIC;
           sonar_echo : in  STD_LOGIC;
			  waiting    : out  std_logic;
           dist_cm  : out std_logic_vector(15 downto 0));
  end component sonar;
  
  	signal PM_A		: std_logic_vector(15 downto 0);
	signal PM_Drd	: std_logic_vector(15 downto 0);
	-- DM
	signal DM_A			: std_logic_vector(15 downto 0); -- 0x00 - xxxx
	signal DM_Areal	: std_logic_vector(15 downto 0); -- 0x60 - xxxx (same as above + io-adr offset)
	signal DM_Drd		: std_logic_vector(7 downto 0);
	signal DM_Dwr		: std_logic_vector(7 downto 0);
	signal DM_rd		: std_logic;
	signal DM_wr		: std_logic;
	-- IO
	signal IO_A		: std_logic_vector(5 downto 0); -- 0x00 - 0x3F
	signal IO_Drd	: std_logic_vector(7 downto 0);
	signal IO_Dwr	: std_logic_vector(7 downto 0);
	signal IO_rd	: std_logic;
	signal IO_wr	: std_logic;

	signal s_PORTB	: std_logic_vector(7 downto 0);
--	signal IO_DrdB	: std_logic_vector(7 downto 0);
   signal pan_data : std_logic_vector(7 downto 0);
	signal tilt_data : std_logic_vector(7 downto 0);
	signal dist_cmL : std_logic_vector(7 downto 0);
	signal s_waiting : std_logic;
begin
	core : mcu_core Port map (
		Clk	=> clk,
		Rst	=> Rst,
		En		=> '1',
		-- PM
		PM_A		=> PM_A,
		PM_Drd	=> PM_Drd,
		-- DM
		DM_A		=> DM_A,
		DM_Areal	=> DM_Areal,
		DM_Drd	=> DM_Drd,
		DM_Dwr	=> DM_Dwr,
		DM_rd		=> DM_rd,
		DM_wr		=> DM_wr,
		-- IO
		IO_A		=> IO_A,
		IO_Drd	=> IO_Drd,
		IO_Dwr	=> IO_Dwr,
		IO_rd		=> IO_rd,
		IO_wr		=> IO_wr,
		-- OTHER
		OT_FeatErr => open,
		OT_InstrErr	=> open
	);

	prgmem : pm port map (
			Clk	=> clk,
			Rst	=> '0',
			-- PM
			PM_A		=> PM_A,
			PM_Drd	=> PM_Drd
	);
	
	datamem : dm port map (
           clk => clk,
           addr => DM_A,
           dataread  => DM_Drd,
           datawrite => DM_Dwr,
           rd => DM_rd, 
           wr =>	DM_wr
	);
	
	pan_servo : SERVO port map (
		MCLK	=> clk,
		nRST	=> NOT Rst,
		DATA	=> pan_data,
		SERVO	=> HServo
		);
	
	tilt_servo : SERVO port map (
		MCLK	=> clk,
		nRST	=> NOT Rst,
		DATA	=> tilt_data,
		SERVO	=> VServo
		);
 	ic_sonar : sonar Port map( 
	        clk  => clk,
           sonar_trig => sonar_trig,
           sonar_echo => sonar_echo,
			  waiting  => s_waiting,
           dist_cm(7 downto 0) => dist_cmL
			  );
			  
   iowr: process(CLK)
    begin
        if (rising_edge(CLK)) then
            if (IO_wr = '1') then
                case IO_A is
		 -- addresses for tiny861 device (use io.h).
       --
                    when PORTA  => -- PORTA=X"1B" (0X3B)
                         Q_PORTA <= IO_Dwr;
                    when  PORTB => -- PORTB=X"18" (0X38)
						       s_PORTB <= IO_Dwr;
						  when DDRA =>
						       pan_data <= IO_Dwr;
						  when DDRB => 
						       tilt_data <= IO_Dwr;
                    when others =>
                end case;
            end if;
        end if;
    end process;
	 lcd_db <= s_PORTB(7 downto 4);
	 lcd_e <= s_PORTB(1);
	 lcd_rs <= s_PORTB(2); 
	 lcd_rw <= s_PORTB(3); 
-- IO read process
--
    iord: process(IO_rd,IO_A)
    begin
        -- addresses for tinyX6 device (use iom8.h).
        --
        if IO_rd = '1' then
          case IO_A is
            when  PINA => IO_Drd <= sw;  -- PINA=X"19" (0X39)
            when  PORTB => IO_Drd <= s_PORTB;  -- PORTB=X"18" (0X38)
				when  PINB => IO_Drd <= dist_cmL; -- resultat sonar
				when  DDRB => IO_Drd <= "0000000" & s_waiting;
            when others => IO_Drd <= X"AA";
          end case;
       end if;
    end process;

end microcontroleur_architecture;

Fichier de contrainte :


# Copyright (C) 1991-2010 Altera Corporation
# Your use of Altera Corporation's design tools, logic functions 
# and other software and tools, and its AMPP partner logic 
# functions, and any output files from any of the foregoing 
# (including device programming or simulation files), and any 
# associated documentation or information are expressly subject 
# to the terms and conditions of the Altera Program License 
# Subscription Agreement, Altera MegaCore Function License 
# Agreement, or other applicable license agreement, including, 
# without limitation, that your use is for the sole purpose of 
# programming logic devices manufactured by Altera and sold by 
# Altera or its authorized distributors.  Please refer to the 
# applicable agreement for further details.

# Quartus II Version 9.1 Build 350 03/24/2010 Service Pack 2 SJ Full Version
# File: E:\SVN\DE2_115\trunk\test\de2_115_golden_sopc\de2_115_golden_sopc.csv
# Generated on: Fri Jun 18 14:51:18 2010

# Note: The column header names should not be changed if you wish to import this .csv file into the Quartus II software.

To,Direction,Location,I/O Bank,VREF Group,I/O Standard,Reserved
CLK,Input,PIN_Y2,2,B2_N0,3.3-V LVTTL,
SW[7],Input,PIN_AC25,5,B5_N2,2.5 V,
SW[6],Input,PIN_AB26,5,B5_N1,2.5 V,
SW[5],Input,PIN_AD26,5,B5_N2,2.5 V,
SW[4],Input,PIN_AC26,5,B5_N2,2.5 V,
SW[3],Input,PIN_AB27,5,B5_N1,2.5 V,
SW[2],Input,PIN_AD27,5,B5_N2,2.5 V,
SW[1],Input,PIN_AC27,5,B5_N2,2.5 V,
SW[0],Input,PIN_AC28,5,B5_N2,2.5 V,
# completement a gauche
Rst,Input,PIN_Y23,5,B5_N2,2.5 V,
# sur GPIO :
HSERVO,Output,PIN_AC15,4,B4_N2,3.3-V LVTTL,
VSERVO,Output,PIN_Y17,4,B4_N0,3.3-V LVTTL,
sonar_trig,Output,PIN_AE16,4,B4_N2,3.3-V LVTTL,
sonar_echo,Input,PIN_Y16,4,B4_N0,3.3-V LVTTL,
# afficheur lcd :
LCD_DB[7],Bidir,PIN_M5,1,B1_N2,3.3-V LVTTL,
LCD_DB[6],Bidir,PIN_M3,1,B1_N1,3.3-V LVTTL,
LCD_DB[5],Bidir,PIN_K2,1,B1_N1,3.3-V LVTTL,
LCD_DB[4],Bidir,PIN_K1,1,B1_N1,3.3-V LVTTL,
LCD_E,Output,PIN_L4,1,B1_N1,3.3-V LVTTL,
LCD_ON,Output,PIN_L5,1,B1_N1,3.3-V LVTTL,
LCD_RS,Output,PIN_M2,1,B1_N2,3.3-V LVTTL,
LCD_RW,Output,PIN_M1,1,B1_N2,3.3-V LVTTL,
# leds
Q_PORTA[7],Output,PIN_H19,7,B7_N2,2.5 V,
Q_PORTA[6],Output,PIN_J19,7,B7_N2,2.5 V,
Q_PORTA[5],Output,PIN_E18,7,B7_N1,2.5 V,
Q_PORTA[4],Output,PIN_F18,7,B7_N1,2.5 V,
Q_PORTA[3],Output,PIN_F21,7,B7_N0,2.5 V,
Q_PORTA[2],Output,PIN_E19,7,B7_N0,2.5 V,
Q_PORTA[1],Output,PIN_F19,7,B7_N0,2.5 V,
Q_PORTA[0],Output,PIN_G19,7,B7_N2,2.5 V,

Programme C pour l'affiche sur l'écran LCD :

//      essai.c
//      
//      Copyright 2014 Michel Doussot <michel@mustafar>
//      
//      This program is free software; you can redistribute it and/or modify
//      it under the terms of the GNU General Public License as published by
//      the Free Software Foundation; either version 2 of the License, or
//      (at your option) any later version.
//      
//      This program is distributed in the hope that it will be useful,
//      but WITHOUT ANY WARRANTY; without even the implied warranty of
//      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//      GNU General Public License for more details.
//      
//      You should have received a copy of the GNU General Public License
//      along with this program; if not, write to the Free Software
//      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
//      MA 02110-1301, USA.

#include <avr/io.h>
#define RS 		0x04
#define E		0x02
#define RW 		0x08
#define DATAS  	0xF0

// unite approximative 2us
void delai(unsigned long int delai) {
	volatile long int i=0;
	for(i=0;i<delai;i+=1);
} 

// portB :
// b7 b6 b5 b4 b3 b2 b1 b0
// D3 D2 D1 D0 RW RS  E CE0
void rs_haut(void) {
   PORTB = PORTB | RS;
}

void rs_bas(void) {
   PORTB = PORTB & ~RS; 
}

void rw_haut(void) {
   PORTB = PORTB | RW;
}

void rw_bas(void) {
   PORTB = PORTB & ~RW; 
}

void e_haut(void) {
   PORTB = PORTB | E;
   delai(8);
}

void e_bas(void) {
    PORTB = PORTB & ~E; 
    delai(8);
}

void e_puls(void) {
   e_haut();
   e_bas();
}

void ecris_4(unsigned char valeur) {
	unsigned char v;
	v = (valeur << 4) & DATAS;
	PORTB = PORTB & ~DATAS ;
	PORTB = PORTB | v ;
    e_puls();
}

void ecris_8(unsigned char valeur) {
	unsigned char v;
	v = valeur & DATAS;
	PORTB = PORTB & ~DATAS ;
	PORTB = PORTB | v ;
    e_puls();
	v = (valeur << 4) & DATAS;
	PORTB = PORTB & ~DATAS ;
	PORTB = PORTB | v ;
    e_puls();    
}


void setup() {

   PORTB = 0;
   delai(6000);
   ecris_4(0x03);
   delai(1600);
   ecris_4(0x03);
   delai(800);
   ecris_4(0x03);
   delai(800);
   ecris_4(0x02);
   delai(40);
   ecris_4(0x02);
   ecris_4(0x08);
   delai(40);
   ecris_4(0x00);
   ecris_4(0x06);
   delai(40);
   ecris_4(0x00);
   ecris_4(0x0C);
   delai(40);
   ecris_4(0x00);
   ecris_4(0x01);
   delai(800);   
}

void writecar(char car) {
	rs_haut();
	ecris_8((unsigned char)car);
}

void writestr(char *chaine) {
	rs_haut();
	while (*chaine) {
		ecris_8((unsigned char)*chaine++);
	}
}

void command (uint8_t value) {
  rs_bas();
  ecris_8(value);
}

#define LCD_SETDDRAMADDR 0x80

void setCursor(uint8_t col, uint8_t row) {
  col = col & 0x0F; // %16
  row = row & 0x01; // %2
  command(LCD_SETDDRAMADDR | (col + 0x40*row));
  delai(100);
}

#define LCD_CLEARDISPLAY 0x01

void clearScreen() {
  command(LCD_CLEARDISPLAY);  // clear display, set cursor position to zero
  delai(1000);  // this command takes a long time!
}

#define LCD_SETCGRAMADDR 0x40
// Allows us to fill the first 8 CGRAM locations
// with custom characters
void createChar(uint8_t location, uint8_t charmap[]) {
  uint8_t i;
  location &= 0x7; // we only have 8 locations 0-7
  command(LCD_SETCGRAMADDR | (location << 3));
  for (i=0; i<8; i++) {
	  writecar((char)charmap[i]);delai(100);
  }
}

uint8_t bar0[8] = { // from Arduino Library
	0b00000,
	0b00000,
	0b00000,
	0b00000,
	0b00000,
	0b00000,
	0b00000,
	0b00000
};

uint8_t bar1[8] = { // from Arduino Library
	0b00000,
	0b00000,
	0b00000,
	0b00000,
	0b00000,
	0b00000,
	0b00000,
	0b11111
};

uint8_t bar2[8] = { // from Arduino Library
	0b00000,
	0b00000,
	0b00000,
	0b00000,
	0b00000,
	0b00000,
	0b11111,
	0b11111
};

uint8_t bar3[8] = { // from Arduino Library
	0b00000,
	0b00000,
	0b00000,
	0b00000,
	0b00000,
	0b11111,
	0b11111,
	0b11111
};

uint8_t bar4[8] = { // from Arduino Library
	0b00000,
	0b00000,
	0b00000,
	0b00000,
	0b11111,
	0b11111,
	0b11111,
	0b11111
};

uint8_t bar5[8] = { // from Arduino Library
	0b00000,
	0b00000,
	0b00000,
	0b11111,
	0b11111,
	0b11111,
	0b11111,
	0b11111
};

uint8_t bar6[8] = { // from Arduino Library
	0b00000,
	0b00000,
	0b11111,
	0b11111,
	0b11111,
	0b11111,
	0b11111,
	0b11111
};

uint8_t bar7[8] = { // from Arduino Library
	0b00000,
	0b11111,
	0b11111,
	0b11111,
	0b11111,
	0b11111,
	0b11111,
	0b11111
};

uint8_t bar8[8] = { // from Arduino Library
	0b11111,
	0b11111,
	0b11111,
	0b11111,
	0b11111,
	0b11111,
	0b11111,
	0b11111
};

int main(void) {
	
	unsigned char tmp,posH, sn,i;
  // setup
	setup();
   	tmp = 0;
        createChar(0,bar0);
		createChar(1,bar1);
		createChar(2,bar2);
		createChar(3,bar3);
		createChar(4,bar4);
		createChar(5,bar5);
		createChar(6,bar6);
		createChar(7,bar7); 
		//createChar(8,bar8);
        clearScreen();
   	writestr("Hello Microsoft ");
    //    setCursor(2,1);//setcursor(h,v)
        //writestr("Hello Linux");
		/*
		for (i=0;i<8;i++)
		  writecar(i); */		
  // loop
	while (1) {
	   setCursor(0,1);
	   for (i=0;i<16;i++) {	
		tmp += 16;	
		posH = PINA;
		DDRA = tmp;//posH;
		delai(100000);
		sn = PINB;
		PORTA = sn;
		writecar(sn>>4);
	   }
	}
	return 0;
}
Calcul distance en barregraphe position A
Calcul distance en barregraphe position B














Fichier:Barregraphe.zip


Travail S4 du binôme Gnagne/Gaya

Le déroulement du S4 est basé sur la programmation avec la carte Altera DE2-115.

Programme de base

Ce programme permet de faire bouger la tourelle de gauche à droite et de bas en haut.

library ieee;
use ieee.std_logic_1164.all;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity toto is port(
	clk : in std_logic;
	pwm : out std_logic
	);
end entity;

architecture titi of toto is
	signal timer: natural range 0 to 3900:=0;
	signal eno: std_logic;
	signal s_compt8: std_logic(7 downto 0);
   signal ref: std_logic(7 downto 0);
begin
process(clk) begin
 if rising_edge(clk) then
          if timer=0 then
	     timer <=3900;
             eno <=1;
	  else
	     timer <=timer-1;
	     eno <=0;
          end if;
	end process; 
	
compt8:process(clk)
	begin
            if rising_edge(clk) then
            if eno ='1' then
	  s_cmpt8 <= s_cmpt8 + 1;
            end if;	
          end if;
	end process; 
	
	comparateur:process(clk) begin
            if rising_edge(clk) then
            if (s_compt8<ref)then
	    pwm='1';
	    else
	    pwm='0'
            end if;	
          end if;
	end process; 
	ref<=x"19";
end titi;

Programme relatif au contrôle du Sonar et des servomoteurs

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity toto is
    Port ( clk        : in  STD_LOGIC;
	        pwm : out std_logic_vector(1 downto 0);
           sonar_trig : out STD_LOGIC;
           sonar_echo : in  STD_LOGIC;
--           anodes     : out STD_LOGIC_VECTOR (3 downto 0);
--           segments   : out STD_LOGIC_VECTOR (6 downto 0));
           Unit7segs : out std_logic_vector(6 downto 0);
			  Diz7segs : out std_logic_vector(6 downto 0)
			  );
end toto;

architecture Behavioral of toto is
--composant servo
component diviseur is port (
	clk : in std_logic;
	eno : out std_logic
--	q : out std_logic_vector(23 downto 0)
	);
end component;

component cmpt_hzt is port (
	clk, en : in std_logic;
	eno : out std_logic;
	s_hzt : out std_logic_vector(7 downto 0)
	);
end component;

component cmpt_vtc is port (
	clk, en : in std_logic;
	s_vtc : out std_logic_vector(7 downto 0)
	);
end component;
--composant servo
component transcod7segs is
    port (  
            I_in4    : in  std_logic_vector(3 downto 0);
				-- Ordre : gfedcba
            Q_7segs  : out std_logic_vector(6 downto 0)
    );
end component transcod7segs;
-- signal sonar
    signal count            : std_logic_vector(16 downto 0) := (others => '0');
    signal centimeters      : std_logic_vector(15 downto 0) := (others => '0');
    signal centimeters_ones : std_logic_vector(3 downto 0)  := (others => '0');
    signal centimeters_tens : std_logic_vector(3 downto 0)  := (others => '0');
    signal output_ones      : std_logic_vector(3 downto 0)  := (others => '0');
    signal output_tens      : std_logic_vector(3 downto 0)  := (others => '0');
    signal digit            : std_logic_vector(3 downto 0)  := (others => '0');
    signal echo_last        : std_logic := '0';
    signal echo_synced      : std_logic := '0';
    signal echo_unsynced    : std_logic := '0';
    signal waiting          : std_logic := '0'; 
    signal seven_seg_count  : unsigned(15 downto 0) := (others => '0');
	 
	--signal servo
	signal timer : natural range 0 to 3900 := 0;
 signal eno : std_logic;
 signal s_cmpt8 : std_logic_vector(7 downto 0);
 signal s_eno, s_eno1 : std_logic;
 signal ref1 : std_logic_vector(7 downto 0);
 signal ref2 : std_logic_vector(7 downto 0);
begin
--servo liaison
    div : diviseur port map (
	clk => clk, eno => s_eno
	);
cmpt1 : cmpt_hzt port map (
	clk => clk, en => s_eno, eno => s_eno1, s_hzt => ref1
	);
cmpt2 : cmpt_vtc port map (
	clk => clk, en => s_eno1, s_vtc => ref2
	);

-- realisation 78 us pour servo
 process(clk)
  begin
    if rising_edge(clk) then
      if timer = 0 then
        timer <= 3900;
        eno <= '1';
      else
        timer <= timer - 1;
		  eno <='0';
      end if;
    end if;
  end process;
 
  cmpt8:process(clk) begin
     if rising_edge(clk) then
	    if eno = '1' then
		   s_cmpt8 <= s_cmpt8 + 1;
		 end if;
	  end if;
	end process; 

--comparaison svm hrz
 process(s_cmpt8)
  begin	
	if (s_cmpt8 < ref1) then
		pwm(0) <= '1';
	else
		pwm(0) <= '0';
	end if;
  end process;
  
  
  --comparaison svm vtc
 process(s_cmpt8)
  begin	
	if (s_cmpt8 < ref2) then
		pwm(1) <= '1';
	else
		pwm(1) <= '0';
	end if;
  end process;

 process(clk)
    begin
        if rising_edge(clk) then
            if waiting = '0' then
                if count = 500 then -- Assumes 50MHz
                   -- After 10us then go into waiting mode
                   sonar_trig <= '0';
                   waiting    <= '1';
                   count       <= (others => '0');
                else
                   sonar_trig <= '1';
                   count <= count+1;
                end if;
            elsif echo_last = '0' and echo_synced = '1' then
                -- Seen rising edge - start count
                count       <= (others => '0');
                centimeters <= (others => '0');
                centimeters_ones <= (others => '0');
                centimeters_tens <= (others => '0');
            elsif echo_last = '1' and echo_synced = '0' then
                -- Seen falling edge, so capture count
                output_ones <= centimeters_ones; 
                output_tens <= centimeters_tens; 
            elsif count = 1450*2 -1 then
                -- advance the counter
                if centimeters_ones = 9 then
                    centimeters_ones <= (others => '0');
                    centimeters_tens <= centimeters_tens + 1;
                else
                    centimeters_ones <= centimeters_ones + 1;
                end if;
                centimeters <= centimeters + 1;
                count <= (others => '0');
                if centimeters = 3448 then
                    -- time out - send another pulse
                    waiting <= '0';
                end if;
            else
                count <= count + 1;                
            end if;

            echo_last     <= echo_synced;
            echo_synced   <= echo_unsynced;
            echo_unsynced <= sonar_echo;
        end if;       
    end process;
	 unite : transcod7segs port map (
       I_in4 => output_ones,
	    Q_7segs => Unit7segs
	  );
  dizaine : transcod7segs port map (
       I_in4 => output_tens,
	    Q_7segs => Diz7segs
	  );
end Behavioral;

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- zero pour allumer les LEDs
--description du composant pour sonar
entity transcod7segs is
    port (  
            I_in4    : in  std_logic_vector(3 downto 0);
				-- Ordre : gfedcba
            Q_7segs  : out std_logic_vector(6 downto 0)
    );
end transcod7segs;

architecture arch of transcod7segs is begin
  with I_in4 select
    Q_7SEGS <= "1000000" when "0000",
	       "1111001" when "0001",
               "0100100" when "0010",
               "0110000" when "0011",
               "0011001" when X"4",
               "0010010" when X"5",
               "0000010" when X"6",
               "1111000" when X"7",
               "0000000" when X"8",
               "0010000" when X"9",
               "0001000" when X"A",
               "0000011" when X"B",
               "1000110" when X"C",
               "0100001" when X"D",
               "0000110" when X"E",
               "0001110" when others; --X"F"
end arch;
--description des composant servo

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity diviseur is port (
	clk : in std_logic;
	eno : out std_logic
--	q : out std_logic_vector(23 downto 0)
	);
end entity diviseur;

architecture arch of diviseur is
signal cmpt : std_logic_vector(23 downto 0);
begin
  process (clk) begin
    if rising_edge(clk) then
	   cmpt <= cmpt+1;
	 end if;
  end process;
  eno <= '1' when cmpt = x"FFFFFF" else
         '0';
end arch;

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity cmpt_hzt is port (
	clk, en : in std_logic;
	eno : out std_logic;
	s_hzt : out std_logic_vector(7 downto 0)
	);
end entity cmpt_hzt;

architecture arch of cmpt_hzt is
  signal cmpt : std_logic_vector(7 downto 0) := x"0A";
begin
  process (clk) begin
    if rising_edge(clk) then
	   if en='1' then
	     if cmpt < x"1F" then
		    cmpt <= cmpt+1;
		  else
		    cmpt <= x"08";
		  end if;
		end if;
	 end if;
  end process;
  eno <= '1' when cmpt = x"1F" else
         '0';
  s_hzt <= cmpt;
end arch;

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity cmpt_vtc is port (
	clk, en : in std_logic;
	s_vtc : out std_logic_vector(7 downto 0)
	);
end entity;

architecture arch of cmpt_vtc is
  signal cmpt : std_logic_vector(7 downto 0) := x"0A";
begin
  process (clk) begin
    if rising_edge(clk) then
	   if en='1' then
	     if cmpt < x"14" then
		    cmpt <= cmpt+1;
		  else
		    cmpt <= x"0A";
		  end if;
		end if;
	 end if;
  end process;
  s_vtc <= cmpt;
end arch;

Réalisation technique

Réalisation de la carte du binôme Baczkowski/To

Nous avons commencé par le composant le plus important, à savoir le connecteur Altera. Toutes les soudures n'étaient pas obligatoires, car la plupart des pattes n'étaient reliées à aucune piste. Néanmoins, par souci de stabilité, nous avons jugé préférable d'effectuer les 40 soudures au dos de la carte, car aucun composant ne nous gênait. Comme nous avions besoin de souder des 2 côtés de la carte, il fallait nous assurer de sa stabilité. Pour cela, nous avons utilisé un étau.
Comme, pour les premières soudures, le fer n'avait assez chauffé, les soudures ont donc bavé. Ce petit défaut récurrent a été légèrement par la suite.

En ce qui concerne les connecteurs mâles des servomoteurs, nous avons eu affaire à une rupture de stock. Nous avons donc choisi des connecteurs femelles, et de placer des adaptateurs dessus.


Mais par la suite, nous nous sommes aperçus que la carte comportait trop d'erreurs. Beaucoup d'entre elles étaient rattrapables, mais certaines ne l'étaient pas. Plutôt que d'utiliser le système D pour tenter de faire fonctionner ladite carte, nous avons préféré tirer profit de nos erreurs, et, puisque nous en avions encore le temps.

En ce qui la fixation du sonar sur la tourelle, plusieurs solutions se présentaient à nous, mais dans tous les cas il nous fallait viser les deux plaques. Pour dimensionner la plaque, et pouvoir l'intégrer dans la structure de la tourelle, nous l'avons d'abord limée. Puis, pour la stabiliser, nous avons choisi un système à 3 vis et 4 écrous : 2 d'entre elles servent à maintenir l'écart entre la plaque et la tourelle. Seule la plaque est percée, et pour l'empêcher de descendre, un écrou est disposé juste en dessous de celle-ci. Pour éviter qu'un des côté ne s'affaisse, les 2 vis sont disposées en diagonale. La dernière vis a 2 fonctions : premièrement, éviter un affaissement diagonal, peu probable mais toujours possible. Dans un second temps, il faut absolument éviter que celle-ci ne s'avance ou ne recule. Donc, cette vis, en plus du premier écrou, doit également en posséder un deuxième, situé de l'autre côté de la plaque qu'il traverse dans un deuxième temps.


Système de fixation de la tourelle


Problèmes rencontrés lors de la réalisation

1) Position et sens des connecteurs
Le premier problème que nous avons rencontré est la position du connecteur Altera. En effet, pour éviter de torsader la nappe, il fallait que le celui-ci ait un sens particulier, car la position de la carte Altera est prédéterminée. Ce problème n'est pas vraiment handicapant, car il est seulement d'ordre esthétique.

2) Problème de la carte en double face
Il s'est rapidement avéré qu'il aurait mieux valu avoir des vias et tout mettre au dos de la carte : en ayant des pistes sur la carte, cela nous empêche d'enfoncer totalement le connecteur Altera, car nous avons besoin de souder le composant des deux côtés. À cause de cela, les soudures pistes/pastilles posent problème au top. Le plus embêtant reste lorsque les pistes viennent de l'autre côté de la carte : la soudure doit alors être faite sous le composant, ce qui pose problème. Mais cela ne se limite pas au composant Altera : les connecteurs 4 pattes, du sonar et du nunchuk, et 3 pattes, des servomoteurs, et les barrettes, ainsi que les connecteurs de la carte MSP432, ont le même problème. Le plus gros problème de la carte est donc d'être en double-face, une carte en simple face n'aurait pas eu tout ces inconvénients. Cela nous a posé problème lorsque nous avons voulu vérifier l'absence de court-circuit et de faux contact.

3) Problème de la position des pistes dans les connecteurs
Le plus gros problème, qui nous a finalement conduit à considérer la première carte réalisée comme un prototype, a été la place des pistes dans les connecteurs. En effet, si pour le sonar, les fils pouvaient être dessoudés et ressoudés à loisir, ce n'était le cas ni pour les servomoteurs ni pour la nunchuk. Si on ajoute à cela le problème de l'adaptateur, comme nous avions encore du temps devant nous, nous avons jugé plus prudent de refaire une carte, quitte à flirter dangereusement, pour nous assurer d'avoir une carte qui conviendrait au projet.

4) Oubli de connexions nécessaires au protocole SPI
Nous avions également confondu les sorties du cavalier du JP4, et celle de l'Altera, nécessaire à l'utilisation du protocole SPI, la patte CS de la MSP432. En outre, nous avions oublié de connecter l'horloge SPI.

Solutions apportées

Lorsque nous avons voulu vérifier l'absence de court-circuit et de faux contact, nous avons dû employer une astuce : afin de pouvoir toucher la patte du composant située sous sa partie plastique, nous avons enroulé un fil en étain autour d'une des pointes.


Technique utilisée pour vérifier l'absence de faux contact à des endroits peu accessibles


Mais ces précautions prennent du temps : pour souder 5 composants, nous avons passé 1h30, et 30 min supplémentaires ont été nécessaires pour les vérifications.

Carte finale

Montage final de l'installation

Sur le deuxième essai, nous avons pris en compte tous ces paramètres afin de faire une carte plus simple à réaliser, à l'utilisation plus intuitive, et surtout immédiatement fonctionnelle.

Nous avons toutefois rencontré, là encore, des difficultés. En particulier, et ça a été une surprise car ça n'avait pas été le cas lors de la réalisation du prototype, lors du perçage. En effet, lors de la création du calque, nous avons sélectionné une catégorie supplémentaire, qui nous a gênés pour distinguer le diamètre des pastilles. Par mesure de sécurité, nous avons décidé de choisir, pour le perçage, un foret de 1mm pour chaque pastille, sauf pour les résistances, car nous avons rapidement vu qu'un diamètre de 0.8mm convenait.

En ce qui concerne la fixation de la tourelle sur la carte, et afin d'avoir une carte nous avions plusieurs solutions :
- premièrement, nous pouvions coller la tourelle sur la carte, en utilisant un pistolet à colle ;
- ensuite, nous pouvions placer des vis du côté supérieur de la carte, et comme celles-ci dépassent de l'autre côté, il aurait aussi fallu placer des entretoises. Comme le diamètre de ces entretoises est supérieur à celui des trous préexistants, il aurait fallu repercer la tourelle ;
- enfin, nous pouvions placer des vis du côté inférieur de la carte.

Nous avons retenu la troisième solution, qui nous a plu par sa simplicité, et afin de stabiliser la carte, nous avons également placé des plots adhésifs sous la carte, afin que celle-ci ne soit pas soutenue par les soudures.

Comme les fils du sonar et des servomoteurs étaient trop grands et gênaient, nous avons résolu le problème en raccourcissant les fils du sonar, et comme cela n'était pas possible pour les fils des servomoteurs, qui avaient une taille fixe, nous avons utilisé un collier de câblage, afin de rassembler les fils.

Côté supérieur de la carte
Côté inférieur de la carte













Réalisation de la carte du binôme Gaya/Gnagne

Nous avons commencé par souder les 6 straps qui était présent sur notre carte, puis nous avons souder notre plus gros composant le connecteur 40 broches, qui sert à la connexion avec l'Altera.
Puisque nous avions router ce composant uniquement du côté "bottom", la soudure de ce composant à été simple. Nous avons ensuite souder les 2 connecteurs 10 broches mâle-mâle, servant à la connexion avec la carte MSP432. Cependant, contrairement au connecteur 40 broches, nous avons du souder des deux côtés le reste des composants, puisqu'ils sont tous en double face.

Problèmes rencontrés lors de la réalisation

1) Espacement entre les composants
Lors de la conception de la carte nous avions mesurer les espaces entre chaque composant, et nous avons pris les distance minimales.
Et donc puisque nous n'avions pas pris en compte le bout de plastique de la carte MSP432. La carte MSP432 chevauchait le connecteur 40 broches.

2)Perçage des pastilles
Nous avons d'abord percer les pastilles des connecteurs en 0.8mm, cependant les connecteurs ne passaient pas.

3) Fixation de la tourelle
Afin que la tourelle soit la plus stable possible, nous avons décider de fixer la tourelle sur la carte.Cependant, il nous est alors venu le problème suivant:comment la fixer.

Solutions apportées

1) Espacement entre les composants
Nous avons donc choisis d’utiliser un connecteur 40 broches, tourné à 90° , ainsi le connecteur 40 broches de l'Altera et la carte MSP432 ne se chevauchaient plus.

Connecteur 40 broches utilisé

2)Perçage des pastilles
Nous avons donc utilisé un perçage de 1mm, afin de faciliter la soudure des composants.

3) Fixation de la tourelle
Afin de fixer la tourelle, nous avons décider de percer la carte et de la fixer à l'aide de vis et de clous. Il a fallu alors mesurer les dimensions de la tourelle et choisir un diamètre de perçage. On a donc eu comme dimensions de la tourelle:

Tourelle dimensions : (37x35)(en mm)
Perçage utilisé: 2mm.

Fixation de la tourelle

Carte finale

Après avoir résolu tous ces problèmes, nous avons pu réaliser la carte sans grand soucis:

Carte (Face Supérieure)
Carte (Face inférieure)














Nous avons réaliser des tests pour vérifier l’absence de faux contacts sur la carte, à l'aide d'un multimètre. Nous avons pu constater quelques faux contacts, nous avons donc souder une deuxième fois certaines pattes de certains composants et le problème était réglé. Par soucis de stabilité de la carte, nous avons choisis de mettre 4 pieds à notre carte, afin qu'elle ne repose pas sur ses soudures, de plus cela empêche tous problème de court-circuit, si la carte serait posée sur une surface métallique.

Améliorations possibles

La carte qu'on obtient au final a un fonctionnement plutôt intuitif, mais elle est loin d'être parfaite.

Son plus gros défaut est le fait qu'elle soit alimentée seulement par la carte Altera : ça implique une dépendance à la carte DE2-115, or cette carte est assez volumineuse et prend de la place. Donc, le FPGA est très puissant, et permet de réaliser beaucoup plus d'applications que la carte MSP432, mais pour les tâches simples, le processeur suffit largement.

D'autre part, nous avons également commis une erreur en utilisant les pattes nécessaires à la liaison série pour la nunchuk. Ce problème nous empêche d'utiliser normalement la carte MSP432 : si on veut utiliser normalement la carte, on a des interférences qui rendent les données reçues par le sonar complétement illisibles. Pour pouvoir recevoir les informations normalement, et mélanger les deux programmes, il faut transformer le montage en une véritable usine à gaz, qui, visuellement, donne ceci :

Azertyuiopqsdfghjklm.jpg

Il est également certain que le programme final, mélangeant les deux précédents programmes, peut être amélioré. Mais nous avons manqué de temps pour sa simplification.