Commits

Sébastien Mengin committed 6a554a3

introduction d'un nouvel environnement de type exercice : ExosConcs

  • Participants
  • Parent commits 8cc74a5

Comments (0)

Files changed (2)

File maquette-classes-prepas.tex

     \end{correction}
   \end{ExosApp}
 
+  \begin{ExosConcs}
+
+
+    % test caignot
+\begin{exoApp}[\calcul]{10}{1}[Asservissement de vitesse d'un moteur à courant continu]\label{Logique:chap2:exo_asserv_moteur}
+
+Le paragraphe \ref{SLCI:chap5:asserv_arduino_scilab} page \pageref{SLCI:chap5:asserv_arduino_scilab} a montré comment réaliser l'asservissement en position d'un moteur à courant continu à partir du module Arduino de Scilab. Néanmoins, cette solution a l'inconvénient d'être dépendant d'une connection USB entre l'ordinateur et la carte de commande. Pour développer une application embarquée pour un robot, il est nécessaire d'implanter le code dans le micro-contrôleur directement.
+
+le montage comporte une carte de commande Arduino, un hacheur PmodHB5 et un moteur à courant continu équipé d'un codeur incrémental (voir figure \ref{SLCI_chap5_montage_arduino} page \pageref{SLCI_chap5_montage_arduino}). Un potentiomètre impose une consigne de vitesse, mesurée sur la broche A0 du micro-contrôleur. Le hacheur admet en consigne un signal PWM connecté à la broche 5 et un signal logique de sens de rotation connecté à la broche 4.
+
+Le codeur incrémental délivre deux signaux carrés dont il faut compter les fronts montants ou descendants. Pour tenir compte immédiatement d'un front, les deux signaux sont connectés aux broches d'interruption 2 et 3 (interruptions 0 et 1). La figure \ref{Logique_chap2_exo_asserv_moteur_signaux_codeur} montre les signaux mesurés pour les deux sens de rotation du moteur.
+
+
+\begin{figure}[!ht]
+\centering
+%\includegraphics[width=8cm]{Logique_chap2_exo_asserv_moteur_signaux_codeur}
+%\begin{tikzpicture}[scale=0.8]
+%\draw[fill=cyan!20] (0,0) -- ++(60:1) -- ++(1,0) node[midway,name=y2] {} 
+%                     -- ++(-120:2) node[midway,name=cs] {}
+%                     -- ($(0,0)+(120:1)+(-1,0)+(-60:2)$) node[midway,name=z] {} 
+%                     -- ++(120:2) node[midway,name=a] {}
+%                     -- ++(1,0) node[midway,name=y1] {} --cycle;
+%\draw[<-,>=latex] (y1.center) -- ++(0,.6) node[above] {$Y_1$};
+%\draw[<-,>=latex] (y2.center) -- ++(0,.6) node[above] {$Y_2$};
+%\draw[->,>=latex] (z.center) -- ++(0,-.6) node[below] {$Z$};
+%\draw[<-,>=latex] (a.center) -- ++(-1,0) node[left] {$A$};
+%\draw[->,>=latex] (cs.center) -- ++(1,0) node[right] {$C,S$};
+%\end{tikzpicture}
+\caption{Signaux issus du codeur incrémental pour les deux sens de rotation du moteur.}
+\label{Logique_chap2_exo_asserv_moteur_signaux_codeur}
+\end{figure}
+
+
+L'objectif est de concevoir le programme d'asservissement à implanter dans le micro-contrôleur. La phase d'initialisation du programme est donnée ci-dessous :
+
+% \lstset{language=C}
+% \begin{lstlisting}
+% int position=0;    // déplacement compté sur le codeur
+% int b2, b3;        // état logique lu sur les broches 2 et 3
+% int K=3;           // gain du correcteur proportionnel
+% int ecart, consigne, vitesse;
+% void setup() {
+% pinMode(4, OUTPUT);   //Sortie sens moteur
+% pinMode(5, OUTPUT);   //Sortie PWM
+% attachInterrupt(0, frontBroche2, CHANGE);
+% attachInterrupt(1, frontBroche3, CHANGE);
+% }
+% \end{lstlisting}
+
+Les fonctions \emph{frontBroche2} et \emph{frontBroche3} traitent les fronts des deux signaux codeur en incrémentant ou décrémentant la variable \emph{position} selon le sens de rotation.
+
+\begin{questions}
+\item Déterminer, lorsque le signal de la broche 2 vient de subir un front montant, la condition pour que le sens de rotation soit positif. En déduire l'équation logique permettant de déterminer, pour tous les fronts de la broche 2, si le sens est positif.
+\item Écrire la fonction \emph{frontBroche2} permettant d'incrémenter ou décrémenter la variable \emph{position} à chaque front de la broche 2. Écrire de même la fonction \emph{frontBroche3}.
+\interenum{La consigne moteur est réactualisée toutes les \SI{100}{ms}. Durant ce temps, la variable \emph{position} évolue. Au terme des \SI{100}{ms}, le rapport déplacement/temps donne la vitesse du moteur. Celle-ci peut alors être comparée à la consigne afin d'élaborer la commande moteur. L'asservissement de vitesse est uniquement dans le sens de rotation positif.}
+\item Proposer un schéma bloc fonctionnel traduisant l'asservissement de vitesse du moteur, en utilisant une correction proportionnelle.
+\item Traduire le schéma bloc sous la forme d'un programme.
+\item La consigne PWM est définie à partir d'un entier sur 8 bits (donc entre 0 et 255). Compléter le programme afin de saturer la commande moteur entre 0 et 255.
+\interenum{Le frottement sec dans le moteur ne permet pas à l'asservissement précédent d'être précis : si la vitesse atteint la consigne, la commande moteur devient nulle donc la vitesse diminue.}
+\item Proposer une modification du programme pour assurer une correction proportionnelle-intégrale.
+
+\end{questions}
+
+\end{exoApp}
+
+
+
+\begin{correction}
+
+\begin{questions}
+\item Lorsque le signal de la broche 2 vient de subir un front montant, le sens de rotation est positif si la broche 3 est à 0, et négatif si la broche 3 est à 1. De même pour un front descendant, le sens de rotation est positif si la broche 3 est à 1, et négatif si la broche 3 est à 0. L'équation logique déterminant, pour tous les fronts de la broche 2, si le sens de rotation est positif vaut $b2.\overline{b3}+\overline{b2}.b3$.
+\item Les fonctions traitées lors des interruptions levées sur les broche 2 et 3 sont donc :
+
+%%\begin{minipage}{0.47\linewidth}
+%%\lstset{language=C}
+%%\begin{lstlisting}
+%%void frontBroche2() {
+%%  b2=digitalRead(2);     // Lecture des états des broches
+%%  b3=digitalRead(3);     // juste après le front
+%%  if ( (b2 & !b3) | (!b2 & b3) ) {    // Condition
+%%     position++;         // Incrémentation (sens +)
+%%     }
+%%  else {
+%%     position--;         // Décrémentation (sens -)
+%%     }
+%%  }
+%%\end{lstlisting}
+%%\end{minipage}\hfill
+%%\begin{minipage}{0.47\linewidth}
+%%\lstset{language=C}
+%%\begin{lstlisting}
+%%void frontBroche3() {
+%%  b2=digitalRead(2);     // Lecture des états des broches
+%%  b3=digitalRead(3);     // juste après le front
+%%  if ( (b2 & b3) | (!b2 & !b3) ) {    // Condition
+%%     position++;         // Incrémentation (sens +)
+%%     }
+%%  else {
+%%     position--;         // Décrémentation (sens -)
+%%     }
+%%  }
+%%\end{lstlisting}
+%%\end{minipage}
+
+
+%% SANS LES COMMENTAIRES DANS LE PROGRAMME
+\begin{minipage}{0.47\linewidth}
+\lstset{language=C}
+\begin{lstlisting}
+void frontBroche2() {
+  b2=digitalRead(2);
+  b3=digitalRead(3);
+  if ( (b2 & !b3) | (!b2 & b3) ) {
+     position++;
+     }
+  else {
+     position--;
+     }
+  }
+\end{lstlisting}
+\end{minipage}\hfill
+\begin{minipage}{0.47\linewidth}
+\lstset{language=C}
+\begin{lstlisting}
+void frontBroche3() {
+  b2=digitalRead(2);
+  b3=digitalRead(3);
+  if ( (b2 & b3) | (!b2 & !b3) ) {
+     position++;
+     }
+  else {
+     position--;
+     }
+  }
+\end{lstlisting}
+\end{minipage}
+
+\item Le schéma bloc fonctionnel figure \ref{Logique_chap2_exo_asserv_moteur_schema_bloc} montre le principe de l'asservissement. La rotation du potentiomètre conduit à une tension variable, convertie en entier par le CAN. Le codeur incrémental génère des tops qui sont comptés dans le micro-controleur. Le bloc $p$ désigne une dérivation, dans cet exercice le rapport du nombre de tops comptés sur le temps écoulé, permettant d'obtenir la vitesse de rotation en top pour \SI{0,1}{s}. Le bloc $K$ représente la correction proportionnelle, c'est-à-dire une simple amplification de l'écart $\varepsilon$.
+
+\begin{figure}[!ht]
+\centering
+%\includegraphics[width=10cm]{Logique_chap2_exo_asserv_moteur_schema_bloc}
+\caption{Schéma bloc représentant l'architecture de l'asservissement.}
+\label{Logique_chap2_exo_asserv_moteur_schema_bloc}
+\end{figure}
+
+
+\item Le programme d'asservissement s'écrit dans la fonction \emph{loop()}.
+\lstset{language=C}
+\begin{lstlisting}
+void loop() {
+  consigne = analogRead(0);   // Mesure de la consigne
+  vitesse = position * 10;    // Vitesse = déplacement / 0.1s
+  ecart = consigne - vitesse;
+  commande = K * ecart;       // Correction proportionnelle
+  digitalWrite(4,HIGH);       // Sens +
+  analogWrite(5,commande);    // Génération du PWM de commande
+  delay(100);                 // Attente de 100 ms avant de reboucler
+  }
+\end{lstlisting}
+
+
+\item La saturation doit intervenir juste avant de générer le signal PWM par la commande \emph{analogWrite} en insérant le code suivant :
+\lstset{language=C}
+\begin{lstlisting}
+  if (commande > 255) commande = 255;
+  if (commande < 0) commande = 0;
+\end{lstlisting}
+
+\item L'action intégrale est réalisée en sommant l'écart à chaque boucle dans une variable \emph{integrale} qui sera prise en compte dans le calcul de la commande :
+\lstset{language=C}
+\begin{lstlisting}
+  ecart = consigne - vitesse;
+  integrale = integrale + ecart;          // Integration numérique
+  commande = K * ecart + integrale;       // Correction proportionnelle et intégrale
+\end{lstlisting}
+Il est évidement possible d'ajouter un coefficient en facteur de l'action intégrale, en faisant attention au fait que les calculs se font sur des entiers.
+\end{questions}
+
+\end{correction}
+\end{ExosConcs}
+
   \begin{ExosTP}
     \begin{exoTP}{20}{1}
       Énoncé d'un exercice de TP.
   }%
 }{\clearpage\Corrigesfalse}
 
-
 % --------------- Environnements « théorèmes-like » --------------
 
 % 1. Définitions
   }%
 }
 
+% Sujets de concours
+\newenvironment{ExosConcs}{%
+  \setcounter{enonceexo}{0}%
+  \global\typeexo\typeApp\relax
+  \verbatimout@write{%
+    \protect\begin{@CorrExosConcs}%
+  }%
+  \setcounter{enonceexo}{0}%
+  \section*{Sujets de concours \bighrulefill{}}%
+  \nonbreak{3}%
+}
+{%
+  \verbatimout@write{%
+    \protect\end{@CorrExosConcs}%
+  }%
+}
+
 \newenvironment{exoApp}{%
   \global\typeexo\typeApp\relax
   \@exoCommun{Exercice}{\arabic}{}{1}
   \nonbreak{3}%
 }
 {}
+\newenvironment{@CorrExosConcs}{%
+  \setcounter{corrigeexo}{0}%
+  \section*{Corrig\'es des sujets de concours \bighrulefill}
+  \nonbreak{3}%
+}
+{}
 \newenvironment{@CorrExosTP}{%
   \setcounter{corrigeexo}{0}%
   \section*{Corrig\'es des exercices de travaux pratiques