viernes, 26 de diciembre de 2014

Algorirmo para manejar "motores dc" en ARDUINO , PIC, etc

Algoritmo para manejar Motores  DC


En este post les traigo una manera facil y sencilla de manejar motores dc con tan solo llamar una funcion. Podemos manejar desde un solo  motor hasta el numero de motores que queramos, utilizando   solo un parametro con su respectivo signo, esto para darle el  set duty del pwm, para asi variar su  respectiva velocidad y tambien la direccion. 

Esto nos permitira manejar con una mayor eficiencia los motores, y claro esta tambien ahorranos muchas lineas de codigo. Es importante destacar que sea cual sea el microcontrolador que usemos, este tiene que contar con los suficentes pines de pwm, es decir, si  vamos a manejar 2 motores, el micro que usemos debe disponer de 2  pines pwm, ademas del driver de motor que utilicemos  este debera contar con los suficientes canales . 

empezaremos por crear nuestra funcion para el manejo de un solo motor, luego extenderemos para la cantidad de motores que querramos

Crearemos la funcion en el que se le dara un paramatro que contendra signo, el signo nos servira para controlar la direccion ( positivo hacia adelante,  negativo hacia atras), por defecto utilizaremo un pwm de 8 bits, arduino y pic utilizan esta resolucion (0-255) 
Para una manera didactica  haremos un seudo codigo, esto para entender la logica, luego implementaremos un algoritmo funcional.


void motores( float pwm)  //funcion con parametro  tipo float llamado pwm, no devuelve valor  
{
  int v1                              / / crearemos y utilizaremos  variable auxiliare  para menejar signos
 si ( pwm >=  0)                     //si el signo del positivo, entonces el motor ira hacia adelante 
   {
      motores_hacia_adelante  //activamos los pines  de driver para mandar motor  haciaadelante
        v1  =  pwm                        //  asignamos el valor de pwm a la variable auxiliar
    }

  si( pwm < 0 )                 //si  el valor  negativo  entonces  mandaremos el motor hacia atras
   {
       motores_hacia_atras     // activaremos pines de driver para mandar motores hacia atras
        v1 = pwm * (-1)        //cambiamos el signo de variable  para asi dar la salida  pwm correcta
    }
microcontrolador_pin_pwm1(v1);//damos el valor de  salida pwm correspondientealmicrocontrolador
}

y si lo llamamos en un bucle quedaria algo asi:

bucle
{
       motores( 100)    // entonces el motor ira hacia adelante con un valor de pwm de 100
       retardo(1000)  // hacemos u retardo de un segundo
       motores( -120)    // entonces el motor ira hacia atras con un valor de pwm de 120
      retardo(1000)   // hacemos u retardo de un segundo
}

Es asi que de una manera practica y facil  podemos manejar el  motor, lo que comunmente era la programacion de muchas lineas de codigopara cada movimieno y direccion, ahora nos basta con crear una funcion  que sera reutilizado en cualquier linea de nuestra programacion

Ahora Crearemos  un ejemplo funcional en arduino, bueno ya que la logica de control esta clara, ahora nos preocuparemos por los pines que utilizaremos del arduino

#define motor_1_a    3
#define motor_1_r    4
#define motor_2_a    5
#define motor_2_r    6
#define pin_pwm1     9
#define pin_pwm2     10
void setup()
{
  delay(500);
  pinMode(motor_1_a,  OUTPUT); 
  pinMode(motor_1_r,  OUTPUT);
  pinMode(motor_2_a,  OUTPUT);
  pinMode(motor_2_r,  OUTPUT);
  pinMode(pin_pwm1,  OUTPUT);
  pinMode(pin_pwm2,  OUTPUT);
}

void loop()

{
 motores (150, 150);
 delay(1000);
 motores(-140, -140);
 delay(1000);
 motores(130, -200);
 delay(1000);
 motores(-255, 0);
 delay(1000);
}

void motores(float pwm1,  float pwm2)

{
   int v1, v2;
   if(pwm1 >= 0) //para el motor 1
   {
     digitalWrite(motor_1_a, HIGH);
     digitalWrite(motor_1_r, LOW);
     v1 = pwm1;
   }
   else if(pwm1 < 0)
   {  
     digitalWrite(motor_1_a, LOW);
     digitalWrite(motor_1_r, HIGH);
     v1 = pwm1 * (-1);
   }

   //para el motor 2

   if(pwm2 >= 0)
   {
     digitalWrite(motor_2_a, HIGH);
     digitalWrite(motor_2_r, LOW);
     v2 = pwm2;
   }
   else if(pwm2<0)
   {
     digitalWrite(motor_2_a, LOW);
     digitalWrite(motor_2_r, HIGH);
     v2 = pwm2 * (-1);
   }
analogWrite(pin_pwm1, v1);
analogWrite(pin_pwm2, v2);
}

Ahora un ejemplo para PIC utilizando  el compilador CCS C vamos a utilizar el pic 16f877a, en si este ejemplo es valido para todas las familias de PIC de gama media y alta, asi que si deseamos utilizar el codigo con otro pic, pues solamente cambiamos los encabezados de configuracion, fuses, y claro esta los pines que diponemos para el pic.  

#include <16F877a.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP,PUT,NOBROWNOUT
#use delay(clock=20000000)
#use standard_io(B)

#define motor_1_a  pin_b0

#define motor_1_r  pin_b1
#define motor_2_a  pin_b2
#define motor_2_r  pin_b3
#define pin_pwm1   pin_c1
#define pin_pwm2   pin_c2

//prototipo para funcion motor

void motores(signed int16 izquierdo,signed int16 derecho); 

void main()

{
   //configuracion del pwm
   setup_ccp1 (CCP_PWM);
   setup_ccp2 (CCP_PWM);
   setup_timer_2 (T2_DIV_BY_1, 255, 1);
   set_pwm1_duty (0);
   set_pwm2_duty (0);
   
   while(true)
   {
      motores(100,100);
   }

}


void motores(signed int16 izquierdo, signed int16 derecho)

{
   int v1=0,v2=0; //variable auxiliar 
   if(derecho >0)
   {
      output_high(motor_1_a);
      output_low(motor_1_r);
      v2=derecho;
   }
    if(derecho <0)
   {
      output_low(motor_1_a);
      output_high(motor_1_r);
      v2=derecho*-1;
   }
     if(derecho==0)
   {
      output_high(motor_1_a);
      output_high(motor_1_r);
      v2=0;
   }
   
   
     if(izquierdo >0)
   {
      output_high(motor_2_a);
      output_low(motor_2_r);
      v1=izquierdo;
   }
   if(izquierdo <0)
   {
      output_low(motor_2_a);
      output_high(motor_2_r);
      v1=izquierdo*-1;
   }
    if(izquierdo==0)
   {
      output_high(motor_2_a);
      output_high(motor_2_r);
       v1=0;
   }
   set_pwm1_duty (v1);
   set_pwm2_duty (v2);
}

3 comentarios:

como puedo ponerme en contacto contigo para algunas dudas

mandarme un correo : marko.antonio.1.16.92@gmail.com

marko, hola,
puedo utlizar arduino en sistema experto basado en reglas de inferencia logica como la de encadenamiento hacia adelante o impulsado por los datos
josezuni1@gmail.com

Publicar un comentario