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... 

Aucun commentaire:

Enregistrer un commentaire