Vous êtes sur la page 1sur 19

CONTROL DE MOTORES CC

con Arduino.
Sab 16.05.2015

CRTL+D, para volver a visitarnos. Creado por: V. Garca.


Tema:
Buscar

Idioma

PROLOGO.
Este artculo, se puede considerar como una aplicacin que puede ser puesta en prctica, de la teora que
se describe, en la que se emplean dos motores de corriente continua cuya aplicacin puede responder a la
necesidad de un proyecto, utilizando su propia placa PCB o si se prefiere a un pequeo robot, en la que
adquirir cierta experiencia en esta materia.
Tambin se puede aplicar, sobre la placa de utilidad que, se encuentra en este mismo sitio, con el
nombre escudo Arduino, principalmente debido a que est basado en la creacin de una tarjeta con los
conectores dispuestos de tal manera que sta tarjeta, se pueda conectar directamente en el soporte del
propio Arduino, digamos a lomos del mismo.

EL CIRCUITO L293.
El circuito integrado en el que nos basaremos es el L293b, en sus hojas de datos, podemos ver que, est
compuesto por cuatro amplificadores con salida triestado, capaz de proporcionar una corriente de salida de
hasta 1A por canal a tensiones de alimentacin desde 4'5V a 36V y con una entrada habilitable (chip
Enable) que permite un control de salida de dos amplificadores. Todas sus entradas son compatibles TTL.
En el L293b, se deben utilizar diodos de alta velocidad externos, en la salida, para la supresin de
transitorios inductivos. En la figura que sigue, se puede apreciar la tabla de la verdad, con la cual debe
familiarizarse para tener un conocimiento ms amplio de como se comporta este circuito.
Segn las especificaciones el L293b es un integrado monoltico de alta tensin, controlador de 4 canales,
de alta corriente. Cada canal es controlado por seales de entrada compatibles TTL y cada pareja de
canales dispone de una seal de habilitacin que desconecta las salidas de los mismos. Bsicamente esto
significa que utilizando este chip, puede utilizar motores de corriente continua y fuentes de alimentacin de
hasta 36 voltios, esos son motores muy grandes y el chip puede suministrar una corriente mxima de 1A por
canal. El chip L293b es tambin lo que se conoce como un tipo de puente H (H-Bridge).

Segn el diagrama, este chip pone a nuestra disposicin dos brazos idnticos e independientes. Cada
uno, consta de dos amplificadores comandados por una lnea de control (EN), con la cual habilitamos el par
de amplificadores que nos interese en cada momento. Esta disposicin, permite distintos montajes para un
motor o ms motores, como veremos. Es necesario resaltar la existencia en el mercado de dos
versiones L293B y L293D, dos diferencias entre ambas, en la versin B, no lleva diodos 'clamp' internos

(se puede utilizar un pequeo puente en los terminales del motor), sin embargo, admite hasta 1Amperio de
consumo, en el caso de la versin D, slo entrega 600mA, llevando los diodos internos. El usuario debe
tomar la decisin de cual utilizar.
El esquema que utilizaremos, est basado en la aplicacin del circuito integrado L293b, que como se
aprecia en las hojas del fabricante, es un driver de 4 canales, con l y unos pocos componentes ms,
podemos controlar fcilmente el giro de un motor o dos motores de corriente continua, con distintos circuitos
de montaje. Adems, tambin se puede controlar un motor bipolar paso a paso.
No

debemos

olvidar:

1)- Refrigerar en lo posible este circuito integrado, ya que puede adquirir bastante temperatura, compruebe
este

dato,

si

va

aplicar

de

forma

continuada

este

chip.

2)- Utilice un pequeo puente tipo W01F, para evitar disgustos con las tensiones inducidas del motor.

EL ESQUEMA ELCTRICO.
El circuito elctrico en el que nos basaremos es el recomendado por el fabricante del IC y que es
mostrado en la siguiente figura. Podemos distinguir dos pares de amplificadores con salidas triestado, con
un control habilitador (EN) comn para ambos, cuyas propiedades descubriremos ms adelante. Por el
momento nos ocuparemos de la parte sencilla.

INICIO SENCILLO.
La figura anterior es bastante explicita. Muestra dos montajes distintos como ya he mencionado. Vamos a
empezar por el control de un motor de juguete M1. En este ejercicio, he supuesto que no es necesario
utilizar el chip L293, ya que, en muchos casos, no tendremos que desembolsar el costo del circuito
integrado, con un pequeo transistor podemos salir al paso.

Las salidas de Arduino, sus pines son ideales para controlar directamente los pequeos elementos
elctricos, como los LED. Sin embargo, cuando se trata de dispositivos de consumos ms grandes (como
un motor de juguete o el de una mquina de lavar), es necesario un controlador externo. Un transistor es
increblemente til. Se obtiene una gran cantidad de corriente con una, mucho menor. Un transistor tipo
NPN, conectaremos la carga (M1) al colector del transistor y el emisor al negativo o masa. As, cuando la
seal alta del pin de nuestro Arduino alcance la base, fluir una pequea corriente por R1 (1K) de la base al
emisor y la corriente a travs del transistor fluir y el motor girar.

Hay miles de transistores del tipo NPN, que se adaptan perfectamente a todas las situaciones. Como voy
a utilizar la tensin de 6V de un cargador que tengo a mano, he elegido el BC337 un transistor comn de
uso general. Los factores ms relevantes en nuestro caso es que la tensin mxima (45 V) y su corriente
media (600 mA) son lo suficientemente alta para nuestro motor de juguete. En cuanto al diodo 1N4001 est
actuando como un diodo de seguridad.

Veamos una aplicacin sencilla, en la que utilizaremos un cdigo de los muchos que existen en la red.
Esto es un programa rpido para probar el circuito:

Cdigo control motor CC

Cdigo sencillo para mover un motor con intervalos de parada.

CDIGO: SELECCIONAR TODO


//
//
//

motorcc.pde

const
int
transistorPin
=
9;
//
connected to the base of the transistor
void
setup()
{
// set the transistor pin as output:
pinMode(transistorPin,
OUTPUT);
}
void

loop()

digitalWrite(transistorPin,
delay(1000);
digitalWrite(transistorPin,
delay(1000);

HIGH);
LOW);

}
En este ejemplo, vemos que pertenece a un circuito sencillo, con el cual hacemos girar un motor de
corriente continua, con intervalos de parada. Debido a lo sencillo del mismo, observamos que no se tiene
ningn control sobre el motor. Tendra ms aplicaciones si pudiramos, poner en marcha con un interruptor,
modificar la direccin de giro y poder variar la velocidad de giro.

Control de un motor CC.


Motor de CC con un potencimetro para cambiar su velocidad.

CDIGO: SELECCIONAR TODO


//
//
//

motordc.pde

int pot = 2;
// asigna pin analgico
2
para
el
pot
int motorPin = 9;
// motor en el pin
9
PWM
void setup()
// ejecutar una vez,
cuando
empieza
{
Serial.begin(9600); // establecer la
librera
serie
a
9600
bps
pinMode(pot,
INPUT);
pinMode(motorPin,
OUTPUT);
}
int
v
v
v
v

getPot()
{
int
v;
=
analogRead(pot);
/=
4;
=
max(v,
50);
=
min(v,
255);
return
v;

}
int

motorForward()
analogWrite(motorPin,

{
getPot());
delay(10);
digitalWrite(motorPin,
LOW);
}

void loop() {
vez

// ejecutar una y otra


motorForward();

Para controlar esto desde el exterior, se puede utilizar un pot en un puerto analgico para variar el nmero
de grados e incrementar su barrido. Puede hacer la prctica, copie el cdigo o bjelo de aqu y crguelo en
el IDE, para ver su efectividad.
Qu ocurre. El motor gira desde un mnimo de velocidad hasta el mximo segn giremos el pot, sin
embargo, se observa que el motor pierde fuerza de torsin (par motor, torque en ingls), esto puede ser
debido en parte, al transistor que utilicemos, pero es ms propio que sea debido al cdigo del programa que
no se adecua a lo que esperbamos. Debemos pensar en otro mtodo para lograr nuestro propsito.
Este es un cdigo bastante bueno, para el control de un motor de corriente continua que, se comporta
muy parecido al cdigo anterior.

Control motor con pot.


Movimiento del motor con potencimetro mejorado.

CDIGO: SELECCIONAR TODO


//
//
Funccion:
//
//
Utilizar
un
controlar
//

CC_motor_control_pot
potenciometro
motor

int sensor_pin = 2; //
entrada
int motor_pin = 9;
//
salida
digital
void

para
CC

debe

ser una
analgica
debe ser una
PWM.

setup()
{
Serial.begin(9600);
pinMode(motor_pin,
OUTPUT)

}
void
loop()
{
int
pot_val,
motor_speed;
pot_val = analogRead( sensor_pin );
motor_speed = pot_val*255.0/1024.0; //
Incluir
decimal

/* Sutil: No utilice valores enteros


como
255
y
1024 aqu. Compiladores agresivo preclculo
la divisin entera del 255/1024 como
cero.
*/
analogWrite(
motor_pin,
motor_speed); // hacer cosas tiles
}

Indagando sobre el tema, he llegado a encontrar una funcin reutilizable para actualizar la velocidad del
motor, veamos unas cuestiones a tener en cuenta. El ajuste de la velocidad del motor se establece dentro
del lazo loop(), en realidad la parte ms relevante se encuentra en el llamado map (), donde los valores
ledos del potencimetro se escalan a la salida.
As pues, necesitamos ...

UNA FUNCIN PARA


ESCALAS LINEALES.
El escalado lineal de los valores
de x para valores de y:
y = f(x)
donde f es un mapeado lineal.

Es decir, dados: x, xmin, xmax, ymin e ymax. Calcular y

TRADUCIR

LAS

UNA FUNCIN PARA


ESCALAS LINEALES.
Entradas

que

necesitamos: pin

de

potencimetro

TRADUCIR
sensor, pin

de

salida

LAS
del

motor.

Que tareas vamos a abordar:

Leer tensin del potencimetro.

Convertir voltaje con escalas de 10 bits a 8 bits PWM y

Cambiar la velocidad del motor.

Introduzca el cdigo de la parte inferior en su boceto. Observe que, el cdigo no est dentro de ningn
bloque de otro programa (como setup() o void()), es parte de una funcin. Cmo comprobar que esta
funcin
int

est
int_scale(int

int

y;

x,

int

ymin

xmin,
float(ymax

int
-

funcionando?
xmax,

ymin)*float(

int
x

ymin,
xmin

int

ymax)

)/float(xmax

{
xmin);

return(y);
}
Este cdigo, es esencialmente una reimplementacin integrada de la funcin map, por los creadores del
Arduino. Ver http://arduino.cc/en/Reference/Map
Nota.- int Devuelve

un

int_scale Es
int

el

x Es

float Se

usa

nombre

la

primera
float

para

entero.
de

la

entrada
una

llamada
mejor

funcin.
x.
precisin.

return(y) Devuelve el valor almacenado en y.


Funciones que llaman a otras funciones: (int x, int xmin, int xmax, int ymin, int ymax);
motor_speed = int_scale(int x = pot_val, int xmin = 0, int xmax = 1024, int ymin = 0, int ymax = 255);
Donde: return(y) = motor_speed
A continuacin, a modo de ejemplo, veremos un cdigo que usa la funcin int_scale.

Control motor con potencimetro.


Nuevo ejemplo.

CDIGO: SELECCIONAR TODO

//
//
Funccion:
//
//
Utilizar
un
controlar

CC_motor_control_pot
potenciometro
motor

para
CC

int sensor_pin = 2;
// debe ser una
entrada
analgica
int motor_pin = 9;
// debe ser una
salida
digital
PWMt
void
setup()
Serial.begin(9600);
pinMode(motor_pin,
}
void

loop()

{
OUTPUT)
{

int
pot_val,
motor_speed;
pot_val = analogRead( sensor_pin );
motor_speed = int_scale( pot_val, 0,
1024,
0,
255;
analogWrite(
motor_pin,
motor_speed);
}
int int_scale(int x, int xmin, int xmax,
int
ymin,
int
ymax)
{
int
y;
y
=
ymin
+
float(ymax
ymin)*float( x - xmin )/float(xmax xmin);
return(y);
}

Si comprueba este cdigo, observar que el incremento de velocidad propuesta por el potencimetro, se
percibe como una continuidad lineal. Esta es la mejora esperada.

CONTROL
L293.

EL

CIRCUITO

INTEGRADO

Hemos probado a utilizar un transistor a la salida de un pin de Arduino y no hemos quedado satisfechos
con los resultados. Cabe la posibilidad de utilizar dos transistores en sendos pines, cada cual conducira un
borne del motor, como dira, el motor entre dos pines, pero no quiero perder ms tiempo. Es el momento de
utilizar el L293, en una de las aplicaciones que vienen en las hojas de especificaciones.
Adems con el L293, no tiene que preocuparse por la regulacin de una tensin mayor, ya que permite
dos fuentes de energa - una fuente directa, hasta 36 V para los motores y otra de 5V, para controlar el CI
que, puede ser conectada a la fuente de alimentacin ya que el suministro de alimentacin del motor
proviene es independiente. En el circuito de abajo, se supone una alimentacin superior para el motor. A
continuacin se puede ver la disposicin de las conexiones para el chip y el motor. La tabla de verdad
muestra la lgica de la salida.

El puente H, es normalmente un circuito elctrico que permite aplicar un voltaje a travs de una carga en
cualquier direccin a una salida, por ejemplo, motor. Esto significa que esencialmente puede invertir la
direccin de la corriente y por lo tanto invertir la direccin del motor. Lo nico que a de recordar es que, la
conexin a tierra debe ser compartida, comn para ambas fuentes.
En este circuito que sigue, no se trata ms que de un control bidireccional, por lo tanto, no se hace
necesario el puente H, lo que resulta ms sencillo en todos los sentidos. Si nos fijamos en la tabla de verdad
que aparece arriba, quedan claras las opciones que nos presenta, he de resaltar que la entrada EN (patilla
1), puede ser definitoria.
Veamos cmo es esto, en cualquier momento. Si se aplica un 1 lgico sobre A1, en la entrada A2,
tenemos que aplicar un 0 lgico, esto har girar el motor en un sentido predeterminado. Para cambiar el
sentido de giro, y respetando las reglas de la mecnica, primero pondremos A1 y A2 en un mismo estado
lgico y acto seguido invertiremos el estado inicial, es decir, A1 en 0 lgico y A2 en 1 lgico.
Con independencia del estado lgico de las entradas A1 y A2, si es necesario detener el motor,
simplemente enviamos un estado lgico bajo (0) a la patilla EN y el motor se para de inmediato. En estas

condiciones no es posible mover el motor, no hasta que, a dicha entrada EN, le enviemos un 1 lgico, en
ese momento, podemos decidir el sentido de giro o la parada del mismo con los valores lgicos que
apliquemos a las patillas A1 y A2. Aunque, lo esencial de esta entrada EN, es que si aplicamos una salida
PWM a ella, simplemente podremos regular la velocidad del motor, esta es su funcionalidad. Ver el
esquema elctrico.

Por seguridad, recomiendo que, conecte una fuente externa de alimentacin de corriente continua a la
entrada de alimentacin externa de Arduino, as, puede alimentar el motor y el Arduino. Adems, puede
dejar conectado el cable USB, para una fcil y rpida reprogramacin, si fuera necesaria. De esta forma,
cualquiera que sea el motor que utilice, se asegura que la fuente de alimentacin es compatible,
naturalmente, no utilice un motor de 5V con una alimentacin de 12V.

EL CDIGO.
La teora es bastante sencilla. Se trata de poner, un estado lgico 1 en la entrada A1, al mismo tiempo que
en la A2 ponemos un 0 lgico. El cdigo para este caso es sencillo, veamos un ejemplo:

Control de motor con potencimetro.


Controlar el giro de un motor de CC mediante un L293.

CDIGO: SELECCIONAR TODO


/*
*
motorpwmpot.pde
*
* Hace girar un motor de CC mediante un
L293
conectado
a
los
pines
* 7 y 8 controlando la velocidad por PWM
sobre
el
pin
Enable
del
L293
* en base a la lectura del potenciometro
conectado
al
pin
2
analgico
*
* Basado en un cdigo de: Miguel Grassi
*
www.miguelgrassi.com.ar
*
*
Modificado
por:
V.
Garca
el
07.02.2011
*
*/
int ledPin = 13;
// LED conectado al
pin
digital
13
int pinA1 = 7;
// entrada Motor A 1
int pinB1 = 8;
// entrada Motor B 1
int
pinEN1
=
9; //
entrada
EN
1
int pinPot = 2; // Lectura analgica del
Potenciometro
int
valorPot=
0;
int
valorVeloc
=
0;
void setup() {
de
pinMode(ledPin,
pinMode(
pinMode(

// Inicializa los pines


salida
OUTPUT);
pinA1,
OUTPUT);
pinB1,
OUTPUT);

pinMode(pinEN1,
OUTPUT);
pinMode(pinPot,
INPUT);
digitalWrite(pinEN1, HIGH); // linea es
la
clave,
RPA
Serial.begin(9600);
// El LED parpadea 3 veces. Esto debera
ocurrir
slo
una
vez.
// Si usted ve el parpadeo del LED tres
veces,
significa
que
// se restablecio (reset) el propio
mdulo.
Probablemente
porque
// el motor provoc una bajada de
voltaje
o
un
corto.
blink(ledPin,
3,
100);
}
void
loop()
{
digitalWrite( pinA1, HIGH); // Valores
ALTO en A y BAJO en B simulaneamente
digitalWrite( pinB1, LOW);
// hacen
girar
el
motor
1
hacia
ADELANTE
valorPot = analogRead(pinPot); // Lee el
valor
del
potenciometro
valorVeloc = map(valorPot, 0, 1023, 55,
255); //Convierte un valor entre 0 y
1023
al
rango
0-255
// valorVeloc = valorPot / 4 ;
//
segunda
opcin
analogWrite(pinEN1,
valorVeloc);//
y
establece la velocidad del motor con ese
valor
}
/*
void

blinks
blink(int

an

LED
whatPin,

*/
int

cuantoTiempo,
int
milliSecs)
{
for (int i = 0; i < cuantoTiempo; i++) {
digitalWrite(whatPin,
HIGH);
delay(milliSecs/2);
digitalWrite(whatPin,
LOW);
delay(milliSecs/2);
}
}

El cdigo est bastante bien descrito y no considero necesario entrar en mayores detalles. Copie el cdigo
o si lo prefiere, bjelo de aqu y crguelo en el IDE, para comprobar su efectividad.
He realizado este ejemplo, utilizando un escudo para Arduino, realizado con placa de tiras preformada,
como se puede apreciar en la imagen de abajo, el esquema utilizado corresponde a la imagen anterior.
Sigue una demo del resultado obtenido.

Vdeo.

EL L293
El circuito integrado L293B, es un driver de 4 canales, capaz de proporcionar una corriente de salida de
hasta 1A por canal. Cada canal, se puede controlar por seales de entrada compatibles TTL y cada par de
canales dispone de una seal de habilitacin que desconecta las salidas de los mismos.
Ahora, vamos a ocuparnos del cdigo necesario para controlar un motor de corriente continua con
Arduino. He decidido probar una idea para que los que tengan inters en hacer su primer mini robot,
empiecen con una experiencia que les anime y levante la moral.
La idea es que con un motor de juguete, movamos el eje delantero de una pequea caja, cualquier recinto
pequeo nos puede servir, en esta, tiene que alojar las cuatro pilas de 1'5V con su porta pilas, el propio
Arduino, el motor, el soporte del eje y una rueda de giro libre en todas direcciones. Algo parecido a la
imagen.

Las fotos, aunque corresponden a otro ejercicio (cosa que no es relevante), dan una idea de lo que se
describe. La prctica demostrar cmo mover un objeto (bot-tarrina), con un slo motor y un interruptor del
tipo 'bumper'. Cuando conectemos la tensin, el Arduino mandar una seal al motor para que gire, por un
tiempo, lo que har avanzar el pequeo robot. Cuando ste, encuentre un obstculo, lo detectar con el
interruptor que tropezar con el objeto esttico, esto producir una seal/orden en el programa, de modo
que el motor cambiar su direccin de giro por un tiempo determinado, tras el cual volver a girar en la
direccin de inicio. Las direcciones son mecnicamente, bastante aleatorias.
Slo se trata de un ejemplo, de como manejar un pequeo robot con un mnimo de componentes. En
posteriores artculos hablaremos con ms profundidad de las posibilidades del L293 en los motores paso a
paso. El siguiente es el cdigo que se encarga de realizar estos cambio de desplazamiento. El cdigo como
se hace notar, lo he adaptado a mis necesidades, con un pequeo cambio.

Control motor con Puente-H.


Cdigo mejorado para el control de un motor de corriente
continua, con control de velocidad por potencimetro.

CDIGO: SELECCIONAR TODO


/* Control de un motor DC con puente H
*
motorL293h.pde
*
*
http://itp.nyu.edu/physcomp/Labs/DCMotor
Control
* Modificado por V. Garcia el 08.02.2011

* Puede adaptarse a un bot con un motor


en
las
ruedas
de
traccion
* y una rueda de giro libre que pivote
cambiando
la
direccion
*/
int switchPin = 2;
// entrada del
switch
int motor1Pin = 7; // pin 1 del L293
int motor2Pin = 8;
// pin 2 del L293
int speedPin = 9;
// pin enable del
L293
int
ledPin
=
13;
//LED
void
setup()
{
// pone el switch como una entrada
pinMode(switchPin,
INPUT);
digitalWrite(switchPin,
HIGH);
// pone todos los otros pines usados
como
salidas
pinMode(motor1Pin,
OUTPUT);
pinMode(motor2Pin,
OUTPUT);
pinMode(speedPin,
OUTPUT);
pinMode(ledPin,
OUTPUT);
// activa la RPA del pin speedPin para
activar
el
motor
digitalWrite(speedPin,
HIGH);
// El LED parpadea 3 veces. Esto debera
ocurrir
slo
una
vez.
// Si usted ve el parpadeo del LED tres
veces,
significa
que
// se restablecio (reset) el propio
mdulo.
Probablemente
porque
// el motor provoc una bajada de
voltaje
o
un
corto.

blink(ledPin,
}

3,

100);

void
loop()
{
// si el switch es high, motor gira en
una
direccion
if (digitalRead(switchPin) == HIGH) {
digitalWrite(motor1Pin, LOW); // pone
motor1
del
H-bridge
low
digitalWrite(motor2Pin, HIGH); // pone
motor2
del
H-bridge
high
}
// si el switch es low, motor gira en la
otra
direccion:
else
{
digitalWrite(motor1Pin, HIGH); // set
leg
1
of
the
H-bridge
high
digitalWrite(motor2Pin, LOW); // set
leg
2
of
the
H-bridge
low
blink(switchPin, 2000, 2); // si
pulsas switch cambia giro un tiempo
}
}
/*
blinks
an
LED
*/
void
blink(int
whatPin,
int
cuantoTiempo,
int
milliSecs)
{
int
i
=
0;
for ( i = 0; i < cuantoTiempo; i++) {
digitalWrite(whatPin,
HIGH);
delay(milliSecs/2);
digitalWrite(whatPin,
LOW);
delay(milliSecs/2);
}
}

Una vez ms, si lo desea, puede copiar y pegar este cdigo, dle un nombre y crguelo en su IDE
Arduino.
En los ejercicios que se han desarrollado en este documento, aunque hemos utilizado el circuito integrado
L293, tan slo se ha empleado un amplificador de los cuatro para manejar el motor, o dos amplificadores,
uno para cada devanado del motor. La parte ms relevante de este circuito integrado, est en utilizar los
cuatro amplificadores de forma que se conoce como Puente-H.

Despus de lo tratado hasta el momento, en este documento, estamos preparados para comprender y
emprender el montaje del L293 en puente-H, para el control de un motor. Es cierto que el control de
motores, tambin se puede conseguir con un circuito integrado como es el ULN2003 que integra una matriz
de siete transistores darlington, capaces de entregar hasta 500mA cada uno y la versin ULN2803, con una
matriz de ocho transistores darlington. Este ltimo, se utiliza en los casos que se tienen que controlar ms
de un motor y sobre todo, con motores unipolares.
Los motores que hemos manejado hasta el momento son motores de corriente continua (DC), en
prximos artculos desarrollaremos controles para motores paso a paso bipolares y unipolares. El control de
un motor unipolar, es ms sencillo que el del motor bipolar, debido a la manera de energizar los devanados