Sensores

Control PID de velocidad de motor DC con arduino

[:es]Diagrama en Proteus

 

Código Arduino

#include <PID_v1.h>
#include <LiquidCrystal.h>
#include "TimerOne.h"


// Desarrollado por Christian A. Vazquez par arduinomexico.com

int potenciometro = A0;    // select the input pin for the potentiometer
int potdigital ;  // 
int salidaPWM = 10;  // salida de señal PWM
int Interruptor = 0;          // El interruptor a utilizar sera el 0 es decir el pin digital 2
long cuentat = 0;  
int pulsos=0;   // variable para contar los pulsos en 1 segundo
int resolucion = 24;  // pulsos por revolución del encoder


//Define Variables we'll be connecting to
double rpm,Setpoint,Output;

//Specify the links and initial tuning parameters
double Kp=2, Ki=5, Kd=1;
PID myPID(&rpm, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);


LiquidCrystal lcd(12,11, 6, 5, 4, 3);

// pin 4 de la LCD (RS)---> pin 7 del arduino (salida digital, PWM)
// pin 5 de la LCD (RW) --> GND de la breadboard (fila -)
// pin 6 de la LCD (E)--> pin 8 de la placa Arduino UNO (PWM)
// pin 11 de la LCD (D4)--> pin 9 de la placa Arduino UNO (PWM)
// pin 12 de la LCD (D5)--> pin 10 de la placa Arduino UNO (PWM)
// pin 13 de la LCD (D6)--> pin 11 de la placa Arduino UNO (PWM)
// pin 14 de la LCD (D7)--> pin 12 de la placa Arduino UNO (PWM)


//Esta seria nuestra funcion interrupcion exte.
void interrupcion_isr()
{  
  pulsos=pulsos+1;
}


void ISR_timer () { 
 cuentat=cuentat+1;
}

void setup() {
  // declare the ledPin as an OUTPUT:
 // Serial.begin(9600);
  pinMode(salidaPWM, OUTPUT);  // decimos que pinOut es salida
  
  lcd.begin(16,2); 
  
  Timer1.initialize(1000);      // Dispara cada 1000 us = 1 ms
  Timer1.attachInterrupt(ISR_timer); // Activa la interrupcion y la asocia a ISR_Blink
  
  //Adjuntamos al interruptor 0 ( pin 2 ) la funcion cambios, cuando suceda un CHANGE
  attachInterrupt(Interruptor, interrupcion_isr, LOW);
  
    Setpoint = 20; // velocidad referencia

  //turn the PID on
  myPID.SetMode(AUTOMATIC);
  
 
}
void loop() {
  // read the value from the sensor:
  
 // potdigital = analogRead(potenciometro); 
 // potdigital = map(potdigital, 0, 1023, 0, 255);
  
//  analogWrite(salidaPWM,potdigital);
  myPID.Compute();
  
  Timer1.pwm(salidaPWM, Output,1000);
 
 // Timer1.disablePwm(salidaPWM); 
  // Serial.println(potdigital);
  
  if(cuentat==1000){
    
    rpm=((double)pulsos/resolucion)*60; 
   // lcd.begin(16,2);              // columns, rows.  use 16,2 for a 16x2 LCD, etc.
    lcd.clear();                  // start with a blank screen
    lcd.setCursor(0,0);            
    lcd.print(rpm);
    
    pulsos=0;
    cuentat=0;
    
}

  
}

 [:en]

 

Code Arduino

#include <PID_v1.h>
#include <LiquidCrystal.h>
#include "TimerOne.h"


// Desarrollado por Christian A. Vazquez par arduinomexico.com

int potenciometro = A0;    // select the input pin for the potentiometer
int potdigital ;  // 
int salidaPWM = 10;  // salida de señal PWM
int Interruptor = 0;          // El interruptor a utilizar sera el 0 es decir el pin digital 2
long cuentat = 0;  
int pulsos=0;   // variable para contar los pulsos en 1 segundo
int resolucion = 24;  // pulsos por revolución del encoder


//Define Variables we'll be connecting to
double rpm,Setpoint,Output;

//Specify the links and initial tuning parameters
double Kp=2, Ki=5, Kd=1;
PID myPID(&rpm, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);


LiquidCrystal lcd(12,11, 6, 5, 4, 3);

// pin 4 de la LCD (RS)---> pin 7 del arduino (salida digital, PWM)
// pin 5 de la LCD (RW) --> GND de la breadboard (fila -)
// pin 6 de la LCD (E)--> pin 8 de la placa Arduino UNO (PWM)
// pin 11 de la LCD (D4)--> pin 9 de la placa Arduino UNO (PWM)
// pin 12 de la LCD (D5)--> pin 10 de la placa Arduino UNO (PWM)
// pin 13 de la LCD (D6)--> pin 11 de la placa Arduino UNO (PWM)
// pin 14 de la LCD (D7)--> pin 12 de la placa Arduino UNO (PWM)


//Esta seria nuestra funcion interrupcion exte.
void interrupcion_isr()
{  
  pulsos=pulsos+1;
}


void ISR_timer () { 
 cuentat=cuentat+1;
}

void setup() {
  // declare the ledPin as an OUTPUT:
 // Serial.begin(9600);
  pinMode(salidaPWM, OUTPUT);  // decimos que pinOut es salida
  
  lcd.begin(16,2); 
  
  Timer1.initialize(1000);      // Dispara cada 20 ms
  Timer1.attachInterrupt(ISR_timer); // Activa la interrupcion y la asocia a ISR_Blink
  
  //Adjuntamos al interruptor 0 ( pin 2 ) la funcion cambios, cuando suceda un CHANGE
  attachInterrupt(Interruptor, interrupcion_isr, LOW);
  
    Setpoint = 20; // velocidad referencia

  //turn the PID on
  myPID.SetMode(AUTOMATIC);
  
 
}
void loop() {
  // read the value from the sensor:
  
 // potdigital = analogRead(potenciometro); 
 // potdigital = map(potdigital, 0, 1023, 0, 255);
  
//  analogWrite(salidaPWM,potdigital);
  myPID.Compute();
  
  Timer1.pwm(salidaPWM, Output,1000);
 
 // Timer1.disablePwm(salidaPWM); 
  // Serial.println(potdigital);
  
  if(cuentat==1000){
    
    rpm=((double)pulsos/resolucion)*60; 
   // lcd.begin(16,2);              // columns, rows.  use 16,2 for a 16x2 LCD, etc.
    lcd.clear();                  // start with a blank screen
    lcd.setCursor(0,0);            
    lcd.print(rpm);
    
    pulsos=0;
    cuentat=0;
    
}

  
}

 [:]

28 Comments

    1. Si, la salida 10 del Arduino es una salida PWN y vhttp://proyectosarduino.xyz/wp-admin/edit-comments.php#comments-forma conectada un Enable del L293 y este a su vez esta conectado con el Motor

          1. disculpa tengo una pequeña duda el potenciometro va conectado al pin A0 verdad..??
            y con eso podre variar la velocidad del motor verdad.?
            y la pantalla me ayuda a ver a que velocidad de giro esta yendo.?
            gracias de antemano
            espero tu respuesta

          2. Si va conectado ahí, saludos, tendrías que des-comentar las lineas

            potdigital = analogRead(potenciometro);

            y agregar la linea

            Setpoint = map(potdigital, 0, 1023, 1, 100);

            Para variar el setpoint de 1 a 100 ( eso rango tu lo escoges )

    1. No pero se le puede agregar fácilmente

      Usar dos salidas digitales para conectarse al Driver ld293 1n1 y 1n2 para controlar el giro

      Usar una entrada digital para un interruptor si es 0 gira en un sentido y si es 1 en otro sentido

      if (digitalRead(2)==HIGH){

      digitalWrite(4,HIGH);
      digitalWrite(5,LOW);

      } else {

      digitalWrite(4,LOW);
      digitalWrite(5,HIGH);

      }

    1. Buenas noches Christian quiero hacer un proyecto pero soy muy malo en la programacion en arduino y para entender la libreria PID que es lo que necesito para llevarlo a la practica del proyecto me queda muy mal, ademas buscando en muchos sitios en internet no hay material que ayude concretamente y las personas que tienen el conocimiento no estan dispuestas en ayudar, pero al mirar esta publicacion y las preguntas y respuestas me doy cuenta que tienes el conocimiento y la buena voluntad en ayudar si es que puedes ofrecerme esa tremenda ayuda estaria eternamente agradecido, mi correo es aaron_zarate1990@hotmail.com y mi numero de whatsapp +595982297095 si puedes entrar en contacto conmigo para poder ayudarme estaria muy agradecido

      1. Estimado Aaron Zarate, apenas estoy leyendo tu mensaje. Si claro te puedo ayudar voy a subir un codigo mejorado para el control PID.

        ¿Que necesitas?

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *