Asservissement vitesse d'un moteur à courant continu

on Wednesday, July 27, 2011
Dans le cadre d'un projet en matière technologie d’acquisition et d'interfaçage j'ai réaliser ce projet qui est mieux expliquer dans la photo en bas.
Schéma synoptique
l'interface:
La carte sur isis:
 PCB sur ARES:

 

Code en c#


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;

namespace WindowsFormsApplication1
{
    using ZedGraph;
    public partial class Form1 : Form
    {
        float temps=0;
        float consigne=0;
        float commande=0;
        float fecartold;
        float fIntegral = 0;
        float fDerive = 0;
        float freponseOld=0;
        byte[] buffer = new byte[8];
        #region partie test pour une foction de transfert numerique        
        float reponse = 0;
        #endregion        
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            CreerGraphique(zedGraphControl1);
        }
        #region  creeer graphique
        private void CreerGraphique(ZedGraphControl zgc)
        {
            GraphPane Pane = zgc.GraphPane;
            PointPairList list1 = new PointPairList();
            PointPairList list2 = new PointPairList();
            PointPairList list3 = new PointPairList();
            LineItem CourbeConsigne = Pane.AddCurve("Consigne", list1, Color.Red);
            LineItem CourbeMesure = Pane.AddCurve("Commande", list2, Color.Black);
            LineItem CourbeCommande = Pane.AddCurve("Mesure", list3, Color.Green);
            Pane.Title.Text = "Simulation en temps réel de la vitesse";
            Pane.XAxis.Title.Text = "Axe X";
            Pane.YAxis.Title.Text = "Axe Y";
            CourbeConsigne.Symbol.Size = 1.0F;
            CourbeConsigne.Line.Width = 2.0F;
            CourbeMesure.Symbol.Size = 1.0F;
            CourbeMesure.Line.Width = 2.0F;
            CourbeCommande.Symbol.Size = 1.0F;
            CourbeCommande.Line.Width = 2.0F;
        }
        #endregion

        #region taswer mte3 lgraph
        private void addDataToGraph(ZedGraphControl zg1, XDate x, double tconsigne,double tcommande, double treponse )
        {
            LineItem curve = zg1.GraphPane.CurveList[0] as LineItem;
            IPointListEdit list = curve.Points as IPointListEdit;
            list.Add(x,tconsigne);
            LineItem curve2 = zg1.GraphPane.CurveList[1] as LineItem;
            IPointListEdit list2 = curve2.Points as IPointListEdit;
            list2.Add(x, tcommande);
            LineItem curve3 = zg1.GraphPane.CurveList[2] as LineItem;
            IPointListEdit list3 = curve3.Points as IPointListEdit;
            list3.Add(x, treponse);            
            zg1.Invalidate();
            zedGraphControl1.AxisChange();
        }
#endregion

    

        private void zedGraphControl1_Load(object sender, EventArgs e)
        {
        }

        private void rdncnvar_CheckedChanged(object sender, EventArgs e)
        {
            if (rdncnvar.Checked==true)
            {
                hscrCons.Value = 0;
                hscrCons.Enabled = true;
                NumConVar.Enabled = true;
            }
            else
            {
                hscrCons.Enabled = false;
                NumConVar.Text = "0";
                NumConVar.Enabled = false;
            }
        }

        private void hscrCons_Scroll(object sender, ScrollEventArgs e)
        {
            NumConVar.Text = hscrCons.Value.ToString();
        }

        private void chkConsBoucleOuverte_CheckedChanged(object sender, EventArgs e)
        {
            if (chkConsBoucleOuverte.Checked == true)
            {
                Régulation.Enabled = false;                
            }
            else
            {
                Régulation.Enabled = true;                
            }
        }

        private void btnOuvrPort_Click(object sender, EventArgs e)
        {
            try
            {
                serialPort1.Open();
                lbCommunication.BackColor = Color.Green;
                lbCommunication.Text = "Connexion établie";
                Consignes.Enabled = true;                
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), "Impossible d'ouvrir le port ");
                
            }
        }

        private void comboCom_SelectedIndexChanged(object sender, EventArgs e)
        {
            serialPort1.PortName = comboCom.Text;
        }

        private void ComboBaude_SelectedIndexChanged(object sender, EventArgs e)
        {
            serialPort1.BaudRate = int.Parse(ComboBaude.Text);
        }

        private void btnFermPort_Click(object sender, EventArgs e)
        {
            timer.Enabled = false;
            serialPort1.Close();
            lbCommunication.BackColor = Color.Red;
            lbCommunication.Text = "Pas de connexion";
            Consignes.Enabled = false;
        }

        private void btnValider_Click(object sender, EventArgs e)
        {
          
            timer.Enabled = true;            
            
        }

        private void timer_Tick(object sender, EventArgs e)
        {
            float inter;
            temps += 0.1F;
            if (rdnEchel.Checked == true)
            {
                float.TryParse(numConEche.Text,out consigne);
            }
            if (rdnRamp.Checked == true)
            {
                if (consigne >= 100) consigne = 100;
                else
                {
                    float.TryParse(NumConRamp.Text, out inter);
                    consigne = inter * temps;
                }                
            }
            if (rdncnvar.Checked == true) //Consigne variable
            {
                float.TryParse(NumConVar.Text,out consigne);
            }            
            float rconsigne = (commande / 100) * 255;
            int iconsigne = (int)rconsigne;
            if (iconsigne>255)
            {
                iconsigne = 255;
            }
            else if(iconsigne<0)
            {
                iconsigne = 0;
            }
            txtMesVit.Text = iconsigne.ToString();
            #region envoi serial
            byte[] wbuffer = new byte[1];
            byte buffe = Convert.ToByte(iconsigne);
            wbuffer[0] = buffe;
            serialPort1.Write(wbuffer, 0, wbuffer.Length);
            #endregion  
            serialPort1.Read(buffer, 0, 1);            
            reponse= BitConverter.ToInt16(buffer, 0);
            reponse = (reponse / 255) * 100;
            if (chkConsBoucleOuverte.Checked == true) commande = consigne;
            else RegulationPID();
            prgbrVitesse.Value = (int)reponse;
            if (commande < 0) commande = 0;
            if (commande > 100) commande = 100;
            txtMesEcar.Text = commande.ToString();    
            addDataToGraph(zedGraphControl1, temps, consigne, commande, reponse);            
            serialPort1.DiscardInBuffer();
            serialPort1.DiscardOutBuffer();
            freponseOld = reponse;  //enregistre la dernière mesure de la reponse
        }
        
        private void button1_Click(object sender, EventArgs e)
        {
            timer.Enabled = false;
        }

        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            if (chkSimul.Checked == true)
            {
                GrpRs232.Enabled = false;
                chkSimul.Text = "End Simulation";
                timer.Enabled = false;
                serialPort1.Close();
                lbCommunication.BackColor = Color.Red;
                lbCommunication.Text = "Pas de connexion";
                Consignes.Enabled = true;
            }
            if (chkSimul.Checked == false)
            {
                GrpRs232.Enabled = true;
                chkSimul.Text = "Start Simulation";
                Consignes.Enabled = false;
            }
        }

        private void RegulationPID()
        {
            float ftermeP = 0;
            float ftermeI = 0;
            float ftermeD = 0;
            float fEcart = consigne-reponse;
            if (rdbTypeIntegral.Checked == true)
            {
                float fI0 = (fEcart + fecartold) / 2f;
                fIntegral+=fI0;
            }
            else fIntegral=0F;

            if (rdbTypeDeriv.Checked == true)
            {
                fDerive = freponseOld - reponse;
            }
            else fDerive = 0f;
           float kp = 0;
           float Ti = 0;
           float Td = 0;
           float.TryParse(txtParaKp.Text.ToString(), out kp);
           float.TryParse(txtParaTi.Text.ToString(), out Ti);
           float.TryParse(txtParaTd.Text.ToString(), out Td);
           ftermeP = fEcart * kp;
           if (Ti > 0.01f)
           ftermeI = fIntegral / Ti;
           ftermeD = Td * fDerive;

           if (rdbTypeProp.Checked==true)//P
           {
               commande = ftermeP;
           }
           else if (rdbTypeIntegral.Checked == true)//PI
           {
               commande = ftermeP + ftermeI;
           }
           else
           {
               commande = ftermeP+ftermeI+ftermeD;
           }
            fecartold=fEcart;
        }

        private void numConEche_TextChanged(object sender, EventArgs e)
        {
            if (this.Text == "1") this.Text = "2";
        }

        private void lbCommunication_Click(object sender, EventArgs e)
        {

        }
    }
}
Code C for PIC
unsigned int reponse=0;
int commande=0;
char txt[4];
void init(){
adc_init();//initialisation du module ANALOGIQUE
uart1_init(9600);//initialisation du module RS232
pwm1_init(12000);
pwm1_set_duty(0);
pwm1_start();
}
void main() {
     init();
     while(1){
        reponse=adc_read(0);
        reponse/=4;
        uart1_write(reponse);
        delay_ms(10);
        if(uart1_data_ready()){
          commande=uart1_read();
          pwm1_set_duty(commande);
        }
     }
}

0 comments:

Post a Comment