\chapter{Présentation du projet} \section{Objectif} L'objectif de l'unité est de concevoir une centrale domotique à partir d'un FPGA, capable de commander un ventilateur et une alarme en fonction de l'état de différents capteurs et des entrées de l'utilisateur. \begin{figure}[h] \centering \includegraphics[width=0.8\textwidth]{resources/project-de2-io} \caption{Capteurs/actionneurs autour de la carte Altera DE2} \end{figure} \section{Matériel} Des contraintes matérielles ont été imposées dans le cadre de ce projet, qui se réalisera autour des composants suivants : \begin{itemize} \item Carte Altera DE2 équipée d'un FPGA Altera Cyclone II avec une horloge à 50MHz et des interfaces utilisateurs (boutons, afficheurs, \ldots) \item Microphone ELECTRET \item Capteur de température LM35 \item Haut-parleur (8 Ohm) \item Ventilateur (12V/1W) \end{itemize} \section{Méthodologie} \subsection{Conception \og{}top-down\fg{}} La conception suivra le schéma \og{}top-down\fg{} : le système sera décomposé en plusieurs sous-systèmes basiques. Ainsi, la centrale domotique comprendra deux sous-systèmes : une partie alarme et une partie ventilation. \begin{figure}[h] \centering \includegraphics[width=0.85\textwidth]{resources/project-topdown-subsystems} \caption{Découpage du système en sous-systèmes} \end{figure} \subsection{Validation \og{}bottom-up\fg{}} Dans le cadre de la validation \og{}bottom-up\fg{}, chaque sous-système unitaire sera testé individuellement, avant d'être intégré au système complet qui sera à nouveau testé globalement. \chapter{Interface de commande} L'interface de commande comprend les entrées et les sorties permettant à l'utilisateur d'intéragir avec la centrale. Celle-ci comprend un module de commande (utilisant les interrupteurs et les ports GPIO de la carte DE2) et un module d'affichage (via les DELs, les afficheurs 7-segments et l'écran à cristaux liquides). \section{Commande} Le module de commande prendra en compte les entrées des paramètres utilisateurs, via les interrupteurs, et des paramètres environnementaux, via les capteurs de bruit et de température connectés aux ports GPIO. \begin{figure}[p] \centering \includegraphics{resources/commande-interrupteurs-legende} \caption{Actions des interrupteurs de la carte DE2} \end{figure} \begin{figure}[p] \centering \includegraphics{resources/schema-commande-io} \caption{Entrées/sorties du sous-système \og{}commande\fg{}} \end{figure} Ce module a été décomposé en deux sous-modules semi-indépendants, l'un destiné à contrôler l'alarme, et l'autre le ventilateur, ce dernier étant désactivé lorsque l'alarme est déclenchée. \begin{figure}[p] \centering \includegraphics{resources/schema-commande-logic} \caption{Schéma bloc du sous-système \og{}commande\fg{}} \end{figure} \newpage \subsection{Commande de l'alarme} \begin{figure}[p] \centering \includegraphics{resources/schema-alarm-io} \caption{Entrées/sorties du sous-sous-système \og{}alarme\fg{}} \centering \includegraphics{resources/schema-alarm-logic} \caption{Schéma du sous-sous-système \og{}alarme\fg{}} \label{fig:alarm-logic} \end{figure} L'alarme doit être activée (state) dans les cas suivants : \begin{itemize} \item Condition nécéssaire : l'utilisateur a activé l'alarme (enable) \item Condition nécéssaire : un bruit est détecté (activate) \item Condition suffisante : l'alarme est déjà activée (alarm) \end{itemize} L'ensemble des situations possibles sont représentables par la table de vérité ~\ref{tab:tab-alarm}. \begin{table}[p] \centering \begin{tabular}{ c | c | c || c } enable & activate & alarm & STATE\\ \hline 0 & 0 & 0 & 0\\ 0 & 0 & 1 & 1\\ 0 & 1 & 0 & 0\\ 0 & 1 & 1 & 1\\ 1 & 0 & 0 & 0\\ 1 & 0 & 1 & 1\\ 1 & 1 & 0 & 1\\ 1 & 1 & 1 & 1\\ \end{tabular} \caption{Table de vérité de l'activation de l'alarme} \label{tab:tab-alarm} \end{table} De cette table, nous obtenons l'équation booléenne évidente : \begin{equation} STATE = (enable \cdot activate) + alarm \end{equation} Le circuit correspondant est ainsi celui de la figure ~\ref{fig:alarm-logic}. %\newpage \subsection{Commande du ventilateur} \begin{figure}[p] \centering \includegraphics{resources/schema-fan-io} \caption{Entrées/sorties du sous-sous-système \og{}ventilation\fg{}} \centering \includegraphics[width=\textwidth]{resources/schema-fan-logic} \caption{Schéma du sous-sous-système \og{}ventilation\fg{}} \label{fig:fan-logic} \end{figure} La sortie $FAN\_AUTO$ indique l'activation du mode automatique lorsque celui-ci est sélectionné et que la vitesse définie manuellement par l'utilisateur est la vitesse 0. Cette dernière condition donnée sur $no\_manual$ est vérifiée à l'aide d'un comparateur. \begin{equation} FAN\_AUTO = fan\_auto\_user \cdot no\_manual \end{equation} Un premier multiplexeur permet de choisir la valeur $fan\_auto\_value$ définie à la vitesse 3 si le capteur de température est activé ($hot$). Un second multiplexeur permet la sélection entre la vitesse manuellement définie par l'utilisateur ($fan\_speed$) ou la vitesse automatique déterminée par l'état du capteur ($fan\_auto\_value$) en fonction de l'activation du mode automatique $FAN\_AUTO$. Un troisième multiplexeur permet de désactiver le ventilateur, quelque soit la vitesse définie manuellement ou automatiquement par l'état du capteur, selon l'entrée $enable$. Le schéma synthétique est celui du ~\ref{fig:fan-logic} \newpage \section{Affichage} L'état de la centrale domotique est visible par l'utilisateur au travers de multiples DELs ainsi que des afficheurs 7-segments. L'écran à cristaux liquide affiche quant à lui un message trivial en 32 caractères. \subsection{Afficheurs 7-segments} \begin{figure}[p] \centering \includegraphics{resources/schema-display-io} \caption{Entrées/sorties du sous-sous-système \og{}display\fg{}} \end{figure} Les huit afficheurs 7-segments, à l'exception de HEX5, sont utilisés. Celui-ci est donc éteint à l'aide d'une constante $7 \times 1$, puisqu'actif à l'état bas. \subsubsection{Témoins d'activation} Les afficheurs HEX7 et HEX6 devant respectivement afficher les lettres \og{}A\fg{} et \og{}F\fg{} quand le mode alarme et la ventilation automatique sont activés, deux constantes ayant pour valeurs hexadécimales A et F ont été créées. Ces constantes sont ensuite traduites par le module seven\_segment\_decoder pour être affichables. Un multiplexeur pour chaque afficheur permet ensuite d'afficher la constante associée ou bien de désactiver l'afficheur. Le schéma associé est le ~\ref{fig:mode-indicator-logic}. \begin{figure}[p] \centering \includegraphics{resources/schema-display-af} \caption{Schéma d'affichage des témoins d'activation} \label{fig:mode-indicator-logic} \end{figure} \subsubsection{Vitesse du ventilateur} Le module seven\_segment\_decoder ayant une entrée sur 4 bits, et la vitesse du ventilateur définie sur l'entrée $SPEED[1..0]$ étant codée sur 2 bits, une constante binaire 00 a été concaténée en LSB. Le résultat de la conversion de la valeur est ensuite directement affichée sur HEX4. Le schéma associé est le ~\ref{fig:speed-indicator-logic}. \begin{figure}[p] \centering \includegraphics{resources/schema-display-speed} \caption{Schéma d'affichage de la vitesse du ventilateur} \label{fig:speed-indicator-logic} \end{figure} \subsubsection{Chenillard} \textit{\og{}Science isn't about WHY. It's about WHY NOT!\fg{}} - Cave Johnson Afin de ne pas laisser les afficheurs 0 à 3 inutilisés, et de rappeler des mauvais souvenirs aux possesseurs de Freebox v5, un chenillard a été ajouté dans un module \og{}useless\fg{}. Celui-ci a été créé en utilisant un registre à décalage de 12 bits (nombre de segments en bordure), \og{}ralentit\fg{} à l'aide d'un module clock\_divider. Les segments du milieu ont été désactivés. Le schéma associé est le ~\ref{fig:speed-useless-logic}. \begin{figure}[p] \centering \includegraphics{resources/schema-display-useless} \caption{Schéma du chenillard} \label{fig:speed-useless-logic} \end{figure} \subsection{LCD} Les modules VHDL lcd\_message et message ont été modifiés pour afficher une vérité établie. Pour ce faire, les lettres composants la phrase ont été transcrite en code ASCII hexadecimal et introduits dans le code du composant message. \chapter{Sous-système \og{}alarme\fg{}} \begin{figure}[h] \centering \includegraphics[width=0.9\textwidth]{resources/alarm-subsubsystems} \caption{Découpage du sous-système \og{}alarme\fg{} en sous-sous-systèmes} \end{figure} \newpage \section{Detection du niveau sonore} \subsection{Câblage du microphone et amplification} En générant une sinusoïde depuis un téléphone nous observons un signal crête crête de $18.8mV$ (figure ~\ref{fig:ampmicsin}). Pour amplifier de manière cohérente se micro il aurait fallu mettre une résistance variable, permettant de jouer sur la \og{}sensibilité\fg{} du micro. Apres avoir, calculé un gain théorique sur papier de $-26$, nous nous sommes rendu compte que c’était bien trop faible. Afin de trouver la résistance idéale nous avons parcourue un jeu de résistance allant de $22k\Omega$ à $560k\Omega$, et retenue une résistance de $120k\Omega$ à $1.5k\Omega$ en entrée nous avons donc un gain de $-80$. \begin{figure}[p] \centering \includegraphics[scale=0.5]{resources/aschema-amplimic} \caption{Schéma de câblage de l'amplificateur du microphone} \end{figure} \begin{figure}[p] \centering \includegraphics{resources/amplification-mic} \caption{Amplification d’un signal sinusoïdal} \label{fig:ampmicsin} \end{figure} \begin{figure}[p] \centering \includegraphics{resources/amplification-mic-saturation} \caption{Amplification d’un signal sinusoïdal, en saturation} \end{figure} \subsection{Detection de niveau sonore} \subsubsection{Détection de crête} En générant une sinusoïde depuis un téléphone nous observons un signal crête crête de $18.8mV$. Une fois notre signal amplifié nous devons récupérer une composante continue afin de pouvoir utiliser celle–ci dans notre Trigger, pour atteindre le basculement. Pour récupérer cette composante continue nous avons utilisé un détecteur de crête. On nous avait imposé un condo de $330nF$ et un temps de décharge de $0.3s$. Le calcul effectué afin de trouver la résistance correspondante à l'aide du temps de décharge du condensateur est ~\ref{eq:crete} \begin{equation} \begin{split} &\tau = R \cdot C\\ &\iff 0.3 = 330nF \cdot R\\ &\iff R = 909090\Omega\\ &\iff R = 1M\Omega \end{split} \end{equation} \label{eq:crete} \begin{figure}[p] \centering \includegraphics[scale=0.5]{resources/aschema-cretemic} \caption{Schéma de câblage du détecteur de crête du microphone} \end{figure} \subsubsection{Détection de niveau} Un comparateur à hystérésis a été utilisé pour la détection du niveau sonore. Le but était de détecter le niveau sonore suivant le principe suivant : \begin{itemize} \item Entrée $ >2V \rightarrow $ Sortie $4V$ \item Entrée $ <1V \rightarrow $ Sortie $0V$ \end{itemize} Il a fallu trouver Vref, il suffit juste de remplacer une de nos deux expression par le jeu de valeur correspondant on trouve ainsi $V_{ref}=1.6V$. Un simple pont diviseur de tension permet d’atteindre ce $V_{ref}$. \begin{equation} \begin{split} V^+ &= \dfrac{ \dfrac{V_{in}}{R_3} + \dfrac{V_{out}}{R_4} }{ \dfrac{1}{R_3} + \dfrac{1}{R_4} }\\ &= \dfrac{V_{in} \cdot R_4}{R_3+R_4} + \dfrac{V_{out} \cdot R_3}{R_3+R_4}\\ &= V_{ref} \end{split} \end{equation} Deux cas possibles de basculement à $1V$ et à $2V$. \begin{equation} \begin{cases} V_{ref} = \dfrac{1 \cdot R_4}{R_3+R_4} + \dfrac{4 \cdot R_3}{R_3+R_4}\\ V_{ref} = \dfrac{2 \cdot R_4}{R_3+R_4} + \dfrac{0 \cdot R_3}{R_3+R_4} \end{cases} \end{equation} \begin{equation} \begin{split} \iff & \dfrac{2 \cdot R_4}{R_3 + R_4} = \dfrac{R_4 + 4 \cdot R_3}{R_3+R_4}\\ \iff & R_4=4 \cdot R_3 \end{split} \end{equation} \begin{figure}[p] \centering \includegraphics{resources/trigger-xy} \caption{Visualisation XY du trigger} \end{figure} \begin{figure}[p] \centering \includegraphics{resources/triggersortiehautparleur} \caption{Visualisation du basculement sur un signal sinusoïdal (GBF)} \end{figure} \begin{figure}[p] \centering \includegraphics{resources/trigger} \caption{Visualisation du basculement sur un signal sinusoïdal (GBF) 2} \end{figure} \begin{figure}[p] \centering \includegraphics[scale=0.5]{resources/aschema-trigmic} \caption{Schéma de câblage du trigger du microphone} \end{figure} \begin{figure}[p] \centering \includegraphics[scale=0.5,angle=90]{resources/aschema-mic} \caption{Schéma global de détection sonore} \end{figure} \newpage \section{Génération du son} Le son strident de l'alarme est généré numériquement sur le FPGA puis convertit en signal analogique via le CODEC. \subsection{Horloge du CODEC} Pour fonctionner, le CODEC de la carte nécessite un signal de référence $xti\_mclk\_a$, auquel s'appliquent plusieurs contraintes temporelles : un état bas ou haut doit avoir une durée d'au minimum 18 ns, et un cycle d'horloge 54 ns. Ainsi, un module $codec\_clock$ a été créé afin de générer ce signal. Celui-ci utilise un composant clock\_divider afin de générer un signal d'horloge de période 60 ns, soit une fréquence de 16.6 MHz avec un état haut et un état bas de 30 ns, répondant aux critères. Une seconde horloge de référence $xti\_mclk\_b$ avec une fréquence de 10 MHz a été aussi créée pour la génération d'un second son strident. \begin{figure}[p] \centering \includegraphics{resources/schema-codecclock-io} \caption{Entrées/sorties du module \og{}codec\_clock\fg{}} \end{figure} \begin{figure}[p] \centering \includegraphics{resources/schema-codecclock-logic} \caption{Schéma du module \og{}codec\_clock\fg{}} \end{figure} Le premier signal de référence $xti\_mclk\_a$ a été visualisé à l'oscilloscope pour validation (figure ~\ref{fig:capture-xtimclk-valid}). Il a été constaté que le signal correspondait aux attentes (fréquences et durée des états hauts et bas). \begin{figure}[p] \centering \includegraphics{resources/capture-xtimclk} \caption{Observation du signal d'horloge généré xti\_mclk\_a} \label{fig:capture-xtimclk-valid} \end{figure} \begin{figure}[p] \centering \includegraphics{resources/schema-soundgene-config} \caption{Schéma de configuration du codec dans \og{}sound\_gene\fg{}} \end{figure} \subsection{Génération du son strident} La génération du son strident s'effectue numériquement à l'aide d'une fonction tabulée dans le sous-système $sound\_gene$. Pour ce faire, un module $dds\_sinus$ a été utilisé en conjonction avec un diviseur d'horloge afin de produire un signal ayant une fréquence audible. Sur ce projet, les horloges de référence $xti\_mclk\_a$ et $xti\_mclk\_b$ sont utilisées alternativement grâce à un multiplexeur, une bascule et un diviseur d'horloge, visibles sur la figure ~\ref{fig:schema-soundgene-gen}. \begin{figure}[p] \centering \includegraphics{resources/schema-soundgene-io} \caption{Entrées/sorties du module \og{}sound\_gene\fg{}} \end{figure} \begin{figure}[p] \centering \includegraphics{resources/schema-soundgene-gen} \caption{Schéma de génération du son strident} \label{fig:schema-soundgene-gen} \end{figure} \newpage \section{Sortie vers le haut-parleur} Calcul de la puissance nécessaire pour que le haut parleur fonctionne. \begin{equation} \begin{split} & P = U \cdot I\\ \iff & 0.5 = 8\Omega \cdot I^2\\ \iff & I = 250mA \end{split} \end{equation} Ce courant est trop grand pour être délivrer par la carte, de plus celle-ci délivre une tension de $3.3V_{cc}$ alors que nous désirons limiter le haut parleur à $1V{cc}$. Nous allons donc utiliser des transistors afin de pouvoir fournir le courant nécessaire. Nous avons utilisé un AOP de gain $1/3$ afin d’atteindre les $1V_{cc}$ que nous désirons. \begin{figure}[h] \centering \includegraphics[scale=0.5]{resources/aschema-shp} \caption{Schéma de câblage de sortie vers le H-P} \end{figure} \chapter{Sous-système \og{}ventilation\fg{}} \begin{figure}[h] \centering \includegraphics[width=0.9\textwidth]{resources/fan-subsubsystems} \caption{Découpage du sous-système \og{}ventilation\fg{} en sous-sous-systèmes} \end{figure} \newpage \section{Détection de la température} \subsection{Câblage du détecteur et amplification} Dans un premier temps nous avons dus amplifier le signal en sortie du capteur analogique LM35 (capteur température), afin de rendre celui-ci exploitable. C’est un ampli non inverseur car les températures sont uniquement positives et c’est avec des tensions positives que nous avons désiré travailler. \begin{figure}[p] \centering \includegraphics[scale=0.5]{resources/aschema-amplitemp} \caption{Schéma de câblage du capteur de température} \end{figure} Une fois notre signal amplifié nous pouvons désormais travailler dessus. \subsection{Detection de niveau de température} Pour éviter les oscillations lorsque notre température ne varie que très peu nous avons utilisé un trigger à hystérésis. \begin{equation} \begin{split} V^+ &= \dfrac{ \dfrac{V_{in}}{R_3} + \dfrac{V_{out}}{R_4} }{ \dfrac{1}{R_3} + \dfrac{1}{R_4} }\\ &= \dfrac{V_{in} \cdot R_4}{R_3+R_4} + \dfrac{V_{out} \cdot R_3}{R_3+R_4}\\ &= V_{ref} \end{split} \end{equation} Deux cas possibles de basculement à $28.4\,^{\circ}{C}$ et $32\,^{\circ}{C}$, soit $2.9V$ et à $3.3V$, avec comme sorties possibles $0V$ et $4V$. \begin{equation} \begin{cases} V_{ref} = \dfrac{2.9 \cdot R_4}{R_3+R_4} + \dfrac{4 \cdot R_3}{R_3+R_4}\\ V_{ref} = \dfrac{3.3 \cdot R_4}{R_3+R_4} + \dfrac{0 \cdot R_3}{R_3+R_4} \end{cases} \end{equation} \begin{align*} 2.9 \cdot R_4 + 4 \cdot R_3 &= 3.3 \cdot R_4\\ 4 \cdot R_3 &= 0.4 \cdot R_3\\ R_3 &= 0.1 \cdot R_4 \end{align*} \begin{figure}[p] \centering \includegraphics[scale=0.5]{resources/aschema-temp} \caption{Schéma global de câblage du capteur de température} \end{figure} \newpage \section{PWM (Pulse Width Modulation)} La commande numérique de la vitesse du ventilateur repose sur le principe de la PWM ou modulation de largeur d'impulsion, implémentée dans le sous-système \og{}pwm\fg{}. La vitesse du ventilateur dépend du rapport de la durée d'impulsion sur la durée d'une période fixe. Ainsi, pour créer les quatre vitesses du ventilateur (0\%, 25\%, 50\% et 75\%), il suffit de créer quatre constantes ayant un rapport cyclique avec une période de révolution fixe associé. Alors qu'un multiplexeur permet le choix de la constante de rapport en fonction de la vitesse souhaitée, un comparateur combiné avec un compteur génère l'impulsion de sortie de rapport correspondant. \begin{figure}[p] \centering \includegraphics{resources/schema-pwm-io} \caption{Entrées/sorties du module \og{}pwm\fg{}} \end{figure} \begin{figure}[p] \centering \includegraphics[width=\textwidth]{resources/schema-pwm-logic} \caption{Schéma du module \og{}pwm\fg{}} \end{figure} \newpage \section{Commande du ventilateur} Le ventilateur nécessite une autre alimentation que celle du FPGA qui génère que du $3V$ avec une intensité trop faible pour le ventilo nous utilisons donc un transistor. Calculons la résistance interne du ventilateur sachant qu’il dissipe $1W$ en $12V$. \begin{align*} I &= 0.833333\\ P &= U \cdot I\\ I &= \dfrac{1}{12}\\ \newline R &= \dfrac{P}{I^2}\\ R &= \dfrac{1}{\left(\dfrac{1}{12}\right)^2}\\ R &= 144\Omega \end{align*} Lorsque le transistor est passant : \begin{align*} I_{bsat} &= 6.96 \cdot 10^{-4} A\\ R &= \dfrac{3-0.6}{I_{bsat}}\\ R &= \dfrac{2.4}{6.96 \cdot 10^{-4}}\\ R &= 3448\Omega \end{align*} On mettra alors une résistance de $3.3k\Omega$. \begin{figure}[p] \centering \includegraphics[scale=0.5]{resources/aschema-vent} \caption{Schéma de câblage du transistor de contrôle du ventilateur} \end{figure}