Showing posts with label Speed Motor. Show all posts
Showing posts with label Speed Motor. Show all posts

Monday, March 28, 2016

Generate PWM Signal From Spartan 3E

Let's get PWM Using Spartan 3E

Dans la meme s�rie de tutoriels que j'ai fait au but de la d�couverte de technologie FPGA et en particulier la carte Spartan 3E, Aujourd'hui je vais vous montrer comment on fait pour generer un signal PWM (pulse widh modulation), vous expliquer les �tapes de programmation que j'ai fait en passant par un test pratique d�monstratif.



Afficher l'image d'origine

La modulation de largeur d'impulsions (MLI ; en anglais : Pulse Width Modulation, soit PWM), est une technique couramment utilis�e pour synth�tiser des signaux continus � l'aide de circuits � fonctionnement tout ou rien, ou plus g�n�ralement � �tats discrets.
Le principe g�n�ral est qu'en appliquant une succession d'�tats discrets pendant des dur�es bien choisies, on peut obtenir en moyenne sur une certaine dur�e n'importe quelle valeur interm�diaire.

R�sultat de recherche d'images pour "pwm mli definition"






Ce ph�nom�ne est fortement recommand� pour assurer la variation de vitesse de moteur a courant continu, aujourd'hui je vais vous d�montrer comment on peut g�n�rer un signal PWM d'une carte FPGA Spartan 3E et visualiser son pr�sence sur des diodes LEDs.


R�sultat de recherche d'images pour "FPGA pwm"  

Passons maintenant au programmation; 


Voici le programme  du projet :



PWM Top Code :

----------------------------------------------------------------------------------
-- Company: There is no company
-- Engineer: Aymen Lachkhem
--
-- Create Date: 02:27:11 03/27/2016
-- Design Name:
-- Module Name: counter - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity top is
Port (
clk : in std_logic;
pwm_out : out std_logic;
rotary_a : in std_logic;
rotary_b : in std_logic
);end top;

architecture Behavioral of top is
component pwm
port(
clk: in std_logic;
pwm_var: in std_logic_vector(7 downto 0);
pwm_out: out std_logic);
end component;
component rotary
port(
pwm_var : out std_logic_vector(7 downto 0);
rotary_a : in std_logic;
rotary_b : in std_logic;
clk : in std_logic);
end component;
signal pwm_var: std_logic_vector (7 downto 0);
begin
U1 : pwm
port map(
clk => clk,
pwm_var=>pwm_var,
pwm_out=>pwm_out
);
U2 : rotary
port map(
pwm_var=>pwm_var,
rotary_a=>rotary_a,
rotary_b=>rotary_b,
clk =>clk
);
end Behavioral;



Pour les configurations physiques de mon programme avec la carte Spartan 3E j'ai choisis ces entr�es sorties: 
NET "clk" PERIOD = 20.0ns HIGH 50%;
NET "clk" LOC = "C9" | IOSTANDARD = LVTTL;
NET "rotary_a"     LOC = "K18" | IOSTANDARD = LVTTL | PULLUP;
NET "rotary_b"     LOC = "G18" | IOSTANDARD = LVTTL | PULLUP;
NET "pwm_out" LOC = "D5" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 6 ;


Le programme TOP il inclus deux component que j'ai �cris en VHDL aussi :



PWM Code :

----------------------------------------------------------------------------------
-- Company: There is no company
-- Engineer: Aymen Lachkhem
--
-- Create Date: 02:27:00 03/27/2016
-- Design Name:
-- Module Name: counter - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;

entity pwm is
port(
clk: in std_logic;
pwm_var: in std_logic_vector(7 downto 0);
pwm_out: out std_logic

);
end pwm;
architecture Behavioral of pwm is
signal counter: std_logic_vector(7 downto 0):="00000000";
signal max_counter: std_logic_vector(7 downto 0):="11111111";
begin
process(clk)
begin
if rising_edge(clk) then
counter <= std_logic_vector( unsigned(counter) + 1 );
if counter=max_counter then
counter<="00000000";
else
if counter<pwm_var then
pwm_out<='1';
else
pwm_out<='0';
end if;
end if;
end if;
end process;
end Behavioral;





Et



ROTARY ENCODER Code :

----------------------------------------------------------------------------------
-- Company: There is no company
-- Engineer: Aymen Lachkhem
--
-- Create Date: 02:24:42 03/27/2016
-- Design Name:
-- Module Name: counter - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity rotary is
Port ( pwm_var : out std_logic_vector(7 downto 0);
rotary_a : in std_logic;
rotary_b : in std_logic;
clk : in std_logic
);end rotary;

architecture Behavioral of rotary is
signal rotary_a_in : std_logic;
signal rotary_b_in : std_logic;
signal rotary_in : std_logic_vector(1 downto 0);
signal rotary_q1 : std_logic;
signal rotary_q2 : std_logic;
signal delay_rotary_q1 : std_logic;
signal rotary_event : std_logic;
signal rotary_left : std_logic;

signal led_pattern : std_logic_vector(7 downto 0):= "00000000";
begin

rotary_filter: process(clk)
begin
if clk'event and clk='1' then
rotary_a_in <= rotary_a;
rotary_b_in <= rotary_b;
rotary_in <= rotary_b_in & rotary_a_in;

case rotary_in is

when "00" => rotary_q1 <= '0';
rotary_q2 <= rotary_q2;

when "01" => rotary_q1 <= rotary_q1;
rotary_q2 <= '0';

when "10" => rotary_q1 <= rotary_q1;
rotary_q2 <= '1';

when "11" => rotary_q1 <= '1';
rotary_q2 <= rotary_q2;

when others => rotary_q1 <= rotary_q1;
rotary_q2 <= rotary_q2;
end case;
end if;
end process rotary_filter;
direction: process(clk)
begin
if clk'event and clk='1' then
delay_rotary_q1 <= rotary_q1;
if rotary_q1='1' and delay_rotary_q1='0' then
rotary_event <= '1';
rotary_left <= rotary_q2;
else
rotary_event <= '0';
rotary_left <= rotary_left;
end if;

end if;
end process direction;
-- PWM control.
led_display: process(clk)
begin
if clk'event and clk='1' then
if rotary_event='1' then
if rotary_left='1' then
led_pattern<=led_pattern+'1'; --INCREASE
else
led_pattern<=led_pattern-'1'; --DECREASE
end if;
end if;
pwm_var <= led_pattern;
end if;
end process led_display;
end Behavioral;






Le reste c'est d�impl�menter  le programme pour avoir ceci : 





Saturday, January 16, 2016

Speed Motor's Variator Using STM32

Speed Motor's Variator Using STM32


R�sultat de recherche d'images pour "stm32 motor"


La variation de vitesse de moteur a courant continu dans cet article est bas�e sur le protocole PWM qu'on peut le d�finir comme ceci :


PWM

La modulation de largeur d'impulsions (MLI ; en anglais : Pulse Width Modulation, soit PWM), est une technique couramment utilis�e pour synth�tiser des signaux continus � l'aide de circuits � fonctionnement tout ou rien, ou plus g�n�ralement � �tats discrets.
Le principe g�n�ral est qu'en appliquant une succession d'�tats discrets pendant des dur�es bien choisies, on peut obtenir en moyenne sur une certaine dur�e n'importe quelle valeur interm�diaire.
R�sultat de recherche d'images pour "pwm mli definition"
Ce ph�nom�ne est fortement recommand� pour assurer la variation de vitesse de moteur a courant continu, aujourd'hui je vais vous d�montrer comment on peut g�n�rer un signal PWM d�une STM32 et visualiser son pr�sence sur des diodes LEDs.

Voici un exemple de comment on genere un signal PWM using Mikro C for ARM et STM32F4:
//Let's Electronic By Aymen Lachkhem
// www.letselectronic.blogspot.com
// Hello in this tutoriel we are going to use 4 buttons (digital Input), the first two will increase and decrease the current duty for the
// first Led and the second two will make the same thing with the other Led.
unsigned int current_duty, old_duty, current_duty1, old_duty1;
unsigned int pwm_period1, pwm_period2;

void InitMain() {
GPIO_Digital_Input (&GPIOA_BASE, _GPIO_PINMASK_3 | _GPIO_PINMASK_4 | _GPIO_PINMASK_5 | _GPIO_PINMASK_6); // configure PORTA pins as input
}

void main() {
InitMain();
current_duty = 100; // initial value for current_duty
current_duty1 = 100; // initial value for current_duty1

pwm_period1 = PWM_TIM1_Init(5000);
pwm_period2 = PWM_TIM4_Init(5000);

PWM_TIM1_Set_Duty(current_duty, _PWM_NON_INVERTED, _PWM_CHANNEL1); // Set current duty for PWM_TIM1
PWM_TIM4_Set_Duty(current_duty1, _PWM_NON_INVERTED, _PWM_CHANNEL2); // Set current duty for PWM_TIM4

PWM_TIM1_Start(_PWM_CHANNEL1, &_GPIO_MODULE_TIM1_CH1_PE9);

PWM_TIM4_Start(_PWM_CHANNEL2, &_GPIO_MODULE_TIM4_CH2_PD13);

while (1) { // endless loop
if (GPIOA_IDR.B3) { // button on RA3 pressed
Delay_ms(1);
current_duty = current_duty + 5; // increment current_duty
if (current_duty > pwm_period1) { // if we increase current_duty greater then possible pwm_period1 value
current_duty = 0; // reset current_duty value to zero
}
PWM_TIM1_Set_Duty(current_duty, _PWM_NON_INVERTED, _PWM_CHANNEL1); // set newly acquired duty ratio
}

if (GPIOA_IDR.B4) { // button on RA4 pressed
Delay_ms(1);
current_duty = current_duty - 5; // decrement current_duty
if (current_duty > pwm_period1) { // if we decrease current_duty greater then possible pwm_period1 value (overflow)
current_duty = pwm_period1; // set current_duty to max possible value
}
PWM_TIM1_Set_Duty(current_duty, _PWM_NON_INVERTED, _PWM_CHANNEL1); // set newly acquired duty ratio
}

if (GPIOA_IDR.B5) { // button on RA5 pressed
Delay_ms(1);
current_duty1 = current_duty1 + 5; // increment current_duty
if (current_duty1 > pwm_period2) { // if we increase current_duty1 greater then possible pwm_period2 value
current_duty1 = 0; // reset current_duty1 value to zero
}
PWM_TIM4_Set_Duty(current_duty1, _PWM_NON_INVERTED, _PWM_CHANNEL2); // set newly acquired duty ratio
}

if (GPIOA_IDR.B6) { // button on RA6 pressed
Delay_ms(1);
current_duty1 = current_duty1 - 5; // decrement current_duty
if (current_duty1 > pwm_period2) { // if we decrease current_duty1 greater then possible pwm_period1 value (overflow)
current_duty1 = pwm_period2; // set current_duty to max possible value
}
PWM_TIM4_Set_Duty(current_duty1, _PWM_NON_INVERTED, _PWM_CHANNEL2);
}

Delay_ms(1); // slow down change pace a little
}
}
    Voici une d�monstration vid�o de fonctionnement :




L�objectif de ce tutoriel est de mettre en oeuvre le contr�le de vitesse de moteur a courant continu de fa�on autonome 
Pour ceci on aura besoin de 
Un Moteur DC
STM32 F4
Transistor TIP122
Diode
Deux boutons poussoirs 
deux r�sistances 1 K

Le principe est tout � fait simple on aura deux boutons poussoirs ou la premi�re va incr�menter la vitesse de moteur et la deuxi�me va faire exactement le contraire.

L�incr�mentation continuera jusqu�� alimenter le moteur en r�gime de rapport cyclique complet puis conditionnement une autre incr�mentation va le remettre a 0 tour/s, le m�me truc se passe avec la d�cr�mentation de rapport d�ja nul va le rendre on vitesse maximale.


Voici un exemple de comment on varie le vitesse de moteur a courant continu using Mikro C for ARM et STM32F4:

//Let's Electronic By Aymen Lachkhem
//
www.letselectronic.blogspot.com
// In This Tutorial We are going to control the speed of dc motor using Stm32 PWM.
unsigned int current_duty, old_duty;
unsigned int pwm_period1, pwm_period2;

void InitMain() {
GPIO_Digital_Input (&GPIOA_BASE, _GPIO_PINMASK_3 | _GPIO_PINMASK_4 ); // configure PORTA pins as speed control input
}

void main() {
InitMain();
current_duty = 100; // initial value for current_duty


pwm_period1 = PWM_TIM1_Init(5000);


PWM_TIM1_Set_Duty(current_duty, _PWM_NON_INVERTED, _PWM_CHANNEL1); // Set current duty for PWM_TIM1

PWM_TIM1_Start(_PWM_CHANNEL1, &_GPIO_MODULE_TIM1_CH1_PE9);



while (1) { // endless loop
if (GPIOA_IDR.B3) { // button on RA3 pressed
Delay_ms(1);
current_duty = current_duty + 1; // increment speed
if (current_duty > pwm_period1) { // if we increase current_duty greater then possible pwm_period1 value
current_duty = 0; // reset current_duty value to zero
}
PWM_TIM1_Set_Duty(current_duty, _PWM_NON_INVERTED, _PWM_CHANNEL1); // set newly acquired duty ratio
}

if (GPIOA_IDR.B4) { // button on RA4 pressed
Delay_ms(1);
current_duty = current_duty - 3; // decrement speed
if (current_duty > pwm_period1) { // if we decrease current_duty greater then possible pwm_period1 value (overflow)
current_duty = pwm_period1; // set current_duty to max possible value
}
PWM_TIM1_Set_Duty(current_duty, _PWM_NON_INVERTED, _PWM_CHANNEL1); // set newly acquired duty ratio
}

Delay_ms(1); // slow down change pace a little
}
}
    Voici une d�monstration vid�o de fonctionnement :