jeudi 28 novembre 2013

Fabrication des pièces

Je vais présenter ici quelques pièces que j'ai réalisé.
Je remercie le responsable du laboratoire de mécanique où j'ai effectué mon dernier stage. Il a eu la bienveillance de m'apprendre à utiliser Inventor pour la conception 3D et aussi à utiliser les machines-outils afin d'être autonome. Sans cela je n'aurai peut-être pas entamé ce projet.


La tige de guidage

Pour cette pièce, un tube en acier d'environ 12 mm de diamètre et 400 mm de long, elle était trop longue à l'origine, il a donc fallut l'usiner pour l'adapter aux dimensions de l'ensemble.

Dessin technique

Tronçonnage et dressage au tour...


Ce sera plus parlant avec une vidéo.
Cette extrait nous montre les différentes étapes de la réalisation de cette pièce au tour.


mercredi 27 novembre 2013

Les premiers pas de l'asservissement en position

Après avoir implémenté le PID numérique sur la carte FPGA et réalisé l'interface avec Labview, voici ce que cela donne.


Dans la vidéo on peut voir l'algorithme en action. Les paramètres ne sont pas encore réglés mais on a déjà un avant gout de sont fonctionnement. Quand j'aurai la table terminé je m'occuperai des réglages et de l'implémentation de l'asservissement en vitesse.


On ne voit pas très bien sur la vidéo mais il est possible de changer les paramètres PID en temps réel.Quand j'augmente la valeur de l'intégral Ki le système diverge.


dimanche 29 septembre 2013

Transmission de la position sur LabView

Il serait intéressant de pouvoir d'afficher la position du chariot sur l'ordinateur pour régler l'asservissement. Pour cela j'utilise LabView avec lequel on peut acquérir, traiter des données et afficher des courbes. Dans cette partie je présenterai la méthode que j'ai utilisée pour transmettre les coordonnées en prenant en compte les spécificités du port série notamment la vitesse de transmission et nombre de bits par trame.

Méthode

Une première idée qui vient à l'esprit pour transmettre la position est simplement d'envoyer la valeur de cette position à chaque instant. Mais sur le chariot on peut avoir jusqu'à 7500 incréments avec 13 bits par incrément (2^13 = 8192). De plus, le temps pour passer de la position 0 à 7500 est grossièrement d'un quart de seconde à vitesse maximale, soit 30 000 positions par seconde. A 13 bits par position il faudrait d'un débit de 390 kbits/sec alors que le débit maximal du port série est de 115,2 kbits/sec.
Pour palier ce problème, au lieu d'envoyer la valeur brut, le système envoie la différence de position delta à intervalle de temps régulier, LabView se charge ensuite d'ajouter à la position initiale cette différence.
Pour un intervalle de 1 milliseconde, on a au maximum une différence de 30 incréments encodable sur 6 bits soit 5 bits pour la valeur et 1 bit de signe. Ainsi un débit de 6 kbits/sec est suffisant pour cette méthode.

Algorithme

Le logigramme suivant représente l'algorithme utilisé pour réaliser ceci.


Explication
A l'état initial, si enable le signal d'autorisation de comptage à la sortie du codeur passe à l'état haut, celui-ci est compté puis on passe à l'état START. Les incréments sont ajoutés pendant l'intervalle de temps. Par sécurité, pour ne pas oublier un incrément, si on en reçoit un à exactement 1 milliseconde, le temporisateur redémarre et on continu à incrémenter. Bien sur on dépasserai les 30 valeurs maximales, mais comme on peut encoder sur toute une trame de 8 bits, on a donc doit à 4 fois à la suite à grande vitesse, ce qui n'est pas très probable vu la vitesse de l'horloge.

Programme VHDL

entity FSM_delta is
port(
clk: in std_logic;
reset : in std_logic;
enable : in std_logic;
downup : in std_logic;
delta_done : out std_logic;
delta: out std_logic_vector(7 downto 0));
end FSM_delta;

architecture behavior of FSM_delta is
type state_type is (idle, start);
signal state_reg, state_next: state_type;
signal d_reg, d_next : std_logic_vector(7 downto 0) :=(others => '0');
signal cnt_reg, cnt_next : std_logic_vector(6 downto 0) :=(others => '0');
signal done_reg, done_next : std_logic := '0';

begin
process(clk, reset)
begin
if (reset = '1') then
state_reg <= idle;
d_reg <= (others => '0');
cnt_reg <= (others => '0');
d_reg <= (others => '0');
elsif (clk'event and clk='1') then
state_reg <= state_next;
d_reg <= d_next;
cnt_reg <= cnt_next;
done_reg <= done_next;
delta <= d_reg;
end if;
end process;
-- next state logic
process (clk, downup, d_reg, enable, cnt_reg, state_reg, done_reg)
begin
state_next <= state_reg;
d_next <= d_reg;
cnt_next <= cnt_reg;
done_next <= done_reg;
case state_reg is
when idle =>
done_next <= '0';
if (enable = '1') then
state_next <= start;
if (downup = '1')then
d_next <= d_reg + 1;
else d_next <= d_reg - 1;
end if;
end if;

when start =>
if (enable = '1') then
if (downup = '1')then d_next <= d_reg + 1; -- incrementation
else d_next <= d_reg - 1;                  -- decrementation
end if;
end if;
if (cnt_reg = "1100011" and enable = '1') then -- cnt_reg depend de l'horloge
cnt_next <= (others => '0');
state_next <= start;
elsif (cnt_reg = "1100011" and enable = '0') then
cnt_next <= (others => '0');
d_next <= (others => '0');
state_next <= idle;
done_next <='1';
else
cnt_next <= cnt_reg + 1;
end if;
end case;
end process;
delta_done <= done_reg;
end behavior;

Vidéo à suivre dans les prochains articles... 

mercredi 18 septembre 2013

PID numérique

Présentation

L’objectif de l’asservissement PID (Proportionnel Intégral Dérivé) est de stabiliser le système en fonction d’une consigne. On cherche à atteindre une position donnée dans le cas du chariot, en traitant l'erreur entre la consigne et la mesure fournit par le capteur par le contrôleur PID, la nouvelle valeur obtenue sert de commande pour le moteur. On aura donc compris que la commande joue simplement sur la vitesse du moteur à travers le PWM.

Structure d'une boucle d'asservissement:


Ce modèle est une structure en parallèle mais il existe plusieurs architectures de PID, en série ou mixte.

Il y a trois paramètres à régler:

  • L’action proportionnel P: amplifie l’erreur d’un facteur Kp (le gain) permettant une réaction plus rapide du système au changement de consigne en fonction du gain, mais peut faire diverger le système si celui-ci est trop élevé.
  • L’action intégrale I: pour compenser l’erreur statique que l’action proportionnelle ne peut pas prendre en charge, l’action intégrale intègre cette erreur pendant un temps Ti, le résultat est ensuite ajouté à la commande. Plus cette action est importante, plus les oscillations autour de la consigne seront accentuées.
  • L’action dérivé D: cette action dérive l’erreur pendant un temps Td, cela permet de diminuer les dépassements et le temps de stabilisation mais est très sensible au bruit.

Un peu de mathématiques pour déterminer l'algorithme du PID numérique

Les calculs suivants traiteront de la forme parallèle du contrôleur PID comme on vient de voir. Il peut paraître fastidieux, j'ai donc essayé de simplifier. Ce qu'il faut vraiment retenir c'est le résultat final et la signification de chaque terme de l'équation.


Pour un contrôleur PID parallèle, l'équation à temps continu s’écrit:
u(t) et ε(t) représentent respectivement le signal de commande et d’erreur à l’instant t. K est le gain proportionnel, Ti le temps d’intégration et Td le temps de dérivation.

A temps discret l’intégrale et la dérivée deviennent:

Te est la période d’échantillonnage.

D’où l’équation du PID à temps discret:
Ce qui permet de définir les paramètres Kp, Ki et Kd en fonction de la période d’échantillonnage:

Maintenant revenons sur l’équation du début à temps continu. Sa transformée de Laplace s'écrit:
L’équivalent à temps discret de la transformée de Laplace est la transformée en Z, ce qui nous donne:
Si on prend en compte les paramètres Kp , Ki et Kd décrits précédemment on aura donc:
En réarrangeant:
Ou encore:

Avec

 En mettant sous la forme d’'une équation aux différences on obtient:
u[k] est la valeur de la commande à l'instant k, elle est calculée en fonction des valeurs de commande et d'erreur à des instants passés représentés par k-1 et k-2.
Cette forme d’équation devient alors facilement implémentable en logique programmable par l'utilisation de bascule D, multiplieurs et additionneurs. 

Schéma bloc du contrôleur PID parallèle numérique:



Programme VHDL

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity PID_simple is
port( clk : in std_logic;
set_point : in signed(15 downto 0); --signal de commande
measure : in signed(15 downto 0); --signal de control
K1,K2,K3 : signed(7 downto 0) := (others => '0'); --parametre PID
PIDout : inout signed(23 downto 0));  --sortie asservissement
end PID_simple;
architecture behavior of PID_simple is
signal error_prev1, error_prev2, error : signed(15 downto 0) := (others => '0');
signal u_prev, add_out : signed(23 downto 0) := (others => '0');
begin
error <= set_point - measure; --calcul de l erreur
add_out <= u_prev + K1*error + K2*error_prev1 + K3*error_prev2; --equation aux differences
process(clk) --retard
begin
if(rising_edge(Clk)) then
error_prev1 <= error;
error_prev2 <= error_prev1;
u_prev <= add_out;
PIDout <= add_out;
end if;
end process;
end behavior;

samedi 14 septembre 2013

Hacheur pour moteur DC

On peut alimenter le moteur et ajuster sa vitesse de rotation en variant le rapport cyclique α du hacheur PWM. Pour être efficace, la fréquence de hachage de ce dernier doit être choisit correctement.

Soit le hacheur en série au borne d'un moteur à courant continu:

On obtient les signaux suivants:
Où I est le courant traversant le moteur

Le calcul de l’ondulation du courant aux bornes du moteur nous donne :
Avec L l’inductance interne du moteur et f la fréquence du hacheur. Notons que la résistance interne du moteur peut être négligée.

Cette valeur est maximal quand α=0,5 d’où :
On essaiera de diminuer ∆imax pour éviter d’avoir des ondulations trop importantes. Pour cela on peut ajouter une inductance en série avec le moteur qui permettra de lisser le courant à ses bornes ou encore augmenter la fréquence de hachage.

vérification expérimentale en cours...

mercredi 11 septembre 2013

Un PWM en VHDL

Un exemple de PWM (Pulse With Modulation) en VHDL. Le rapport cyclique du signal de sortie est contrôlé à l'entrée duty_cycle de 0 à 100% par pas de 10.



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

entity pwm is port (
      clk: in std_logic;
      SW : in std_logic_vector (3 downto 0); --rapport cyclique (de 0 à 10) 
      reset : in std_logic;
      GPIO_0 : out std_logic_vector(35 downto 0)); -- sortie
end pwm;

architecture behavior of pwm is

signal cnt : std_logic_vector(3 downto 0) := "0000";
signal s : std_logic;

begin
process (clk,rst) begin
  if reset ='1' then s<=(others=>'0');
  elsif (clk'event and clk='1') then
    if (cnt < SW) then s <='1'; --met la sortie à 1 jusqu'a 
    else s <='0';               --la valeur du rapport cyclique
    end if;
    if (cnt >= "1001") then cnt<="0000"; --remet le compteur à 0 
    else cnt <= cnt + 1;                 --quand on a compté jusqu'a 10
    end if;
  end if;
end process;
GPIO_0(29) <= s;
end behavior;

Simulation sous ModelSim


Le circuit L298

Comparé au circuit utilisant le relais mécanique, avec le circuit L298 ou Dual Full-Bridge Driver, on a un pilotage assez aisé des moteurs. Il intègre 2 ponts en H, idéal pour chaque moteur. Le pont en H a pour but de changer le sens de rotation en mettant à l'état logic '1' l'une ou l'autre des entrées dédiées IN1 et IN2. Une entrée Enable autorise ou non le contrôle du pont. On peut ainsi adjoindre un signal PWM pour faire varier la vitesse de rotation en hachant la tension l'alimentation. Cela devient donc plus simple pour un microcontrôleur.

Schéma électronique du pont en H


Lorsque ENABLE = '1', si IN1 = '1' et IN2 = '0' les transistors T1 et T4 sont saturés laissant passer le courant dans le moteur dans un sens, T2 et T3 sont bloqué. Si maintenant IN1 = '0' et IN2 = '1', c'est T2 et T3 qui laisse passer le courant dans l'autre sens. Pour IN1 et IN2 dans le même état logique, on a affaire à un freinage moteur.

Schéma de montage du L298


Les 4 diodes aux bornes du moteur sont des diodes rapides ou diodes de Schottky. Elles jouent principalement le rôle de diode de roue libre pour l'inductance interne du moteur afin de protéger le circuit des surtensions lors du freinage.
On inclut dans le montage des capacités de découplage. Ces capacités, placées au plus près de l'alimentation des circuits numériques vont supprimer les signaux hautes fréquences parasites qui pourraient remonter le long de la ligne d'alimentation, par exemple lors du hachage créé par le PWM.
Une résistance placée entre la masse et le circuit de puissance permet de déterminer le courant traversant le moteur par la loi d'Ohm en mesurant la tension à ses bornes. Elle sert de shunt de mesure.
Pour plus de détails sur le L298, consulter le datasheet.


Voici le L298, une modification a été apportée au niveau des pattes car les dimensions ne sont pas adaptées à la platine d'essai. Il est aussi nécessaire d'ajouter un dissipateur thermique par rapport au courant qui peu monter jusqu'à 1A voir 2A pour les deux moteurs en service.