lunes, 5 de diciembre de 2016

Driver Drv8833 y arduino (tutorial)

Driver drv8833 y arduino

 (tutorial)








#include <QTRSensors.h>
/////////////////////////////////////////////////////////////////////////////////////
//*************  Programa realizado por MARCO A. CABALLERO MORENO***************   //
// Solo para fines educativos   
// robot velocista mini FK BOT  V 2.0                                            //
// micro motores pololu MP 10:1, sensores qtr 8rc, driver drv8833, arduino nano    //
//                                     05/12/2014                  
// ACTUALIZADO 29/3/2015            
/////////////////////////////////////////////////////////////////////////////////////

#define NUM_SENSORS   8     //numero de sensores usados
#define TIMEOUT       2000  // tiempo de espera para dar resultado en uS
#define EMITTER_PIN   6     //pin led on
///////////////pines arduino a utilizar/////////////////////
#define led1          13 
#define led2          4  
#define mot_i         7
#define mot_d         8
#define sensores      6
#define boton_1       2  //pin para boton
#define pin_pwm_i     9
#define pin_pwm_d     10

QTRSensorsRC qtrrc((unsigned char[]) {19, 18, 17, 16,15,14,11,12}
,NUM_SENSORS, TIMEOUT, EMITTER_PIN);

//variables para almacenar valores de sensores y posicion
unsigned int sensorValues[NUM_SENSORS];
unsigned int position=0;

/// variables para el pid
int  derivativo=0, proporcional=0, integral=0; //parametros
int  salida_pwm=0, proporcional_pasado=0;

///////////////AQUI CAMBIEREMOS LOS PARAMETROS DE NUESTRO ROBOT!!!!!!!!!!!!!!!
int velocidad=120;              //variable para la velocidad, el maximo es 255
float Kp=0.18, Kd=4, Ki=0.001;  //constantes
//variable para escoger el tipo de linea
int linea=0;                    //  0 para lineas negra, 1 para lineas blancas

void setup()
{
 delay(800);
 pinMode(mot_i, OUTPUT);//pin de direccion motor izquierdo
 pinMode(mot_d, OUTPUT);//pin de direccion motor derecho
 pinMode(led1, OUTPUT); //led1
 pinMode(led2, OUTPUT); //led2
 pinMode(boton_1, INPUT); //boton 1 como pull up
        
 for (int i = 0; i <40; i++)  //calibracion durante 2.5 segundos,
 {                                 //para calibrar es necesario colocar los sensores sobre la superficie negra y luego 
  digitalWrite(led1, HIGH);  //la blanca
  delay(20);
  qtrrc.calibrate();    //funcion para calibrar sensores   
  digitalWrite(led1, LOW);  
  delay(20);
 }
digitalWrite(led1, LOW); //apagar sensores para indicar fin de calibracion 
delay(400); 
digitalWrite(led2,HIGH); //encender led 2 para indicar la
while(true)
{
    int x=digitalRead(boton_1); //leemos y guardamos el valor
                                      // del boton en variable x
    delay(100);
    if(x==0) //si se presiona boton 
    {
        digitalWrite(led2,LOW); //indicamos que se presiono boton
        digitalWrite(led1,HIGH); //encendiendo led 1
        delay(100);
        break; //saltamos hacia el bucle principal
    }
}
}       


void loop()
{

 //pid(0, 120, 0.18, 0.001, 4 );
  pid(linea,velocidad,Kp,Ki,Kd); //funcion para algoritmo pid 
                                 //primer parametro: 0 para lineas negras, tipo 1 para lineas blancas
                                 //segundo parametro: velocidad pwm de 0 a 255
                                 //tercer parametro: constante para accion proporcional
                                 //cuarto parametro: constante para accion integral
                                 //quinto parametro: constante para accion derivativa
  //frenos_contorno(0,700);
  frenos_contorno(linea,700); //funcion para frenado en curvas tipo 
                              //primer parametro :0 para lineas negras, tipo 1 para lineas blancas
                              //segundo parametro:flanco de comparación va desde 0 hasta 1000 , esto para ver 
}

////////funciones para el control del robot////
 void pid(int linea, int velocidad, float Kp, float Ki, float Kd)
{
  position = qtrrc.readLine(sensorValues, QTR_EMITTERS_ON, linea); //0 para linea negra, 1 para linea blanca
  proporcional = (position) - 3500; // set point es 3500, asi obtenemos el error
  integral=integral + proporcional_pasado; //obteniendo integral
  derivativo = (proporcional - proporcional_pasado); //obteniedo el derivativo
  if (integral>1000) integral=1000; //limitamos la integral para no causar problemas
  if (integral<-1000) integral=-1000;
  salida_pwm =( proporcional * Kp ) + ( derivativo * Kd )+(integral*Ki);
  
  if (  salida_pwm > velocidad )  salida_pwm = velocidad; //limitamos la salida de pwm
  if ( salida_pwm < -velocidad )  salida_pwm = -velocidad;
  
  if (salida_pwm < 0)
 {
  motores(velocidad+salida_pwm, velocidad);
 }
 if (salida_pwm >0)
 {
  motores(velocidad, velocidad-salida_pwm);
 }

 proporcional_pasado = proporcional;  
}

//funcion para control de motores
void motores(int motor_izq, int motor_der)
{
  if ( motor_izq >= 0 )  //motor izquierdo
 {
  digitalWrite(mot_i,HIGH); // con high avanza
  analogWrite(pin_pwm_i,255-motor_izq); //se controla de manera
                                        //inversa para mayor control
 }
 else
 {
  digitalWrite(mot_i,LOW); //con low retrocede
  motor_izq = motor_izq*(-1); //cambio de signo
  analogWrite(pin_pwm_i,motor_izq); 
 }

  if ( motor_der >= 0 ) //motor derecho
 {
  digitalWrite(mot_d,HIGH);
  analogWrite(pin_pwm_d,255-motor_der);
 }
 else
 {
  digitalWrite(mot_d,LOW);
  motor_der= motor_der*(-1);
  analogWrite(pin_pwm_d,motor_der);
 }

  
}

void frenos_contorno(int tipo,int flanco_comparacion)
{
  
if(tipo==0)
{
  if(position<=50) //si se salio por la parte derecha de la linea
 {
  motores(-80,90); //debido a la inercia, el motor 
                                  //tendera a seguri girando
                                  //por eso le damos para atras , para que frene
                                 // lo mas rapido posible 
  while(true)  
  {
   qtrrc.read(sensorValues); //lectura en bruto de sensor   
   if( sensorValues[0]>flanco_comparacion || sensorValues[1]>flanco_comparacion ) 
   //asegurar que esta en linea
   {
    break;
   } 
  }
 }

 if (position>=6550) //si se salio por la parte izquierda de la linea
 { 
  motores(90,-80);
  while(true)
  {
   qtrrc.read(sensorValues);
   if(sensorValues[7]>flanco_comparacion || sensorValues[6]>flanco_comparacion )
   {
    break;
   }  
  }
 }
}

if(tipo==1) //para linea blanca con fondo negro
{
 if(position<=50) //si se salio por la parte derecha de la linea
 {
  motores(-80,90); //debido a la inercia el motor 
                   //tendera a seguri girando
                   //por eso le damos para atras  
                   //para que frene lo mas rapido posible 
  while(true)  
  {
   qtrrc.read(sensorValues); //lectura en bruto de sensor
   if(sensorValues[0]<flanco_comparacion || sensorValues[1]<flanco_comparacion )   //asegurar que esta en linea
   {
    break;
   }
  }
 }

 if(position>=6550) //si se salio por la parte izquierda de la linea
 { 
  motores(90,-80);
  while(true)
  {
   qtrrc.read(sensorValues);
   if(sensorValues[7]<flanco_comparacion || sensorValues[6]<flanco_comparacion)
   {
    break;
   }  
  }
 }
}
}

miércoles, 30 de noviembre de 2016

Robot Velocista QTR8A (Parte III - Programacion del Robot)

Programación del Robot


Algoritmo PID

Este sera el encargado de regular el comportamienito del robot y corregir su marcha en el recorrido de la pista, recibe datos entrada (sensores) , las procesa, (PID) y envia la señal de correccion hacia los motores (salida de control) y nuevamente repite el proceso coparando la salida con la entrada (retroalimentacion) sin entrar en mas teoría se puede resumir de manera esquematica este controlador
  • Entrada de mando: Vendría a ser el punto de referencia en donde queremos fijar al robot "Set point", nuestro objetivo es que el robot no se salga de la linea, por lo tanto lo deseado es que siempre se mantenga centrado en el medio, como se vio anteriormente el centro de los sensores arrojaba un valor de posición relativa de 3500, este sera nuestra referencia o "set point" (donde queremos que el robot se mantenga siempre.
  • Controlador :  En este caso el controlador es el encargado de corregir y mantener en marcha al robot, su objetivo es que no se salga del punto de referencia o que almenos logre tenerlo dentro de los rangos permitidos. lo ideal es que mantenga al robot fijado en el centro, pero en la realidad ocurrirá que el mundo externo provoque muchas  perturbaciones haciendo que el robot oscile o se salga del punto de referencia por lo que tendrá que corregir continuamente la marcha. Si este controlador es el "PID"... Que para nuestro caso sera un algoritmo programado en arduino.
  • Planta: La planta esta relacionada con las condiciones físicas del robot, peso, longitud, traccion de los motores, velocidad, rozamiento, inercia, etc.  Como se ve el diagrama de bloques, el controlador modifica el comportamiento de la planta, osea el comportamiento del robot.
  • Salida o señal de control: Es la respuesta producida por el control aplicado en el robot, en este caso la salida  de control se envia al driver de motor y luego a los motores para que puedan corregir la marcha constantemente. la medición de esta salida es jutamente la señal es la posicion actual del robot medido .
  • Realimentacion: Esta compuesta de la adquisición de datos, osea la de los sensores del robot, que va leer la posición relativa actual del robot la procesa y manda nuevamente a comparararse con la referencia que es el "set point"  , esta comparación traerá un resultado llamado error que nuevamente es entregado al controlador para que pueda procesarla y enviar una señal de correccion, la realimentacion es la comparación de la salida con respecto a la entrada, 
Todo esto en gran parte sera el algoritmo de control del robot: Se que es muy abstracto todo lo que concierne con PID, pero con la practica algunos de estos conceptos estaran claros.

En este post ya tramos acerca de cada una de las acciones del PID,  de las constantes y el procedimiento para sintonizar, por lo que ya no seré tan redundante explicando nuevamente. : http://aprendiendofacilelectronica.blogspot.pe/2014/12/robot-velocista-de-competencia_4.html


Circuito del Robot Velocista


Programa Completo

/////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////

#include <QTRSensors.h>

  //entradas
#define btn1      0
#define btn2      1
  //salidas
#define led1      13

#define led_on    9   //~
#define mi1       3
#define mi2       4
#define pwmi      6   //~
#define md1       8
#define md2       7
#define pwmd      5   //~
  

#define NUM_SENSORS             8  // number of sensors used
#define NUM_SAMPLES_PER_SENSOR  1 // average 4 analog samples per sensor reading
#define EMITTER_PIN             9   // emitter is controlled by digital pin 2

QTRSensorsAnalog qtra((unsigned char[]) {7, 6, 5, 4, 3, 2,1,0},NUM_SENSORS, NUM_SAMPLES_PER_SENSOR, EMITTER_PIN);
unsigned int sensorValues[NUM_SENSORS];
int proporcional=0;
int derivativo=0;
int integral=0;
int salida_pwm=0;
int proporcional_pasado=0;
int position=0;

////////////////////Parametros PID/////////////////////////////////
int velocidad=120;
//float KP=0.15, KD=2.2, KI=0.006; //reaccion rapida
float KP=0.01, KD=0.15 , KI=0.0001; //reaccion rapida
///////////////////////////////////////////////////////

/////////////////parametros de sensado/////////////////////////////
int linea=0; //0 linea negra, 1 para linea blanca
int flanco_color=  0 ;
int en_linea=  500 ;
int ruido= 30;
/////////////////////////////////////////////////////////
int boton1=7;
int boton2=7;

void setup()
{
    pinMode(led1,OUTPUT);
    pinMode(led_on,OUTPUT);
    pinMode(mi1,OUTPUT);
    pinMode(mi2,OUTPUT);
    pinMode(pwmi,OUTPUT);
    pinMode(md1,OUTPUT);
    pinMode(md2,OUTPUT);
    pinMode(pwmd,OUTPUT);

digitalWrite(led1,HIGH);
delay(200);
digitalWrite(led1,LOW);
delay(200);

digitalWrite(led1, HIGH);    // turn on Arduino's LED to indicate we are in calibration mode
  for (int i = 0; i < 200; i++)  // make the calibration take about 10 seconds
  {
    qtra.calibrate();       // reads all sensors 10 times at 2.5 ms per six sensors (i.e. ~25 ms per call)
  }
  digitalWrite(led1, LOW);     // turn off Arduino's LED to indicate we are through with calibration
 //Serial.begin(115200);
   //Serial.println();

   while(true)
   {
      botones();
      if(boton2==0) 
      {
        delay(20);
        digitalWrite(led1,HIGH);
        delay(100);
        digitalWrite(led1,LOW);
        delay(100);
        break;
      }
   }
  
Serial.begin(115200);
//bt.println("Hello, world?");

}

void loop()
{
  pid(1,velocidad,KP,KI,KD);
  frenos_contorno(600);

 Serial.println(position);
 delay(2);
}

void pid(int linea, int velocidad, float Kp, float Ki, float Kd)
{
   
   position = qtra.readLine(sensorValues,QTR_EMITTERS_ON, linea, flanco_color, en_linea, ruido);
  //0 linea negra, 1 para linea blanca
  
      //  Serial.println(position);
  proporcional = (position) - 3500; // set point es 3500, asi obtenemos el error
  integral=integral + proporcional_pasado; //obteniendo integral
  derivativo = (proporcional - proporcional_pasado); //obteniedo el derivativo
  int ITerm=integral*KI;
  if(ITerm>=255) ITerm=255;
  if(ITerm<=-255) ITerm=-255;
  
  salida_pwm =( proporcional * KP ) + ( derivativo * KD )+(ITerm);
  
  if (  salida_pwm >velocidad )  salida_pwm = velocidad; //limitamos la salida de pwm
  if ( salida_pwm  <-velocidad )  salida_pwm = -velocidad;
  
  if (salida_pwm < 0)
 {
    int der=velocidad-salida_pwm; //(+)
    int izq=velocidad+salida_pwm;  //(-)
    if(der>=255)der=255;
    if(izq<=0)izq=0;
    motores(izq, der);
 }
 if (salida_pwm >0)
 {
  int der=velocidad-salida_pwm; //(-)
  int izq=velocidad+salida_pwm; //(+)
  
  if(izq >= 255) izq=255;
  if(der <= 0) der=0;
  motores(izq ,der );
 }

 proporcional_pasado = proporcional;  
}


void frenos_contorno(int flanco_comparacion)
{
    if (position <=10) //si se salio por la parte derecha de la linea
    {
      while(true)
      { 
        digitalWrite(led1,HIGH);
        motores(-125,60);
        qtra.read(sensorValues); //lectura en bruto de sensor
        if ( sensorValues[0]<flanco_comparacion || sensorValues[1]<flanco_comparacion || sensorValues[2]<flanco_comparacion || sensorValues[3]<flanco_comparacion || sensorValues[4]<flanco_comparacion || sensorValues[5]<flanco_comparacion || sensorValues[6]<flanco_comparacion || sensorValues[7]<flanco_comparacion)
        {
          break;
        }
        
      }
    }

    if (position>=6990) //si se salio por la parte izquierda de la linea
    {
      while(true)
      {
        digitalWrite(led1,HIGH);
        motores(60,-125); 
        qtra.read(sensorValues);
        if (sensorValues[7]<flanco_comparacion || sensorValues[6]<flanco_comparacion|| sensorValues[5]<flanco_comparacion || sensorValues[4]<flanco_comparacion || sensorValues[3]<flanco_comparacion || sensorValues[2]<flanco_comparacion || sensorValues[1]<flanco_comparacion|| sensorValues[0]<flanco_comparacion)
        {
          break;
        }
      }
  }
  digitalWrite(led1,LOW);
}


void motores(int motor_izq, int motor_der)
{
  if ( motor_izq >= 0 )  
  {
    digitalWrite(mi1,LOW);
    digitalWrite(mi2,HIGH); 
    analogWrite(pwmi,motor_izq); 
  }
  else
  {
    digitalWrite(mi1,HIGH); 
    digitalWrite(mi2,LOW);
    motor_izq = motor_izq*(-1); 
    analogWrite(pwmi,motor_izq);
  }

  if ( motor_der >= 0 ) //motor derecho
  {
    digitalWrite(md1,LOW);
    digitalWrite(md2,HIGH);
    analogWrite(pwmd,motor_der);
  }
  else
  {
    digitalWrite(md1,HIGH);
    digitalWrite(md2,LOW);
    motor_der= motor_der*(-1);
    analogWrite(pwmd,motor_der);
  }
}

void botones()
{
    boton1=digitalRead(btn2);
    boton2=digitalRead(btn1); ///boton izquierdo, derecho
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Nota: este programa esta utilizando la libreria modificada de este post Modificacion de libreria QTR, si estas usando la libreria sin modificar, que de hecho no funcionara con este codigo tendrás que descargarlo desde este link: https://mega.nz/#!CkMkiZhA!FMK4eJQVmOGZK9GZzfqSKRgEPOijTSkMmbNDUwbf5C0 en instalarlo nuevamente. 

Instalacion de Libreria QTR SENSORS:


Esquematicos de FK-BOT:

Ya que me estuvieron pidiendo esquemáticos por mucho tiempo, pues aqui las libero.
 He pasado muy buenos días diseñando este robot, que fue considerado en su momento como el más rapido, ya ha pasado los años y cumplio su mision ...

La mejor forma de agradecerme es que le des clic a los anuncios de la parte superior del blog (cosa que no te costara nada hacerlo) , asi me ayudaras mucho! Saludos amigos robotero!!!  😊😎🙌



Cifrado: !tBRwDXi3MO-D9U3xMqgBTw

Driver Sparkfun-Compatible(rojo): https://mega.nz/#F!Ok1jULzb!DFAwhpyvyMLxdrc3C_xedw
Cifrado: !DFAwhpyvyMLxdrc3C_xedw


PRUEBAS FINALES: 





Post Anterior  << Manejando sensores QTR8A y Driver

martes, 29 de noviembre de 2016

Robot Velocista QTR8A (Parte II - Manejando Sensores y Motores)

 Manejando Sensores QTR8A


1. Manejando Sensor QTR8A con la libreria

Uso de librería Qtr8a en Arduino:


  • https://www.pololu.com/product/960/resources (mayor información)
  • Descargar la librería desde aquí : https://mega.nz/#F!78FVmD7Q!auGJgTr0Muo9qkNtl9CuLA
  • Una vez descargado instalar la librería de modo convencional en arduino: Copiar y pegar en la carpeta “librerías” de la carpeta donde esta instalado arduino.
  • Generalmente en esta dirección esta instalada C:\Program Files (x86)\Arduino\libraries
Descargar, descomprimir y copiar .

Ubicar la dirección donde se instalo arduino y buscar la carpeta libraries, y pergar la libreria QTRSensors.


La conexión sera la siguiente: 



  • La librería contiene un ejemplo básico de uso de los sensores
  • “QTRAExample”, abrirla y experimentar…


Configurando pines para uso de sensores Qtr8a :

Como estamos usando la regleta que trae 8 sensores, entonces debemos configurarlo para usar los 8 sensores, ya que por defecto esta configurado para usar 6, en esta imagen se muestra como configurarlo correctamente de acuerdo a las conexiones que se tienen en arduino de la imagen previa.


El código completo :
/////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#include <QTRSensors.h>

#define NUM_SENSORS             8  // number of sensors used
#define NUM_SAMPLES_PER_SENSOR  4  // average 4 analog samples per sensor reading
#define EMITTER_PIN             9  // emitter is controlled by digital pin 2

// sensors 0 through 5 are connected to analog inputs 0 through 5, respectively
QTRSensorsAnalog qtra((unsigned char[]) {7, 6, 5, 4, 3, 2, 1, 0}, 
  NUM_SENSORS, NUM_SAMPLES_PER_SENSOR, EMITTER_PIN);
unsigned int sensorValues[NUM_SENSORS];


void setup()
{
  delay(500);
  pinMode(13, OUTPUT);
  digitalWrite(13, HIGH);    // turn on Arduino's LED to indicate we are in calibration mode
  for (int i = 0; i < 400; i++)  // make the calibration take about 10 seconds
  {
    qtra.calibrate();       // reads all sensors 10 times at 2.5 ms per six sensors (i.e. ~25 ms per call)
  }
  digitalWrite(13, LOW);     // turn off Arduino's LED to indicate we are through with calibration

  // print the calibration minimum values measured when emitters were on
  Serial.begin(9600);
  for (int i = 0; i < NUM_SENSORS; i++)
  {
    Serial.print(qtra.calibratedMinimumOn[i]);
    Serial.print(' ');
  }
  Serial.println();
  
  // print the calibration maximum values measured when emitters were on
  for (int i = 0; i < NUM_SENSORS; i++)
  {
    Serial.print(qtra.calibratedMaximumOn[i]);
    Serial.print(' ');
  }
  Serial.println();
  Serial.println();
  delay(1000);
}


void loop()
{
  unsigned int position = qtra.readLine(sensorValues);
  
  // print the sensor values as numbers from 0 to 1000, where 0 means maximum reflectance and
  // 1000 means minimum reflectance, followed by the line position
  for (unsigned char i = 0; i < NUM_SENSORS; i++)
  {
    Serial.print(sensorValues[i]);
    Serial.print('\t');
  }
  //Serial.println(); // uncomment this line if you are using raw values
  Serial.println(position); // comment this line out if you are using raw values
  
  delay(50);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



Calibración

  • Previamente, para poder utilizar los sensores es necesario hacer una rutina de calibración, esto  durante algunos segundos. esto hace que la librería procese los datos de sensado, y muestre valores correctos.
  • En el proceso de calibración es necesario pasar repetidas veces los sensores sobre la línea negra y luego sobre la superficie blanca si levantar los sensores.
  • Se recomienda hacer la calibración de manera a una distancia constante sobre la superficie.
Lo que hace este código ejemplo es hacer uso de la librería QTRSensors ,se  obtienen los datos  de los sensores, que son las 8 primeras columnas. La 9na columna son los datos de posición relativa del sensor que vas desde 0 hasta 7000, en donde el centro se encuentra en 3500 a este valor le llamaremos set point. Este valore nos sera util para utilizar el algoritmo PID que controlara al Robot. Ademas se puede notar que cuando los sensores estan posicionados en la linea negra, los valores de sensado unitario incrementan alrededor de 800 a 1000 y cuando están sobre superficie blanca los valores son 0. Para visualizar estos datos se tiene que Abrir el monitor serie de Arduino.

 funciones de la librería Qtr8a

  • qtra.calibrate();  
                   Primera función a ser llamada, antes de usar los sensores, hace calibración de sensores                       (debe usarse un tiempo adecuado)
  • qtra.read(sensorValues);
                    Hace lectura de cada sensor y los guarda en matriz “sensorValues[ ];”
                    Rango de lectura de cada sensor : 0 a 1000.
  • int position = qtra.readLine(sensorValues);
                     Esta función devolverá la posición de sensores (necesario  PID)


2. Manejando Motores 

La conexión es la siguiente:

Ya hice un post para manejar este tipo de driver con arduino pueden verlo aca:  http://aprendiendofacilelectronica.blogspot.pe/2016/11/control-de-motores-dc-con-modulo-driver.html

Simplemente lo que haremos aca es utilizar otros pines con arduino  definiendolos nuevamente y listo, el programa de control de motores para el velocista  esta aqui:

///////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#define mi1        3
#define mi2        4
#define pwmi       6
#define md1        8
#define md2        7
#define pwmd       5

void setup() 
{
  pinMode(mi1,OUTPUT);
  pinMode(mi2,OUTPUT);
  pinMode(md1,OUTPUT);
  pinMode(md2,OUTPUT);
}

void loop()
{
  motores(100,100);
}

void motores(int motor_izq, int motor_der)
{
  if( motor_izq >=0)
    {
      digitalWrite (mi1,HIGH);
      digitalWrite (mi2,LOW);
      analogWrite (pwmi,motor_izq);
    }
  else
    {
      digitalWrite(mi1,LOW);
      digitalWrite(mi2,HIGH);
      motor_izq = motor_izq*(-1);
      analogWrite(pwmi,motor_izq); 
    }
  if(motor_der>=0)
    {
      digitalWrite(md1,HIGH);
      digitalWrite(md2,LOW);
      analogWrite(pwmd,motor_der);
  }
  else
     {
      digitalWrite(md1,LOW);
      digitalWrite(md2,HIGH);
      motor_der=motor_der*(-1);
      analogWrite(pwmd,motor_der);    
     }
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////









Anterior post << Materiales
Siguiente post >> Programacion PID Robot

martes, 15 de noviembre de 2016

Sensor GP2Y0D340K y Arduino

Sensor GP2Y0D340K y Arduino

El sensor GP2Y0D340K o mas conocido como Sharp340k es un sensor de distancia IRED, que posee un procesador de señal integrado, lo cual facilita enormemente ya que a su salida dara un valor digital "0" o "LOW" si hay un obstáculo y "1" o "HIGH" si no encuentra obstáculo alguno. Su pequeño tamaño lo hace ideal para aplicaciones como detección de obstáculos, sensor de proximidad, y porsupuesto para aplicaciones de robotica, como los robots minisumos.
Estas son algunas de sus características a destacar:


  • Salida de tipo digital.
  • Distancia máxima de detección 40.00 cm.
  • Consumo tipico de 31 mA.
  • Velocidad de respuesta de 8 ms.
  • Tamaño  de 15 x 9.6 x 8.7 mm.
  • Voltaje de funcionamiento de 4.5 a 5.5V.
Esquema en Bloques:


Modo de Conexión:









Código Ejemplo:

Este ejemplo hace una lectura del pin donde esta el sensor y si detecta algo, imprimirá en pantalla y a la vez encenderá el led del pin 13.


#define sensor 9  // lectura en pin D9 
#define led    13 // D13

int lectura;
void setup() {
  pinMode(sensor, INPUT);
  pinMode(led,OUTPUT);
  Serial.begin(9600);
}
void loop() {
  lectura=digitalRead(sensor);
  if(lectura==0)
  {
    digitalWrite(led,HIGH);
    Serial.println("Obstaculo");
  }
  else{
    digitalWrite(led,LOW);
    Serial.println("No obstaculo");
  }




viernes, 4 de noviembre de 2016

Driver TB6612fNG y ARDUINO (Control de Motores DC + programa)

  Driver TB6612fNG y  ARDUINO

 (Pololu, Sparkfun Breakout)



El Modulo driver Tb6612fng cuenta con las siguientes características:

  • Puente H doble de tecnología LD MOS (2 canales para manejar 2 motores DC)
  • Voltaje máximo de entrada de hasta 15V.
  • Corriente de trabajo tipico de 1.2 A por canal y 3A pico por un lapso de 10 milisegundos
  • 2 entradas para PWM con una frecuencia máxima de hasta 100KHz
Estas características ademas de ser muy pequeño (2.0x2.0 cm como máximo ) y de ser altamente eficiente a comparación  al modulo L298N que esta basado en tecnologia bjt (no muy eficiente por lo que las baterías se agotan demasiado rapido), lo hacen un modulo driver muy versatil para distintos proyectos en donde se tenga hacer uso de motores DC, y en especial en robotica donde se le puede sacar bastante provecho usandolos con micromotores Pololu.

En este apartado explicare a como usarlos correctamente y conectarlos a la placa Arduino en donde describire  un codigo  que es altamente eficiente en el control de los motores (velocidad y dirección): Pero antes de ello tenemos que saber que en el mercado existen varios fabricantes de estos módulos usando el chip TB6612FNG y que sus patillajes no son necesariamente los mismos, por el contrario tienen diferente dispocicion de pines, pero el funcionamiento sigue siendo el mismo. Debemos verificar cual es el que vamos a usar, a continuación explico algunas características de estos:

TB6612FNG Pololu


Este modulo es fabricado por Pololu, cuenta con un transistor mosfet que evita que al conectar de manera inversa no se queme o que cuando reciba una corriente inversa  que puede ser muy perjudicial no lo dañe permanentemente. También cuenta con algunos condensadores filtros que atenúan el ruido producido por los motores DC. Tienen un tamaño de 1.5 x2.0 cm. 
Estos Módulos son generalmente un poco mas costosos que los que fabrica Sparkfun o compatibles. se conecta de esta Forma:


TB6612FNG Sparkfun Breakout y compatibles chinos

Estos módulos son fabricados por sparkfun y también por varios fabricantes chinos, No cuenta con un circuito proteccion de corriente inversa, por lo que se debe tener cuidado al conectar las polaridades de la batería de forma correcta (es recomendado poner un diodo en la alimentacion). Cuenta con  capacitores filtros que atenúan el ruido eléctrico producido por los motores.
Son mucho mas baratos  a comparación de los módulos de Pololu, varios fabricantes chinos lo comercializan a muy bajo costo por lo que si se te quema no te perjudicara económicamente. Tienen una medida de 2 . 0 x 2.0 cm. La forma de conectarlo correctamente es la Siguiente:


Código en Arduino Para manejar motores DC:

Este código Funciona de la siguiente manera: 
  • Podemos controlar velocidad y dirección de cada motor independiente del otro para esto creamos una función que recibe 2 parámetros numéricos el primero es para el motor izquierdo el segundo para el motor derecho : " void   motores(int izq , int der) "
  • Para controlar la velocidad solo basta variar el valor de los parámetros desde 0 a 255, que justamente es el pwm del arduino. Ejemplo motores(150,150);
  • Si queremos que gire en sentido inverso  los motores, pues simplemente colocamos un valor negativo desde -1 hasta -255,  la función se encargara de dar la dirección y velocidad. Ejemplo: motores(-150,-150);
  • Si queremos parar pues damos motores(0,0); 

//Se definen los pines a usar del arduino

#define pwm_i 9 //~
#define izq_1 4
#define izq_2 5

#define pwm_d 10 //~
#define der_1 6
#define der_2 7

void setup() {
  delay(1000);
pinMode(izq_1,OUTPUT);
pinMode(izq_2,OUTPUT);
pinMode(der_1,OUTPUT);
pinMode(der_2,OUTPUT);
}

void loop() {
  motores(150,150);
}

void motores(int izq, int der)
{
  if(izq>=0)
  {
    digitalWrite(izq_1,HIGH);
    digitalWrite(izq_2,LOW);
    analogWrite(pwm_i,izq);
  }
  if(izq<0)
  {
    digitalWrite(izq_1,LOW);
    digitalWrite(izq_2,HIGH);
    izq=izq*-1;
    analogWrite(pwm_i,izq);
  }

  if(der>=0)
  {
    digitalWrite(der_1,HIGH);
    digitalWrite(der_2,LOW);
    analogWrite(pwm_d,der);
  }
  if(der<0)
  {
    digitalWrite(der_1,LOW);
    digitalWrite(der_2,HIGH);
    der=der*-1;
    analogWrite(pwm_d,der);
  }
}


sábado, 10 de septiembre de 2016

Crea tu propio arreglo de sensores Pololu QTR XA

Crea tu propio arreglo de sensores Pololu QTR XA  


En este post vamos a aprender a diseñar nuestros propios sensores para robots seguidores de lineas,  velocistas,  robots maze  etc.
Muchos de nosotros  que nos apasiona la robotica de competición, específicamente los que tenga que ver con los del tipo seguidores de lineas, los sensores son la parte esencial del diseño del robot. El 99.9%  de robots de este tipo  utilizan sensores del tipo IR fotorreflexivos activos (infrarojos), el cual consta  de un led emisor IR, el cual emite la luz infrarroja, y el fototransistor NPN que es muy sensible y capta  a las luz IR.

Este sensor lo podemos utilizar  para poder identificar superficies de color blanco o oscuras. Bien sabemos por fisica cuantica que un cuerpo negro absorve la luz y energia, caso contrario con un cuerpo blanco que refleja la luz. Este principio se utiliza poder captar las variaciones de tonos, y bingo! se puede identificar el color negro y blanco.



Ahora que ya sabemos un poco de teoria, lo que sigue es diseñar nuestro arreglo de sensores, para esto necesitamos usar sensores que de este tipo que esten disponibles en el mercado, uno de estos sensores son los "QRE 1113GR de Fairchild Semiconductor". estos sensores son ideales para usarlos en robotica ya que son de tamaño pequeño (SMD) de  buena estabilidad y  calidad, ademas de que las regletas pololu QTR8A usan estos sensores.

Uno de los puntos débiles de las regletas pololu es que solamente dispone a lo maximo de 8 sensores IR, y muchas veces se nos queda corto, ademas de que el tamaño es muy pequeño como para hacer robots mucho mas rapidos y que no se salgan de la linea con facilidad. Otro punto débil también es que la dispocicion de los sensores es de forma recta, y muchas veces lo mas ideal es que sean de forma de media luna.
Si quisiéramos diseña nuestro propio arreglo de sensores, pues nos podemos guiar del diagrama que nos muestra pololu. No es complicado de implementarlo, tan solo consta de resistencias unos cuantos condensadores filtro y un transistor mosfet como un switch que enciende y apaga los leds IR del los sensores 



Yo hice mi propio diseño en proteus, solamente me haria falta el diseño en ares para el pcb y darle una forma ovalada, y listo!! Inclusive puedo hacer uso de mas de 8 sensores y no habria problemas de  seguir usando la libreria. Nota, El transistor mosfet puede ser remplazado por cualquier transistor NPN BJT  siempre y cuando tolere corrientes mayores a 100 ma , por ejemplo el famosos 2n22222a


En un Siguiente post explicare como usar 16 sensores, pero en este caso haciendo uso de un multiplexor analogico.

jueves, 19 de mayo de 2016

Taller "Robot Velocista de Competencia"


Tallere de Robot Velocista de Competencia 


El día sábado 14 de mayo dicte una conferencia acerca de como elaborar un robot velocista de competencias, les comparto la presentación espero sus comentarios amigos roboteros ;)

Materiales:
-Sensores analogicos Qtr8a
-Micrmotores motores pololu HP 30:1
-Driver drv tb6612fng
-Arduino Nano
-Par de brackets
-Call caster plastico pololu
-Baterias de Lipo 7.4 v 500 mA

https://drive.google.com/file/d/0B2Y4LRrUn7QJWFAxM1ZWYkM3Y2c/view?usp=sharing

martes, 26 de abril de 2016

Proyecto Robot Sumo de Competencia


En este proyecto se hace uso de sensores ultrasonidos para que el robot sea capaz de detectar al oponentes, de esta forma podrá atacarlo y sacarlo de la competencia.







miércoles, 2 de marzo de 2016

Robot Velocista QTR8A (Parte I - Materiales)

MATERIALES




Esta sera una serie de post relacionados a la construcción de un robot velocista de competencias basado en los sensores QTR8A. sera una continuacion con la serie de post:
http://aprendiendofacilelectronica.blogspot.pe/2014/12/robot-velocista-de-competencia.html
http://aprendiendofacilelectronica.blogspot.pe/2014/12/robot-velocista-de-competencia_3.html
http://aprendiendofacilelectronica.blogspot.pe/2014/12/robot-velocista-de-competencia_4.html
http://aprendiendofacilelectronica.blogspot.pe/2015/04/modificacion-libreria-qtr-sensors-para.html
http://aprendiendofacilelectronica.blogspot.pe/2015/04/modificacion-libreria-qtr-sensors-para_18.html
en donde  el robot velocista se basaba en los sensores QTR8RC.
La construcción es de forma similar, por lo que ya no entrare en detalles, entonces empezemos!



  1. Modulo de sensores QTR8A

Estos sensores funciona de manera analógica, es decir que dependiendo de lo opaco que sea la superficie obtendremos valores de voltaje, para  obtener estos valores, ya que son 8, sera necesario hacer uso de un microcontrolador  que disponga de 8 pines de entradas analógicas (ADC) , el llamado para serlo es el popular arduino. Adicionalmente de 3 pines , "alimentacion de 5 V", "GND" y "Led on", este ultimo sirve para controlar el encendido y apagado de los sensores. Ademas dispone de estas características:
  • Dimensiones: 749,3 x 12,7 mm (pines sin cabecera instalada)
  • Tensión de funcionamiento: 5,0 V
  • Corriente de alimentación: 100 mA
  • Formato de salida: 8 analogicos
  • Rango de tensión de salida: 0 V a 5V
  • Óptima distancia de detección: 3 mm
  • Alcance máximo recomendado: 6 mm
  • Peso sin pines del cabezal: 3,09 g
Cuando el sensor detecta una superficie negra, la tensión de salida de los sensores aumentara en un rango cercano a los 5 volts, y cuando detecta una superficie blanca, la tensión de salida del los senores sera cercana a los 0 volts. Pololu nos facilita una libreria en arduino con el cual facilita el uso de este arreglo de sensores puedes descargarlo de este link:

    2. Arduino Nano

El infaltable y omnipresente arduino que todo lo puede, amen. En su versión reducida llamada "Nano" sera el cerebro principal que comandara al robot pues su facil y sintaxis de programación y hardware ya montado para su funcionamiento  nos permitira realizarlo en un menor tiempo, ademas de que contamos con un sin numero de librerias y uno de esas es justamente la de los sensores qtr8a. Se pueden usar otro  tipo de microntroladores, siempre y cuando se disponga de las 8 entradas analógicas necesarias para el uso de los sensores.

     5. Micromotores 10:1 HP Pololu (micrometal gear motor)


Estos motores funcionan a 6 V y tienen 3000 rpm de velocidad a ese voltaje, incluyen tmabien una caja de engranajes reductores de 10:1 con el cual obtenemos un torque final de 0.3 Kg-cm, suficientes para hacer correr como un rayo a nuestro robot. Al ser un motor de tipo HP (High Power), el consumo de estos es de 1.6 A en Pico, 120 ma libre sin cargaalguna ,y  con carga consumen alrededor de 500 mA.
Es importante tener en cuenta que si el voltaje del motor es aumentado, corre el riesgo de que se pueda quemar ya que  sus escobillas internas son muy finas, si quieres usar algo mas robusto en cuanto a duracion puedes elegir el de tipo (HPCB), que dispone de escobillas de carbon, la cual garantiza su durabilidad en competiciones. link: https://www.pololu.com/product/999

    4. Driver TB6612FNG


La función del driver de motor es la de suministrar la suficiente energía a los motores  para que entreguen toda su potencia sin ningun inconveniente, la capacidad de entregar corriente es un parametro importante en los drivers, ya que si por ejemplo nuestro micromotor exige una corriente de 1 Amp, y el driver es de solo 500 ma, pues al que le ira mal es al driver, corriendo el riesgo que se queme mas no el motor. en este este post explico mas a profundidad sobre el uso de este driver :http://aprendiendofacilelectronica.blogspot.pe/2016/11/control-de-motores-dc-con-modulo-driver.html

    

    5. Brackets 

Usaremos estos brackets de pololu en su version pequeña, la funcion de los brackets sera la de unir el los micromotores con el chasis del motor.

    6. Ball Caster 3/8 " de plastico  Pololu

 
Usaremos 2 de estas ball caster, que  seran en tercer punto de apoyo del robot, la ventaja de estas ballcaster es que son muy pequeñas y livianas por lo que el robot se puede desplazar con suma facilidad sobre la superficie sin mucho rozamiento.

    7. Bateria de Lipo de 7.4 Volts

Existen variedad de vaterias de lipo como tambien las hay de diversas marcas, lo que nos intereza aca es saber su capacidad de corriente y volaje, para el robot velocista es necesario que el voltaje de la bateria se de 7.4 volts, ya que nuestro motor funciona a ese voltaje, conviene usar una bateria que su capacidad de corriente este alrededor de los 500 mA a 1000 mA, oviamente que la bateria al almacenar mas cargas, es mas costosa y pesada, mucho ojo con esto, ya que no nos conviene que el robot sea muy pesado y que tampoco se agoten rapidamente las baterias.

    7. Llantas de Goma



Este tipo de llanatas no son muy comerciales, y solo las venden en algunas tiendas especializadas, la ventaja de estas llantas con otras convencionales, es que estas estan hechas de caucho liquido silicon, es por ello que presentan un mejor agarre, permitiendo ir  a velocidades mayores sin correr riesgo de derrape. Si deseas este tipo de llantas puedes comunicarte conmigo, (Lima-Provincias) a mi correo electronico. Tambien puedes empezar con las llantas convencionales de pololu como esta https://www.pololu.com/category/41/solarbotics-wheels

    8 . PCB Chasis



Si lo que quieres es hacer algo mas profesional y competitivo, pues puedes fabricarte con tu propio diseño y forma este tipo de chasis, en donde es a la misma vez el circuito electrónico donde se montan las partes electrónicas y mecánicas del robot. es importante que la pcb sea de doble cara para que el circuiro sea pequeño y de fibra, para que sea resistente.
Si deseas adquirir este tipo de placas o obtener los planos de diseño puede comunicarte conmigo a mi correo electronico: marko.antonio.1.16.92@gmail.com.
El diseño puede ser realizado en Ares de proteus o eagle ambos software disponen de las herramientas necesarias para el diseño del PCB unir pistas y trabajar en doble capa asi tambien como dar forma a la pcb etc.

   9 . Componentes electronicos varios

  • Switch de encendido apagado
  • Pulsadores
  • resistencias smd de 330 Ohms
  • Leds smd
  • diodo rectificador de 2 Amp
  • Capacitores filtro de 1000uf 
  • Capacitoresfiltro  ceramicos de codigo 104 - 0.1 uf, 103 - 0.01uf
  • Espadines machos.


Consideraciones a tener en cuenta para diseño de robot

Consideraciones para realizar un robot velocista:
  • Tiempo de realización del robot 
  • Disponibilidad de materiales en el mercado local.
  • Importación (caso que no hayan piezas en mercado local).
  • Complejidad del diseño (hardware y software) 
  • Mayor complejidad , mayor tiempo , menor complejidad, menor tiempo 
Consideraciones:
  • Peso
  • Centro de masa
  • Baterias
  • Tamaño
  • Filtrado de ruido
  • Llantas 
Diseño de Placa PCB
  • software Proteus (isis ares) o Eagle
  • Componentes superficiles (smd)
  • Recomendado usar doble capa
  • Peso debe centarce en el eje de  motores, 
  • No debe exeder los 20 x 25cm
  • Reacomendable usar  PCB fibra 
Reglas en competencias 
  • Solo tracción tipo diferencial.
  • Dimensiones máximas de robot: 20 cm ancho x 25 cm de largo.
  • Solo se permite accionamiento manual del robot.
  • Pista de Competencia contendrá 2 colores: blanco y negro.
  • Grosor de la línea de la pista: 2cm máximo.
  • Radio de Curvas Mínimo: 10 Cm
  • La pista generalmente es impresa sobre banner publicitario o sobre tabla de madera melamine.


sábado, 6 de febrero de 2016

Robot controlado por Bluetooth + aplicacion android (apk)


Materiales:

  • Kit motores reductores + llantas (esos chinos amarillos que venden en las tiendas de electrónica).
  • Modulo  driver de motor L298N.
  • Arduino (Uno, Nano, Mega, etc). (recomiendo el  nano por el tamaño reducido)
  • Modulo bluetooth hc05 0 hc06  (solo recibira datos desde el android para manejar el carrito).
  • Cables machos para protoboard ( para unir el circuito en el protoboard).
  • 1 switch, 1 led, 1 resistencia de 1K.
  • Un mini Protoboar. 
  • Ball Caster o rueda loca
  • Tornillos largos (para unir el ball caster o rueda loca al chasis)
  • Baterias de litio, lipo o kit de pilas con voltajes de 7.4v  a 9 v ( mayor a 5 V si no el arduino no  arrancara). 
  • Portapilas AA (si utilizas pilas, compra una que venga de 6 ,  o sino una de 4 y la otra de 2)
  • Celular o tablet android con conectividad bluetooth.
  • El chasis puede ser de acrilico, triplay (darle forma ).

La Forma del Chasis:

Hay que hacer un cuadrado y dentro de el hacer una circunferencia en la plataforma (acrilico, triplay, etc) .
 Luego cortar dos esquinas del cudrado, esto para colocar los motores y las llantas, hacerlo con mucho cuidado de no quebrar.
Los agujeros serviran para colocar tornillos que sujeten alos motores y ball caster o rueda loca.
Las baterias para ahorrar espacio se pueden colocar debajo.


El circuito electrónico:



Programa en Arduino:

En escencia lo que hace el el programa del arduino es recibir un caracter  y adicionalmente una bandera para indicar si es un dato de dirección("d") o de la velocidad("#") y los concatena. De esa manera se podra manejar mejor la comunicación.
Adicionalmente el control del robot tebnra una función para  aumentar o disminuir la velocidad.

////////
#include <SoftwareSerial.h>
#define motor_1_a    7
#define motor_1_r    8
#define motor_2_a    5
#define motor_2_r    6
#define pin_pwm1     9
#define pin_pwm2     10
#define led1         13
#define led2         11
int numero=0;
int direccion=0;
SoftwareSerial bluetooth(2, 3); // RX, TX
String readString="";
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);
}

void setup()
{
  delay(500);
  pinMode(led1,  OUTPUT);
  pinMode(led2,  OUTPUT);
  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);

  digitalWrite(led1,HIGH);
  delay(500);
  digitalWrite(led1,LOW);
  delay(500);
  digitalWrite(led1,HIGH);
  delay(500);
  digitalWrite(led1,LOW);
  delay(500);
  digitalWrite(led1,HIGH);
   delay(500);
   Serial.begin(9600);
 bluetooth.begin(9600);
}

void loop()
{

readString="";
while( bluetooth.available())
  {
    delay(2);
    char c=bluetooth.read();
    if(c=='#')//bandera velocidad
    {
       numero=readString.toInt(); //convierte cadena a entero numero
        numero=numero*2.54;
       Serial.println(numero);
     }
    if(c=='d')//bandera direccion
    {
      direccion=readString.toInt();
      Serial.print("dato direccion ");
       Serial.println(direccion);
    }  
 
    readString+=c; //concatena datos que llegan
  }
        if(direccion==0)   {digitalWrite(led2,LOW); motores(0,0);}
        if(direccion==1)   {digitalWrite(led2,HIGH);motores(numero,numero-5);}
        if(direccion==2)   {digitalWrite(led2,HIGH);motores(-numero,-numero);}
        if(direccion==3)   {digitalWrite(led2,HIGH);motores(0,numero-3);}
        if(direccion==4)   {digitalWrite(led2,HIGH);motores(numero,0);}      
}





Aplicacion Android ".apk":

Lo que hace la aplicación es enviar caracteres numéricos  seguido de una bandera para identificar que tipo de dato es. Si es de dirección (avanzar=1, retroceder=2, izquierda=3, derecha=4) adicionando la bandera "d" que indicara que es justamente de direccion. Si no se preciona nada, entonces enviara "0" (detenido). De esta forma el robot funcionara si solamente es presionado algún boton de direccion.
Ln el slider de velocidad la logica es similar, pero en este caso enviara datos numerico que van desde 0 hasta 255, que justamente es el pwm con el cual variaremos la velocidad en el arduino, seguido de la bandera "#" que justamente identifica que es un dato de direccion.
Todo esos datos son enviados mediante la rutina  call bluetoothClient como se nota en la imagen.

Puedes descargarlo desde aqui : apk carrito bluetooth
clave de cifrado: !H2nwlNrYYt_EaM-xcvGrmQKe1VcPZl8lv_xcqZQKjkI

Imagen de la aplicacion desde dispositivo android:


Nota: antes de presionar los botones, primero hay que conectarse con el modulo bluetooth desde el botón correspondiente, sino dara un mensaje de error.





viernes, 22 de enero de 2016

Variador de velocidad AC con Triac y PIC - Parte II : Programacion, simulacion y pruebas reales


 Programacion, simulacion y pruebas reales


Programación en el  PIC 16f876a


  •   El microcontrolador PIC se  encargara de recibir las señales del circuito de cruce por cero, para esto se hara uso del módulo  de “interrupción por el pin  RB0”  ya que  cada vez que reciba la señal del fototransistor, automáticamente saltara de todo lo que esté haciendo el PIC en ese momento para atender a esa señal y sincronizar el disparo hacia el triac.
  •   Para controlar la velocidad, se hará uso de la “lectura analógica por el pin A0” de un potenciómetro. Ya que la lectura analógica toma algún tiempo para la conversión a digital, no sería viable usarlo en el bucle del programa principal, pues esto retrasaría las demás funciones que realizara el pic . Se optó por hacer una lectura del potenciómetro  usando un temporizado de cada  200 ms, configurando el “Timer 1” del Pic a ese periodo.
  •  El pin que dispara al moc 3020 sera el “Pin Rb7” cuya duración del ancho de pulso será de 200 uS.
  •   Existen 2 leds indicadores: señal del cruce por 0 “Pin Rb1”, Señal de de cruce por 0 dividida entre 60 (0.5 seg) “Pin RB2” 
e
Entradas al pic :
#define   potenciometro        pin_a0  //entrada analogica para control 
#define   cruze_x_cero         pin_b0  //entrada digital para el sincronismo del disparo

Salidas del Pic:
#define   disparo                  pin_b7    //disparo hacia la etapa de potencia
#define   frec_1                    pin_b1    //indicador de cruce por cero 60 hz
#define   frec_2                    pin_b2    //indicador cruce por cero 1 hz

Variables del Pic:
long  delay=7000;
short  bandera1=0;
int      contador=0;

long    adc=0;
Programa en Pic C (CCS C compiler):

#include <16f876a.h>
#device adc = 10
#fuses hs,nowdt,put,nobrownout,nolvp,
#use delay(clock=20M)
#use standard_io(a)
#use standard_io(b)
#use standard_io(c)
#priority  INT_RB   //prioridad interrupcion por rb0

#define potenciometro pin_a0
#define cruze_x_cero  pin_b0
#define frec_1        pin_b1
#define frec_2        pin_b2
#define disparo       pin_b7

long delay=7000;
short bandera1=0;
int contador=0;
long adc=0;

#INT_timer1
void timer1()
{
      adc=read_adc(); //lectura de potenciometro externo para temporizar disparo
      delay_us(20);   //tiempo de conversion adc
      delay=adc*7.7;        //escalamiento hasta maximo periodo  adc 0 a 1024
      //                  //120Hz -> T:8mS = 8333uS max
     set_timer1 (65526);
}
#int_ext
void ext_isr()
{
   bandera1=1;     //si entro pulso, poner en 1 bandera de sincronizacion
   output_toggle(frec_1); //indicador de interrupcion
   //si todo esta correcto frec de interrupcion = 60Hz
   //=>120hz/60=1hz ==>T=0.5seg
   contador++;
   if(contador==60)
   {
       output_toggle(frec_2);
       contador=0;
   }
}

void main()
{
   delay_ms(100);
   output_high(frec_1);
   output_high(frec_2);
   delay_ms(500);
   output_low(frec_1);
   output_low(frec_2);
   delay_ms(500);
 
   enable_interrupts(int_ext);
   ext_int_edge(L_TO_H);

   setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);//Setup timer: Reloj interno, preescaler= 8
   enable_interrupts(INT_TIMER1);//Habilito interrupción particular del TIMER1
   set_timer1(65526);//Carga del TMR1 para 20 mhz q 200 ms

   setup_adc_ports(an0);
   setup_adc(adc_clock_internal);
   set_adc_channel(0);
 
   enable_interrupts(GLOBAL);//Habilito interrupciones globales


   while (true)
   {
      if(bandera1==1) //espera bandera de sincronizacion
      {
         delay_us(delay+440);
         output_high(disparo);
         delay_us(200);
         output_low(disparo);
         bandera1=0;
      }
   }  
}


Simulación


Pruebas en físico:


Link de descarga: https://mega.nz/#F!CxVHlLbZ!7-ff8bQFLlMAXJCPWJ0adA
clave de cifrado: !7-ff8bQFLlMAXJCPWJ0adA



Mejoras:
-Es Ovbio que  este proyecto realiza el mismo trabajo que un simple  Dimer analogico. Pero la gran potencialidad que este proyecto presenta no esta en solo controlar velocidad por medio de un potenciometro, si no que al ser diseñado para ser controlado por medio de un   microcontrolador, este es mucho mas inteligente y se pueden programar mas cosas. Puede añadirse sensores  de velocidad, temperatura, etc. Para hacer un control con un algoritmo PID de velocidad, temperatura pero en AC. Este es solo la parte básica,lo demás dependerá de  la imaginacion e ingenio para aplicarlo en algo util.

<< Primera parte del proyecto