Archivo de la categoría: Programación

Arduino: cómo hacer que los HEX queden en una carpeta conocida

Varias veces me han preguntado cómo se obtiene el archivo final de la compilación en «idioma de máquina» o hexadecimal (NombrePrograma.HEX) de un programa creado con el IDE de Arduino (también llamado Sketch por algunos).

Este archivo es útil para varias operaciones, como por ejemplo «descompilarlo» para ver el assembler, y también porque sería posible grabar el programa usando un programador de chips en un lote de microcontroladores que se necesite para un proyecto, sin usar bootloader ni una placa Arduino cuando vamos a producir una equis cantidad de plaquetas para uso personal, o para un cliente.

La secuencia para tenerlos en una carpeta accesible es:

1) Abrir el IDE de Arduino

2) Abrir el menú «Archivos» y allí elegir «Preferencias»

3) En el panel de Preferencias, abajo de todo, ingresar a la capeta de «preferences.txt» por medio del enlace que está debajo de un texto que dice «Más preferencias pueden se editadas [etc]…»

4) Una vez abierta la carpeta donde esta el archivo de preferencias, cerrar el IDE de Arduino (esto es muy importante)

5) Hacer una copia del archivo de preferencias para tenerlo de reserva por cualquier problema que se presente.

6) Abrir el TXT preferences.txt con un editor de texto simple, como el Bloc de Notas o Notepad

7) Hay una extensa lista allí. Buscar en el archivo de preferencias la zona donde está esta opción:

sketchbook.path=C:\Users\toshiba pc\Documents\Arduino

Obvio que la dirección dentro del disco C: que va luego del signo «=» será propia de cada máquina

8) Puede estar o no definida la opción build.path (es la que le indica al compilador dónde debe guardar el archivo compilado). Allí se puede crear o editarla. En mi caso, yo debí insertarla porque no existía y escribí:

build.path=C:\Users\toshiba pc\Documents\Arduino\HEX

Nota: En la publicación fuente de esta aplicación dice que es importante que este código agregado quede ubicado después de la opción export.application, pero sin embargo esto sería en una versión anterior, ya que ahora cada vez que se abre el IDE de Arduino estas opciones quedan ordenadas alfabéticamente.

9) Ahora sólo queda guardar este archivo editado y correr el IDE




10) Para comprobar que funciona, compilar cualquier programa y revisar si ha aparecido la carpeta HEX, y dentro de ella el compilado .HEX. Por ejemplo, si se compila el famoso ejemplo Blink.ino encontraremos el archivo Blink.ino.hex. Pero también encontrarán un Blink.ino.with_bootloader.hex. Es importante, ya que en este caso obtendrán un HEX con el que se podrán programar chips que además posean el habitual bootloader de la placa Arduino.

11) Luego uno puede ir distribuyendo estos .HEX en las carpetas de cada proyecto, ya que sólo estarán allí hasta que se haga la compilación de un nuevo programa. El IDE de la versión actual los borra antes de escribir un nuevo HEX.



Arduino: Usando la función millis() en lugar de delay()

El código que sigue es un típico ejemplo de escritura a través de la comunicación serie de Arduino. Escribe “Hola” a través del puerto COM serie (visible con el Monitor Serie de Arduino, en la pestaña Herramientas), y espera durante 1000 milisegundos (1 segundo) al final de cada iteración del bucle.

La función delay() es muy fácil de usar para crear esperas, pero tiene un inconveniente: deja al microcontrolador «atrapado» dentro de la ejecución de esta función durante el tiempo que se ha indicado. Si hubiese un cambio en un pin que debería detectar, o si llegase información a través de cualquiera de las comunicaciones posibles (serie, I2C o SPI) el microcontrolador sólo se enteraría luego de completarse el retardo.

Una solución es crear un retardo que no deje insensible al sistema durante un tiempo tan extenso.

La función millis()

millis() devuelve el número de milisegundos desde que la placa Arduino empezó a ejecutar, luego de un reinicio o el encendido. Este número se desbordará (volverá a cero), después de aproximadamente 50 días.

Retorna la cantidad de milisegundos en un valor long sin signo (unsigned long).

Nota: Tenga en cuenta que como el valor de retorno para millis() es un long sin signo (unsigned long), pueden producirse errores lógicos si un programador intenta hacer operaciones aritméticas con tipos de datos más pequeños, como de tipo int. Incluso con los long con signo se pueden producir errores ya que su valor máximo es la mitad que la de su contraparte sin signo.




Ejemplo de texto «Hola» utilizando la función millis()

Hacerlo de esta manera solo tiene sentido como ejemplo, ya que es evidente que en este caso directamente se puede usar una función delay(1000). Pero de todos modos la diferencia entre este ejemplo y el código que usa la función delay(1000) es que el ciclo del código que usa la función millis() se ejecutará una vez por segundo con la máxima precisión posible. El bucle en un código con delay(1000) se ejecutará en algo más de tiempo, ya que se produce un retardo al ejecutar Serial.println(«Hola»). Ocurrirá igual con cualquier otra serie de instrucciones que se incluyan dentro del bucle.

¿Por qué usar millis() en lugar de delay()?

Presentaré dos ventajas al utilizar millis() para crear retardos, en comparación con el uso habitual de delay().

1. Cronometraje preciso

La primera ventaja que discutiremos es la exactitud en el tiempo.

Con millis() podemos garantizar que el bucle se ejecute tantas veces como queramos dentro del retardo sin afectar su extensión, independientemente del tiempo de ejecución (obviamente, siempre que el tiempo de ejecución de todas las instrucciones sea menor al retardo deseado).

Con delay() esto no es posible, ya que no sabemos cuánto tiempo durará el tiempo de ejecución de todas las instrucciones de programa que están dentro del ciclo.

Una sincronización precisa como esta es muy útil cuando se muestrea a una cierta frecuencia, o cuando se utilizan filtros, entre otras cosas.

2. Sin bloqueo

La ventaja principal de la función millis() es que no nos impide ejecutar otro código mientras estamos «esperando».

Ejemplo: digamos que queremos imprimir «Hola» en el puerto serie una vez por segundo mientras hacemos otras cosas. Esto no es posible con delay(), ya que entrar a la función delay() pausa todo el código.

Aquí hay una manera de hacer esto:

Este fragmento de código es bastante similar al primer ejemplo que mostramos, excepto que este no bloquea el resto del programa mientras no se está imprimiendo hacia la línea serie.

3. Un simple secuenciador

Vamos a escribir un ejemplo simple en el que creamos un planificador que imprime ciertos trozos de texto a través de la línea serie a diferentes intervalos.

Así es como se ven los primeros 60 segundos en el Monitor Serie:

Esta es una manera agradable y fácil de sincronizar las ejecuciones en su código. También se puede ejecutar otras partes de código simultáneamente.

4. Una nueva función delay()

La función delay() estándar podemos reemplazarla por una implementada con la función millis(). Si bien parece que es lo mismo, ya veremos a continuación qué ventaja nos puede ofrecer su estructura de programa:

Además de esperar el tiempo indicado, esta función monitorea un pin de entrada del Arduino que haya sido cableado para detectar que ha sucedido algún evento externo. Si esa señal va a nivel BAJO (LOW), se interrumpe el retardo.

Para conectar varias entradas capaces de interrumpir el ciclo de retardo, se pueden agregar más elementos en la comparación de cierre del while, por ejemplo

while (Contador<=millis() && digitalRead(12)==HIGH) && digitalRead(11)==HIGH);

O se puede conectar a la entrada por el pin 12 (u otro pin elegido) un circuito como el que sigue, un AND realizado con lógica de diodos de señal (1N914 o 1N4148), que tiene la ventaja de que se puede ampliar indefinidamente. También se puede implementar con un circuito integrado compuerta AND.

Nota: quede claro que el circuito se representa con pulsadores, pero cada una de estas entradas puede ser un microswith, los contactos de un relé, o cualquier otro sensor que cierre circuito hacia GND (tierra o común).

Función micros() y desbordamiento

Al igual que delay() tiene una versión en microsegundos llamada delayMicroseconds(), la función millis() tiene como compañera para tiempos breves la función micros(). Si necesitamos una mejor resolución, micros() puede ser el camino a seguir. Sin embargo, tenga en cuenta que el valor devuelto por micros() se desbordará (volverá a cero) después de aproximadamente 70 minutos, en comparación con los 50 días de millis(). “Desbordamiento” significa que el conteo llega a su máximo, y entonces los valores de retorno de la función recomienzan desde cero.

Resumen

millis() y micros() son funciones realmente útiles para usar en tareas relacionadas con el tiempo. La opción inicial y típica de un programador de Arduino es usar delay(), que no siempre funcionará tan bien, principalmente cuando se programan muchas funciones que tienen que ver con el tiempo y existen eventos que no se pueden perder.




VL53L0X: Sensor de distancia que mide por la velocidad de la luz (Time-of-Fly)

El VL53L0X es un producto novedoso basado en el sistema FlightSense de la empresa ST Microelectronics. Es una tecnología innovadora que permite medir distancia con independencia de la reflectividad del objetivo.

En lugar de calcular la distancia midiendo la cantidad de luz reflejada desde el objeto (en lo que influye significativamente el color y tipo de superficie), el VL53L0X mide con precisión el tiempo que tarda la luz en viajar desde el objeto más cercano y volver reflejada hasta el sensor (un proceso llamado Time-of-Fly, o Tiempo de vuelo).

Debido a que utiliza una fuente de luz con un haz muy estrecho, es bueno para determinar la distancia de solamente la superficie que está directamente delante. A diferencia de los sonares ultrasónicos que hacen rebotar sus ondas de sonido, en este caso el «cono» de la detección es muy estrecho. A diferencia de los sensores de distancia IR que intentan medir la cantidad de luz que regresa, el VL53L0x es mucho más preciso y no tiene problemas de linealidad o «imágenes dobles», en las que no se puede saber si un objeto está muy lejos o muy cerca.

Puede medir distancia con un alcance de hasta 2 m.

El control del procesador y la lectura de los resultados se realizan por medio de una interfaz I2C.

Características clave

  • Emisor infrarrojo: 940 nm
  • Distancia: hasta 2000 mm
  • Dirección I2C: Programable
  • Fuente de luz VCSEL (Vertical-cavity surface-emitting laser = Láser de emisión de superficie de cavidad vertical)
  • Sensor de rango con avanzado microcontrolador
  • El chip mide sólo 4,4 x 2,4 x 1,0 mm
  • Medición de distancia rápida y precisa
  • Mide rango absoluto hasta 2 m.
  • El rango reportado es independiente de la reflectividad del objetivo
  • Compensación óptica cruzada integrada avanzada para simplificar la selección del vidrio de cobertura
  • Seguro para el ojo humano
  • Dispositivo láser de clase 1 que cumple con la última norma IEC 60825-1: 2014 – 3ª edición
  • Fácil integración por el sistema de montaje de soldadura del chip
  • No tiene óptica adicional
  • Fuente de alimentación individual
  • Regulador de voltaje integrado en la plaqueta
  • Interfaz I2C para control de dispositivos y transferencia de datos
  • Pines de entrada salida de uso general Xshutdown (para reinicio) e Interrupt (interrupción)
  • Dirección I2C programable

Conexión con Arduino

  • VCC (en algunos fabricantes VIN) es la fuente de alimentación, el módulo acepta de 3 a 5V de alimentación. Use el mismo voltaje en el que se basa la lógica del microcontrolador. Para la mayoría de los Arduinos es 5V.
  • Conecte GND a tierra/alimentación común (marcado también GND en el Arduino).
  • Conecte el pin SCL al pin SCL (señal de reloj I2C en su Arduino. En un Arduino UNO también se conoce como pin A5, aunque está disponible del lado de los pines digitales. En un Mega es el digital 21 y en un Leonardo es el digital 3.
  • Conecte el pin SDA al pin SDA (datos I2C) en su Arduino. En un Arduino UNO también se conoce como pin A4, en un Mega es el digital 20 y en un Leonardo es el digital 2.

Los pines adicionales son:

GPIO1: este es un pin que usa el sensor para indicar que están listos los datos. Es útil para cuando se realiza una detección continua. Tenga en cuenta que no hay ajuste de nivel en este pin, es posible que no se pueda leer el voltaje de nivel lógico de 2,8V en un microcontrolador de 5V (podríamos en un Arduino UNO, pero no es seguro). La biblioteca de Adafruit no hace uso de este pin, pero está ahí para usuarios avanzados.

XSHUT – es el pin de apagado/reinicio para el sensor. Por defecto es alto. Hay un diodo de cambio de nivel para que se pueda usar la lógica de 3,3 – 5 V en este pin. Cuando el pin va a nivel bajo, el sensor entra en modo de apagado.




Abra el IDE de Arduino. Mantenga siempre actualizado a la última versión.

Abra en el menú HERRAMIENTAS la opción ADMINISTRAR BIBLIOTECAS.

Búsqueda y carga en el IDE Arduino de la biblioteca del VL53L0X

La elección ADMINISTRAR BIBLIOTECAS abrirá la siguiente ventana del Gestor de Bibliotecas:

En esa ventana tenemos, en la parte superior derecha una ventana de editor con la leyenda «Filtre su búsqueda…«, donde debemos escribir el nombre del dispositivo:

Esta búsqueda nos ofrece varias bibliotecas. Para Arduino UNO y relacionados tenemos la de Adafruit y la de Pololu. En artículos en la web recomiendan la de Pololu, porque es más simple que la del otro fabricante. De todos modos, podemos instalar ambas. No hay conflictos en esto. El botón que dice «Instalar» aparece cuando se coloca el puntero del mouse en la biblioteca elegida. Si no aparece, es porque ya está instalada. Si no fuese así, recurra a el enlace «More info» y descargue la biblioteca desde el sitio GitHub, en formato ZIP, y proceda a instalarla con las instrucciones que ofrecen AQUÍ.

El gestor nos indicará que la biblioteca está lista con un cartel remarcado «INSTALLED».

Las bibliotecas quedan listas para ser utilizadas. La que corresponde a Pololu se llama VL53L0X, mientras que la de Adafruit se llama igual y está dentro de todas las bibliotecas de este fabricante, que llevan su nombre comercial como prefijo.

Dirección para el bus I2C

La dirección por defecto de I2C es 0x29, pero recuerde que es posible programar esta dirección en el VL53L0X. Con la biblioteca Adafruit, hay dos maneras de establecer la nueva dirección. Durante la inicialización, en lugar de llamar a lox.begin(), se llama a lox.begin(0x30) para establecer la dirección en 0x30. O se puede, más adelante, llamar a lox.setAddress(0x30) en cualquier momento. Es importante realizar esta operación con una sola placa VL53L0X conectada al bus I2C, o todas quedarán cambiadas.

Programas de prueba

«Continuous», de Pololu
(Este ejemplo muestra cómo usar el «modo continuo» para tomar mediciones de distancia con el VL53L0X. La información se muestra en la pantalla emergente del Monitor Serie, que debe estar fijado en 9600 baudios.)

Y el que sigue es un ejemplo con la biblioteca de Adafruit, con los comentarios traducidos. Siempre con la misma conexión del diagrama de arriba.

En el programa que sigue, para reducir el ruido de la medición se muestra el promedio de varias medidas. Las líneas comentadas muestran los distintos modos de funcionamiento.



Puente H: Placa controladora de motores L9110S

La placa L9110S está diseñada para que los microcontroladores o circuitos lógicos puedan controlar con sencillez motores de corriente continua.

Driver de motores L9110S

El circuito está diseñado en base al chip controlador L9110, fabricado en la clásica cápsula DIP8 o en un diseño SOP8 SMD y basado en transistores MOSFET.

Circuito integrado L9110S

La tensión de alimentación para los motores puede variar de 2,5 a 12 V.

Diagrama de conexión

Como se observa en el siguiente diagrama, el control con el cableado típico no requiere componentes adicionales.

Conexión básica

Las entradas se pueden conectar directamente al microcontrolador. Si se conectan a un circuito que tiene salidas OC (Open Colector, o Colector Abierto) se requiere una resistencia pull-up conectada a la alimentación de 5V. Si bien en la hoja de datos del chip indica que el valor adecuado es ?1 k?, el módulo en sí incluye en su circuito resistores de 10 k? conectados al voltaje de alimentación de la lógica, o Vcc.

El circuito tiene dos entradas: una que puesta en ALTO hará que el motor avance, y una que puesta en ALTO hará que retroceda. Si se desea que el motor esté detenido, ambas entradas deben estar en el mismo valor: las dos en estado BAJO (LOW), o ambas en estado alto (HIGH). La placa tiene dos salidas, con bornera, que se conectan directamente al motor.

Las entradas que no se conectan a un circuito son tomadas como nivel BAJO (L, o Low) sin que ingrese ruido. Con un nivel ALTO (H, o HIGH), la corriente en esa entrada será de alrededor de 1 mA. El nivel de tensión para que el chip detecte la entrada en estado lógico BAJO o L es como máximo de 0,7 V.

Típicamente, para el nivel ALTO o H, la tensión en el pin de entrada debe ser de alrededor de la mitad del valor de alimentación o más (hasta, como máximo, el valor de la tensión de alimentación).

La corriente del motor se puede mantener constantemente desde 0,75 hasta 0,8 A (750 a 800 mA), y el circuito soporta picos de 1,5 a 2 A.

La hoja de datos ofrece una lista de los valores lógicos de las entradas y salidas.

nuevo-5

Esta tabla se puede ampliar para situaciones no típicas. Si sólo hay una entrada en el nivel H y la otra está en nivel L, el motor gira. Pero si ambas entradas están en H, o ambas entradas están en L, las salidas están en un tercer estado, o “flotante” (ningún voltaje), y no ambas en 0 volt, o “L”, como se muestra en la tabla.

Las salidas están conectadas internamente a diodos que protegen al circuito de los pulsos de contracorriente.




El L9110 gestiona dinámicamente frecuencias de hasta 40 kHz, mientras que el tiempo de conmutación más breve para la regulación por ancho de pulso (PWM) es de alrededor de 15 uS.

Diagrama de conexiones

Conexiones

Diagrama eléctrico

Circuito Eléctrico

Ejemplo práctico para controlar un robot

Ejemplo práctico - Control de un Robot

Ejemplo de programa para Arduino: prueba de movimientos

L9110S como amplificador de sonido para su robot

El control de un motor no es la única aplicación posible. El circuito también se puede utilizar como un sustituto de amplificador de potencia para una salida de audio digital de un microcontrolador.

En lugar de conmutar corriente a través del parlante como se realiza habitualmente, con un transistor, este circuito proporciona una doble amplitud de los impulsos de salida y, por lo tanto, aporta una potencia significativamente mayor.

Para una fuente de alimentación de 5 V es conveniente conectar un altavoz con una impedancia de 8 ? (o superior), mientras que con una entrada de 3 voltios puede utilizarse un altavoz adaptado a un voltaje menor. Para controlar el altavoz es necesario utilizar dos salidas en las que el nivel H alternará en cada media onda de la frecuencia del sonido.

En la siguiente figura hay una conexión que es normal con una salida, y funciona bien de 5 Hz a aproximadamente 30 kHz. Es importante mantener la condición de salida del microcontrolador en un nivel H cuando no se emite sonido, de lo contrario circulará corriente constante por el parlante.

Amplificador

Artículos relacionados:
Uso de la placa L298N para motores de CC
Puente H: Placa controladora de motores L9110S
Guía rápida de placas de control de motores
Manejo de potencia para motores con el integrado L293D
Control de motores de CC por Ancho de Pulso (PWM)



Manejo de potencia para motores con el integrado L293D

El integrado L293D incluye cuatro circuitos para manejar cargas de potencia media, en especial pequeños motores y cargas inductivas, con la capacidad de controlar corriente hasta 600 mA en cada circuito y una tensión entre 4,5 V a 36 V.

L293D

Los circuitos individuales se pueden usar de manera independiente para controlar cargas de todo tipo y, en el caso de ser motores, manejar un único sentido de giro. Pero además, cualquiera de estos cuatro circuitos sirve para configurar la mitad de un puente H.

El integrado permite formar, entonces, dos puentes H completos, con los que se puede realizar el manejo de dos motores. En este caso el manejo será bidireccional, con frenado rápido y con posibilidad de implementar fácilmente el control de velocidad.

Diagrama detallado del circuito interno

Diagrama simplificado

Las salidas tienen un diseño que permite el manejo directo de cargas inductivas tales como relés, solenoides, motores de corriente continua y motores por pasos, ya que incorpora internamente los diodos de protección de contracorriente para cargas inductivas.

Las entradas son compatibles con niveles de lógica TTL. Para lograr esto, incluso cuando se manejen motores de voltajes no compatibles con los niveles TTL, el chip tiene patas de alimentación separadas para la lógica (VCC1, que debe ser de 5V), y para la alimentación de la carga (VCC2, que puede ser entre 4,5V y 36V).

Las salidas poseen un circuito de manejo en configuración «totem-pole» (término en inglés que se traduce como «poste de tótem», nombre que, gráficamente, nos remite a un «apilamiento» de transistores, como las figuras en los famosos totems indígenas).

En esta estructura, unos transistores en configuración Darlington conducen la pata de salida a tierra y otro par de transistores en conexión seudo Darlington aporta la corriente de alimentación desde VCC2. Las salidas tienen diodos incorporados en el interior del chip para proteger al circuito de manejo de potencia de las contracorrientes de una carga inductiva.

Estos circuitos de salida se pueden habilitar en pares por medio de una señal TTL. Los circuitos de manejo de potencia 1 y 2 se habilitan con la señal 1,2EN y los circuitos 3 y 4 con la señal 3,4EN.

Las entradas de habilitación permiten controlar con facilidad el circuito, lo que facilita la regulación de velocidad de los motores por medio de una modulación de ancho de pulso. En ese caso, las señales de habilitación en lugar de ser estáticas se controlarían por medio de pulsos de ancho variable.




Las salidas actúan cuando su correspondiente señal de habilitación está en alto. En estas condiciones, las salidas están activas y su nivel varía en relación con las entradas. Cuando la señal de habilitación del par de circuitos de manejo está en bajo, las salidas están desconectadas y en un estado de alta impedancia.

Conexionado para un motor con giro en ambos sentidos (lado izquierdo) y con motores con giro en sentido único en dos salidas (lado derecho)


Por medio de un control apropiado de las señales de entrada y conectando el motor a sendas salidas de potencia, cada par de circuito de manejo de potencia conforma un puente H completo, como se ve en el diagrama de arriba, lado izquierdo. En la tabla de funcionamiento que sigue se puede observar los niveles TTL que corresponden a cada situación de trabajo:

Ejemplo de circuito en forma de puente H (para control bidireccional del motor) y su tabla de manejo

Disipador

Las patas centrales de la cápsula del chip están pensadas para proveer el contacto térmico con un dispador que permitirá lograr la potencia máxima en el manejo del integrado. En la figuras que siguen se observa la distribución de pines afectados a esta disipación, el área de cobre que se deja en el circuito impreso por debajo y a los lados del chip, y el diseño del disipador que propone el fabricante. La hoja de datos aporta una curva que permite una variación de estos tamaños según la potencia a manejar.

Shield de Arduino

Esta plaqueta posee dos L293D, o sea que permite controlar 4 motores de CC o dos motores paso a paso. Tiene aparte otras salidas.

Diagrama de la placa

Utiliza estos pines en el Arduino UNO:

Digital 4 – DIR_CLK
Digital 7 – DIR_EN
Digital 8 – DIR_SER
Digital 12 – DIR_LATCH
Digital 11 – PWM_Motor1
Digital 3 – PWM_Motor2
Digital 6 – PWM_Motor3
Digital 5 – PWM_Motor4
Digital 9 – Servo_1
Digital 10 – Servo_2

Descargamos ahora una librería de Adafruit para manejar el Shield directamente, ya que si no el manejo podría resultar bastante complicado.

La librería que necesitamos es esta adafruit-Adafruit-Motor-Shield-library-8119eec, y para instalarla seguimos el procedimiento habitual.

Para iniciar la plaqueta, necesitamos incluir este par de instrucciones:

La primera línea incluye la librería de AdaFruit en el programa. La segunda crea una instancia de un motor conectado a la puerta M1. La inicialización se define con el parámetro que le pasamos, que puede ir del 1 = M1 al 4 = M4.

Para establecer la velocidad del motor:

La primera línea define la velocidad el motor a 200. El valor 255 sería el máximo de RPM. La segunda línea indica que deseaemos dejar el motor en punto muerto.

Para que el motor avance usamos:

Y para que retroceda:

Es todo lo necesario para controlar un motor.

Si queremos hacer un primer programa sencillo que haga avanzar el motor unos segundos y después retroceda, he aquí el programa:

En caso de querer controlar cuatro motores:

Enlaces: L293D, Hoja de datos – Quadruple Half-H Drivers

Artículos relacionados:
Uso de la placa L298N para motores de CC
Puente H: Placa controladora de motores L9110S
Guía rápida de placas de control de motores
Manejo de potencia para motores con el integrado L293D
Control de motores de CC por Ancho de Pulso (PWM)