Affichage des articles dont le libellé est PWM. Afficher tous les articles
Affichage des articles dont le libellé est PWM. Afficher tous les articles

lundi 8 août 2016

How To Make Your Own Robot Controlled With C#, Followed By A WebCam.

How To Make Your Own Robot Controlled With C#, Followed By A WebCam. 

Hello my dears followers, Like it is mentionned in the article title. Today i m going to demonstrate how we could make an intelligent robot, Controlled by your own C# application made in Visual Studio 2012, Followed by a WebCam.





To Make a full project like this one you have many choices to choose. 
The Hard part of this project is done using an Atmega 328p like a principal MCU. You could use any other MCU, For exemple A PIC like PIC16F877 is able also to replace the Atmega328p.
We know that the principal MCU based on the Arduino UNO is ATmega328 so You Could also use Arduino to get the robot working.

ATmega 328p pins 



   
Those Kind of project based essentially an serial communication. so you have just to use a MCU able to support UART.
There is a step in my project based in PWM so the MCU used have to support PWM also.
And for those how dont know what that means UART and PWM they have just to take a look here:

I choosed directly the ATmega 328p because this one is easier in programming and cheap in price. 
Résultat de recherche d'images pour "atmega328"
ATmega 328p


The robot move in 4 directions using a 4 simple DC motors, and those motors are controlled by 2 L293D.
The camera is just placed in the first servomotor. and this one is place in other one to get sure that the position where the camera is putted could  cover every point. 
Résultat de recherche d'images pour "servo motor web cam"
Placing the WebCam

I showed in this article programming ATmega like an Arduino how to program an ATmega32p like programming a simple arduino. this solution is used today also and this is the full program placed in the MCU memory to make the robot moving.



/*  Control and follow your robot using c# application and webcam 
 *  Project done by : Aymen Lachkhem
 *  Aymenlachkem@gmail.com
 *  Blog site : letselectronic.blogspot.com
 */
#include <Servo.h>
Servo myservo1;
Servo myservo2;
void setup() {
         pinMode(A0, OUTPUT);
         pinMode(A1, OUTPUT);
         pinMode(A3, OUTPUT);
         pinMode(A4, OUTPUT);
         pinMode(2, OUTPUT);
         pinMode(3, OUTPUT);
         pinMode(4, OUTPUT);
         pinMode(5, OUTPUT);
         pinMode(6, OUTPUT);
         pinMode(7, OUTPUT);         
         pinMode(11, OUTPUT);
         pinMode(12, OUTPUT);
         digitalWrite(A0,LOW);
         digitalWrite(A1,LOW);
         digitalWrite(A3,LOW);
         digitalWrite(A4,LOW);
         digitalWrite(2,LOW);
         digitalWrite(3,LOW);
         digitalWrite(4,LOW);
         digitalWrite(5,LOW);
         digitalWrite(6,LOW);
         digitalWrite(7,LOW);
         digitalWrite(11,LOW);
         digitalWrite(12,LOW);
           myservo1.attach(9);
           myservo2.attach(10);
            int i1 = 0;
            int i2 = 90;
         myservo1.write(i1);
         myservo2.write(i2);
}

void loop() {       
  blinker();
  Serial.begin(9600);  
   if (Serial.available() > 0) {
    char a = Serial.read();
if ( a == '1'){robot_left(); }  
if ( a == '2'){robot_up();}
if ( a == '3'){robot_right();}
if ( a == '4'){robot_down();}
if ( a == '5'){camera2_down();}
if ( a == '6'){camera1_up();}
if ( a == '7'){camera2_up();}
if ( a == '8'){camera1_down();}
}}
void blinker()
{ 
  digitalWrite(A3,HIGH);
  digitalWrite(A4,LOW);
  delay(100);
  digitalWrite(A3,LOW);
  digitalWrite(A4,HIGH);
  delay(100);
}  
void robot_left()
{
  digitalWrite(A1,HIGH);
  digitalWrite(A0,LOW);
  digitalWrite(2,HIGH);
  digitalWrite(3,LOW);
  digitalWrite(4,LOW);
  digitalWrite(5,HIGH);
  digitalWrite(6,LOW);
  digitalWrite(7,HIGH);
}
void robot_up()
{
  digitalWrite(A1,HIGH);
  digitalWrite(A0,LOW);
  digitalWrite(2,HIGH);
  digitalWrite(3,LOW);
  digitalWrite(4,HIGH);
  digitalWrite(5,LOW);
  digitalWrite(6,HIGH);
  digitalWrite(7,LOW);  
}  
void robot_right()
{
  digitalWrite(A0,HIGH);
  digitalWrite(A1,LOW);
  digitalWrite(3,HIGH);
  digitalWrite(2,LOW);
  digitalWrite(4,HIGH);
  digitalWrite(5,LOW);
  digitalWrite(6,HIGH);
  digitalWrite(7,LOW);  
}
void robot_down()
{
  digitalWrite(A0,HIGH);
  digitalWrite(A1,LOW);
  digitalWrite(3,HIGH);
  digitalWrite(2,LOW);
  digitalWrite(5,HIGH);
  digitalWrite(4,LOW);
  digitalWrite(7,HIGH);
  digitalWrite(6,LOW);  
}

void camera2_down()
{
  int i3 = myservo2.read();
  myservo2.write(i3 - 1);
}
void camera2_up()
{
  int i4 = myservo2.read();
  myservo2.write(i4 + 1);
}
void camera1_down()
{
  int i5 = myservo1.read();
  myservo1.write(i5 - 1);
}
void camera1_up()
{
  int i6 = myservo1.read();
  myservo1.write(i6 + 1);
}


   


This is The Complet Circuit that you have to draw.

Full Circuit




The Hard part of the project is just done so let's talk about the soft part.
We have here to build an Application based in serial communication able to connect directly the robot.
There is many solution to do this, for exemple Labview is one of the best interfacing system also Visual Basic or C#.
I  used C# to do this. A simple application in one only panel with a serial communication platform.
Many Buttons to control the robot and the camera.







How The Application Work ?

This is simple, We have just to add a serial platform to the app. This one will always ask for the port com and the baud rate. Since the moment your choose your serial parametres the fonctionnemnet of buttons starts. 
Every button you will click will send a code to the MCU and exactly like this that's working.

Résultat de recherche d'images pour "serial communication"



How the WebCam Works ?

In fact, there is a direct library you have to add to your visual studio named AFroge.net Direct Download. After adding this one to your visual studio you have to add this two reference to your project.






The rest is easy, you have just to give the application the permission to look for webcam devices plug in your computer, starts showing what she see, Capture button to save directly the view.

This is the full program written with C# in Visual Studio 2012.

/* Robot controlled by C# , Follewed by a Webcam
Letselectronic.blogspot.com
aymenlachkem@gmail.com
*/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using AForge.Video.DirectShow;
using System.IO.Ports;
using System.Diagnostics;


namespace Camera_Project_Lachkhem
{
    public partial class Form1 : Form
    {
        VideoCaptureDevice capture;

        public Form1()
        {
            InitializeComponent();
            getAvailablePorts();


            FilterInfoCollection info = new FilterInfoCollection(FilterCategory.VideoInputDevice);
            if (info != null)
            {
                capture = new VideoCaptureDevice(info[0].MonikerString);
                capture.NewFrame += (s, e) => pictureBox1.Image = (Bitmap)e.Frame.Clone();
                capture.Start();
            }
        }
        void getAvailablePorts()
        {
            string[] Ports = SerialPort.GetPortNames();
            portcom.Items.AddRange(Ports);
        }
        private void button1_Click(object sender, EventArgs e)
        {
            pictureBox1.Image.Save("snapchot.png", System.Drawing.Imaging.ImageFormat.Png);
        }
        protected override void OnClosed(EventArgs e)
        {
            base.OnClosed(e);
            if (capture != null && capture.IsRunning)
            {
                capture.SignalToStop();
                capture = null;

            }

        }

        private void button2_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void dateTimePicker1_ValueChanged(object sender, EventArgs e)
        {

        }

        private void label5_Click(object sender, EventArgs e)
        {

        }

        private void connecter_Click(object sender, EventArgs e)
        {
            {
                try
                {
                    if (portcom.Text == "" || baudrate.Text == "")
                    {
                        textbox1.Text = "Please select port setting ? ";
                    }
                    else
                    {

                        serialPort1.PortName = portcom.Text;
                        serialPort1.BaudRate = Convert.ToInt32(baudrate.Text);
                        progressBar1.Value = 100;
                        textbox1.Text = "Connected";


                    }
                }
                catch (UnauthorizedAccessException)
                {
                    baudrate.Text = "Unauthorized Access";
                }
            }
        }

        private void button3_Click(object sender, EventArgs e)
        {
            serialPort1.Close();
            progressBar1.Value = 0;
        }

        private void Contact_Me_Click(object sender, EventArgs e)
        {
            ProcessStartInfo startInfo = new ProcessStartInfo("iexplore.exe", "http://https://letselectronic.blogspot.com/p/blog-page.html/");
            Process.Start(startInfo);
        }

        private void Visit_My_Blog_Click(object sender, EventArgs e)
        {
            ProcessStartInfo startInfo = new ProcessStartInfo("iexplore.exe", "http://https://letselectronic.blogspot.com/p/blog-page.html/");
            Process.Start(startInfo);
        }

        private void button12_Click(object sender, EventArgs e)
        {
            var myLines = new List<string>();

            myLines.Add("Hello, This Windows application give their Users the ability to control serially or with wirless communication a Robot Followed By a WebCam.");
            myLines.Add("- The MCU used is The high-performance Atmel 8-bit AVR RISC-based microcontroller ATmega 328 ");
            myLines.Add("- The Control Application was made in Visual Studio 2012, written using C# ");
            

            myLines.Add("----------------------------------------- Blog: Letselectronic.blogspot.com ----------------------------------------------------------------------");
            myLines.Add("----------------------------------------- Contact: Aymenlachkem@gmail.com ------------------------------------------------------------------");

            textBox2.Lines = myLines.ToArray();
        }

        private void button7_Click(object sender, EventArgs e)
        {
            serialPort1.Open();
            serialPort1.Write("1");
            serialPort1.Close();
        }

        private void button5_Click(object sender, EventArgs e)
        {
            serialPort1.Open();
            serialPort1.Write("2");
            serialPort1.Close();
        }

        private void button8_Click(object sender, EventArgs e)
        {
            serialPort1.Open();
            serialPort1.Write("3");
            serialPort1.Close();
        }

        private void button6_Click(object sender, EventArgs e)
        {
            serialPort1.Open();
            serialPort1.Write("4");
            serialPort1.Close();
        }

        private void button11_Click(object sender, EventArgs e)
        {
            serialPort1.Open();
            serialPort1.Write("6");
            serialPort1.Close();
        }

        private void button4_Click(object sender, EventArgs e)
        {
            serialPort1.Open();
            serialPort1.Write("5");
            serialPort1.Close();
        }

        private void button9_Click(object sender, EventArgs e)
        {
            serialPort1.Open();
            serialPort1.Write("7");
            serialPort1.Close();
        }

        private void button10_Click(object sender, EventArgs e)
        {
            serialPort1.Open();
            serialPort1.Write("8");
            serialPort1.Close();
        }

        private void turn_on_Click(object sender, EventArgs e)
        {
            serialPort1.Open();
            serialPort1.Write("9");
            serialPort1.Close();
        }

        private void turn_off_Click(object sender, EventArgs e)
        {
            serialPort1.Open();
            serialPort1.Write("a");
            serialPort1.Close();
        }
    }
}






Built your application, Get your file.exe and the Setup. Like always this is a video for more details.

I have all files of this project collected in compressed directory so just contact me to have your free files.



                                                                 See you Soon AYMEN LACHKHEM

   





lundi 28 mars 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 : 





dimanche 17 janvier 2016

Interfacing Servo-Motor With STM32


Interfacing Servo-Motor With STM32



Bonjour, Aujourd'hui on va discuter le fonctionnent du servo moteur en essayant de le contrôler avec un STM32F4, contrôler veut dire contrôler quelle angle il la tourne vers. donc Commençons par une petite définition d'un servomoteur.

Un servomoteur est un système motorisé capable d'atteindre des positions prédéterminées, puis de les maintenir. La position est : dans le cas d’un moteur rotatif, une valeur d'angle et, dans le cas d’un moteur linéaire une distance. On utilise des moteurs électriques (continu, asynchrone, brushless) aussi bien que des moteurs hydrauliques. Le démarrage et la conservation de la position prédéterminée sont commandés par un système de réglage.     

Mais savez vous que la commande de servo-moteur est pas totalement comme le moteur dc genre on l'alimente alors il tourne ? savez vous que chaque servo-moteur a sa propre méthode de commande et de fonctionnement ?
On peut tout être d'accord que chaque servo moteur il fonctionne avec un signal PWM pulse with modulation que j'ai déjà définit sur cet article PWM. Mais il faut bien comprendre que chaque servo a sa propre façon de commande qu'on peut seulement la comprendre sur son fichier technique.

Alors pour comprendre le fonctionnement de chaque un, on qu'aller a sa fichier technique et lire exactement le pulse associer a chaque angle par rapport au période cyclique qu'il a chaque un . citons cette exemple 

les servomoteurs sont commander par les envoyer des pulsations. Ici le servo doit recevoir chaque 20 ms une pulsation ou le longueur de cette dernière va indiquer a quelle angle exactement il doit tourner notre servomoteur. 

Voila cette exemple:
  • si a chaque 20 ms j'envoi une pulsation de longueur 1 ms le servo va tourner vers 0 degré 
  • si a chaque 20 ms j'envoi une pulsation de 1.5 ms le servo va tourner précisément vers 90 degré
  • ......


D'ici on peut conclure la méthode de la quelle le servo on doit le commander avec notre microcontrôleur, une seule sortie numérique est capable de le commander si je la met on niveau haut pendant la période ou pulsation est active et je la met en niveau bas pendant le reste de la période (20ms - pulsation).

Aujourd'hui je vais commander ce servomoteur via une carte STM32 F4
Résultat de recherche d'images pour "servomoteurs"
on se référant de sa fichier technique j'ai écris le programme suivant:




//Let's electronic By Aymen Lachkhem
// Interfacing Servo-motor to STM32
// Letselectronic.blogspot.com
void servoRotate0() //0 Degree
{
  unsigned int i;
  for(i=0;i<50;i++)
  {
    gpiob_odr.f3 = 1;
    Delay_us(1000);
    gpiob_odr.f3 = 0;
    Delay_us(19000);
  }
}
     void servoRotate90() //90 Degree
{
  unsigned int i;
  for(i=0;i<50;i++)
  {
    gpiob_odr.f3 = 1;
    Delay_us(2500);
    gpiob_odr.f3 = 0;
    Delay_us(17500);
  }
}
     void servoRotate180() //180 Degree
{
  unsigned int i;
  for(i=0;i<50;i++)
  {
    gpiob_odr.f3 = 1;
    Delay_us(4400);
    gpiob_odr.f3 = 0;
    Delay_us(16000);
  }
}
void main(){


GPIO_Digital_Output(&GPIOB_ODR, _GPIO_PINMASK_3);     // configuration of pb3 as Digital Output
GPIO_Digital_Input (&GPIOA_BASE, _GPIO_PINMASK_3 | _GPIO_PINMASK_4 | _GPIO_PINMASK_5); // configure PORTA pins as speed control input
  while (1) {
     if (GPIOA_IDR.B3) {
    servoRotate0(); //0 Degree
    Delay_ms(2000);}
     if (GPIOA_IDR.B4) {
    servoRotate90(); //90 Degree
    Delay_ms(2000);}
     if (GPIOA_IDR.B5) {
    servoRotate180(); //180 Degree
    Delay_ms(2000);}
  }
}


Il est tout indiquer au commentaire de programme a propos la configuration, le principe est totalement simple ou j'aurai 3 entrées numériques que je vais utiliser comme des boutons poussoires qui vont forcer le servo moteur relier au  sortie numérique a tournée vers une angle bien précise comme il est citer au vidéo au dessous 


Une démonstration vidéo qui résume tout le travail fait.



   




samedi 16 janvier 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 :