IMA3/IMA4 2018/2020 P23 : Différence entre versions
(→Liste de composants) |
(→Documents Rendus) |
||
(169 révisions intermédiaires par 4 utilisateurs non affichées) | |||
Ligne 686 : | Ligne 686 : | ||
=Projet S8= | =Projet S8= | ||
==Remise à zéro== | ==Remise à zéro== | ||
− | Suite aux remarques de la soutenance intermédiaire de projet, notre groupe a décidé d'abandonner la gestion des LEDs via l'utilisation du | + | Suite aux remarques de la soutenance intermédiaire de projet, notre groupe a décidé d'abandonner la gestion des LEDs via l'utilisation du microcontrôleur, pour nous diriger vers la réalisation d'une carte électronique comportant comme élément principal un FPGA. Ce dernier sera accompagné d'un ensemble de composants permettant au premier abord la réception d'un son (microphone), suivi d'une conversion analogique-numérique (CAN) pour pouvoir traiter le signal au sein du FPGA. Il effectuera des FFT dans le but de déterminer les fréquences audibles (ou non) du signal sonore reçu. L'objectif sera d'afficher sur une matrice de LEDs découpée en plusieurs rangées de fréquences l'intensité des amplitudes perçues, pour obtenir comme résultat un fréquencemètre audio. Ceci sera possible grâce à la création en VHDL des protocoles existant pour communiquer avec la matrice de LEDs dans ce cas précis. De plus, un module Bluetooth permettra à l'utilisateur de personnaliser et de contrôler son utilisation par le biais d'une application Android. |
− | == | + | ==Liste de composants== |
− | + | ===Premier choix de technologie=== | |
+ | '''Les choix des composants présentés dans les deux paragraphes suivants ont été abandonnés, en effet, nous ne pouvons pas souder les FPGA de série 7 Xilinx avec le matériel qui est à notre disposition.''' | ||
− | == | + | <s>'''Choix du FPGA'''</s> |
+ | |||
+ | Beaucoup de FPGA sont disponibles sur le marché et nous avons peu de connaissances sur les caractéristiques importantes d'un FPGA. En décidant d'utiliser en premier lieu un [https://www.xilinx.com/support/documentation/ip_documentation/xfft/v9_0/pg109-xfft.pdf module VHDL] pour effectuer la FFT, nous avons récupéré de la documentation qui nous a permis d'axer notre choix sur les FPGA Xilinx de série 7. | ||
+ | |||
+ | Xilinx fournit également des informations concernant les [https://www.xilinx.com/support/documentation/ip_documentation/ru/xfft.html ressources utilisées] par le module. En considérant que notre application ne nécessite pas une FFT supérieure à plus de 512 points, et que nos utilisations ne semblent pas très gourmandes en ressources, un FPGA "bas de gamme" se présente une bonne solution. Ne connaissant pas les nécessités de la gestion des LEDs dans le FPGA (composition et transmission en série d'une trame de 4608 bits) et du traitement du bluetooth, nous allons concerter un encadrant pour recevoir son avis. Pour le moment, nous avons décidé d'utiliser un [https://www.mouser.fr/ProductDetail/Xilinx/XC7A15T-1CPG236C?qs=rrS6PyfT74dwiUBTveYiww== FPGA Artix-7], sur lequel les ressources seront forcément suffisantes. | ||
+ | |||
+ | <s>'''Choix de la mémoire de programme'''</s> | ||
− | + | La [https://www.xilinx.com/support/documentation/user_guides/ug470_7Series_Config.pdf documentation] concernant les FPGA de série 7 Xilinx nous donne la longueur des bitstreams selon chaque FPGA (Table 1-1), notre mémoire doit être supérieure à la longueur du bitstream produit pour notre FPGA (soit 32Mbits minimum). | |
− | + | Les documents [https://www.xilinx.com/support/documentation/application_notes/xapp586-spi-flash.pdf Using SPI Flash] ainsi que les schémas de câblages de boards telle la [https://store.digilentinc.com/cmod-a7-breadboardable-artix-7-fpga-module/ Cmod A7] seront nos sources d'inspiration pour le câblage et la configuration de notre mémoire de programme. | |
− | + | ===Rectification=== | |
+ | |||
+ | '''Choix du FPGA''' | ||
− | + | Pour pouvoir souder notre FPGA sur notre carte, nous nous sommes tournés vers les FPGA plus anciens de Xilinx, les [https://www.xilinx.com/products/silicon-devices/fpga/spartan-3.html Spartan-3] peuvent être soudés. Nous avons choisi le | |
+ | [https://www.mouser.fr/ProductDetail/Xilinx/XC3S500E-4VQG100C?qs=sGAEpiMZZMvoScKlWpK8TKikNydnC9nifIuirGpjEhE%3D XC3S500E-4VQG100C] qui fait parti des [https://www.xilinx.com/support/documentation/data_sheets/ds312.pdf Spartan-3E]. | ||
− | + | Pour la réalisation du schematic, nous nous inspirerons de différentes boards existantes, et notamment la board Xilinx [https://www.waveshare.com/open3s500e-standard.htm Open3S500E], qui utilise le même FPGA que le nôtre. | |
− | + | '''Récapitulatif''' | |
{| class="wikitable center" | {| class="wikitable center" | ||
− | ! Composants !! | + | ! Composants !! Fournisseurs !! Fabricants !! Références fab !! URL !! Commentaires |
|- | |- | ||
− | | FPGA || Mouser || Xilinx | + | | FPGA || Mouser || Xilinx || XC3S500E-4VQG100C || [https://www.mouser.fr/ProductDetail/Xilinx/XC3S500E-4VQG100C?qs=sGAEpiMZZMvoScKlWpK8TKikNydnC9nifIuirGpjEhE%3D XC3S500E-4VQG100C] || / |
|- | |- | ||
− | | SPI Flash || Mouser || | + | | SPI Flash || Mouser || Xilinx || XCF04SVOG20C || [https://www.mouser.fr/ProductDetail/Xilinx/XCF04SVOG20C?qs=sGAEpiMZZMtDDQqI6EIC7hkwnPtRd%2FJBOFnwBS3gn%252BM%3D XCF04SVOG20C] || Minimum 4Mb data |
− | |||
|- | |- | ||
− | | Horloge || | + | | Horloge || Mouser || CTS Electronic Components || CB3LV-3I-100M0000 || [https://www.mouser.fr/ProductDetail/CTS-Electronic-Components/CB3LV-3I-100M0000?qs=sGAEpiMZZMt8zWNA7msRCq3UU5kBF8XUXwDzBPavbnU%3D CB3LV-3I-100M0000] || / |
|- | |- | ||
− | | Bluetooth || | + | | Bluetooth || / || / || / || [https://www.gotronic.fr/art-module-bluetooth-hc05-26097.htm HC05] || Déjà possédé |
|- | |- | ||
− | | Microphone || | + | | Microphone || / || Adafruit || MAX4466 || [https://cdn-shop.adafruit.com/datasheets/MAX4465-MAX4469.pdf MAX4466] || Déjà possédé |
|- | |- | ||
− | | CAN || Mouser || Texas Instruments || ADS7868IDBVR || [https://www.mouser.fr/ProductDetail/Texas-Instruments/ADS7868IDBVR?qs=sGAEpiMZZMvTvDTV69d2Qt3F3KjDSYf5IFO8E4Bk9Lk%3D ADS7868IDBVR] || | + | | CAN || Mouser || Texas Instruments || ADS7868IDBVR || [https://www.mouser.fr/ProductDetail/Texas-Instruments/ADS7868IDBVR?qs=sGAEpiMZZMvTvDTV69d2Qt3F3KjDSYf5IFO8E4Bk9Lk%3D ADS7868IDBVR] || / |
− | | port microUSB || || | + | |- |
+ | | port microUSB || / || / || / || / || Pour alimenter la carte | ||
+ | |} | ||
+ | |||
+ | ''Remarque : Pas besoin de mémoires RAM et ROM externes car nous n'utiliserons pas de logiciels sur notre FPGA. La mémoire interne du processeur devrait suffire pour l'utilisation/exécution de nos codes''. | ||
+ | |||
+ | Pour la liste des composants du USB to JTAG, voir la section "Semaines 5 à 7 - 10/02". | ||
+ | |||
+ | La liste d'achats est la suivante pour un prototype complet : [[Fichier:P23-Mouser-Commande1prototype.pdf]]. Nous avons doublé les composants en cas de mauvais montage (sauf pour l'embrasse de 14 pin), la liste devient : [[Fichier:P23-Mouser-CommandeDoublée.pdf]] | ||
+ | |||
+ | ==Avancées du projet== | ||
+ | |||
+ | ===Gestion des Leds avec FPGA=== | ||
+ | |||
+ | L'objectif de cette partie sera de récupérer en entrée le résultat de la FFT. Nous aurons des amplitudes selon les fréquences émises par le son en entrée, puis nous devrons utiliser le FPGA pour savoir quelles leds allumer en sortie. | ||
+ | |||
+ | ====Premier test==== | ||
+ | |||
+ | Dans un premier temps, nous voulions simplement gérer l'allumage d'une seule LED. Pour se faire, nous avons opéré le code suivant : | ||
+ | |||
+ | <pre> | ||
+ | library IEEE; | ||
+ | use IEEE.STD_LOGIC_1164.ALL; | ||
+ | |||
+ | entity LEDS is | ||
+ | |||
+ | generic ( | ||
+ | N : INTEGER := 8 | ||
+ | ); | ||
+ | |||
+ | Port ( clk : in STD_LOGIC; | ||
+ | enable : in STD_LOGIC; | ||
+ | red : in STD_LOGIC_VECTOR (N-1 downto 0); | ||
+ | green : in STD_LOGIC_VECTOR (N-1 downto 0); | ||
+ | blue : in STD_LOGIC_VECTOR (N-1 downto 0); | ||
+ | white : in STD_LOGIC_VECTOR (N-1 downto 0); | ||
+ | full_frame : out STD_LOGIC); | ||
+ | end LED1; | ||
+ | |||
+ | architecture Behavioral of LED1 is | ||
+ | |||
+ | signal frame_bit : STD_LOGIC := '0'; | ||
+ | signal lancement, cpt : integer := 0; | ||
+ | signal trame : STD_LOGIC_VECTOR(4*N-1 downto 0); | ||
+ | </pre> | ||
+ | |||
+ | Parmi les paramètres d'entrée : ''enable'' permet d'autoriser la led à réagir à la trame d'entrée et donc de s'allumer. On peut le comparer à un top départ, soit au signal sortant de la FFT de notre projet. Le protocole [https://cdn-shop.adafruit.com/product-files/2757/p2757_SK6812RGBW_REV01.pdf SK6812] indique, page 6, que chaque LED Adafruit pourra s'allumer suivant une structure de 32 bits : soit les 4 entrées de 8 bits ''red'', ''green'', ''blue'' et ''white''. | ||
+ | |||
+ | Enfin, en sortie nous avons la ''full_frame'' qui doit représenter la trame de 32 bits. | ||
+ | |||
+ | Nous verrons dans la partie 2 l'utilité de nos signaux internes : | ||
+ | |||
+ | <pre> | ||
+ | begin | ||
+ | process(clk) | ||
+ | begin | ||
+ | if rising_edge(enable) and lancement=0 then | ||
+ | lancement <= 1; | ||
+ | cpt <= 4*N-1; | ||
+ | end if; | ||
+ | if lancement=1 and rising_edge(clk) then | ||
+ | frame_bit <= trame(cpt); | ||
+ | cpt <= cpt - 1; | ||
+ | end if; | ||
+ | if cpt<0 then | ||
+ | cpt <= 0; | ||
+ | lancement <= 0; | ||
+ | end if; | ||
+ | if lancement=0 then | ||
+ | frame_bit <= '0'; | ||
+ | end if; | ||
+ | end process; | ||
+ | full_frame <= frame_bit; | ||
+ | trame <= red & green & blue & white; | ||
+ | end Behavioral; | ||
+ | </pre> | ||
+ | |||
+ | Avant tout, lorsque ''enable'' présente un front montant et que ''lancement'' vaut 0, on peut lancer le compteur décroissant à partir de 4*N-1 (soit 32). La ''trame'' est la structure de 32 bits d'une LED. La stratégie consiste donc à récupérer chaque bit de la trame dans ''frame_bit'' au rythme du compteur. Au final, c'est la sortie ''full_frame'' qui prendra la valeur de ''frame_bit'' bit par bit. | ||
+ | |||
+ | '''Code de la simulation :''' | ||
+ | |||
+ | <pre> | ||
+ | library IEEE; | ||
+ | use IEEE.STD_LOGIC_1164.ALL; | ||
+ | use IEEE.STD_LOGIC_ARITH.ALL; | ||
+ | |||
+ | entity LEDS_tb is | ||
+ | -- Port ( ); | ||
+ | end LEDS_tb; | ||
+ | |||
+ | architecture Behavioral of LEDS_tb is | ||
+ | component LED1 | ||
+ | Port( clk : in STD_LOGIC; | ||
+ | enable : in STD_LOGIC; | ||
+ | red : in STD_LOGIC_VECTOR (7 downto 0); | ||
+ | green : in STD_LOGIC_VECTOR (7 downto 0); | ||
+ | blue : in STD_LOGIC_VECTOR (7 downto 0); | ||
+ | white : in STD_LOGIC_VECTOR (7 downto 0); | ||
+ | full_frame : out STD_LOGIC | ||
+ | ); | ||
+ | end component; | ||
+ | |||
+ | signal clk : STD_LOGIC; | ||
+ | signal enable : STD_LOGIC; | ||
+ | signal red : STD_LOGIC_VECTOR (7 downto 0); | ||
+ | signal green : STD_LOGIC_VECTOR (7 downto 0); | ||
+ | signal blue : STD_LOGIC_VECTOR (7 downto 0); | ||
+ | signal white : STD_LOGIC_VECTOR (7 downto 0); | ||
+ | signal full_frame : STD_LOGIC; | ||
+ | |||
+ | begin | ||
+ | UUT: LEDS port map (clk => clk, enable => enable, red => red, green => green, blue => blue, white => white, full_frame => full_frame); | ||
+ | |||
+ | --Génération d'un signal d'horloge de 800KHz de période 1.25us | ||
+ | clk_gen : process | ||
+ | begin | ||
+ | clk <= '1'; wait for 0.625us; | ||
+ | clk <= '0'; wait for 0.625us; | ||
+ | end process; | ||
+ | |||
+ | --Génération de la mise à 1 de enable | ||
+ | enable_gen : process | ||
+ | begin | ||
+ | enable <= '0'; wait for 112.5us; | ||
+ | enable <= '1'; wait for 12.5us; | ||
+ | end process; | ||
+ | |||
+ | --Génération des valeurs de red | ||
+ | red_gen : process | ||
+ | begin | ||
+ | red <= CONV_STD_LOGIC_VECTOR(255,8); | ||
+ | green <= CONV_STD_LOGIC_VECTOR(0,8); | ||
+ | blue <= CONV_STD_LOGIC_VECTOR(255,8); | ||
+ | white <= CONV_STD_LOGIC_VECTOR(1,8); | ||
+ | wait for 1250us; | ||
+ | red <= CONV_STD_LOGIC_VECTOR(204, 8); wait for 1250us; | ||
+ | red <= CONV_STD_LOGIC_VECTOR(1, 8); wait for 1250us; | ||
+ | end process; | ||
+ | |||
+ | end Behavioral; | ||
+ | </pre> | ||
+ | |||
+ | Pour simuler notre code, nous envoyons une trame correspondant à ''FF 00 FF 01'' pour l'allumage d'une LED. En sortie, il faudrait donc que ''full_frame'' puisse reproduire le signal pour l'envoyer à une LED. | ||
+ | |||
+ | [[Fichier:simul1.png|center||1000px|thumb|Simulation du premier test]] | ||
+ | |||
+ | D'après la simulation ci-dessus, c'est un succès. Cependant, le code n'a pas tout à fait respecté le protocole [https://cdn-shop.adafruit.com/product-files/2757/p2757_SK6812RGBW_REV01.pdf SK6812], notamment au niveau du ''reset code''. La structure du code nous a quand même servit pour nos prochains tests. | ||
+ | |||
+ | ====Gestion d'une seule LED==== | ||
+ | [[Fichier:Demo mauvais proto.gif|150px|thumb|right|Utilisation du mauvais protocole]] | ||
+ | |||
+ | Nous avons ensuite mis en place l'horloge asymétrique décrite dans le protocole [https://cdn-shop.adafruit.com/product-files/2757/p2757_SK6812RGBW_REV01.pdf SK6812RGBW]. Nous avons ensuite simulé notre code et arrivons au résultat attendu: la trame correspond au protocole. | ||
+ | |||
+ | [[Fichier:P23 mauvais protocole.PNG|center|x150px|Démo avec le mauvais protocole]] | ||
+ | |||
+ | Après avoir adapté le fichier de contraintes de la Basys3 à notre programme, nous avons pu implémenter le programme sur la carte. Nous avons utilisé les 4 premiers switches de la carte pour contrôler les bits de poids forts des couleurs à envoyer (''red[7]'',''green[7]''...), un des boutons pour contrôler notre signal de départ (''enable'') et l'horloge de la carte. Tous les bits de poids faibles pour contrôler les LEDS sont programmés en pulldown. | ||
+ | |||
+ | Nous avons pu effectuer deux observations : | ||
+ | *Utiliser les LEDS à la moitié de leur puissance maximale est déjà beaucoup pour le rendu visuel (nous le savions déjà), nous utiliserons alors au maximum les 5 bits de poids faible de notre programme. | ||
+ | *La deuxième LED du bandeau était allumée alors que, selon le protocole, nous ne devions pas lui envoyer d'information. Nous avons alors choisit de vérifier le protocole, et il s'avère qu'il n'est pas celui utilisé par notre bandeau. Notre bandeau de LED communique via un protocole semblable mais pas identique: [https://cdn-shop.adafruit.com/datasheets/WS2812B.pdf WS2812B]. | ||
+ | |||
+ | Le code précédemment créé a donc été modifié pour respecter le protocole de notre bandeau, après simulation et implémentation sur la carte, nous avons réussi à contrôler l'affichage sur une LED. | ||
+ | |||
+ | [[Fichier:Led seule bon protocole.PNG|center|x150px|Démo avec le mauvais protocole]] | ||
+ | |||
+ | ====Gestion de toutes les LEDs==== | ||
+ | Maintenant, l'objectif est de pouvoir contrôler l'ensemble de notre panneau de 144 LEDs. Pour rappel, la composition des données 24 bits de la trame d'une LED est la suivante : | ||
+ | :{| class="wikitable" | ||
+ | ! G7 | ||
+ | ! G6 | ||
+ | ! G5 | ||
+ | ! G4 | ||
+ | ! G3 | ||
+ | ! G2 | ||
+ | ! G1 | ||
+ | ! G0 | ||
+ | ! R7 | ||
+ | ! R6 | ||
+ | ! R5 | ||
+ | ! R4 | ||
+ | ! R3 | ||
+ | ! R2 | ||
+ | ! R1 | ||
+ | ! B7 | ||
+ | ! B6 | ||
+ | ! B5 | ||
+ | ! B4 | ||
+ | ! B3 | ||
+ | ! B2 | ||
+ | ! B1 | ||
+ | ! B0 | ||
+ | |} | ||
+ | |||
+ | '''Premièrement''', nous devons créer une instance de ''one_LED'' (VHDL permettant le contrôle d'une LED) dans le composant ''all_LEDs'' que nous venons de créer pour la gestion de plusieurs LEDs, afin de pouvoir l'appeler. Les entités de ces 2 composants sont : | ||
+ | <pre> | ||
+ | entity one_LED is | ||
+ | generic( | ||
+ | N : INTEGER := 8 | ||
+ | ); | ||
+ | Port( | ||
+ | clk : in STD_LOGIC; --clock de 100MHz reçu | ||
+ | enable : in STD_LOGIC; --active l'envoie de la trame | ||
+ | red : in STD_LOGIC_VECTOR (N-1 downto 0); --données de l'octet red | ||
+ | green : in STD_LOGIC_VECTOR (N-1 downto 0); --données de l'octet green | ||
+ | blue : in STD_LOGIC_VECTOR (N-1 downto 0); --données de l'octet blue | ||
+ | full_frame : out STD_LOGIC --émission série de la trame | ||
+ | ); | ||
+ | end one_LED; | ||
+ | </pre> | ||
+ | |||
+ | <pre> | ||
+ | entity all_LEDs is | ||
+ | generic( | ||
+ | Nb_leds: integer := Nb_leds_library --Nombre de LEDs sur notre panneau, "Nb_leds_library" est une variable égale à 144 stocker dans une librairie personnelle | ||
+ | ); | ||
+ | Port( | ||
+ | vec_rgb : in myTab_rgb; --Tableau contenant sur 3 bits l'information RGB pour chaque LED | ||
+ | enable_trame_leds : in STD_LOGIC; --Le enable qui autorise l'envoie de la trame sur la sortie physique | ||
+ | clk : in STD_LOGIC; --Récepetion de l'horloge de 100MHz | ||
+ | trame_leds : out STD_LOGIC --Emission série venant de one_LED pour l'envoyer à une sortie physique | ||
+ | ); | ||
+ | end all_LEDs; | ||
+ | </pre> | ||
+ | |||
+ | Pour la gestion des couleurs RGB, la luminosité 255 est trop élevée et consomme plus de courant. Par conséquent, nous allons uniquement utiliser et ne choisir que le bit [5] à mettre à 1 ou 0, cela représentera environ 25% de la luminosité et consommera moins de courant. Nous nous sommes restreints à un choix de couleurs limités (7 couleurs possibles + "1 couleur éteinte") dans le but de diminuer la lourdeur du programme VHDL (soit environ plus de 16 millions de couleurs). Les couleurs choisies sont les suivantes : | ||
+ | |||
+ | {| border="0" align="center" style="border: 1px solid #999; background-color:#FFFFFF" | ||
+ | |-align="center" bgcolor="#CCCCCC" | ||
+ | ! En décimal | ||
+ | ! R | ||
+ | ! G | ||
+ | ! B | ||
+ | ! Couleur | ||
+ | |----- align="center" | ||
+ | | 0 || 0 || 0 || 0 || LED éteinte | ||
+ | |----- align="center" bgcolor="#EFEFEF" | ||
+ | | 1 || 0 || 0 || 1 || style="background:#00F;color:white" | bleu | ||
+ | |----- align="center" | ||
+ | | 2 || 0 || 1 || 0 || style="background:#0F0" | vert | ||
+ | |----- align="center" bgcolor="#EFEFEF" | ||
+ | | 3 || 0 || 1 || 1 || style="background:#0FF" | cyan | ||
+ | |----- align="center" | ||
+ | | 4 || 1 || 0 || 0 || style="background:#F00" | rouge | ||
+ | |----- align="center" bgcolor="#EFEFEF" | ||
+ | | 5 || 1 || 0 || 1 || style="background:#F0F" | magenta | ||
+ | |----- align="center" | ||
+ | | 6 || 1 || 0 || 1 || style="background:#FF0" | jaune | ||
+ | |----- align="center" bgcolor="#EFEFEF" | ||
+ | | 7 || 1 || 1 || 1 || style="background:#FFF" | blanc | ||
|} | |} | ||
− | '' | + | Ce choix est la raison de la création de la variable ''vec_rgb'' de type ''myTab_rgb'', ce type a été créé dans ''myLibrary.vhd'' et correspond à un tableau de vecteur (extrait ci-dessous). |
+ | |||
+ | <pre> | ||
+ | library IEEE; | ||
+ | use IEEE.STD_LOGIC_1164.ALL; | ||
− | = | + | package tab_rgb_type is --Notre propre type pour pouvoir l'utiliser dans le "port" de "entity" |
+ | constant Nb_leds_library: integer := 144+1; --cas général 144, le +1 est présent en raison d'un bug expliqué ultérieurement | ||
+ | type myTab_rgb is array(0 to (Nb_leds_library-1)) of std_logic_vector (2 downto 0); --mon tableau | ||
+ | end package tab_rgb_type; | ||
+ | </pre> | ||
− | + | La passage à la deuxième étape est effectué une fois les entités ''all_LEDs'' et ''one_LED'' programmées et testées avec un test bench. | |
− | |||
− | + | '''Deuxièmement''', l'objectif est d'envoyer une trame complète depuis la Basys3 vers le panneau LEDs. Le visuel choisi sera un égaliseur fixe pour nous donner un premier aperçu. Le visuel est le suivant : | |
− | {| | + | {| border="1" align="center" style="border: 1px solid #999; background-color:#FFFFFF" |
− | + | | bgcolor=#FFF|120 || bgcolor=#FFF|121 || bgcolor=#FFF|122 || bgcolor=#FFF|123 || bgcolor=#FFF|124 || bgcolor=#FFF|125 || bgcolor=#FFF|126 || bgcolor=#FFF|127 || bgcolor=#FFF|128 || bgcolor=#FFF|129 || bgcolor=#FFF|130 || bgcolor=#FFF|131 || bgcolor=#FFF|132 || bgcolor=#FFF|133 || bgcolor=#FFF|134 || bgcolor=#FFF|135 || bgcolor=#FFF|136 || bgcolor=#FFF|137 || bgcolor=#FFF|138 || bgcolor=#FFF|139 || bgcolor=#FFF|140 || bgcolor=#FFF|141 || bgcolor=#FFF|142 || bgcolor=#FFF|143 | |
|- | |- | ||
− | | | + | | bgcolor=#FFF|119 || bgcolor=#FFF|118 || bgcolor=#FFF|117 || bgcolor=#FFF|116 || bgcolor=#FFF|115 || bgcolor=#FFF|114 || bgcolor=#FFF|113 || bgcolor=#F0F|112 || bgcolor=#F0F|111 || bgcolor=#FFF|110 || bgcolor=#FFF|109 || bgcolor=#FFF|108 || bgcolor=#FFF|107 || bgcolor=#FFF|106 || bgcolor=#FFF|105 || bgcolor=#F0F|104 || bgcolor=#F0F|103 || bgcolor=#FFF|102 || bgcolor=#FFF|101 || bgcolor=#FFF|100 || bgcolor=#FFF|99 || bgcolor=#FFF|98 || bgcolor=#FFF|97 || bgcolor=#FFF|96 |
− | + | |- | |
− | | | + | | bgcolor=#FFF|72 || bgcolor=#FFF|73 || bgcolor=#FFF|74 || bgcolor=#FFF|75 || bgcolor=#FFF|76 || bgcolor=#F00|77 || bgcolor=#F00|78 || bgcolor=#F0F|79 || bgcolor=#F0F|80 || bgcolor=#FF0|81 || bgcolor=#FF0|82 || bgcolor=#FFF|83 || bgcolor=#FFF|84 || bgcolor=#FF0|85 || bgcolor=#FF0|86 || bgcolor=#F0F|87 || bgcolor=#F0F|88 || bgcolor=#F00|89 || bgcolor=#F00|90 || bgcolor=#FFF|91 || bgcolor=#FFF|92 || bgcolor=#FFF|93 || bgcolor=#FFF|94 || bgcolor=#FFF|95 |
− | + | |- | |
+ | | bgcolor=#FFF|71 || bgcolor=#FFF|70 || bgcolor=#FFF|69 || bgcolor=#0FF|68 || bgcolor=#0FF|67 || bgcolor=#F00|66 || bgcolor=#F00|65 || bgcolor=#F0F|64 || bgcolor=#F0F|63 || bgcolor=#FF0|62 || bgcolor=#FF0|61 || bgcolor=#FFF|60B || bgcolor=#FFF|59B || bgcolor=#FF0|58 || bgcolor=#FF0|57 || bgcolor=#F0F|56 || bgcolor=#F0F|55 || bgcolor=#F00|54 || bgcolor=#F00|53 || bgcolor=#0FF|52 || bgcolor=#0FF|51 || bgcolor=#FFF|50 || bgcolor=#FFF|49 || bgcolor=#FFF|48 | ||
+ | |- | ||
+ | | bgcolor=#FFF|24 || bgcolor=#0F0|25 || bgcolor=#0F0|26 || bgcolor=#0FF|27 || bgcolor=#0FF|28 || bgcolor=#F00|29 || bgcolor=#F00|30 || bgcolor=#F0F|31 || bgcolor=#F0F|32 || bgcolor=#FF0|33 || bgcolor=#FF0|34 || bgcolor=#FFF|35B || bgcolor=#FFF|36B || bgcolor=#FF0|37 || bgcolor=#FF0|38 || bgcolor=#F0F|39 || bgcolor=#F0F|40 || bgcolor=#F00|41 || bgcolor=#F00|42 || bgcolor=#0FF|43 || bgcolor=#0FF|44 || bgcolor=#0F0|45 || bgcolor=#0F0|46 || bgcolor=#FFF|47 | ||
+ | |- | ||
+ | | bgcolor=#00F|23 || bgcolor=#0F0|22 || bgcolor=#0F0|21 || bgcolor=#0FF|20 || bgcolor=#0FF|19 || bgcolor=#F00|18 || bgcolor=#F00|17 || bgcolor=#F0F|16 || bgcolor=#F0F|15 || bgcolor=#FF0|14 || bgcolor=#FF0|13 || bgcolor=#FFF|12B || bgcolor=#FFF|11B || bgcolor=#FF0|10 || bgcolor=#FF0|9 || bgcolor=#F0F|8 || bgcolor=#F0F|7 || bgcolor=#F00|6 || bgcolor=#F00|5 || bgcolor=#0FF|4 || bgcolor=#0FF|3 || bgcolor=#0F0|2 || bgcolor=#0F0|1 || bgcolor=#00F|0 | ||
|} | |} | ||
− | + | Nous devons créer une instance de ''all_LEDs'' dans le composant ''equalizer_fixed'' que nous venons de créer pour la gestion de l'égaliseur fixe en fonction des couleurs vues précédemment. L'entité de ce composant est : | |
+ | <pre> | ||
+ | entity equalizer_fixed is | ||
+ | Port( | ||
+ | clk : in STD_LOGIC; --Récepetion de l'horloge de 100MHz | ||
+ | enable_equalizer : in STD_LOGIC; --Récepetion de l'ordre d'envoi de la trame | ||
+ | enable_choice : in STD_LOGIC_VECTOR (0 downto 0); --Choix du mode de trame que l'on veut envoyer, 0 pour envoyer une trame d'extinction du panneau LEDs, 1 pour envoyer l'égaliseur; STD_LOGIC_VECTOR pour les futurs applications | ||
+ | trame_equalizer : out STD_LOGIC --Emission de la trame vers le panneau LEDs | ||
+ | ); | ||
+ | end equalizer_fixed; | ||
+ | </pre> | ||
+ | |||
+ | Une simulation de nos 3 fichiers VHDL a été réalisée à l'aide d'un test bench. Ce test bench fait le script suivant : | ||
+ | <pre> | ||
+ | --Génération d'un signal d'horloge de 100MHz (période de 10ns) | ||
+ | clk_gen : process | ||
+ | begin | ||
+ | clk <= '1'; wait for 5ns; | ||
+ | clk <= '0'; wait for 5ns; | ||
+ | end process; | ||
+ | |||
+ | --Génération du switch de enable_choice pour envoyer la trame extinction ou equalizer | ||
+ | enable_trame_choice_gen : process | ||
+ | begin | ||
+ | enable_choice <= "0"; wait for 4ms; --trame extinction | ||
+ | enable_choice <= "1"; wait for 4ms; --trame equalizer | ||
+ | end process; | ||
+ | |||
+ | --Génération de la mise à 1 (de l'appui sur un bouton) de enable pour donner l'ordre d'envoyer la trame vers les LEDs | ||
+ | enable_trame_leds_gen : process | ||
+ | begin | ||
+ | enable_equalizer <= '0'; wait for 0.97ms; | ||
+ | enable_equalizer <= '1'; wait for 30us; | ||
+ | enable_equalizer <= '0'; wait for 4ms; | ||
+ | end process; | ||
+ | </pre> | ||
+ | |||
+ | Sur le scope de la simulation nous retrouvons les variables essentielles présentes dans ''equalizer_fixed.vhd'' et nous montre le résultat suivant : | ||
+ | [[Fichier:Simulation1-equalizer-fixed.PNG|center||1464×213px]] | ||
+ | |||
+ | Calcul théorique d'envoi d'une trame pour 145 LEDS (144+1 expliqué dans le ''Troisièmement''): | ||
+ | |||
+ | :10ns[clock]*40[temps pour envoyer 1 bit]*3[nombre d'états pour la compréhension d'1 bit par le protocole]*24[nombre de bits dans une trame RGB]*145[nombre de LEDs] = 10*40*3*24*145 = 4176000ns = 4,176ms | ||
+ | |||
+ | Calcul pratique (en simulation) grâce aux curseurs d'envoi d'une trame : | ||
+ | :Le deuxième curseur est au front descendant du dernier bit à 1, ne prenant pas en compte les 2 derniers bits à 0, d'où l'ajout des (400ns*2). | ||
+ | :(10,17665ms+(400ns*2))-6ms = (10,176650+(0,000400*2))-6 = 4,17745 ms | ||
+ | |||
+ | La différence est de : 4,17745-4,176000 = 0,00145 = 1,45 us et s'explique par le retard d'un coup d'horloge (10ns) de chaque trame de LEDs dans l'envoi global, soit 145*10ns = 1450ns. | ||
+ | |||
+ | |||
+ | '''Troisièmement''', nous avons réalisé le test sur le matériel et nous avons rencontré plusieurs problèmes. Tout d'abord (problème n°1), l'information de la trame de la LED[0] ne lui est pas transmis et reçoit à la place celle de la LED[1] causant un décalage dans tout l'affichage. On ajoute une LED fantôme à notre circuit et notre panneau comprends maintenant 145 LEDs (dont 144 réelles). Puis (problème n°2), l'extinction des LEDs par le choix du switch à 0 ne fonctionne pas. Uniquement l'émission d'une trame par implémentation du programme dans la board fonctionne pour le moment (problème à régler plus tard). L'affichage sur les LEDs est le suivant : | ||
+ | [[Fichier:P23-equalizer-fixed-3.jpg|center||500px]] | ||
+ | |||
+ | En raison d'une soudure cassée des fils d'alimentations et du fil de transmission de données, la dernière ligne est inutilisable (les 24 LEDs tout en haut). | ||
+ | |||
+ | ===ADC de la Basys3=== | ||
+ | |||
+ | Afin de convertir un signal analogique en un signal numérique pour une démonstration, nous utiliserons l'IP XADC de notre Basys3. | ||
+ | |||
+ | ''Caractéristiques:'' | ||
+ | |||
+ | * Lors de la création du projet, nous utilisons la carte : ''xc7a35tcpg236-1'' d'après cette [https://www.unilim.fr/pages_perso/vahid.meghdadi-neyshabouri/VHDL/XADCinBays3.xhtml?fbclid=IwAR2ZrJozhxo-IBdkWW7P2zY0sCnTF3csqNJOP3LbFH3wYuE2_-zUHBQTLsc source] | ||
+ | |||
+ | * Nous utiliserons la chaîne 6 (VAUXP6 et VAUXN6) car d'après le [http://www.physics.umd.edu/hep/drew/programmable/xc7a35tcpg236pkg.txt mapping du XADC], ils correspondent aux pins J3/K3 soit aux ports 1/7 du header. | ||
+ | |||
+ | * Pour une utilisation simple et le plus efficace possible, nous configurons notre IP comme suit : | ||
+ | |||
+ | [[Fichier:xadc1.png]] | ||
+ | |||
+ | Grâce à cette configuration par défaut, les registres (''generic map()'') et le ''port map'' de notre XADC nommé ''xadc_wiz_0'' sont pré-configurés. C'est d'ailleurs la raison pour laquelle elle est en mode ''"Read Only"''. | ||
+ | |||
+ | ====Notre composant ADC_v2==== | ||
+ | |||
+ | Pour définir les entrées/sorties de notre composant, nous nous basons sur l'exemple de cette [https://www.xilinx.com/support/documentation/user_guides/ug480_7Series_XADC.pdf datasheet], la section ''Port Descriptions'' de la datasheet de [https://www.xilinx.com/support/documentation/ip_documentation/xadc_wiz/v3_0/pg091-xadc-wiz.pdfl l'XADC] et le ''port map'' de notre IP. Ainsi nous définissons : | ||
+ | |||
+ | <pre> | ||
+ | entity ADC_v2 is | ||
+ | port | ||
+ | ( | ||
+ | DCLK : in STD_LOGIC; -- Clock input | ||
+ | RESET : in STD_LOGIC; -- Reset | ||
+ | VAUXP, VAUXN : in STD_LOGIC_VECTOR (15 downto 0); | ||
+ | VP, VN : in STD_LOGIC; | ||
+ | MEASURED_VCCINT : out STD_LOGIC_VECTOR (15 downto 0); -- Mesure de la tension | ||
+ | EOC : out STD_LOGIC; | ||
+ | EOS : out STD_LOGIC | ||
+ | ); | ||
+ | </pre> | ||
+ | |||
+ | Suite à cela, il est nécessaire d'appeler l'IP xadc_wiz_0 (avec ses entrées/sorties) dans l'architecture comportementale de notre composant ADC_v2 : | ||
+ | |||
+ | <pre> | ||
+ | component xadc_wiz_0 is | ||
+ | port | ||
+ | ( | ||
+ | daddr_in : in STD_LOGIC_VECTOR (6 downto 0); -- Address bus for the dynamic reconfiguration port | ||
+ | den_in : in STD_LOGIC; -- Enable Signal for the dynamic reconfiguration port | ||
+ | di_in : in STD_LOGIC_VECTOR (15 downto 0); -- Input data bus for the dynamic reconfiguration port | ||
+ | dwe_in : in STD_LOGIC; -- Write Enable for the dynamic reconfiguration port | ||
+ | do_out : out STD_LOGIC_VECTOR (15 downto 0); -- Output data bus for dynamic reconfiguration port | ||
+ | drdy_out : out STD_LOGIC; -- Data ready signal for the dynamic reconfiguration port | ||
+ | dclk_in : in STD_LOGIC; -- Clock input for the dynamic reconfiguration port | ||
+ | reset_in : in STD_LOGIC; -- Reset signal for the System Monitor control logic | ||
+ | vauxp6 : in STD_LOGIC; -- Auxiliary Channel 5 | ||
+ | vauxn6 : in STD_LOGIC; | ||
+ | busy_out : out STD_LOGIC; -- ADC Busy signal | ||
+ | channel_out : out STD_LOGIC_VECTOR (4 downto 0); -- Channel Selection Outputs | ||
+ | eoc_out : out STD_LOGIC; -- End of Conversion Signal | ||
+ | eos_out : out STD_LOGIC; -- End of Sequence Signal | ||
+ | alarm_out : out STD_LOGIC; -- OR'ed output of all the Alarms | ||
+ | vp_in : in STD_LOGIC; -- Dedicated Analog Input Pair | ||
+ | vn_in : in STD_LOGIC); | ||
+ | end component; | ||
+ | </pre> | ||
+ | |||
+ | Ensuite, nos signaux internes nous serviront à instancier le composant et décrire la partie Hardware : | ||
+ | |||
+ | <pre> | ||
+ | signal vauxp_active : STD_LOGIC_VECTOR (15 downto 0); -- Pour initialisation | ||
+ | signal vauxn_active : STD_LOGIC_VECTOR (15 downto 0); -- Pour initialisation | ||
+ | signal daddr : STD_LOGIC_VECTOR (6 downto 0); | ||
+ | signal den : STD_LOGIC; | ||
+ | signal di_drp : STD_LOGIC_VECTOR (15 downto 0); | ||
+ | signal dwe : STD_LOGIC; | ||
+ | signal do_drp : STD_LOGIC_VECTOR (15 downto 0); | ||
+ | signal drdy : STD_LOGIC; | ||
+ | signal eoc_drp : STD_LOGIC; | ||
+ | signal eos_drp : STD_LOGIC; | ||
+ | signal busy : STD_LOGIC; | ||
+ | signal dclk_bufg : STD_LOGIC; | ||
+ | </pre> | ||
+ | |||
+ | Voici au final le port map() obtenu lors de l'instanciation : | ||
+ | |||
+ | <pre> | ||
+ | U0 : xadc_wiz_0 | ||
+ | port map ( | ||
+ | daddr_in(6 downto 0) => daddr(6 downto 0), | ||
+ | dclk_in => DCLK, | ||
+ | den_in => den, | ||
+ | di_in(15 downto 0) => di_drp(15 downto 0), | ||
+ | dwe_in => dwe, | ||
+ | reset_in => RESET, | ||
+ | vauxn6 => VAUXN(6), | ||
+ | vauxp6 => VAUXP(6), | ||
+ | busy_out => busy, | ||
+ | do_out(15 downto 0) => MEASURED_VCCINT(15 downto 0), | ||
+ | drdy_out => drdy, | ||
+ | eoc_out => EOC, | ||
+ | eos_out => EOS, | ||
+ | vn_in => VN, | ||
+ | vp_in => VP | ||
+ | ); | ||
+ | </pre> | ||
+ | |||
+ | ====Block Diagram==== | ||
+ | |||
+ | Notre première intention était de créer une version de notre ADC pouvant mesurer une tension. L’objectif était de récupérer la valeur de notre tension pour l’afficher en hexadécimal. Vous pouvez trouver ci-dessous le Block Diagram de la dernière version de notre composant. | ||
+ | |||
+ | [[Fichier:Block_design.PNG|center|x500px|Block Design de notre ADC]] | ||
+ | |||
+ | Sur une première version (et non celle-ci), nous avons codé en machines d’état. Nous avions décidé de changer de version plus tard pour des problèmes liés à la simulation. Plus de détails sont inscrits dans le rapport. L’objectif était de pouvoir mémoriser l’état interne dans le registre d’état et de les synchroniser avec l’horloge. Nous pouvions alors gérer la fréquence de conversion de notre ADC. | ||
+ | Comme nous avons utilisé la chaîne 6 de l’IP, ce sont VAUXP(6) et VAUXN(6) qui récupéreront le signal analogique. La conversion se fera à travers notre composant et l’IP pour que le vecteur MEASURED_VCCINT puisse récupérer un signal numérique en sortie. | ||
+ | |||
+ | ====Simulation==== | ||
+ | |||
+ | Afin de simuler notre convertisseur et vérifier le bon fonctionnement de notre code, nous devons lancer une simulation. Cependant, nos signaux VAUXP et VAUXN correspondent à des STD_LOGIC_VECTOR, soit des vecteurs de types numériques. En effet, Vivado ne comprend pas les signaux analogiques. Pour créer une entrée analogique, soit une stimulation, il faut alors utiliser un fichier design.txt. | ||
+ | |||
+ | Plusieurs sources sur internet montrent des façons différentes de créer un fichier stimulant. Cependant, Vivado n’en comprend qu’une seule, comme vous pouvez le voir ci-dessous : | ||
+ | |||
+ | [[Fichier:Exemple_stimulus.PNG|right|x150px|Format d'un fichier design.txt]] | ||
+ | |||
+ | Cet exemple est affiché dans la TCL Console lorsque le logiciel ne comprend pas le fichier. Nous avons alors créé notre propre fichier de stimulation, avec les signaux et les chaînes qui nous intéressaient : | ||
+ | |||
+ | [[Fichier:My_design.PNG|center|x400px|Block Design de notre ADC]] | ||
+ | |||
+ | ====Problèmes et méthodes de résolution==== | ||
+ | |||
+ | Ces dernières semaines, notre plus gros souci a été de lire et récupérer les données du fichiers design.txt. Toutes nos démarches sont détaillées dans le rapport. | ||
+ | |||
+ | '''Méthode 1 : S’inspirer de la datasheet et des exemples Vivado''' <br> | ||
+ | |||
+ | |||
+ | Notre première idée pour comprendre le fonctionnement du testbench de cet IP, était de générer l’exemple du logiciel. Malheureusement, ce dernier était en Verilog, soit un autre langage. | ||
+ | |||
+ | En consultant les datasheets, il s’avère que le fichier peut être généré par défaut. Cependant, en lançant notre simulation, rien ne se passe. Nous décidons alors de consulter l’exemple d’un ingénieur Xilinx via la datasheet de l’XADC : l’ug480. Dans le testbench codé en VHDL, il n’y a aucune trace de lecture du fichier. Seuls le RESET et l’horloge sont créés. En effet, cet exemple se sert des commandes sur la TCL Console. Cependant, en suivant les instructions dans le readme.txt, il semblerait que la commande ne fonctionne pas. Cela est sûrement dû à un problème de librairies et de fichiers introuvables… Ce qui paraît logique lorsqu’on sait qu’on a récupéré cet exemple via le site de Xilinx à l’aide de nos identifiants Xilinx. Ce n’est peut-être pas censé être publique. | ||
+ | |||
+ | '''Méthode 2 : La librairie STD.TEXTIO.ALL''' <br> | ||
+ | |||
+ | |||
+ | Cette librairie nous aura causé bien des problèmes pendant nos recherches. En effet, nous décidons de récupérer directement les valeurs de notre fichier design.txt. Il semblerait que nous ne sommes pas les seuls à opter pour cette solution, plusieurs personnes sur des forums utilisent cette librairie. | ||
+ | |||
+ | Nous avons codé notre processus de façon à ce qu’il puisse récupérer les valeurs, grâce à la lecture de ligne, READ et HREAD. Cependant, nous avions longtemps eu des erreurs uniquement avec HREAD. En effet, contrairement à ce [https://www.csee.umbc.edu/portal/help/VHDL/packages/std_logic_textio.vhd « package de STD.TEXTIO.ALL »], il fallait ajouter la librairie standard utilisée dans IEEE : <pre>IEEE.STD_LOGIC_TEXTIO.ALL</pre> | ||
+ | |||
+ | Malgré plusieurs rectifications de notre testbench, nous ne pouvions pas lancer la simulation. En effet, nous avons réussit à rentrer dans le fichier mais impossible de récupérer les valeurs souhaitées. Les démarches seront précisées dans le rapport. Voici un exemple d’erreur lors de notre simulation : | ||
+ | |||
+ | [[Fichier:Erreur_testbench.PNG|center|x200px|Erreur dans la TCL Console]] | ||
+ | |||
+ | Nous pouvons voir surligné en jaune des notes que nous avons volontairement laissé dans notre code pour tenter de débugger nos erreurs. Il semblerait que nous avions réussit à rentrer dans le fichier à ce moment précis. Puis on remarque avec la ligne « Failure » surlignée en jaune que la lecture pose problème. Nous nous sommes alors demandés si ce n’était pas à cause de l’en-tête… mais elle est obligatoire selon le logiciel. Ce fût une de nos plus grosses difficultés et nous ne sommes pas parvenus à extraire ces données pour lancer une simulation. | ||
+ | |||
+ | ====Alternative==== | ||
+ | Dans le but de pouvoir donner en entrée de la FFT des valeurs numériques cohérentes similaire à celle de l'ADC, nous allons générer ce signal d'entrée grâce à des sinus de fréquences différentes. Nous avons utilisé l'IP [https://www.xilinx.com/support/documentation/ip_documentation/dds_compiler/v6_0/pg141-dds-compiler.pdf DDS Compiler] permettant de produire des formes d'ondes sinusoïdales. | ||
+ | |||
+ | Dans notre cas, nous choisirons les fréquences sinusoïdales suivantes : 31, 62, 125, 250, 500, 1 000, 2 000, 4 000, 8 000 et 16 000 Hz. | ||
+ | |||
+ | Après avoir configuré l'IP, et associé 1 switch à chaque fréquence avec la configuration de ce tableau : | ||
+ | |||
+ | {| class="wikitable" style="margin: auto;" | ||
+ | ! Fréquences (Hz) !! switch (bit n°) | ||
+ | |- | ||
+ | | 31 || 9 | ||
+ | |- | ||
+ | | 62 || 8 | ||
+ | |- | ||
+ | | 125 || 7 | ||
+ | |- | ||
+ | | 250 || 6 | ||
+ | |- | ||
+ | | 500 || 5 | ||
+ | |- | ||
+ | | 1 000 || 4 | ||
+ | |- | ||
+ | | 2 000 || 3 | ||
+ | |- | ||
+ | | 4 000 || 2 | ||
+ | |- | ||
+ | | 8 000 || 1 | ||
+ | |- | ||
+ | | 16 000 || 0 | ||
+ | |} | ||
+ | |||
+ | Nous avons réalisé une simulation où l'on injecte des sinus, pour le signal d'entrée de la FFT, à chaque changement de switch dans cet ordre précisément : | ||
+ | |||
+ | {| class="wikitable" style="margin: auto;" | ||
+ | ! switch (binaire) !! switch (hexa) !! Fréquences (Hz) | ||
+ | |- | ||
+ | | 10_0000_0000 || 0x200 || 31 | ||
+ | |- | ||
+ | | 11_0000_0000 || 0x300 || 62 + 31 | ||
+ | |- | ||
+ | | 11_1000_0000 || 0x380 || 125 + 62 + 31 | ||
+ | |- | ||
+ | | 11_1100_0000 || 0x3c0 || 250 + 125 + 62 + 31 | ||
+ | |- | ||
+ | | 11_1110_0000 || 0x3e0 || 500 + 250 + 125 + 62 + 31 | ||
+ | |- | ||
+ | | 11_1111_0000 || 0x3f0 || 1 000 + 500 + 250 + 125 + 62 + 31 | ||
+ | |- | ||
+ | | 11_1111_1000 || 0x3f8 || 2 000 + 1 000 + 500 + 250 + 125 + 62 + 31 | ||
+ | |- | ||
+ | | 11_1111_1100 || 0x3fc || 4 000 + 2 000 + 1 000 + 500 + 250 + 125 + 62 + 31 | ||
+ | |- | ||
+ | | 11_1111_1110 || 0x3fe || 8 000 + 4 000 + 2 000 + 1 000 + 500 + 250 + 125 + 62 + 31 | ||
+ | |- | ||
+ | | 11_1111_1111 || 0x3ff || 16 000 + 8 000 + 4 000 + 2 000 + 1 000 + 500 + 250 + 125 + 62 + 31 | ||
+ | |} | ||
+ | Nous obtenons la simulation suivante où la sortie numérique (avec une visualisation analogique) "m_axis_data_tdata_sine[15:0]" transporte les sinusoïdes : | ||
+ | |||
+ | [[Fichier:P23-10sinus.PNG]] | ||
+ | |||
+ | ===Implémentation de la FFT=== | ||
+ | |||
+ | ====Création avec le module xfft==== | ||
+ | |||
+ | Dans un premier temps, on va se servir de l'IP déjà mis à disposition par Vivado. On peut voir via ce [https://www.xilinx.com/products/intellectual-property/fft/fft-software-requirements.html site] l'exigence logicielle de la fft et que la version 9.1 est prise en charge par la famille artix-7 en AXI-Stream. Pour le FPGA que nous avons choisit (Spartan3), il faut une version plus ancien (7.1) mais il reste quand même compatible avec le module également. | ||
+ | |||
+ | En se servant de la [https://www.xilinx.com/support/documentation/ip_documentation/xfft/v9_1/pg109-xfft.pdf datasheet], on peut configurer le module xfft_0 de la façon suivante : | ||
+ | |||
+ | {| class="wikitable center" style="margin: auto;" | ||
+ | |[[Fichier:Fft_config_1.png|280px|fft Configuration]] | ||
+ | |||
+ | |[[Fichier:Fft_config_2.png|280px|fft configuration]] | ||
+ | |||
+ | |} | ||
+ | |||
+ | Il faut ensuite lui envoyer un signal en entrée. Pour cela, on utilise l'IP [https://www.xilinx.com/support/documentation/ip_documentation/dds_compiler/v6_0/pg141-dds-compiler.pdf DDS_compiler] décrit dans la partie précédente pour simuler une onde sinusoïdale. On rajoute une '''clock''' en entrée de fréquence 100MHz. | ||
+ | Pour les entrées du bloc fft, on relie la sortie m_axis_data_tdata qui est un bus 16 bits à l'entrée du bloc fft m_axis_data_tdata qui est réglée pour accueillir un bit de cette longueur. | ||
+ | |||
+ | Pour que le module puisse recevoir et envoyer des données, il est nécessaire de connecter les voies '''s_axis_data_tdata''' et '''m_axis_data_tready''' à une constante que l'on modélisera à l'aide de l'IP [https://www.xilinx.com/support/documentation/ip_documentation/xilinx_com_ip_xlconstant/v1_1/pb040-xilinx-com-ip-xlconstant.pdf xconstant]. | ||
+ | |||
+ | En sortie, on récupère séparément la composante réelle et imaginaire du signal grâce aux IP [https://www.xilinx.com/support/documentation/ip_documentation/xilinx_com_ip_xlslice/v1_0/pb042-xilinx-com-ip-xlslice.pdf xslice] qui sont utilisés pour extraire des bits d'un réseau de bus. | ||
+ | |||
+ | Pour avoir l'amplitude du signal de sortie, nous nous sommes inspirés de ce [http://web.mit.edu/6.111/www/f2015/projects/mitchgu_Project_Final_Report.pdf projet]. En effet, pour avoir l'ampiltude, il faut appliquer la formule : {{sqrt|((real component)² + (imaginary component)²)}}. | ||
+ | Pour ce faire, on rajoute deux blocs d'IP [https://www.xilinx.com/support/documentation/ip_documentation/mult_gen/v12_0/pg108-mult-gen.pdf multiplier] et un bloc IP [https://www.xilinx.com/support/documentation/ip_documentation/addsub/v12_0/pg120-c-addsub.pdf adder] pour effectuer ce calcul. Enfin, pour effectuer la racine carrée, on ajoute le module [https://www.xilinx.com/support/documentation/ip_documentation/cordic/v6_0/pg105-cordic.pdf Cordic]. Il sera également nécessaire de relier une constante à la voie '''s_axis_cartesian_tvalid''' pour pouvoir recevoir les données. | ||
+ | |||
+ | ====Block diagram final==== | ||
+ | |||
+ | On arrive au block diagram final suivant : | ||
+ | |||
+ | [[Fichier:Block_design1.png|center|x450px|Block_diagram]] | ||
+ | |||
+ | |||
+ | ====Simulation==== | ||
+ | |||
+ | Pour effectuer la simulation on crée le '''HDL Wrapper''' qui va nous donner le code du diagramme final. Ensuite on crée le test bench pour lancer la simulation : | ||
+ | |||
+ | <pre> | ||
+ | |||
+ | library IEEE; | ||
+ | use IEEE.STD_LOGIC_1164.ALL; | ||
+ | library UNISIM; | ||
+ | use UNISIM.VCOMPONENTS.ALL; | ||
+ | |||
+ | entity design_1_tb is | ||
+ | end design_1_tb; | ||
+ | |||
+ | architecture Behavioral of design_1_tb is | ||
+ | |||
+ | component design_1 is | ||
+ | port ( | ||
+ | clk : in STD_LOGIC | ||
+ | ); | ||
+ | end component design_1; | ||
+ | |||
+ | signal clk : STD_LOGIC := '0'; | ||
+ | |||
+ | begin | ||
+ | design_1_i: design_1 port map (clk => clk); | ||
+ | |||
+ | --Génération d'un signal d'horloge de 100KHz | ||
+ | clk_gen : process | ||
+ | begin | ||
+ | clk <= '1'; wait for 500ns; | ||
+ | clk <= '0'; wait for 500ns; | ||
+ | end process; | ||
+ | |||
+ | end Behavioral; | ||
+ | |||
+ | </pre> | ||
+ | |||
+ | Après simulation, on obtient les résultats suivants : | ||
+ | |||
+ | [[Fichier:Resultfft.png|center|600px|Résultat fft]] | ||
+ | |||
+ | On voit bien une sinusoïde en entrée mais le résultat en sortie n'est pas concluant. En effet, on devrait normalement observer des pics périodiquement mais à la place on observe des oscillations. En réessayer en changeant les données du bloc FFT, on arrive aussi à des résultats infructueux. | ||
+ | |||
+ | ===Création du PCB=== | ||
+ | |||
+ | Pour réaliser le PCB, nous nous sommes appuyé sur les cartes de développement existantes, et notamment la carte [https://www.waveshare.com/open3s500e-standard.htm Open3S500E] qui utilise le même FPGA que nous. | ||
+ | |||
+ | Les schematics des cartes existantes masquent tous la partie entre la configuration et l'arrivée USB, l'arrivée de l'information se fait en JTAG. Deux solutions s'offrent à nous: acheter un câble de programmation USB->JTAG ou implanter un circuit de conversion USB->JTAG sur notre PCB. Après consultation des enseignants, la deuxième solution est la meilleure. Nous allons réaliser les deux schematics séparément puis les rassembler pour plus d'efficacité. | ||
+ | |||
+ | Le FPGA est un composant électronique possédant de nombreuses broches d'entrées/sorties, pour cette raison il est assez lourd à utiliser dans un schematic. Le nôtre est décomposé en 7 parties distinctes, qui correspondent à plusieurs fonctions (Configuration, alimentation, entrées/sorties), ce qui rend le schematic plus lisible. | ||
+ | |||
+ | {| class="wikitable center" style="margin: auto;" | ||
+ | |[[Fichier:FPGA configuration.PNG|280px|FPGA Configuration]] | ||
+ | |||
+ | FPGA Configuration | ||
+ | |[[Fichier:FPGA alimentation.PNG|280px|FPGA Alimentation]] | ||
+ | |||
+ | FPGA Alimentation | ||
+ | |[[Fichier:FPGA IO.PNG|280px|FPGA Alimentation]] | ||
+ | |||
+ | FPGA I/O | ||
+ | |[[Fichier:Schematic JTAG.PNG|280px|FPGA Alimentation]] | ||
+ | |||
+ | USB -> JTAG | ||
+ | |||
+ | |} | ||
− | |||
− | + | Une fois les fichiers schematics terminés, nous avons pu réaliser le routage du PCB sous Altium. | |
− | + | {| class="wikitable center" style="margin: auto;" | |
+ | |[[Fichier:p23_fpga_routage.PNG|300px|FPGA Alimentation]] | ||
+ | |[[Fichier:p23_fpga_routage2.PNG|300px|FPGA Alimentation]] | ||
+ | |[[Fichier:Routage_USU_to_JTAG.png|450px|USB to JTAG]] | ||
+ | |} | ||
+ | ==Agenda== | ||
===Semaine 1 - 13/01=== | ===Semaine 1 - 13/01=== | ||
Ligne 764 : | Ligne 1 396 : | ||
===Semaine 2 - 20/01=== | ===Semaine 2 - 20/01=== | ||
− | * Composants pour notre board : puce FPGA - port USB JTAG/UART - SPI Flash - ( SPI header ) - Micron DDR3 memory - régulateur de tension | + | * Composants pour notre board à acquérir : puce FPGA - port USB JTAG/UART - SPI Flash - ( SPI header ) - Micron DDR3 memory - régulateur de tension |
'''Notes pour plus tard :''' | '''Notes pour plus tard :''' | ||
− | * | + | * Il faudra élaborer le protocole de communication sous VHDL pour communiquer avec la [https://www.adafruit.com/product/2848 matrice de LEDs] en respectant son protocole [https://cdn-shop.adafruit.com/product-files/2757/p2757_SK6812RGBW_REV01.pdf SK6812]. Voici un lien sur la documentation relative aux matrices de LEDs Adafruit : [https://learn.adafruit.com/adafruit-dotstar-leds?view=all ici]. |
− | * | + | * Nous nous sommes documentés pour réaliser une [https://www.xilinx.com/support/documentation/ip_documentation/xfft/v9_0/pg109-xfft.pdf FFT] sur une puce Xilinx. |
===Semaine 3 - 27/01=== | ===Semaine 3 - 27/01=== | ||
Ligne 773 : | Ligne 1 405 : | ||
* Installation du logiciel [https://www.xilinx.com/support/download.html Vivado Design Suite] pour les produits Xilinx remplaçant "Xilinx ISE" pour le développement sur puce FPGA. | * Installation du logiciel [https://www.xilinx.com/support/download.html Vivado Design Suite] pour les produits Xilinx remplaçant "Xilinx ISE" pour le développement sur puce FPGA. | ||
* Entraînement sur la [https://store.digilentinc.com/zybo-zynq-7000-arm-fpga-soc-trainer-board/ Zybo Zynq-7000 ARM/FPGA SoC Trainer Board] car le bloc FFT est compatible avec la puce FPGA et nous permettrait de commencer le développement logiciel. [https://forums.xilinx.com/t5/AI-Engine-DSP-IP-and-Tools/FFT-8-0-Design-Example/td-p/338079 Exemples] d’utilisation du bloc. | * Entraînement sur la [https://store.digilentinc.com/zybo-zynq-7000-arm-fpga-soc-trainer-board/ Zybo Zynq-7000 ARM/FPGA SoC Trainer Board] car le bloc FFT est compatible avec la puce FPGA et nous permettrait de commencer le développement logiciel. [https://forums.xilinx.com/t5/AI-Engine-DSP-IP-and-Tools/FFT-8-0-Design-Example/td-p/338079 Exemples] d’utilisation du bloc. | ||
− | * | + | * Nous avons effectué la liste des composants : voir cette [https://projets-ima.plil.fr/mediawiki/index.php/IMA3/IMA4_2018/2020_P23#Liste_de_composants section]. |
− | * | + | * Nous avons eu un doute quant à l'utilisation du convertisseur analogique numérique : soit on prend le CAN Pmod AD2, soit on s'inspire de son [https://reference.digilentinc.com/_media/reference/pmod/pmodad2/pmodad2_sch.pdf schematic] et de son [https://www.mouser.fr/ProductDetail/Analog-Devices/AD7991YRJZ-1500RL7?qs=sGAEpiMZZMvTvDTV69d2QgYdPJm2vkaB5IU1atCXVS0%3D CAN]. |
===Semaine 4 - 03/02=== | ===Semaine 4 - 03/02=== | ||
'''Xilinx Vivado''' | '''Xilinx Vivado''' | ||
− | * | + | * Installation des fichiers relatifs à la board Zybo : [https://reference.digilentinc.com/reference/software/vivado/board-files Board File]. Dossier "zybo" de l'archive précédente à copier-coller dans le dossier "zynq" où est présent le logiciel. |
<pre> | <pre> | ||
...\vivado-boards-master\new\board_files\zybo | ...\vivado-boards-master\new\board_files\zybo | ||
Ligne 784 : | Ligne 1 416 : | ||
</pre> | </pre> | ||
− | * | + | * Nous avons récupéré 2 boards FPGA pour nos tests : Zybo Zynq-7010 et [https://store.digilentinc.com/basys-3-artix-7-fpga-trainer-board-recommended-for-introductory-users/ Artix Basys 3] avec l'accord de nos encadrants. |
− | * | + | * Nous avons effectué nos premières manipulations avec Vivado et le VHDL pour nous familiariser avec ces outils. |
Nous sommes maintenant bien équipés pour commencer nos premiers tests et savoir quels composants il nous faudra, en fonction de la consommation de nos tests. | Nous sommes maintenant bien équipés pour commencer nos premiers tests et savoir quels composants il nous faudra, en fonction de la consommation de nos tests. | ||
− | === | + | ===Semaines 5 à 7 - 10/02=== |
− | '' | + | |
+ | '''USB to JTAG''' | ||
+ | |||
+ | *Pour programmer la puce FPGA par le biais d'une connexion filaire microUSB du PC au PCB, il est nécessaire de passer par une interface JTAG, voici quelques [https://www.fpga4fun.com/JTAG1.html explications]. Cette liaison peut être réalisée par un [https://store.digilentinc.com/jtag-programmers-fpga-programming-solutions/ câble] en fonction de nos besoins. | ||
+ | *Dans notre cas, nous allons procéder à la réalisation de ce module grâce à des documentations open source. Nous allons reprendre le [https://www.ftdichip.com/Support/Documents/DataSheets/Modules/DS_FT2232H_Mini_Module.pdf Mini Module] qui a pour composant principal un [https://www.ftdichip.com/Support/Documents/DataSheets/ICs/DS_FT2232H.pdf FT2232H]. | ||
+ | *Le schematic sera celui présent dans la datasheet du module page 9. La liste des composants est la suivante à acquérir : | ||
+ | |||
+ | {| class="wikitable center" | ||
+ | ! Description !! Fabricant !! Référence Fab !! Empreinte !! Désignation carte !! Quantité !! Réf Mouser !! Réf Farnell !! Prix unitaire !! URL achat | ||
+ | |- | ||
+ | | Connecteurs USB MICRO USB B RECPT BTTM MOUNT ASSY || Molex || 47346-0001 || 47346-0001 || CN1 || 1 || 538-47346-0001 || / || 0.86 || [https://www.mouser.fr/ProductDetail/Molex/47346-0001?qs=sGAEpiMZZMulM8LPOQ%252BykxKOk52KZ3dlOv3hZ6FZMJU%3D URL1] | ||
+ | |- | ||
+ | | Suppresseurs ESD / diodes TVS || Littelfuse || PGB1010603 || 0603 || CR1, CR2 || 2 || 576-PGB1010603MR || / || 0.54 || [https://www.mouser.fr/ProductDetail/Littelfuse/PGB1010603MR?qs=gu7KAQ731URLg4GSnNNN7Q== URL2] | ||
+ | |- | ||
+ | | Perles de ferrite 600ohms 500mA || Murata || BLM18EG601SZ1D || 0603 || FB1, FB2, FB3 || 3 || 81-BLM18EG601SZ1D || / || 0.21 || [https://www.mouser.fr/ProductDetail/Murata-Electronics/BLM18EG601SZ1D?qs=sGAEpiMZZMtdyQheitOmRQALsn%2F4R2uW7Rq1DCQWwSVlWV5VKIadAA%3D%3D URL3] | ||
+ | |- | ||
+ | | EEPROM 128x16 || Microchip || 93LC56BT-I/OT || SOT-23-6 || U2 || 1 || 579-93LC56BT-I/OT || / || 0.20 || [https://www.mouser.fr/ProductDetail/Microchip-Technology/93LC56BT-I-OT?qs=sGAEpiMZZMuVhdAcoizlRTtWxdtwgs5N9nX1gxGZgqQ%3D URL4] | ||
+ | |- | ||
+ | | Circuit intégré d'interface USB USB HS to Dual UART/ FIFO/SPI/JTAG/I2C || FTDI || FT2232HL-REEL || LQFP-64 || U1 || 1 || 895-FT2232HL || / || 6.04 || [https://www.mouser.fr/ProductDetail/FTDI/FT2232HL-REEL?qs=D1%2FPMqvA100v7FHcEx164g%3D%3D URL5] | ||
+ | |- | ||
+ | | Horloge 12MHz || ABRACON || ABLS7M2-12.000MHZ-D2Y-T || 7 mm x 4.1 mm || Y1 || 1 || 815-ABLS7M212MHZD2YT || / || 0.33 || [https://www.mouser.fr/ProductDetail/ABRACON/ABLS7M2-12000MHZ-D2Y-T?qs=sGAEpiMZZMsBj6bBr9Q9abMK2mGYOCsJNRbffcWEGaeNvZ3QFgIHrw%3D%3D URL6] | ||
+ | |- | ||
+ | | Régulateurs de tension LDO 500mA Lo-Noise LDO Vltg Reg || Texas Instruments || TL5209DR || SOIC-8 || U3 || 1 || 595-TL5209DR || / || 1.02 || [https://www.mouser.fr/ProductDetail/Texas-Instruments/TL5209DR?qs=sGAEpiMZZMsGz1a6aV8DcKyc140gPNQrTkZBGjruB8Y%3D URL7] | ||
+ | |- | ||
+ | | Embases et logements de câbles 2x13 pin male header || TE || 1-215309-3 || https://www.mouser.fr/datasheet/2/418/NG_CD_215309_E-1247367.pdf || CN2, CN3 || 2 || 571-1-215309-3 || / || 3.07 || [https://www.mouser.fr/ProductDetail/TE-Connectivity-AMP/1-215309-3?qs=sGAEpiMZZMs%252BGHln7q6pm8SOCK6aAoLgbIkv1jVEs%252BM%3D URL8] | ||
+ | |} | ||
+ | |||
+ | Suivi des capacités 0603 et résistances 0603 : | ||
+ | {| class="wikitable center" | ||
+ | ! Désignation carte !! C1, C9 !! C2, C7, C11, C12, C14 !! C3, C4, C8, C10, C13, C15, C16 à C22 !! C5, C6 !! R1 !! R2, R6 !! R3 !! R4, R5 !! R7 | ||
+ | |- | ||
+ | | Valeurs || 10nF || 4.7uF || 100nF || 30pF || 15k || 10k || 12k/1% || 10R = 10 ohm || 2k | ||
+ | |} | ||
+ | |||
+ | * Installation de la [http://mouser.componentsearchengine.com/pcb-libraries.php?fbclid=IwAR2f84s3b__mjj4Wg2Fp9cB9W3zsd6xP015Y6ifyLM953Zprz51H-lZ0GCE librairie Altium] de recherche de composants. | ||
+ | |||
+ | |||
+ | |||
+ | '''PCB FPGA''' | ||
+ | |||
+ | *Choix du FPGA modifié [https://www.mouser.fr/ProductDetail/Xilinx/XC3S500E-4VQG100C?qs=sGAEpiMZZMvoScKlWpK8TKikNydnC9nifIuirGpjEhE%3D XC3S500E-4VQG100C] pour pouvoir le souder. La programmation de cette puce se fera sous [https://www.xilinx.com/support/download/index.html/content/xilinx/en/downloadNav/vivado-design-tools/archive-ise.html ISE Design Suite]. | ||
+ | *Réalisation du schematic sous Altium. | ||
+ | |||
+ | |||
+ | '''Développements sous Vivado pour Basys 3''' | ||
+ | |||
+ | * Nous avons commencé à créer une [https://projets-ima.plil.fr/mediawiki/index.php/IMA3/IMA4_2018/2020_P23#Premier_test première version] de la gestion de nos LEDs avec Vivado. | ||
+ | |||
+ | ===Semaine 8 - 02/03=== | ||
+ | '''Développements Basys 3''' | ||
+ | *Nous avons amélioré le code permettant de gérer la trame de LEDs. Dans cette [https://projets-ima.plil.fr/mediawiki/index.php/IMA3/IMA4_2018/2020_P23#Gestion_d.27une_seule_LED section] nous pouvons voir qu'au final, que les LEDs ne s'allumaient pas exactement comme nous le voulions. C'était la deuxième version de notre code. | ||
+ | *Nous avons pu récupérer le [https://www.xilinx.com/support/documentation/university/Vivado-Teaching/HDL-Design/2015x/Basys3/Supporting%20Material/Basys3_Master.xdc fichier (.xdc)] de contraintes de la Basys3 à utiliser. Il nous servira à effectuer nos tests réels sur la board. | ||
+ | |||
+ | ===Semaine 9 - 09/03=== | ||
+ | '''Développements Basys 3''' | ||
+ | *Nous avons réussit à gérer les couleurs d'une LED sur le bandeau grâce à notre protocole, en utilisant les switchs de la board. Cependant, on s'est rendu compte que le protocole n'était pas le bon. | ||
+ | *Après plusieurs recherches, il s'avère que le protocole correct est le [https://cdn-shop.adafruit.com/datasheets/WS2812B.pdf WS2812B]. Nous avions la mauvaise référence de notre panneau LEDs. | ||
+ | *'''Objectif :''' contrôler toutes les LEDs en envoyant une trame complète. | ||
+ | |||
+ | |||
+ | Mis à part le PCB à créer, on pense éventuellement à utiliser la borde Basys3 pour une démonstration : | ||
+ | |||
+ | *Nous avons donc fait une première approche de l'IP XADC de Vivado pour notre convertisseur ADC. Lien de la datasheet : [https://www.xilinx.com/support/documentation/ip_documentation/xadc_wiz/v3_0/pg091-xadc-wiz.pdf XADC]. | ||
+ | |||
+ | ===Semaine 10 - 16/03=== | ||
+ | |||
+ | A partir de ce lundi 16/03, les circonstances ont voulu que l'école ferme. Nous possédons le matériel nécessaire pour continuer à effectuer le projet. | ||
+ | |||
+ | '''Mercredi 18/03 : Réunion sur [https://chat.plil.fr/ima4/channels/projets chat] avec les professeurs :''' | ||
+ | |||
+ | *Tout le matériel est possédé par Stephen (Basys3, microphone MAX4466, Bluetooth HC05, panneau LEDs SJ-100144-2811 et ATMega 2560). La possession du matériel par une personne n’est pas contraignante, car on ne passe aux tests uniquement si la simulation en amont est concluante et correspond aux protocoles attendus. | ||
+ | |||
+ | *Niveau PCB : Il nous reste à intégrer nos entrées/sorties (Bluetooth, Microphone et bandeau LEDS) à notre board, toute la configuration du FPGA a été faite. Il faudra aussi faire le routage de la carte FPGA et du FTDI indépendamment (à fusionner une fois validées). | ||
+ | |||
+ | *Niveau VHDL : On travaille sur la Basys3. On a géré le protocole d'envoi de trame pour notre bandeau de LEDs, le résultat actuel est l’allumage de la première LED avec le RGB que l’on souhaite. Il faut optimiser le déroulement du code pour utiliser toutes les capacités que peut offrir un FPGA, et continuer à travailler sur toutes les autres entrées/sorties (Bluetooth, microphone). | ||
+ | |||
+ | '''Organisation du groupe :''' | ||
+ | |||
+ | ''Stephen'' : Rendre le CAN de la Basys3 fonctionnel pour la démonstration | ||
+ | |||
+ | ''Quentin et Simon'' : Router le PCB pour la fin de semaine. Parties USB to JTAG, et FPGA séparées puis à mettre en commun | ||
+ | |||
+ | ''Robin'' : Pouvoir contrôler le panneau LEDs entièrement, optimiser le fonctionnement en VHDL. Communication Bluetooth. Application Android. | ||
+ | |||
+ | Travail à venir : FFT. | ||
+ | |||
+ | ===Semaine 11 - 23/03=== | ||
+ | |||
+ | Avancées individuelles sur nos tâches respectives. | ||
+ | |||
+ | Côté ADC : Erreurs d'instanciation. Un des signaux crée ne reconnaît pas un élément particulier (do_out) du port map du composant XADC. | ||
+ | Dans ce cas, une lecture de datasheets et de forums est nécessaire pour comprendre comment il fonctionne : | ||
+ | |||
+ | * [http://www.physics.umd.edu/hep/drew/programmable/#xadc_wizard Instanciation en Verilog pour comprendre la logique] | ||
+ | * [http://www.physics.umd.edu/hep/drew/programmable/xc7a35tcpg236pkg.txt Le mapping du XADC] | ||
+ | * La datasheet nommée Xilinx 7 Series FPGA and Zynq-7000 All Programmable - SoC Libraries Guide for HDL Designs | ||
+ | * [https://www.xilinx.com/support/documentation/user_guides/ug480_7Series_XADC.pdf Datasheet du XADC] | ||
+ | * [https://www.unilim.fr/pages_perso/vahid.meghdadi-neyshabouri/VHDL/XADCinBays3.xhtml?fbclid=IwAR2ZrJozhxo-IBdkWW7P2zY0sCnTF3csqNJOP3LbFH3wYuE2_-zUHBQTLsc Exemple d'utilisation du XADC] (qui n'a pas l'air de fonctionner après l'avoir testé en simulation) | ||
+ | |||
+ | ===Semaine 12 - 30/03=== | ||
+ | '''Basys 3''' | ||
+ | *LEDs : Ajout du résultat de l'émission d'une trame complète dans [https://projets-ima.plil.fr/mediawiki/index.php/IMA3/IMA4_2018/2020_P23#Gestion_de_toutes_les_LEDs Gestion de toutes les LEDs]. | ||
+ | *XADC : Instanciation de l'IP : section [https://projets-ima.plil.fr/mediawiki/index.php/IMA3/IMA4_2018/2020_P23#ADC_de_la_Basys3 ADC de la Basys3] | ||
+ | '''PCB''' | ||
+ | *FPGA : Ajout du routage de notre carte électronique autour de la puce FPGA dans [https://projets-ima.plil.fr/mediawiki/index.php/IMA3/IMA4_2018/2020_P23#Cr.C3.A9ation_du_PCB Création du PCB]. | ||
+ | *USB to JTAG : Routage autour du FTDI dans la section citée précédemment. | ||
+ | |||
+ | ===Semaine 13 - 06/04=== | ||
+ | '''Basys 3''' | ||
+ | *Bluetooth : Notre communication UART est opérationnelle en simulation, en réception comme en émission. Pour la tester avec la board, on enverra un caractère ASCII depuis notre smartphone par le biais d'un terminal Bluetooth. Sa représentation binaire permettra d'allumer les 8 LEDs sur 16 déjà présentes sur la Basys 3. La simulation répond à la demande souhaitée, la synthèse se réalise avec succès également, mais l'implémentation détecte des erreurs liées aux "no input/output delays". Malgré cela, on génère le bitstream et on arrive à allumer certaines LEDs de la Basys 3. Malheureusement, l'allumage des LEDs se fait de manière aléatoire. | ||
+ | |||
+ | *XADC : Implémentation de "State Machines" pour la gestion de l'ADC : débogage et création du testbench. ''Sources : [https://www.intel.com/content/www/us/en/programmable/quartushelp/13.0/mergedProjects/hdl/vhdl/vhdl_pro_state_machines.htm lien 1] et [https://www.allaboutcircuits.com/technical-articles/implementing-a-finite-state-machine-in-vhdl/ lien 2].'' | ||
+ | |||
+ | *Début de recherche avec l'[https://www.xilinx.com/support/documentation/ip_documentation/xfft/v9_1/pg109-xfft.pdf IP FFT] de Vivado pour effectuer notre fft. | ||
+ | |||
+ | ===Semaines 14 à 16 - 13/04=== | ||
+ | '''Basys 3''' | ||
+ | *XADC : Problèmes liés à la lecture du fichier de stimulation analogique design.txt pour faire fonctionner le testbench. On apprend à utiliser la librairie ''use STD.TEXTIO.ALL'' | ||
+ | *Panneau LEDs : Nous avons un problème d'actualisation de ce dernier lié à un nouveau motif d'animations lumineux crée. Nous voulions commander le changement d'animations mais seule une animation pouvait être envoyée lors du test réel. Ce problème a été résolu et nous maîtrisons désormais les LEDs de notre panneau. | ||
+ | *Bluetooth : Il y a une mauvaise communication entre le HC05 et le FPGA pour interpréter la donnée émise par le module. On cherche à isoler les causes. Pour être sûr que le FPGA interprète correctement ce qu'il reçoit en RX, on décide de lui envoyer ce qu'il émet lui-même en TX. Le résultat est cohérent puisqu'il comprend la donnée. Le soucis viendrait du HC05. | ||
+ | Ce problème a été résolu après des modifications du code VHDL et un ajustement des alimentations, notamment un rééquilibrage des masses. | ||
+ | *Développements Vivado : | ||
+ | :- Fusion des codes VHDL comprenant l'UART et le contrôle du panneau LEDs. | ||
+ | *Nous avons crée une application Android pour communiquer avec le FPGA, l'application est opérationnelle et nous pouvons contrôler nos LEDs via le module Bluetooth. | ||
+ | |||
+ | ===Résultat final=== | ||
+ | |||
+ | Voici les différentes animations possibles de notre projet. | ||
+ | |||
+ | [[Fichier:P23-video.mp4|600px]] | ||
+ | |||
+ | Avec le montage ci-dessous : | ||
+ | |||
+ | [[Fichier:montagefpga_final.PNG|280px|Montage final]] [[Fichier:fritzing_fpga.PNG|400px|Schéma Montage final]] | ||
==Documents Rendus== | ==Documents Rendus== | ||
+ | Rapport : [[Fichier:IMA4-S8-P23-Rapport.pdf]] | ||
+ | |||
+ | Diaporama : [[Fichier:IMA4-S8-P23-Diapo.pdf]] | ||
+ | |||
+ | Archives du projet : [https://archives.plil.fr/Quentin/projet_p23.git Git] |
Version actuelle datée du 5 mai 2020 à 09:44
Sommaire
- 1 Présentation générale
- 2 Analyse du projet
- 2.1 Positionnement par rapport à l'existant
- 2.2 Analyse du premier concurrent: LumiGram
- 2.3 Analyse du second concurrent : Lumiwear
- 2.4 Analyse du troisième concurrent : Heart Jacking
- 2.5 Scénario d'usage du produit ou du concept envisagé
- 2.6 Réponses aux questions difficiles
- 2.7 Bibliographie et webographie
- 3 Préparation du projet
- 4 Réalisation du Projet
- 5 Projet S7
- 6 Projet S8
- 6.1 Remise à zéro
- 6.2 Liste de composants
- 6.3 Avancées du projet
- 6.4 Agenda
- 6.4.1 Semaine 1 - 13/01
- 6.4.2 Semaine 2 - 20/01
- 6.4.3 Semaine 3 - 27/01
- 6.4.4 Semaine 4 - 03/02
- 6.4.5 Semaines 5 à 7 - 10/02
- 6.4.6 Semaine 8 - 02/03
- 6.4.7 Semaine 9 - 09/03
- 6.4.8 Semaine 10 - 16/03
- 6.4.9 Semaine 11 - 23/03
- 6.4.10 Semaine 12 - 30/03
- 6.4.11 Semaine 13 - 06/04
- 6.4.12 Semaines 14 à 16 - 13/04
- 6.4.13 Résultat final
- 6.5 Documents Rendus
Présentation générale
Description
Ce projet a pour but de concevoir un vêtement (robe, jupe, veste ou accessoires) agrémenté d'animations lumineuses. Ce vêtement serait le complément idéal pour des occasions spéciales (anniversaires, mariages, soirées) afin d'attirer l'attention sur vous et d'intriguer les personnes aux alentours.
Pour cela, nous utiliserons des modules de LEDs situés sous un vêtement (T-shirt) et pilotés par des microcontrôleurs. L'objectif est de réaliser une extension légère à porter et simple à câbler.
Un harnais de poitrine viendra se placer sous un t-shirt et le premier motif serait un spectre lumineux d'un égaliseur audio (voir ci-dessous) présent sur le côté avant. Il réagirait en fonction du niveau sonore dans l'environnement autour de lui (écoute avec un microphone). D'autres motifs pourront être programmé par la suite.
Objectifs
L'objectif principal est d'animer via des effets lumineux un vêtement pour attirer l’attention. Pour ce faire, nous allons découper le projet en différents objectifs :
- Capter et analyser un signal sonore ambiant (musique)
- Créer des animations lumineuses suivant les fréquences captées ou niveaux d'intensité
- Établir une communication Bluetooth entre l'électronique embarqué et le smartphone de l'utilisateur
- Réfléchir aux modules complémentaires pouvant être ajouté pour la suite du projet en IMA4
Ces premiers objectifs vont nous permettre de concevoir notre cahier des charges et par la suite nous guider dans le choix des technologies à choisir et à utiliser.
Analyse du projet
Positionnement par rapport à l'existant
Il existe déjà plusieurs fabricants de vêtements lumineux, cependant les prix sont très élevés, ou les animations sont limitées.
Nous allons donc essayer de trouver une solution abordable, et ajouter diverses animations lumineuses qui réagiront à l'environnement sonore.
Analyse du premier concurrent: LumiGram
LumiGram est une entreprise italienne créée en 2006. Elle est spécialisée dans le domaine des tissus et textiles lumineux (tissus fibre optique). L'entreprise commercialise ses produits sur sa boutique en ligne et peut également effectuer des commandes sur mesure.
Le tissu lumineux est fait de fibres optiques tissées avec des fibres synthétiques. Ces fibres sont traitées pour émettre de la lumière sur toute leur longueur. Elles sont ensuite connectées à des LEDs qui injectent de la lumière dans le tissu. Les produits sont alimentés par un adaptateur secteur 110/220 Volt pour les applications fixes, ou par piles et sont dirigés par un interrupteur.
Les tissus lumineux produits par LumiGram sont utilisés dans différents domaines:
- L'habillement: ils créent des vêtements prévues pour des soirées ou des spectacles, utilisés par exemple, par certaines stars lors d’événements internationaux tel que le SuperBowl.
- La décoration: de nombreux produits de décorations sont vendus tels que des coussins, rideaux, nappes, parures de chaises, etc. Ces éléments peuvent être utilisés à l'occasion de soirées mais également dans la vie quotidienne.
Avantages | Inconvénients |
---|---|
|
|
Analyse du second concurrent : Lumiwear
Le second concurrent est Lumiwear (marque française fondée en 2012) proposant des vestes lumineuses modulaires. Cette veste se veut totalement personnalisable avec ses bandes velcro équipé sur le torse, le dos et les manches permettant d'y accrocher des rubans leds monocouleurs ou RGB. Elle est ajustée de façon à rendre son utilisation agréable : poches de rangement (batteries rechargeables), câblage électrique, légèreté, démontable et lavable. Ce vêtement se définit comme "Plug and Play" dans la mesure où il est possible de créer son propre design lumineux sans aucune soudure ni outil.
Lumiwear propose par exemple la veste Light1 entièrement équipée et vendu au prix de 339€ sur leur boutique en ligne. Cette veste comprend à titre informatif:
- 1 câblage électrique RGB adapté
- 2 connecteurs 2 sorties et 2 connecteurs 4 sorties
- 1 batterie rechargeable 4200mAh avec chargeur
- 4 rubans led RGB de 20cm et 4 rubans led RGB de 40cm prêt à poser
- 1 contrôleur RGB avec télécommande radiofréquence
Avantages | Inconvénients |
---|---|
|
|
Analyse du troisième concurrent : Heart Jacking
Heart Jacking est une société française créée en 2006 par Alexandre Tete. La marque est spécialisée dans la création et le commerce de vêtements et accessoires, notamment lumineux. Elle propose des produits à prix abordables, avec des motifs illuminés sur l'avant des vêtements.
L'entreprise propose différents types de technologie, certains produits utilisent la fibre optique comme les produits Lumigram, alors que d'autres utilisent des leds, cachées derrières des motifs situés au niveau du torse sur les vêtements, et destinées à éclairer ces derniers.
Les produits proposent des animations lumineuses fixes, chaque vêtement possède une animation lumineuse qui ne peut être modifié après l'achat, excepté un pull et un t-shirt qui permettent d'afficher un message que l'utilisateur programme au préalable.
Avantages | Inconvénients |
---|---|
|
|
Scénario d'usage du produit ou du concept envisagé
Dans notre premier scénario d'usage, nous prenons le cas d'un jeune homme, nommé Jacques, qui veut rejoindre ses amis en soirée.
Jacques aime faire la fête et séduire des filles, or Jacques n'arrive pas à attirer leur attention, elle est déjà accaparée par son ami Franck.
Alors Jacques, enfile sa veste équipée de LEDs et part en soirée. Une fois arrivé, ni une ni deux il allume sa veste et tout le monde se tourne vers lui, en lui demandant de leur expliquer quelle est cette drôle de veste.
Ainsi Jacques a réussi à attirer l'attention de tout le monde, notamment celle des filles et peut maintenant s'amuser.
Dans notre second scénario d'usage, nous prendrons un jeune, nommé Thibault, faisant partie de la sono (association Polytech'Lille).
Thibault aime pendant les soirées mixer et user d'effets de lumière pour créer une bonne ambiance, mais pour s'investir encore plus, il a décidé d'être lui même les effets de lumière en portant un t-shirt agrémenté de led's réagissant au son mixé par Thibault.
Ainsi, Thibault n'en est que plus satisfait de sa prestation.
Procédé d'utilisation
L'utilisateur souhaite s'équiper de l'assortiment de LEDs. Pour ce faire, il branche les 2 connecteurs USB sur la batterie externe afin d'alimenter l'Arduino et le circuit électronique. Il enfile le harnais de poitrine au dessus d'un t-shirt et remet par dessus un autre t-shirt. Puis, il se connecte avec son smartphone Android à l'Arduino grâce à la communication Bluetooth. A partir de ce moment, l'utilisateur peut décider des modes qu'il souhaite afficher. Lorsqu'il décidera d'enlever l'équipement, il procédera aux mêmes étapes à l'envers, et pourra laver ses vêtements personnels. Enfin, pour une utilisation de longue durée, l'utilisateur devra recharger sa batterie externe au maximum pour profiter pleinement des animations lumineuses.
Réponses aux questions difficiles
- Quels moyens d'affichage existent-ils et lequel choisirez-vous ?
Il existe différents types d'affichage tels que des rubans leds, des écrans "flexible" à leds, des écrans rigides à leds. Dans notre projet, nous avons décidé de construire une matrice de leds à partir de rubans leds. Ce choix est détaillé dans la partie "Réalisation du Projet - Projet S6 - Semaine 5 à 8".
- Comment allez-vous procéder à la communication entre les modules ?
La communication sera filaire pour les modules présents sur le harnais de poitrine, puis sera piloter depuis un smartphone grâce à un module bluetooth pour contrôler le mode des animations.
- Quelle est la puissance requise pour votre conception ?
Nous savons qu'une led consomme à pleine luminosité 60 mA (20 mA par émission de couleur (Rouge, Vert, Bleu)) sous une tension de 5V. Ce qui donne une puissance de 0,06*5=0,3W pour un total de 0,3*144=43,2W. Cette puissance est évidemment très élevée et nécessite les pires conditions d'utilisation tels que l'allumage de toutes les leds en blanc avec la luminosité au maximum. Pour palier ce problème, nous limiterons la luminosité des leds à 10% de ses capacités maximales pour une utilisation standard, ce qui offre une expérience utilisateur toujours agréable. Egalement, nous serons rarement dans le cas où toutes les leds sont allumées au même moment.
- Quelle est la puissance de calcul nécessaire au fonctionnement de votre matrice de leds ?
Les programmes de pilotage de LEDs sont volumineux, pour éviter l'ajout d'un micro-contrôleur externe, nous nous sommes orientés vers une Arduino Mega 2560 offrant un espace de stockage plus conséquent. Voici un tableau comparatif entre deux cartes Arduino.
Carte | SRAM | EEPROM | Flash |
---|---|---|---|
Uno | 2Ko | 1Ko | 32Ko |
Mega 2560 | 8Ko | 4Ko | 256Ko |
- Comment comptez-vous rendre votre pull lavable ?
Nous collerons les leds sur un harnais de poitrine pouvant s'enfiler sous un vêtement pour que le système ne soit pas fixé à un vêtement. De cette manière, notre système n'empêche pas le lavage, et permet d'être utilisé sous différents vêtements.
Bibliographie et webographie
Sites web des concurrents:
Préparation du projet
Cahier des charges du groupe
Les différents points que nous souhaitons aboutir dans notre projet sont les suivants. Nous voulons des modules de LEDs modulables grâce à un harnais de poitrine (équipé de scratch) posé en dessous du t-shirt. Notre produit doit être simple d'utilisation et agréable (léger, souple) à porter pour le particulier. Il doit également être rechargeable et lavable. Les câbles et circuits électroniques doivent être résistants aux chocs et sans danger (court-circuit par exemple). L'extension doit avoir une autonomie d'au minimum 2 heures. La matrice de LEDs située sur le torse pourra comprendre plusieurs animations (égaliseur audio, drapeaux de pays, morpion ou autre mini-jeux, ...).
Cahier des charges des équipes
Equipe principale
Dû au départ de Baptiste GIBARU pour sa préparation militaire, le projet se composera d'une équipe principale, comprenant Robin COUBELLE et Quentin BARGIBANT. Par conséquent, le "Cahier des charges du groupe" est le "Cahier des charges de l'équipe principale".
Choix techniques : matériel et logiciel
Equipe principale
Le matériel nécessaire à la réalisation du prototype est le suivant :
- 1 Arduino Mega 2560; les pixels seront gourmand en RAM, par conséquent l’utilisation de l’Arduino Uno sera par exemple limitée à 150 LEDs.
- 1 Batterie externe (Varta Power Bank 57960); capable de délivrer 5V 2400mA et d’une capacité de 6000mAh, qui comporte 2 entrées USB pour alimenter la carte et les LEDs.
- 1 Bandeau de LEDs (Adafruit NeoPixel Digital RGBW LED Strip - Black PCB 144 LED/m - 1m).
- 1 capacité 1000 µF, 6.3V ou plus; entre les bornes + et – qui alimenteront le circuit électronique. Cela protège les NéoPixels des dommages du "torrent initial" de courant.
- 1 résistance 470 Ohms; entre la broche de donnée du microcontrôleur et l'entrée de donnée NéoPixels ("data input") sur le ruban NéoPixel pour prévenir des pointes de tensions sur la ligne de donnée qui pourrait endommager le premier Pixel.
- 1 microphone (Adafruit MAX4466) ; pour l’égaliseur audio.
- 1 module Bluetooth (HC-05) ; pour la communication smartphone-arduino.
- 1 harnais de poitrine qui sera conçu en IMA4.
- Un multimètre pour faire des mesures de courant et de tension.
Les logiciels utilisés seront :
- Arduino IDE pour la programmation de la carte électronique.
- Fritzing pour les schémas de câblage.
- Bluetooth Terminal est une application Android permettant de communiquer entre smartphone et un module Bluetooth.
- MIT App Inventor 2 pour l'application Android développé en IMA4.
Liste des tâches à effectuer
Equipe principale
La liste des tâches à effectuer est énumérée dans le diagramme qui suit.
Calendrier prévisionnel
Veuillez trouver ci-dessous le calendrier prévisionnel sous la forme d'un diagramme de GANTT créé à partir du logiciel MindView.
Equipe principale
Update : 01/06/2019
Réalisation du Projet
Projet S6
Semaine 5 à 8
Modèle envisagé
Nous avons décidé d'appuyer certains aspects de notre projet, qui en feront ses points forts:
- Premièrement, notre vêtement sera composé de plusieurs modules d'animations: un module principal destiné à se situer au centre du vêtement, et deux modules plus petits, destinés à se trouver sur les cotés du vêtement (épaules par exemple). Ces modules d'animations seront alimentés par une batterie, et contrôlés par un microcontrôleur, situés tout deux au niveau de la nuque (ou sous forme de sac/sacoche) de l'usager, ce qui nous semble être le plus pratique (dans le cas où l'utilisateur s'assied, l'électronique n'est pas touché).
- Deuxièmement, notre projet sera de type "Plug&Play", nous voulons mettre en avant le fait que le vêtement soit totalement modulable, aussi bien au niveau des animations qu'au niveau du placement de ces dernières. Pour ce faire, le vêtement sera orné de scratch à plusieurs niveaux, permettant de changer la position des modules.
- Dernièrement le confort nous semble être un point primordial, nous avons donc décidé que le projet ne se situera pas à même le vêtement, mais il sera placé sur un harnais de poitrine, placé sous le vêtement à éclairer, et qui nous permettra d'éclairer n'importe quel vêtement assez fin pour faire passer la lumière.
Trois différentes possibilités s'offrent à nous pour réaliser ce projet: les matrice de leds, les circuits imprimés ainsi que les bandeaux leds.
- Matrice de leds
Les matrices de leds souple nous paraissent être une solution envisageable pour notre projet: elles permettent de programmer facilement des animations poussées, en commandant chacune des led de la matrice. Le rendu visuel nous parait être le meilleur.
Il existe différentes types de matrices, et différentes tailles, ce qui nous permettrait de choisir un module principal et plusieurs modules complémentaires facilement.
Cependant travailler avec des matrices de leds adressable une par une nous confronte à un gros problème: la gestion de la puissance utilisée par notre système. En effet, en prévoyant de coller 3 matrices sur le harnais de poitrine, utiliser chaque led à sa luminosité maximale et en couleur blanche nous oblige à fournir quasiment 9A au système, ce qui est impossible.
Un second inconvénient des matrices de leds souples, est la rigidité, la matrice est flexible mais nécessite une pression plutôt forte pour être plier, utiliser cette technologie réduira fortement le confort de notre produit pour l'utilisateur.
Module principal possible: Matrice 16x16
Module complémentaire possible: Matrice 8x8
- Circuits imprimés
Les circuits imprimés comportant des leds sont également une possibilité pour notre projet, elles permettent d'utiliser beaucoup moins de puissance que les deux autres technologies. Cette technologie nous a été conseillé par les enseignants pour son énorme gain d'énergie (notamment si l'on multiplexait les leds).
Cependant, l'objectif de notre projet est de fabriquer un vêtement lumineux, nous avons pensé que les principales contraintes était le confort d'utilisation ainsi que le rendu visuel du projet (qui est subjectif). Les PCB possèdent trop de défauts pour notre projet: premièrement la rigidité de la carte empêche le confort de l'usager lorsqu'il utilise le vêtement. Dans un second temps, les leds multiplexées proposent trop peu d'animations. Nous avons donc préféré ne pas utiliser cette technologie dans notre projet.
- Bandeaux leds
La dernière technologie que nous avons envisagé d'utiliser sont les bandeaux de leds, ils existent de nombreux bandeaux, de plusieurs tailles et d'un nombre de leds différents. Le fonctionnement des bandeaux ressemble à celui des matrices, chaque led est adressable, ce qui nous permet de créer un nombre quasi-illimité d'animations.
Les bandeaux ont deux avantages par rapport aux matrices:
- Premièrement, les bandeaux peuvent être coupés, cela nous permet d'avoir des modules modifiables, au niveau de la forme ou de la longueur par exemple.
- Deuxièmement les bandeaux sont plus souples que les matrices, et permettent un confort excellent pour l'utilisateur.
Nous rencontrerons deux difficultés en utilisant les bandeaux:
- En les coupant, nos modules seront plus fragiles qu'une matrice ou qu'un circuit imprimé.
- Le système pourra demander une grande puissance selon les animations demandées si la luminosité est mal gérée (explication à la 3ème question difficile).
Semaine 9
Après avoir étudié les différents avantages et inconvénients de chaque possibilité, notre groupe a décidé d'utiliser les bandeaux leds pour réaliser le harnais de poitrine lumineux. Ce choix a été fait pour optimiser la modulation et les animations de notre projet, il faudra donc faire attention à la possible fragilité des bandeaux lorsqu'on les séparera en plusieurs morceaux.
Après avoir choisi notre technologie, nous avons tout d'abord préparé les modules principaux, indispensable au projet et qui nous serviront pour la réalisation de notre prototype. Trois modules seront donc réalisés en priorité:
- L'alimentation et le microcontrôleur.
- Le module d'animation principal, situé généralement sur le torse du harnais.
- Le microphone.
A ces trois modules, il sera ajouté un module bluetooth, qui connectera le système à un téléphone. Nous allons créer une application (MIT App Inventor 2), pour le prototype nous nous limiterons à un terminal Android bluetooth, permettant à l'usager de choisir les animations sur son vêtement, et potentiellement une interaction pour des mini-jeux par exemple.
Pour créer les différentes animations sous Arduino, nous utiliserons 3 bibliothèques: Adafruit GFX Library, Adafruit NeoPixel, Adafruit NeoMatrix. Ces bibliothèques nous permettent de définir notre bandeau led (sous forme de matrice ou non) et de gérer facilement l'affichage led par led. Pour prendre en main la programmation du bandeau led, nous utiliserons les différents programmes de test présents dans les librairies, et nous les modifierons pour comprendre chaque fonction utilisée.
Semaine 10
Nous avons réalisé le schéma de câblage permettant la bonne utilisation de nos modules. Puis, nous avons commencé à mettre en place des programmes pour tester indépendamment chaque module.
Remarque: L'alimentation de la carte Arduino est bien fourni par la batterie portable qui comprend 2 ports USB.
Semaine 11
Nous avons commencé cette semaine en mesurant la demande en courant de notre bandeau, en fonction du nombre de leds, de l'intensité lumineuse et de la couleur demandée. Nous avons obtenu les résultats suivants:
- Mesures sur un programme d'exemple (strandtest) fourni par une des librairies utilisées, sur 144 LEDs.
Luminosité (0 à 255) | Mode clignotement | Mode multicouleurs | Une couleur R/G/B au max |
---|---|---|---|
25 | 0,15A | 0,33A | Pas mesuré |
155 | 0,3A | 1,40A | 1,13A |
255 | 0,84A | 2,24A | 1,80A |
- Mesures de l'intensité avec la couleur "blanc", couleur demandant le plus de courant, sur un nombre de LEDs variables.
Luminosité (0 à 255) | 10 LEDs | 20 LEDs | 144 LEDs |
---|---|---|---|
10 | 0,15A | 0,16A | 0,32A |
25 | 0,17A | 0,20A | 0,60A |
145 | 0,31A | 0,52A | 2,80A |
255 | 0,46A | 0,81A | Pas assez de courant délivré |
Remarque: Circuit alimenté avec sur le bandeau une seule LED blanche allumée consomme 0,13A.
Il faut également noter que l'intensité lumineuse maximale est utile uniquement si le bandeau est exposé au soleil, ce qui ne sera pas notre cas, car notre produit sera utilisé principalement lors de soirée, quand il fera sombre ou noir. L'intensité maximale ne sera donc quasiment jamais utilisée car elle sera désagréable à observer.
Les résultats nous montrent ce que le fabricant nous avait indiqué: le bandeau est très gourmand en énergie à pleine puissance. Cependant nous sommes satisfait du rendu à très faible intensité lumineuse (10% de l'intensité maximale est déjà très visible à travers un tissu fin), et étant donné que les animations allumeront les leds à tour de rôle, le courant demandé nous semble correct. Pour éviter toute demande d'énergie excessive, nous avons décidé qu'au début de chaque fonction correspondant à une animation, le niveau de luminosité sera ajusté en fonction du courant maximal demandé par l'animation (et du rendu désiré en second lieu).
Nous avons également écrit nos premiers programmes d'animations ayant un rendu visuel en lignes et/ou en colonnes, certains n'ont pas pu être testés correctement sur le bandeau, étant donné qu'il n'était pas encore sous forme matricielle. Les premiers programmes interagissent avec le micro, ils correspondent aux animations d'égaliseur lignes et colonnes.
Semaine 12
Nous avons choisi de découper notre bandeau en une matrice 24*6, pour avoir des possibilités sur la hauteur (6 pixels) et garder une certaine longueur pour pouvoir moduler à nouveau notre bandeau si nous le désirons.
Durant la soudure, nous avons rencontré un problème car les pin du bandeau sont extrêmement petits, ce qui ne nous permettait pas de mettre assez d'étain sur chaque fil rendant la soudure fragile. Pour palier à ce problème nous utiliserons des barrettes, qui permettront aux trois fils d'être reliés physiquement entre eux (pas électriquement) et qui permettront d'être soudé en trois points, réduisant la fragilité rencontrée précédemment.
Nous avons également rendu la connexion Bluetooth smarpthone-Arduino opérationnelle.
Voici par exemple un simple code pour montrer que toutes les LEDs fonctionnent.
if(message == "fr"){ matrix.clear(); for (int i=0;i<8;i++){ for (int j=0; j<lignes; j++){ matrix.drawPixel(i,j,colors[0]); //colors[0] représente le rouge } } for (int i=8;i<16;i++){ for (int j=0; j<lignes; j++){ matrix.drawPixel(i,j,colors[12]); //colors[12] représente le blanc } } for (int i=16;i<24;i++){ for (int j=0; j<lignes; j++){ matrix.drawPixel(i,j,colors[8]); //colors[8] représente le bleu } } matrix.show(); }
Prototype
Voici un exemple d'utilisation de l'égaliseur dans un environnement sonore sur notre prototype final du S6, avec un tissu au-dessus de la matrice de LEDs.
Documents Rendus
- Rapport de projet : Fichier:P23 Rapport S6.pdf
- Diaporama soutenance : Fichier:P23 Projet LEDs diapo.pdf
- Programme S6 : Fichier:P23 Version S6.zip
Remarques suite à la soutenance
Suite à la soutenance de fin de semestre 6, les encadrants nous ont évoqués de potentiels problèmes, ainsi que de potentielles améliorations que nous devrons étudier:
- La dissipation de chaleur du système, qui sera directement ressenti par l'utilisateur.
- Le développement d'animations par l'utilisateur, pour lui permettre de personnaliser encore plus son produit.
- L'utilisation de petits écrans pour les modules complémentaires.
- La conception du PCB et la révision de notre microcontrôleur.
Projet S7
Préparation du projet
Réorganisation du projet
Suite aux remarques qui ont été faites lors de la soutenance du S6, nous avons fait un travail de reformulation de notre projet.
Entre temps, nous avons intégré Stephen Andriambolisoa et Simon Lecoutère dans notre groupe. Cela nous permettra de pousser davantages nos recherches et ainsi fournir un contenu plus abondant.
Nouveau cahier des charges
L'objectif principal de notre projet est de créer un support lumineux pouvant être porté sous un vêtement, réagissant aux sons audibles environnementaux.
Ainsi, plusieurs contraintes s'imposent pour ce projet, notamment suite aux remarques des professeurs:
- Faire réagir un certain nombre de LEDS en fonction de la fréquence écoutée en entrée ;
- Amoindrir la consommation énergétique de notre système: soit limiter la dissipation de chaleur ;
- Amoindrir le poids total du système pour pouvoir le porter sur une longue durée: soit limiter le nombre de composants.
Pistes
Après quelques réunions, nous nous sommes concertés pour diviser ce projet en deux parties. D'une part, nous voulons explorer les pistes envisageables avec un FPGA, plus rapide et plus puissant, et d'autre part, assurer la réalisation de notre matrice de leds en concevant une carte PCB. C'est pour cela que nous créerons deux équipes pour essayer de réaliser les deux versions du projet, l'équipe 1 assurera la réalisation via un micro-contrôleur alors que la seconde équipe approfondira le sujet via le FPGA.
Équipe 1 (Microcontrôleur) | Équipe 2 (FPGA) |
---|---|
Quentin Robin |
Stephen Simon |
Recherches FPGA
Choix fenêtre : pas besoin d'une fenêtre de fréquences précise
Choix gestion du bruit : attention il faut un traitement instantané (pas forcément précis)
Principe
Le but principal du projet cette année est de récupérer le signal d'un enregistrement audio pour représenter sa gamme de fréquences échantillonnées sur des matrices de LEDs.
Dans un premier temps, à l'aide d'un CAN (convertisseur analogique - numérique), nous allons échantillonner le signal récupéré.
Par la suite, ce qui représentera l'étape la plus importante, à l'aide d'un FPGA nous nous sommes intéressé à la conception d'un algorithme de FFT sur notre signal échantillonné.
A partir des spectres obtenus, on sépare les différentes raies en plage de fréquences pour ensuite additionner les amplitudes de toutes les raies de chaque plage.
Grâce aux amplitudes obtenues, on pense utiliser un microcontrôleur pour gérer les matrices de LEDs via une liaison série en adaptant le nombre de LEDs allumées en fonction de l'amplitude des différentes plages.
Faisabilité
Utiliser un FPGA permet d'effectuer les calculs de FFT en parallèle, ce qui améliore le rendu de notre projet en temps réel.
Cependant, la complexité du langage de programmation VHDL ainsi que le manque de ressources nous ont pris beaucoup de temps et n'ont pas permis de simuler notre premier programme.
De plus, la consommation énergétique d'un FPGA est également trop élevée pour pouvoir l'utiliser dans un projet de wearable electronics. Un des points de notre cahier des charges n'est donc pas respecté. Nous allons tout de même nous lancer pour le point pédagogique et la curiosité. Nous pourrons préalablement trouver une solution plus tard.
Choix du CAN
D'après la référence inscrite sur notre microphone, nous avons le GY-MAX4466 illustré ci-dessous :
Certains points de sa datasheet nous seront utiles pour notre projet :
Un potentiomètre est situé au dos du microphone pour ajuster le gain de 25x a 125x. Il peut délivrer entre 200mVpp et 1Vpp, ce qui semble parfait pour lire à partir d'un ADC. Avec un son fort, on peut atteindre les 5Vpp.
Après quelques recherches grâce au site analog.com, nous avons pu choisir le CAN LTC1420CGN#PBF adapté à notre projet. On peut retrouver ses caractéristiques ci-dessous :
Nombre de chaînes | Résolution | Taux d'échantillonnage | Intervalle de tension d'entrée (Vpp) | Puissance dissipée | Prix |
---|---|---|---|---|---|
1 | 12 bits | 10Msps | 4,096Vpp | 250mW | ~7USD |
Pourquoi ce choix?
Nous avons qu'une seule entrée à traiter avec notre microphone donc nous n'aurons besoin que d'une seule chaîne. De plus, ce convertisseur fait partie de la catégorie des "High speed ADC finder" (10Msps). Ceci nous permettra de faire du traitement en temps réel et d'échantillonner de manière plutôt précise le signal d'entrée (avec un taux élevé). Sachant que nous avons un microphone qui génère un signal entre 0 et 5V, le choix des 4,096Vpp était le meilleur compte tenu du prix et de la puissance dissipée par le CAN. En effet, pour du wearable electronic il faudra dissiper le moins de chaleur possible (donc puissance) mais convertir le plus de données possibles à faible coût.
Choix du FPGA
Pour le choix du FPGA, nous avons opté pour un Altera, EP4CE15E22C8N, Cyclone IV E.
Ce FPGA offre un bon compromis entre un prix raisonnable et une performance correcte. En effet, Il possède un DSP dédié pour effectuer des calculs complexes et être combiné avec le CAN que nous allons utiliser et également un nombre d'éléments logiques de 15 000.
De plus, il possède une RAM de 504Kbit, ce qui nous paraît suffisant pour contenir les programmes de FFT.
Voici ci-dessous les caractéristiques du FPGA, Altera, EP4CE15E22C8N, Cyclone IV E que nous avons choisi pour notre projet :
Nombre de cellules logiques | Nombre de multiplieurs | Nombre de bits de RAM | Prix |
---|---|---|---|
15408 | 56 (18 x 18) | 504 Kbits | ~23€ |
HardWare
Gestion du bruit
Réalisation par microcontrôleur
Choix du microcontrôleur
Nous utiliserons le microcontrôleur ATMEGA328P-PU pour notre projet. Le nombre d'entrées/sorties du microcontrôleur est suffisant pour notre application.
La version PU de l'ATMEGA328P nous permettra d'implanter du nouveau code si nécessaire et ceci plus facilement contrairement à la version AU même si cette dernière propose une taille réduite.
Analyseur spectral
Notre signal sonore sera récupéré par le microphone utilisé au Semestre 6, on traitera alors ce signal avant d'envoyer la donnée à utiliser au microcontrôleur.
La solution envisagée pour réaliser le traitement de signal est l'utilisation de circuits passe-bandes. A différentes bandes passantes comprises dans les fréquences audibles, nous identifierons le pic de fréquence maximal, et nous l'utiliserons pour notre analyseur spectral. Nous voulions utiliser des filtres passe-bande actifs comme ci-dessous, en parallèle pour chaque plage de fréquences.
Il s'agit là d'un filtre passe-bas en cascade avec un filtre passe-haut. Le but était de retrouver les fréquences de coupures de chaque filtre pour en tirer une plage de fréquences. Il aurait fallu dimensionner chaque filtre passe-bande pour finalement avoir un circuit qui traite notre signal audio d'entrée. Cependant, avec ce schéma il nous aurait fallu 14 AOP pour 7 plages de fréquences (définies et pouvant être modifiées grâce à des résistances variables). La carte électronique serait assez grande et moins confortable à porter par conséquence.
L'utilisation de notre analyseur spectrale ne nécessite pas une précision extrême, et nous sera utile uniquement dans le domaine du visible: l'analyseur affichera les fréquences de la musique entendue par l'utilisateur. Pour cette raison les filtres passe-bandes peuvent être fixé dans le domaine audible. On utilisera alors un composant électronique composé de 7 passe-bandes: le MSGEQ7.
Le circuit d'égalisation graphique à sept bandes est une puce CMOS qui divise le spectre audio en sept bandes: 63Hz, 160Hz, 400Hz, 1kHz, 2,5kHz, 6,25kHz et 16kHz. Les sept fréquences sont détectées en crête et multiplexées à la sortie pour fournir une représentation en courant continu de l'amplitude de chaque bande. Aucun composant externe n'est nécessaire pour sélectionner les réponses des filtres. Seule une résistance et un condensateur hors puce sont nécessaires pour sélectionner la fréquence de l'oscillateur d'horloge sur puce. Les fréquences centrales du filtre suivent cette fréquence.
Alimentation du circuit
Notre projet sera toujours alimenté par une batterie externe possédant 2 sorties. Une sortie alimentera la carte et donc le microcontrôleur, l'autre alimentera les LEDs, qui consomment la plupart de l'énergie de notre système.
L'utilisation des batteries externes permet d'avoir une autonomie correcte (pas encore calculée), et permet une utilisation constante du produit si l'utilisateur possède une seconde batterie avec lui.
Panneau leds / module bluetooth / microphone
Concernant le panneau leds, nous allons exploiter celui utilisé lors du S6. Des extensions de modules de leds seront par la suite design pour venir s'ajouter à la tenue générale, par exemple au niveau des épaules.
Le module bluteooth HC05 sera repris et le microphone MAX4466 également. Sur le PCB il sera intéressant de venir enficher ces deux éléments. Le microphone pourra être connecté grâce à des fils électriques permettant de le placer à un endroit stratégique sous le vêtement de l'utilisateur afin de récupérer un son de bonne qualité (vers le haut du corps), tout en pouvant isoler la carte électronique (dans la ceinture corps par exemple).
Schéma électronique et PCB
Schéma électronique
Le schéma électronique est le suivant, il contient tout les éléments que nous allons utiliser:
Nous pouvons diviser notre schéma électronique en quatre sous-parties ayant chacune une fonction précise:
Sous circuit 1 |
Sous circuit 2 |
Sous circuit 3 |
Sous circuit 4 |
Sous-circuit 1
Notre premier sous-circuit correspond à l'arrivée de notre alimentation. Nous avons décidé d'utiliser une entrée micro-USB pour alimenter notre circuit, pour utiliser une entrée de taille plus petite. Nous utilisons un régulateur de tension pour notre Vcc et d'être sur d'avoir 5V constamment. Les capacités d'entrée et de sortie du régulateur ont été choisies en fonction des conseils de la datasheet du composant.
Sous-circuit 2
Le second sous-circuit correspond à l'entrée de notre microphone. Nous utilisons le même microphone qu'au semestre précédent, il ne sera pas directement implanté sur la carte, et sera relié de façon filaire, pour être placé au plus proche de l'oreille de l'utilisateur, pour que le rendu corresponde au mieux à ce que l'utilisateur entend. L'entrée du microphone est ensuite traitée par le composant MSGEQ7, qui nous donnera la valeur des pics de fréquences dans différentes bandes de fréquences. Ce composant est relié à notre microcontrôleur par trois liaisons analogiques, qui nous permettront de communiquer les fréquences demandées au composant puis de les recevoir.
Sous-circuit 3
Le troisième sous-circuit correspond à la sortie vers notre panneau de led, il ne sera pas relié à la carte tout comme le micro, mais sera relié également de façon filaire. Nous avons choisi d'installer une entrée d'alimentation différente de celle du reste du circuit pour ne pas imposer un courant trop fort (que les LED nécessitent) au circuit global.
Sous-circuit 4
Le dernier sous-circuit est simplement le module bluetooth que nous avons déjà utilisé au S6, les broches de communication série sont reliés au microcontrôleur.
Routage
Voici une vue d'ensemble du PCB. Cette version comprend des erreurs de "Design Rule" à cause du design de certains composants, mais n'impact pas le fonctionnement de la carte (demander l'avis avant de renoncer à cette violation de règle).
Voici une vue 3D de notre carte électronique cependant cette dernière n'est pas complète. En effet, il faudra modifier le nom des composants (nom court et sur la plaque), de plus certains composants n'ont pas de modèle 3D (ici les 3 female headers de 3, 4 et 6 pin; et le filtre passe-bande IC2), le modèle 3D des entrées USB est mal positionnée mais son empreinte est correct (et repositionner correctement l'empreinte sur le PCB (mauvaise ici à cause du modèle 3D que l'on a voulu bien placé)).
Liste des composants
Description | Fabricant | Référence fab | Empreinte | Désignation carte | Quantité | réf Mouser | réf Farnell | Prix unitaire |
---|---|---|---|---|---|---|---|---|
Résistances CMS | 3 | |||||||
22 kΩ | J1-0603 | R1 | 1 | |||||
200 kΩ | J1-0603 | R2 | 1 | |||||
470 Ω | J1-0603 | R3 | 1 | |||||
Capacités CMS | 6 | |||||||
100 nF | C1206 | C1, C4 | 2 | |||||
2.2 uF | C1206 | C2 | 1 | |||||
10 nF | C1206 | C3 | 1 | |||||
33 pF | C1206 | C5 | 1 | |||||
1000 uF | C1206 | C6 | 1 | |||||
Semiconducteurs | 3 | |||||||
Microcontrôleurs 8 bits - MCU 32KB In-system Flash 20MHz 1.8V-5.5V | Microchip Technology / Atmel | ATMEGA328P-PU | DIP794W53P254L3467H457Q28N | microcontroleur | 1 | 556-ATMEGA328P-PU | 1,87 | |
Régulateur de tension | STMicroelectronics | KF50BD-TR | SOIC127P600X175-8N | Regulateur-tension | 1 | 511-KF50BD-TR | 0,801 | |
Seven Band Graphic Equalizer Display Filter | SparkFun | COM-10468 | *SOIC8 | MSGEQ7 | 1 | 474-COM-10468 | 4,46 | |
Miscellaneous / Divers | 5 | |||||||
Connecteurs USB MICRO USB B RECPT BTTM MOUNT ASSY | Molex | 47346-0001 | 47346-0001 | uUSB_alim-leds, uUSB_alim-controle | 2 | 538-47346-0001 | 0,855 | |
Embases et logements de câbles 3 WAY SIL HORIZ SMT SKT T&R | Harwin | M20-7910342R | M207910342R | pin-microphone_MAX4466 | 1 | 855-M20-7910342R | 0,72 | |
Embases et logements de câbles 4 WAY SIL HORIZ SMT SKT T&R | Harwin | M20-7910442R | M207910442R | pin_bandeaux-leds | 1 | 855-M20-7910442R | 0,774 | |
Embases et logements de câbles 6 WAY SIL HORIZ SMT SKT T&R | Harwin | M20-7910642R | M20-7910642R | pin-Bluetooth_HC05 | 1 | 855-M20-7910642R | 0,891 | |
Déjà possédé | ||||||||
Microphone MAX4466 | ||||||||
Bluetooth HC05 | ||||||||
Batterie externe 2 ports USB | ||||||||
2 câbles USB vers microUSB |
Les résistances et les condensateurs n'ont pas de fournisseurs puisqu'elles nécessitent un achat par lot de composant et qu'elles sont peut-être déjà disponibles à l'école.
Un projet similaire sur un panneau LCD.
Comment programmer sur le micro-contrôleur ATmega328P-PU.
Projet S8
Remise à zéro
Suite aux remarques de la soutenance intermédiaire de projet, notre groupe a décidé d'abandonner la gestion des LEDs via l'utilisation du microcontrôleur, pour nous diriger vers la réalisation d'une carte électronique comportant comme élément principal un FPGA. Ce dernier sera accompagné d'un ensemble de composants permettant au premier abord la réception d'un son (microphone), suivi d'une conversion analogique-numérique (CAN) pour pouvoir traiter le signal au sein du FPGA. Il effectuera des FFT dans le but de déterminer les fréquences audibles (ou non) du signal sonore reçu. L'objectif sera d'afficher sur une matrice de LEDs découpée en plusieurs rangées de fréquences l'intensité des amplitudes perçues, pour obtenir comme résultat un fréquencemètre audio. Ceci sera possible grâce à la création en VHDL des protocoles existant pour communiquer avec la matrice de LEDs dans ce cas précis. De plus, un module Bluetooth permettra à l'utilisateur de personnaliser et de contrôler son utilisation par le biais d'une application Android.
Liste de composants
Premier choix de technologie
Les choix des composants présentés dans les deux paragraphes suivants ont été abandonnés, en effet, nous ne pouvons pas souder les FPGA de série 7 Xilinx avec le matériel qui est à notre disposition.
Choix du FPGA
Beaucoup de FPGA sont disponibles sur le marché et nous avons peu de connaissances sur les caractéristiques importantes d'un FPGA. En décidant d'utiliser en premier lieu un module VHDL pour effectuer la FFT, nous avons récupéré de la documentation qui nous a permis d'axer notre choix sur les FPGA Xilinx de série 7.
Xilinx fournit également des informations concernant les ressources utilisées par le module. En considérant que notre application ne nécessite pas une FFT supérieure à plus de 512 points, et que nos utilisations ne semblent pas très gourmandes en ressources, un FPGA "bas de gamme" se présente une bonne solution. Ne connaissant pas les nécessités de la gestion des LEDs dans le FPGA (composition et transmission en série d'une trame de 4608 bits) et du traitement du bluetooth, nous allons concerter un encadrant pour recevoir son avis. Pour le moment, nous avons décidé d'utiliser un FPGA Artix-7, sur lequel les ressources seront forcément suffisantes.
Choix de la mémoire de programme
La documentation concernant les FPGA de série 7 Xilinx nous donne la longueur des bitstreams selon chaque FPGA (Table 1-1), notre mémoire doit être supérieure à la longueur du bitstream produit pour notre FPGA (soit 32Mbits minimum).
Les documents Using SPI Flash ainsi que les schémas de câblages de boards telle la Cmod A7 seront nos sources d'inspiration pour le câblage et la configuration de notre mémoire de programme.
Rectification
Choix du FPGA
Pour pouvoir souder notre FPGA sur notre carte, nous nous sommes tournés vers les FPGA plus anciens de Xilinx, les Spartan-3 peuvent être soudés. Nous avons choisi le XC3S500E-4VQG100C qui fait parti des Spartan-3E.
Pour la réalisation du schematic, nous nous inspirerons de différentes boards existantes, et notamment la board Xilinx Open3S500E, qui utilise le même FPGA que le nôtre.
Récapitulatif
Composants | Fournisseurs | Fabricants | Références fab | URL | Commentaires |
---|---|---|---|---|---|
FPGA | Mouser | Xilinx | XC3S500E-4VQG100C | XC3S500E-4VQG100C | / |
SPI Flash | Mouser | Xilinx | XCF04SVOG20C | XCF04SVOG20C | Minimum 4Mb data |
Horloge | Mouser | CTS Electronic Components | CB3LV-3I-100M0000 | CB3LV-3I-100M0000 | / |
Bluetooth | / | / | / | HC05 | Déjà possédé |
Microphone | / | Adafruit | MAX4466 | MAX4466 | Déjà possédé |
CAN | Mouser | Texas Instruments | ADS7868IDBVR | ADS7868IDBVR | / |
port microUSB | / | / | / | / | Pour alimenter la carte |
Remarque : Pas besoin de mémoires RAM et ROM externes car nous n'utiliserons pas de logiciels sur notre FPGA. La mémoire interne du processeur devrait suffire pour l'utilisation/exécution de nos codes.
Pour la liste des composants du USB to JTAG, voir la section "Semaines 5 à 7 - 10/02".
La liste d'achats est la suivante pour un prototype complet : Fichier:P23-Mouser-Commande1prototype.pdf. Nous avons doublé les composants en cas de mauvais montage (sauf pour l'embrasse de 14 pin), la liste devient : Fichier:P23-Mouser-CommandeDoublée.pdf
Avancées du projet
Gestion des Leds avec FPGA
L'objectif de cette partie sera de récupérer en entrée le résultat de la FFT. Nous aurons des amplitudes selon les fréquences émises par le son en entrée, puis nous devrons utiliser le FPGA pour savoir quelles leds allumer en sortie.
Premier test
Dans un premier temps, nous voulions simplement gérer l'allumage d'une seule LED. Pour se faire, nous avons opéré le code suivant :
library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity LEDS is generic ( N : INTEGER := 8 ); Port ( clk : in STD_LOGIC; enable : in STD_LOGIC; red : in STD_LOGIC_VECTOR (N-1 downto 0); green : in STD_LOGIC_VECTOR (N-1 downto 0); blue : in STD_LOGIC_VECTOR (N-1 downto 0); white : in STD_LOGIC_VECTOR (N-1 downto 0); full_frame : out STD_LOGIC); end LED1; architecture Behavioral of LED1 is signal frame_bit : STD_LOGIC := '0'; signal lancement, cpt : integer := 0; signal trame : STD_LOGIC_VECTOR(4*N-1 downto 0);
Parmi les paramètres d'entrée : enable permet d'autoriser la led à réagir à la trame d'entrée et donc de s'allumer. On peut le comparer à un top départ, soit au signal sortant de la FFT de notre projet. Le protocole SK6812 indique, page 6, que chaque LED Adafruit pourra s'allumer suivant une structure de 32 bits : soit les 4 entrées de 8 bits red, green, blue et white.
Enfin, en sortie nous avons la full_frame qui doit représenter la trame de 32 bits.
Nous verrons dans la partie 2 l'utilité de nos signaux internes :
begin process(clk) begin if rising_edge(enable) and lancement=0 then lancement <= 1; cpt <= 4*N-1; end if; if lancement=1 and rising_edge(clk) then frame_bit <= trame(cpt); cpt <= cpt - 1; end if; if cpt<0 then cpt <= 0; lancement <= 0; end if; if lancement=0 then frame_bit <= '0'; end if; end process; full_frame <= frame_bit; trame <= red & green & blue & white; end Behavioral;
Avant tout, lorsque enable présente un front montant et que lancement vaut 0, on peut lancer le compteur décroissant à partir de 4*N-1 (soit 32). La trame est la structure de 32 bits d'une LED. La stratégie consiste donc à récupérer chaque bit de la trame dans frame_bit au rythme du compteur. Au final, c'est la sortie full_frame qui prendra la valeur de frame_bit bit par bit.
Code de la simulation :
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; entity LEDS_tb is -- Port ( ); end LEDS_tb; architecture Behavioral of LEDS_tb is component LED1 Port( clk : in STD_LOGIC; enable : in STD_LOGIC; red : in STD_LOGIC_VECTOR (7 downto 0); green : in STD_LOGIC_VECTOR (7 downto 0); blue : in STD_LOGIC_VECTOR (7 downto 0); white : in STD_LOGIC_VECTOR (7 downto 0); full_frame : out STD_LOGIC ); end component; signal clk : STD_LOGIC; signal enable : STD_LOGIC; signal red : STD_LOGIC_VECTOR (7 downto 0); signal green : STD_LOGIC_VECTOR (7 downto 0); signal blue : STD_LOGIC_VECTOR (7 downto 0); signal white : STD_LOGIC_VECTOR (7 downto 0); signal full_frame : STD_LOGIC; begin UUT: LEDS port map (clk => clk, enable => enable, red => red, green => green, blue => blue, white => white, full_frame => full_frame); --Génération d'un signal d'horloge de 800KHz de période 1.25us clk_gen : process begin clk <= '1'; wait for 0.625us; clk <= '0'; wait for 0.625us; end process; --Génération de la mise à 1 de enable enable_gen : process begin enable <= '0'; wait for 112.5us; enable <= '1'; wait for 12.5us; end process; --Génération des valeurs de red red_gen : process begin red <= CONV_STD_LOGIC_VECTOR(255,8); green <= CONV_STD_LOGIC_VECTOR(0,8); blue <= CONV_STD_LOGIC_VECTOR(255,8); white <= CONV_STD_LOGIC_VECTOR(1,8); wait for 1250us; red <= CONV_STD_LOGIC_VECTOR(204, 8); wait for 1250us; red <= CONV_STD_LOGIC_VECTOR(1, 8); wait for 1250us; end process; end Behavioral;
Pour simuler notre code, nous envoyons une trame correspondant à FF 00 FF 01 pour l'allumage d'une LED. En sortie, il faudrait donc que full_frame puisse reproduire le signal pour l'envoyer à une LED.
D'après la simulation ci-dessus, c'est un succès. Cependant, le code n'a pas tout à fait respecté le protocole SK6812, notamment au niveau du reset code. La structure du code nous a quand même servit pour nos prochains tests.
Gestion d'une seule LED
Nous avons ensuite mis en place l'horloge asymétrique décrite dans le protocole SK6812RGBW. Nous avons ensuite simulé notre code et arrivons au résultat attendu: la trame correspond au protocole.
Après avoir adapté le fichier de contraintes de la Basys3 à notre programme, nous avons pu implémenter le programme sur la carte. Nous avons utilisé les 4 premiers switches de la carte pour contrôler les bits de poids forts des couleurs à envoyer (red[7],green[7]...), un des boutons pour contrôler notre signal de départ (enable) et l'horloge de la carte. Tous les bits de poids faibles pour contrôler les LEDS sont programmés en pulldown.
Nous avons pu effectuer deux observations :
- Utiliser les LEDS à la moitié de leur puissance maximale est déjà beaucoup pour le rendu visuel (nous le savions déjà), nous utiliserons alors au maximum les 5 bits de poids faible de notre programme.
- La deuxième LED du bandeau était allumée alors que, selon le protocole, nous ne devions pas lui envoyer d'information. Nous avons alors choisit de vérifier le protocole, et il s'avère qu'il n'est pas celui utilisé par notre bandeau. Notre bandeau de LED communique via un protocole semblable mais pas identique: WS2812B.
Le code précédemment créé a donc été modifié pour respecter le protocole de notre bandeau, après simulation et implémentation sur la carte, nous avons réussi à contrôler l'affichage sur une LED.
Gestion de toutes les LEDs
Maintenant, l'objectif est de pouvoir contrôler l'ensemble de notre panneau de 144 LEDs. Pour rappel, la composition des données 24 bits de la trame d'une LED est la suivante :
G7 G6 G5 G4 G3 G2 G1 G0 R7 R6 R5 R4 R3 R2 R1 B7 B6 B5 B4 B3 B2 B1 B0
Premièrement, nous devons créer une instance de one_LED (VHDL permettant le contrôle d'une LED) dans le composant all_LEDs que nous venons de créer pour la gestion de plusieurs LEDs, afin de pouvoir l'appeler. Les entités de ces 2 composants sont :
entity one_LED is generic( N : INTEGER := 8 ); Port( clk : in STD_LOGIC; --clock de 100MHz reçu enable : in STD_LOGIC; --active l'envoie de la trame red : in STD_LOGIC_VECTOR (N-1 downto 0); --données de l'octet red green : in STD_LOGIC_VECTOR (N-1 downto 0); --données de l'octet green blue : in STD_LOGIC_VECTOR (N-1 downto 0); --données de l'octet blue full_frame : out STD_LOGIC --émission série de la trame ); end one_LED;
entity all_LEDs is generic( Nb_leds: integer := Nb_leds_library --Nombre de LEDs sur notre panneau, "Nb_leds_library" est une variable égale à 144 stocker dans une librairie personnelle ); Port( vec_rgb : in myTab_rgb; --Tableau contenant sur 3 bits l'information RGB pour chaque LED enable_trame_leds : in STD_LOGIC; --Le enable qui autorise l'envoie de la trame sur la sortie physique clk : in STD_LOGIC; --Récepetion de l'horloge de 100MHz trame_leds : out STD_LOGIC --Emission série venant de one_LED pour l'envoyer à une sortie physique ); end all_LEDs;
Pour la gestion des couleurs RGB, la luminosité 255 est trop élevée et consomme plus de courant. Par conséquent, nous allons uniquement utiliser et ne choisir que le bit [5] à mettre à 1 ou 0, cela représentera environ 25% de la luminosité et consommera moins de courant. Nous nous sommes restreints à un choix de couleurs limités (7 couleurs possibles + "1 couleur éteinte") dans le but de diminuer la lourdeur du programme VHDL (soit environ plus de 16 millions de couleurs). Les couleurs choisies sont les suivantes :
En décimal | R | G | B | Couleur |
---|---|---|---|---|
0 | 0 | 0 | 0 | LED éteinte |
1 | 0 | 0 | 1 | bleu |
2 | 0 | 1 | 0 | vert |
3 | 0 | 1 | 1 | cyan |
4 | 1 | 0 | 0 | rouge |
5 | 1 | 0 | 1 | magenta |
6 | 1 | 0 | 1 | jaune |
7 | 1 | 1 | 1 | blanc |
Ce choix est la raison de la création de la variable vec_rgb de type myTab_rgb, ce type a été créé dans myLibrary.vhd et correspond à un tableau de vecteur (extrait ci-dessous).
library IEEE; use IEEE.STD_LOGIC_1164.ALL; package tab_rgb_type is --Notre propre type pour pouvoir l'utiliser dans le "port" de "entity" constant Nb_leds_library: integer := 144+1; --cas général 144, le +1 est présent en raison d'un bug expliqué ultérieurement type myTab_rgb is array(0 to (Nb_leds_library-1)) of std_logic_vector (2 downto 0); --mon tableau end package tab_rgb_type;
La passage à la deuxième étape est effectué une fois les entités all_LEDs et one_LED programmées et testées avec un test bench.
Deuxièmement, l'objectif est d'envoyer une trame complète depuis la Basys3 vers le panneau LEDs. Le visuel choisi sera un égaliseur fixe pour nous donner un premier aperçu. Le visuel est le suivant :
120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 |
119 | 118 | 117 | 116 | 115 | 114 | 113 | 112 | 111 | 110 | 109 | 108 | 107 | 106 | 105 | 104 | 103 | 102 | 101 | 100 | 99 | 98 | 97 | 96 |
72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 |
71 | 70 | 69 | 68 | 67 | 66 | 65 | 64 | 63 | 62 | 61 | 60B | 59B | 58 | 57 | 56 | 55 | 54 | 53 | 52 | 51 | 50 | 49 | 48 |
24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35B | 36B | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 |
23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12B | 11B | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
Nous devons créer une instance de all_LEDs dans le composant equalizer_fixed que nous venons de créer pour la gestion de l'égaliseur fixe en fonction des couleurs vues précédemment. L'entité de ce composant est :
entity equalizer_fixed is Port( clk : in STD_LOGIC; --Récepetion de l'horloge de 100MHz enable_equalizer : in STD_LOGIC; --Récepetion de l'ordre d'envoi de la trame enable_choice : in STD_LOGIC_VECTOR (0 downto 0); --Choix du mode de trame que l'on veut envoyer, 0 pour envoyer une trame d'extinction du panneau LEDs, 1 pour envoyer l'égaliseur; STD_LOGIC_VECTOR pour les futurs applications trame_equalizer : out STD_LOGIC --Emission de la trame vers le panneau LEDs ); end equalizer_fixed;
Une simulation de nos 3 fichiers VHDL a été réalisée à l'aide d'un test bench. Ce test bench fait le script suivant :
--Génération d'un signal d'horloge de 100MHz (période de 10ns) clk_gen : process begin clk <= '1'; wait for 5ns; clk <= '0'; wait for 5ns; end process; --Génération du switch de enable_choice pour envoyer la trame extinction ou equalizer enable_trame_choice_gen : process begin enable_choice <= "0"; wait for 4ms; --trame extinction enable_choice <= "1"; wait for 4ms; --trame equalizer end process; --Génération de la mise à 1 (de l'appui sur un bouton) de enable pour donner l'ordre d'envoyer la trame vers les LEDs enable_trame_leds_gen : process begin enable_equalizer <= '0'; wait for 0.97ms; enable_equalizer <= '1'; wait for 30us; enable_equalizer <= '0'; wait for 4ms; end process;
Sur le scope de la simulation nous retrouvons les variables essentielles présentes dans equalizer_fixed.vhd et nous montre le résultat suivant :
Calcul théorique d'envoi d'une trame pour 145 LEDS (144+1 expliqué dans le Troisièmement):
- 10ns[clock]*40[temps pour envoyer 1 bit]*3[nombre d'états pour la compréhension d'1 bit par le protocole]*24[nombre de bits dans une trame RGB]*145[nombre de LEDs] = 10*40*3*24*145 = 4176000ns = 4,176ms
Calcul pratique (en simulation) grâce aux curseurs d'envoi d'une trame :
- Le deuxième curseur est au front descendant du dernier bit à 1, ne prenant pas en compte les 2 derniers bits à 0, d'où l'ajout des (400ns*2).
- (10,17665ms+(400ns*2))-6ms = (10,176650+(0,000400*2))-6 = 4,17745 ms
La différence est de : 4,17745-4,176000 = 0,00145 = 1,45 us et s'explique par le retard d'un coup d'horloge (10ns) de chaque trame de LEDs dans l'envoi global, soit 145*10ns = 1450ns.
Troisièmement, nous avons réalisé le test sur le matériel et nous avons rencontré plusieurs problèmes. Tout d'abord (problème n°1), l'information de la trame de la LED[0] ne lui est pas transmis et reçoit à la place celle de la LED[1] causant un décalage dans tout l'affichage. On ajoute une LED fantôme à notre circuit et notre panneau comprends maintenant 145 LEDs (dont 144 réelles). Puis (problème n°2), l'extinction des LEDs par le choix du switch à 0 ne fonctionne pas. Uniquement l'émission d'une trame par implémentation du programme dans la board fonctionne pour le moment (problème à régler plus tard). L'affichage sur les LEDs est le suivant :
En raison d'une soudure cassée des fils d'alimentations et du fil de transmission de données, la dernière ligne est inutilisable (les 24 LEDs tout en haut).
ADC de la Basys3
Afin de convertir un signal analogique en un signal numérique pour une démonstration, nous utiliserons l'IP XADC de notre Basys3.
Caractéristiques:
- Lors de la création du projet, nous utilisons la carte : xc7a35tcpg236-1 d'après cette source
- Nous utiliserons la chaîne 6 (VAUXP6 et VAUXN6) car d'après le mapping du XADC, ils correspondent aux pins J3/K3 soit aux ports 1/7 du header.
- Pour une utilisation simple et le plus efficace possible, nous configurons notre IP comme suit :
Grâce à cette configuration par défaut, les registres (generic map()) et le port map de notre XADC nommé xadc_wiz_0 sont pré-configurés. C'est d'ailleurs la raison pour laquelle elle est en mode "Read Only".
Notre composant ADC_v2
Pour définir les entrées/sorties de notre composant, nous nous basons sur l'exemple de cette datasheet, la section Port Descriptions de la datasheet de l'XADC et le port map de notre IP. Ainsi nous définissons :
entity ADC_v2 is port ( DCLK : in STD_LOGIC; -- Clock input RESET : in STD_LOGIC; -- Reset VAUXP, VAUXN : in STD_LOGIC_VECTOR (15 downto 0); VP, VN : in STD_LOGIC; MEASURED_VCCINT : out STD_LOGIC_VECTOR (15 downto 0); -- Mesure de la tension EOC : out STD_LOGIC; EOS : out STD_LOGIC );
Suite à cela, il est nécessaire d'appeler l'IP xadc_wiz_0 (avec ses entrées/sorties) dans l'architecture comportementale de notre composant ADC_v2 :
component xadc_wiz_0 is port ( daddr_in : in STD_LOGIC_VECTOR (6 downto 0); -- Address bus for the dynamic reconfiguration port den_in : in STD_LOGIC; -- Enable Signal for the dynamic reconfiguration port di_in : in STD_LOGIC_VECTOR (15 downto 0); -- Input data bus for the dynamic reconfiguration port dwe_in : in STD_LOGIC; -- Write Enable for the dynamic reconfiguration port do_out : out STD_LOGIC_VECTOR (15 downto 0); -- Output data bus for dynamic reconfiguration port drdy_out : out STD_LOGIC; -- Data ready signal for the dynamic reconfiguration port dclk_in : in STD_LOGIC; -- Clock input for the dynamic reconfiguration port reset_in : in STD_LOGIC; -- Reset signal for the System Monitor control logic vauxp6 : in STD_LOGIC; -- Auxiliary Channel 5 vauxn6 : in STD_LOGIC; busy_out : out STD_LOGIC; -- ADC Busy signal channel_out : out STD_LOGIC_VECTOR (4 downto 0); -- Channel Selection Outputs eoc_out : out STD_LOGIC; -- End of Conversion Signal eos_out : out STD_LOGIC; -- End of Sequence Signal alarm_out : out STD_LOGIC; -- OR'ed output of all the Alarms vp_in : in STD_LOGIC; -- Dedicated Analog Input Pair vn_in : in STD_LOGIC); end component;
Ensuite, nos signaux internes nous serviront à instancier le composant et décrire la partie Hardware :
signal vauxp_active : STD_LOGIC_VECTOR (15 downto 0); -- Pour initialisation signal vauxn_active : STD_LOGIC_VECTOR (15 downto 0); -- Pour initialisation signal daddr : STD_LOGIC_VECTOR (6 downto 0); signal den : STD_LOGIC; signal di_drp : STD_LOGIC_VECTOR (15 downto 0); signal dwe : STD_LOGIC; signal do_drp : STD_LOGIC_VECTOR (15 downto 0); signal drdy : STD_LOGIC; signal eoc_drp : STD_LOGIC; signal eos_drp : STD_LOGIC; signal busy : STD_LOGIC; signal dclk_bufg : STD_LOGIC;
Voici au final le port map() obtenu lors de l'instanciation :
U0 : xadc_wiz_0 port map ( daddr_in(6 downto 0) => daddr(6 downto 0), dclk_in => DCLK, den_in => den, di_in(15 downto 0) => di_drp(15 downto 0), dwe_in => dwe, reset_in => RESET, vauxn6 => VAUXN(6), vauxp6 => VAUXP(6), busy_out => busy, do_out(15 downto 0) => MEASURED_VCCINT(15 downto 0), drdy_out => drdy, eoc_out => EOC, eos_out => EOS, vn_in => VN, vp_in => VP );
Block Diagram
Notre première intention était de créer une version de notre ADC pouvant mesurer une tension. L’objectif était de récupérer la valeur de notre tension pour l’afficher en hexadécimal. Vous pouvez trouver ci-dessous le Block Diagram de la dernière version de notre composant.
Sur une première version (et non celle-ci), nous avons codé en machines d’état. Nous avions décidé de changer de version plus tard pour des problèmes liés à la simulation. Plus de détails sont inscrits dans le rapport. L’objectif était de pouvoir mémoriser l’état interne dans le registre d’état et de les synchroniser avec l’horloge. Nous pouvions alors gérer la fréquence de conversion de notre ADC. Comme nous avons utilisé la chaîne 6 de l’IP, ce sont VAUXP(6) et VAUXN(6) qui récupéreront le signal analogique. La conversion se fera à travers notre composant et l’IP pour que le vecteur MEASURED_VCCINT puisse récupérer un signal numérique en sortie.
Simulation
Afin de simuler notre convertisseur et vérifier le bon fonctionnement de notre code, nous devons lancer une simulation. Cependant, nos signaux VAUXP et VAUXN correspondent à des STD_LOGIC_VECTOR, soit des vecteurs de types numériques. En effet, Vivado ne comprend pas les signaux analogiques. Pour créer une entrée analogique, soit une stimulation, il faut alors utiliser un fichier design.txt.
Plusieurs sources sur internet montrent des façons différentes de créer un fichier stimulant. Cependant, Vivado n’en comprend qu’une seule, comme vous pouvez le voir ci-dessous :
Cet exemple est affiché dans la TCL Console lorsque le logiciel ne comprend pas le fichier. Nous avons alors créé notre propre fichier de stimulation, avec les signaux et les chaînes qui nous intéressaient :
Problèmes et méthodes de résolution
Ces dernières semaines, notre plus gros souci a été de lire et récupérer les données du fichiers design.txt. Toutes nos démarches sont détaillées dans le rapport.
Méthode 1 : S’inspirer de la datasheet et des exemples Vivado
Notre première idée pour comprendre le fonctionnement du testbench de cet IP, était de générer l’exemple du logiciel. Malheureusement, ce dernier était en Verilog, soit un autre langage.
En consultant les datasheets, il s’avère que le fichier peut être généré par défaut. Cependant, en lançant notre simulation, rien ne se passe. Nous décidons alors de consulter l’exemple d’un ingénieur Xilinx via la datasheet de l’XADC : l’ug480. Dans le testbench codé en VHDL, il n’y a aucune trace de lecture du fichier. Seuls le RESET et l’horloge sont créés. En effet, cet exemple se sert des commandes sur la TCL Console. Cependant, en suivant les instructions dans le readme.txt, il semblerait que la commande ne fonctionne pas. Cela est sûrement dû à un problème de librairies et de fichiers introuvables… Ce qui paraît logique lorsqu’on sait qu’on a récupéré cet exemple via le site de Xilinx à l’aide de nos identifiants Xilinx. Ce n’est peut-être pas censé être publique.
Méthode 2 : La librairie STD.TEXTIO.ALL
Cette librairie nous aura causé bien des problèmes pendant nos recherches. En effet, nous décidons de récupérer directement les valeurs de notre fichier design.txt. Il semblerait que nous ne sommes pas les seuls à opter pour cette solution, plusieurs personnes sur des forums utilisent cette librairie.
IEEE.STD_LOGIC_TEXTIO.ALL
Malgré plusieurs rectifications de notre testbench, nous ne pouvions pas lancer la simulation. En effet, nous avons réussit à rentrer dans le fichier mais impossible de récupérer les valeurs souhaitées. Les démarches seront précisées dans le rapport. Voici un exemple d’erreur lors de notre simulation :
Nous pouvons voir surligné en jaune des notes que nous avons volontairement laissé dans notre code pour tenter de débugger nos erreurs. Il semblerait que nous avions réussit à rentrer dans le fichier à ce moment précis. Puis on remarque avec la ligne « Failure » surlignée en jaune que la lecture pose problème. Nous nous sommes alors demandés si ce n’était pas à cause de l’en-tête… mais elle est obligatoire selon le logiciel. Ce fût une de nos plus grosses difficultés et nous ne sommes pas parvenus à extraire ces données pour lancer une simulation.
Alternative
Dans le but de pouvoir donner en entrée de la FFT des valeurs numériques cohérentes similaire à celle de l'ADC, nous allons générer ce signal d'entrée grâce à des sinus de fréquences différentes. Nous avons utilisé l'IP DDS Compiler permettant de produire des formes d'ondes sinusoïdales.
Dans notre cas, nous choisirons les fréquences sinusoïdales suivantes : 31, 62, 125, 250, 500, 1 000, 2 000, 4 000, 8 000 et 16 000 Hz.
Après avoir configuré l'IP, et associé 1 switch à chaque fréquence avec la configuration de ce tableau :
Fréquences (Hz) | switch (bit n°) |
---|---|
31 | 9 |
62 | 8 |
125 | 7 |
250 | 6 |
500 | 5 |
1 000 | 4 |
2 000 | 3 |
4 000 | 2 |
8 000 | 1 |
16 000 | 0 |
Nous avons réalisé une simulation où l'on injecte des sinus, pour le signal d'entrée de la FFT, à chaque changement de switch dans cet ordre précisément :
switch (binaire) | switch (hexa) | Fréquences (Hz) |
---|---|---|
10_0000_0000 | 0x200 | 31 |
11_0000_0000 | 0x300 | 62 + 31 |
11_1000_0000 | 0x380 | 125 + 62 + 31 |
11_1100_0000 | 0x3c0 | 250 + 125 + 62 + 31 |
11_1110_0000 | 0x3e0 | 500 + 250 + 125 + 62 + 31 |
11_1111_0000 | 0x3f0 | 1 000 + 500 + 250 + 125 + 62 + 31 |
11_1111_1000 | 0x3f8 | 2 000 + 1 000 + 500 + 250 + 125 + 62 + 31 |
11_1111_1100 | 0x3fc | 4 000 + 2 000 + 1 000 + 500 + 250 + 125 + 62 + 31 |
11_1111_1110 | 0x3fe | 8 000 + 4 000 + 2 000 + 1 000 + 500 + 250 + 125 + 62 + 31 |
11_1111_1111 | 0x3ff | 16 000 + 8 000 + 4 000 + 2 000 + 1 000 + 500 + 250 + 125 + 62 + 31 |
Nous obtenons la simulation suivante où la sortie numérique (avec une visualisation analogique) "m_axis_data_tdata_sine[15:0]" transporte les sinusoïdes :
Implémentation de la FFT
Création avec le module xfft
Dans un premier temps, on va se servir de l'IP déjà mis à disposition par Vivado. On peut voir via ce site l'exigence logicielle de la fft et que la version 9.1 est prise en charge par la famille artix-7 en AXI-Stream. Pour le FPGA que nous avons choisit (Spartan3), il faut une version plus ancien (7.1) mais il reste quand même compatible avec le module également.
En se servant de la datasheet, on peut configurer le module xfft_0 de la façon suivante :
Il faut ensuite lui envoyer un signal en entrée. Pour cela, on utilise l'IP DDS_compiler décrit dans la partie précédente pour simuler une onde sinusoïdale. On rajoute une clock en entrée de fréquence 100MHz. Pour les entrées du bloc fft, on relie la sortie m_axis_data_tdata qui est un bus 16 bits à l'entrée du bloc fft m_axis_data_tdata qui est réglée pour accueillir un bit de cette longueur.
Pour que le module puisse recevoir et envoyer des données, il est nécessaire de connecter les voies s_axis_data_tdata et m_axis_data_tready à une constante que l'on modélisera à l'aide de l'IP xconstant.
En sortie, on récupère séparément la composante réelle et imaginaire du signal grâce aux IP xslice qui sont utilisés pour extraire des bits d'un réseau de bus.
Pour avoir l'amplitude du signal de sortie, nous nous sommes inspirés de ce projet. En effet, pour avoir l'ampiltude, il faut appliquer la formule : Modèle:Sqrt. Pour ce faire, on rajoute deux blocs d'IP multiplier et un bloc IP adder pour effectuer ce calcul. Enfin, pour effectuer la racine carrée, on ajoute le module Cordic. Il sera également nécessaire de relier une constante à la voie s_axis_cartesian_tvalid pour pouvoir recevoir les données.
Block diagram final
On arrive au block diagram final suivant :
Simulation
Pour effectuer la simulation on crée le HDL Wrapper qui va nous donner le code du diagramme final. Ensuite on crée le test bench pour lancer la simulation :
library IEEE; use IEEE.STD_LOGIC_1164.ALL; library UNISIM; use UNISIM.VCOMPONENTS.ALL; entity design_1_tb is end design_1_tb; architecture Behavioral of design_1_tb is component design_1 is port ( clk : in STD_LOGIC ); end component design_1; signal clk : STD_LOGIC := '0'; begin design_1_i: design_1 port map (clk => clk); --Génération d'un signal d'horloge de 100KHz clk_gen : process begin clk <= '1'; wait for 500ns; clk <= '0'; wait for 500ns; end process; end Behavioral;
Après simulation, on obtient les résultats suivants :
On voit bien une sinusoïde en entrée mais le résultat en sortie n'est pas concluant. En effet, on devrait normalement observer des pics périodiquement mais à la place on observe des oscillations. En réessayer en changeant les données du bloc FFT, on arrive aussi à des résultats infructueux.
Création du PCB
Pour réaliser le PCB, nous nous sommes appuyé sur les cartes de développement existantes, et notamment la carte Open3S500E qui utilise le même FPGA que nous.
Les schematics des cartes existantes masquent tous la partie entre la configuration et l'arrivée USB, l'arrivée de l'information se fait en JTAG. Deux solutions s'offrent à nous: acheter un câble de programmation USB->JTAG ou implanter un circuit de conversion USB->JTAG sur notre PCB. Après consultation des enseignants, la deuxième solution est la meilleure. Nous allons réaliser les deux schematics séparément puis les rassembler pour plus d'efficacité.
Le FPGA est un composant électronique possédant de nombreuses broches d'entrées/sorties, pour cette raison il est assez lourd à utiliser dans un schematic. Le nôtre est décomposé en 7 parties distinctes, qui correspondent à plusieurs fonctions (Configuration, alimentation, entrées/sorties), ce qui rend le schematic plus lisible.
FPGA Configuration |
FPGA Alimentation |
FPGA I/O |
USB -> JTAG |
Une fois les fichiers schematics terminés, nous avons pu réaliser le routage du PCB sous Altium.
Agenda
Semaine 1 - 13/01
- Redéfinition du projet.
- Point de départ grâce aux ressources présentes sur Digilent Documentation.
- Etudes des boards Cmod A7 et Cmod S6 pour choisir nos composants et élaborer le circuit de notre carte électronique en fonction de nos besoins.
A revoir pour l'intégrer à notre carte :
- Microphone actuel MAX4466, réutilisation (ou microphone electret + circuit amplificateur).
- Module Bluetooth actuel HC05, voir liste des composants pour le nouveau module Bluetooth.
- Module de CAN Pmod AD2 utile à notre application.
Semaine 2 - 20/01
- Composants pour notre board à acquérir : puce FPGA - port USB JTAG/UART - SPI Flash - ( SPI header ) - Micron DDR3 memory - régulateur de tension
Notes pour plus tard :
- Il faudra élaborer le protocole de communication sous VHDL pour communiquer avec la matrice de LEDs en respectant son protocole SK6812. Voici un lien sur la documentation relative aux matrices de LEDs Adafruit : ici.
- Nous nous sommes documentés pour réaliser une FFT sur une puce Xilinx.
Semaine 3 - 27/01
- Installation du logiciel Vivado Design Suite pour les produits Xilinx remplaçant "Xilinx ISE" pour le développement sur puce FPGA.
- Entraînement sur la Zybo Zynq-7000 ARM/FPGA SoC Trainer Board car le bloc FFT est compatible avec la puce FPGA et nous permettrait de commencer le développement logiciel. Exemples d’utilisation du bloc.
- Nous avons effectué la liste des composants : voir cette section.
- Nous avons eu un doute quant à l'utilisation du convertisseur analogique numérique : soit on prend le CAN Pmod AD2, soit on s'inspire de son schematic et de son CAN.
Semaine 4 - 03/02
Xilinx Vivado
- Installation des fichiers relatifs à la board Zybo : Board File. Dossier "zybo" de l'archive précédente à copier-coller dans le dossier "zynq" où est présent le logiciel.
...\vivado-boards-master\new\board_files\zybo ...\Xilinx\Vivado\2019.2\data\boards\board_parts\zynq
- Nous avons récupéré 2 boards FPGA pour nos tests : Zybo Zynq-7010 et Artix Basys 3 avec l'accord de nos encadrants.
- Nous avons effectué nos premières manipulations avec Vivado et le VHDL pour nous familiariser avec ces outils.
Nous sommes maintenant bien équipés pour commencer nos premiers tests et savoir quels composants il nous faudra, en fonction de la consommation de nos tests.
Semaines 5 à 7 - 10/02
USB to JTAG
- Pour programmer la puce FPGA par le biais d'une connexion filaire microUSB du PC au PCB, il est nécessaire de passer par une interface JTAG, voici quelques explications. Cette liaison peut être réalisée par un câble en fonction de nos besoins.
- Dans notre cas, nous allons procéder à la réalisation de ce module grâce à des documentations open source. Nous allons reprendre le Mini Module qui a pour composant principal un FT2232H.
- Le schematic sera celui présent dans la datasheet du module page 9. La liste des composants est la suivante à acquérir :
Description | Fabricant | Référence Fab | Empreinte | Désignation carte | Quantité | Réf Mouser | Réf Farnell | Prix unitaire | URL achat |
---|---|---|---|---|---|---|---|---|---|
Connecteurs USB MICRO USB B RECPT BTTM MOUNT ASSY | Molex | 47346-0001 | 47346-0001 | CN1 | 1 | 538-47346-0001 | / | 0.86 | URL1 |
Suppresseurs ESD / diodes TVS | Littelfuse | PGB1010603 | 0603 | CR1, CR2 | 2 | 576-PGB1010603MR | / | 0.54 | URL2 |
Perles de ferrite 600ohms 500mA | Murata | BLM18EG601SZ1D | 0603 | FB1, FB2, FB3 | 3 | 81-BLM18EG601SZ1D | / | 0.21 | URL3 |
EEPROM 128x16 | Microchip | 93LC56BT-I/OT | SOT-23-6 | U2 | 1 | 579-93LC56BT-I/OT | / | 0.20 | URL4 |
Circuit intégré d'interface USB USB HS to Dual UART/ FIFO/SPI/JTAG/I2C | FTDI | FT2232HL-REEL | LQFP-64 | U1 | 1 | 895-FT2232HL | / | 6.04 | URL5 |
Horloge 12MHz | ABRACON | ABLS7M2-12.000MHZ-D2Y-T | 7 mm x 4.1 mm | Y1 | 1 | 815-ABLS7M212MHZD2YT | / | 0.33 | URL6 |
Régulateurs de tension LDO 500mA Lo-Noise LDO Vltg Reg | Texas Instruments | TL5209DR | SOIC-8 | U3 | 1 | 595-TL5209DR | / | 1.02 | URL7 |
Embases et logements de câbles 2x13 pin male header | TE | 1-215309-3 | https://www.mouser.fr/datasheet/2/418/NG_CD_215309_E-1247367.pdf | CN2, CN3 | 2 | 571-1-215309-3 | / | 3.07 | URL8 |
Suivi des capacités 0603 et résistances 0603 :
Désignation carte | C1, C9 | C2, C7, C11, C12, C14 | C3, C4, C8, C10, C13, C15, C16 à C22 | C5, C6 | R1 | R2, R6 | R3 | R4, R5 | R7 |
---|---|---|---|---|---|---|---|---|---|
Valeurs | 10nF | 4.7uF | 100nF | 30pF | 15k | 10k | 12k/1% | 10R = 10 ohm | 2k |
- Installation de la librairie Altium de recherche de composants.
PCB FPGA
- Choix du FPGA modifié XC3S500E-4VQG100C pour pouvoir le souder. La programmation de cette puce se fera sous ISE Design Suite.
- Réalisation du schematic sous Altium.
Développements sous Vivado pour Basys 3
- Nous avons commencé à créer une première version de la gestion de nos LEDs avec Vivado.
Semaine 8 - 02/03
Développements Basys 3
- Nous avons amélioré le code permettant de gérer la trame de LEDs. Dans cette section nous pouvons voir qu'au final, que les LEDs ne s'allumaient pas exactement comme nous le voulions. C'était la deuxième version de notre code.
- Nous avons pu récupérer le fichier (.xdc) de contraintes de la Basys3 à utiliser. Il nous servira à effectuer nos tests réels sur la board.
Semaine 9 - 09/03
Développements Basys 3
- Nous avons réussit à gérer les couleurs d'une LED sur le bandeau grâce à notre protocole, en utilisant les switchs de la board. Cependant, on s'est rendu compte que le protocole n'était pas le bon.
- Après plusieurs recherches, il s'avère que le protocole correct est le WS2812B. Nous avions la mauvaise référence de notre panneau LEDs.
- Objectif : contrôler toutes les LEDs en envoyant une trame complète.
Mis à part le PCB à créer, on pense éventuellement à utiliser la borde Basys3 pour une démonstration :
- Nous avons donc fait une première approche de l'IP XADC de Vivado pour notre convertisseur ADC. Lien de la datasheet : XADC.
Semaine 10 - 16/03
A partir de ce lundi 16/03, les circonstances ont voulu que l'école ferme. Nous possédons le matériel nécessaire pour continuer à effectuer le projet.
Mercredi 18/03 : Réunion sur chat avec les professeurs :
- Tout le matériel est possédé par Stephen (Basys3, microphone MAX4466, Bluetooth HC05, panneau LEDs SJ-100144-2811 et ATMega 2560). La possession du matériel par une personne n’est pas contraignante, car on ne passe aux tests uniquement si la simulation en amont est concluante et correspond aux protocoles attendus.
- Niveau PCB : Il nous reste à intégrer nos entrées/sorties (Bluetooth, Microphone et bandeau LEDS) à notre board, toute la configuration du FPGA a été faite. Il faudra aussi faire le routage de la carte FPGA et du FTDI indépendamment (à fusionner une fois validées).
- Niveau VHDL : On travaille sur la Basys3. On a géré le protocole d'envoi de trame pour notre bandeau de LEDs, le résultat actuel est l’allumage de la première LED avec le RGB que l’on souhaite. Il faut optimiser le déroulement du code pour utiliser toutes les capacités que peut offrir un FPGA, et continuer à travailler sur toutes les autres entrées/sorties (Bluetooth, microphone).
Organisation du groupe :
Stephen : Rendre le CAN de la Basys3 fonctionnel pour la démonstration
Quentin et Simon : Router le PCB pour la fin de semaine. Parties USB to JTAG, et FPGA séparées puis à mettre en commun
Robin : Pouvoir contrôler le panneau LEDs entièrement, optimiser le fonctionnement en VHDL. Communication Bluetooth. Application Android.
Travail à venir : FFT.
Semaine 11 - 23/03
Avancées individuelles sur nos tâches respectives.
Côté ADC : Erreurs d'instanciation. Un des signaux crée ne reconnaît pas un élément particulier (do_out) du port map du composant XADC. Dans ce cas, une lecture de datasheets et de forums est nécessaire pour comprendre comment il fonctionne :
- Instanciation en Verilog pour comprendre la logique
- Le mapping du XADC
- La datasheet nommée Xilinx 7 Series FPGA and Zynq-7000 All Programmable - SoC Libraries Guide for HDL Designs
- Datasheet du XADC
- Exemple d'utilisation du XADC (qui n'a pas l'air de fonctionner après l'avoir testé en simulation)
Semaine 12 - 30/03
Basys 3
- LEDs : Ajout du résultat de l'émission d'une trame complète dans Gestion de toutes les LEDs.
- XADC : Instanciation de l'IP : section ADC de la Basys3
PCB
- FPGA : Ajout du routage de notre carte électronique autour de la puce FPGA dans Création du PCB.
- USB to JTAG : Routage autour du FTDI dans la section citée précédemment.
Semaine 13 - 06/04
Basys 3
- Bluetooth : Notre communication UART est opérationnelle en simulation, en réception comme en émission. Pour la tester avec la board, on enverra un caractère ASCII depuis notre smartphone par le biais d'un terminal Bluetooth. Sa représentation binaire permettra d'allumer les 8 LEDs sur 16 déjà présentes sur la Basys 3. La simulation répond à la demande souhaitée, la synthèse se réalise avec succès également, mais l'implémentation détecte des erreurs liées aux "no input/output delays". Malgré cela, on génère le bitstream et on arrive à allumer certaines LEDs de la Basys 3. Malheureusement, l'allumage des LEDs se fait de manière aléatoire.
- XADC : Implémentation de "State Machines" pour la gestion de l'ADC : débogage et création du testbench. Sources : lien 1 et lien 2.
- Début de recherche avec l'IP FFT de Vivado pour effectuer notre fft.
Semaines 14 à 16 - 13/04
Basys 3
- XADC : Problèmes liés à la lecture du fichier de stimulation analogique design.txt pour faire fonctionner le testbench. On apprend à utiliser la librairie use STD.TEXTIO.ALL
- Panneau LEDs : Nous avons un problème d'actualisation de ce dernier lié à un nouveau motif d'animations lumineux crée. Nous voulions commander le changement d'animations mais seule une animation pouvait être envoyée lors du test réel. Ce problème a été résolu et nous maîtrisons désormais les LEDs de notre panneau.
- Bluetooth : Il y a une mauvaise communication entre le HC05 et le FPGA pour interpréter la donnée émise par le module. On cherche à isoler les causes. Pour être sûr que le FPGA interprète correctement ce qu'il reçoit en RX, on décide de lui envoyer ce qu'il émet lui-même en TX. Le résultat est cohérent puisqu'il comprend la donnée. Le soucis viendrait du HC05.
Ce problème a été résolu après des modifications du code VHDL et un ajustement des alimentations, notamment un rééquilibrage des masses.
- Développements Vivado :
- - Fusion des codes VHDL comprenant l'UART et le contrôle du panneau LEDs.
- Nous avons crée une application Android pour communiquer avec le FPGA, l'application est opérationnelle et nous pouvons contrôler nos LEDs via le module Bluetooth.
Résultat final
Voici les différentes animations possibles de notre projet.
Avec le montage ci-dessous :
Documents Rendus
Rapport : Fichier:IMA4-S8-P23-Rapport.pdf
Diaporama : Fichier:IMA4-S8-P23-Diapo.pdf
Archives du projet : Git