Quantcast
Channel: Luis Llamas
Viewing all 1123 articles
Browse latest View live

Usar Arduino para reprogramar el bootloader de otro Arduino

$
0
0
arduino-grabar-bootloader

El bootloader de Arduino es un software alojado en la memoria flash que nos permite programar Arduino a través del puerto de serie sin necesidad de usar un programador externo.

De forma resumida, durante el arranque de Arduino el bootloader comprueba si se está intentando programar el Arduino. Si es así, graba el programa en la memoria, y reinicia Arduino. En caso contrario, el bootloader ejecuta el último programa grabado.

El bootloader de Arduino es una de las partes esenciales en las que reside la comodidad y sencillez de uso de Arduino (y por tanto de su éxito). En general lo normal es que no necesitemos lidiar con él.

Sin embargo, hay varias circustancias en las que necesitaremos ser capaces de modificar el bootloader de Arduino. Por ejemplo:

  • Los usuarios avanzados pueden querer modificar y personalizar el proceso de arranque.
  • En proyectos grandes, podemos querer aprovechar el espacio ocupado por el bootloader.
  • Algunos fabricantes envían sus placas sin el bootloader precargado.
  • En alguna circunstancia el bootloader puede corromperse.

En cualquiera de los casos, no necesitamos disponer de un programador externo si no que podemos grabar el bootloader de un Arduino usando otro Arduino como programador.

Al Arduino que actúa como programador lo llamaremos master, y al que vamos a programar slave. La comunicación entre PC y master se realiza a través de puerto de serie, mientras que el master se comunicará con el slave a través de SPI.

Preparar el Arduino Master

En primer lugar vamos a configurar nuestro Arduino Master como programador. Para ello, simplemente tenemos que carga el Sketch “Arduino ISP” de la librería de ejemplos de Arduino. Lo cargamos en el Master como cualquier otro sketch.

arduino-as-isp

Así de fácil. Con esto hemos convertido nuestro Arduino en un programador ISP.

Conectar Arduino Master con Slave

Desconectamos el master del ordenador, y conectamos master y slave. Para ello, alimentamos el Arduino Slave desde el Master conectando Vcc y Gnd de ambas placas. Por otro lado, conectamos los pines del bus SPI entra ambas placas.

Si, por ejemplo, estamos usando un Arduino UNO como programador Master y un Arduino Mini como slave, el esquema de conexión en el master a los pines del slave quedarían de la siguiente forma.

arduino-grabar-bootloader-master

Mientras que la conexión vista desde slave (Mini en el ejemplo) a los pines del master serían las siguientes.

arduino-grabar-bootloader-slave

Grabando el bootloader

Ahora podemos proceder a quemar el bootloader en el Arduino. Conectamos el master al ordenador a través del puerto de serie, manteniendo la conexión entre master y slave.

Configuramos el IDE de Arduino. Seleccionamos:

  • El puerto COM al que tenemos conectado el master.
  • El modelo de placa del slave
  • Como programador, “Arduino ISP”

arduino-as-isp-2

Finalmente seleccionamos “Quemar bootloader” para iniciar el proceso de grabación.

arduino-as-isp-3

Tras un montón de lucecitas y parpadeos en los LED de ambas placas veremos un mensaje en el IDE informando de que el bootloader se he grabado correctamente.

Listo, hemos grabado con éxito el bootloader, y podemos desconectar ambos Arduinos y usarlos con normalidad.

Si te ha gustado esta entrada y quieres leer más puedes consultar el resto de tutoriales de Arduino


Conectar Arduino a un display LCD HITACHI HD44780

$
0
0
arduino-lcd-hitachi-hd44780

¿Qué es un LCD HITACHI HD44780?

Las pantallas LCD (Liquid Cristal Display) son una de las formas más sencillas y económicas de dotar de un display a un autómata.

El Hitachi HD44780 es uno de los controladores de LCDs más ampliamente extendidos por su sencillez y bajo precio.

El HD44780 está diseñado para controlar LCDs monocromos de hasta 80 caracteres alfanuméricos y símbolos. También dispone de una pequeña memoria RAM para configurar nuestros propios caracteres o dibujos.

Las pantallas LCD con el controlador HD44770 se fabrican en distintos tamaños, siendo comunes 16×02 (2 líneas de 16 caracteres), 20×02, 20×04 y 40×02.

Las pantallas LCD disponen de retroiluminación trasera en azul o en verde. El contraste puede ser variado conectando un potenciómetro al LCD.

Conectar directamente un LCD a Arduino requiere una gran cantidad de pines. Suele ser aconsejable emplear un adaptador I2C.

Precio

Los LCD con controlador HD44770 son componentes barato. Su precio varía en función del tamaño y el número de caracteres.

Podemos encontrar el tamaño 16×02 (LCD1602), muy habitual, por 1.4€, en vendedores internacionales de Ebay o AliExpress. El LCD de 20×4 (LCD2004) es, lógicamente, algo más caro. Podemos encontrarlo por 3.4€.

arduino-lcd-hitachi-hd44780-componente

Esquema eléctrico

Como hemos adelantado, conectar un Arduino a una pantalla LCD HD44770 sin usar un adaptador I2C requiere una gran cantidad de cables. El esquema de conexión visto desde el LCD a los pines de Arduino es el siguiente.

arduino-lcd-hitachi-hd44780-esquema

Mientras que la conexión desde el lado de Arduino quedaría así.

arduino-lcd-hitachi-hd44780-conexion

Si quisiéramos controlar el contraste de la pantalla, añadiríamos un potenciómetro para regular la tensión en V0.

Ejemplos de código

El IDE de Arduino incorpora de serie la librería LiquidCrystal, para controlar pantallas LCD HD44770 de forma sencilla.

Por ejemplo, el siguiente sketch muestra el uso de las funciones de la librería para mostrar los textos “Linea 1” y “Linea 2” en una pantalla de 16×02.

/* Conexión
PIN2 - LCD4 (RS)
PIN3 - LCD5 (R/W)
PIN4 - LCD6 (E)

PIN8 - LCD11 (D4)
PIN9 - LCD12 (D5)
PIN10 - LCD13 (D6)
PIN11 - LCD14 (D7)
*/

#include 			

LiquidCrystal lcd(2, 3, 4, 8, 9, 10, 11); //(RS,RW, E, D4,D5, D6, D7)

void setup()
{
	lcd.begin(16, 2);	// Inicia un LCD 16x02 (columnas,fila)
	lcd.setCursor(0, 0);	// Pone el cursor en las coordenadas (0,0)
	lcd.print("Linea 1");	// Escribe el LCD
	lcd.setCursor(0, 1);	// Ponemos el cursor en la segunda Fila
	lcd.print("Linea 2");   // Escribe el LCD
}

void loop()
{
	//Apagar cursor
	lcd.noCursor();
	delay(500);
	
	//Apagar encender cursor
	lcd.cursor();
	delay(500);
}

El siguiente sketch usa las funciones scroll para desplazar un texto horizontalmente en la pantalla.

/* Conexión
PIN2 - LCD4 (RS)
PIN3 - LCD5 (R/W)
PIN4 - LCD6 (E)

PIN8 - LCD11 (D4)
PIN9 - LCD12 (D5)
PIN10 - LCD13 (D6)
PIN11 - LCD14 (D7)
*/	
#include 

LiquidCrystal lcd(2, 3, 4, 8, 9, 10, 11); //(RS,RW, E, D4,D5, D6, D7)

void setup() {
  lcd.begin(16, 2);
  
  lcd.print("¡Hola mundo!");
  delay(1000);
}

void loop() {
  
  //mover 13 posiciones (longitud del texto) a la izquierda
  //para sacar el texto de la pantalla por la izquierda
  for (int positionCounter = 0; positionCounter < 13; positionCounter++) {
    lcd.scrollDisplayLeft();
    delay(150);
  }

  //mover 29 posiciones (longitud del texto + ancho del display) a la derecha
  //para sacar el texto de la pantalla por la derecha
  for (int positionCounter = 0; positionCounter < 29; positionCounter++) {
    lcd.scrollDisplayRight();
    delay(150);
  }

  //mover 16 posiciones (29-13) a la izquierda
  //para devolver el texto a la posición inicial
  for (int positionCounter = 0; positionCounter < 16; positionCounter++) {
    lcd.scrollDisplayLeft();
    delay(150);
  }
  
  delay(1000);
}

La librería LiquidCrystal contiene más ejemplos sobre su uso. Resulta aconsejable examinar su código, en general son sencillos de entender.

Si te ha gustado esta entrada y quieres leer más puedes consultar el resto de tutoriales de Arduino

Arreglar el aviso “Tarjeta SIM extraída” en Samsung Galaxy S4

$
0
0
Galaxy-s4-tarjeta-sim-extraida

Si sois propietarios de un Samsung Galaxy S4 es posible que en algún momento os encontréis un problema que aparece en estos terminales con el paso del tiempo, el error de “Tarjeta SIM extraída”.

Sin realizar ninguna acción, de forma totalmente aleatoria y repentina, nuestro Galaxy S4 muestra un cartel indicando “Tarjeta SIM extraída, No se puede encontrar la tarjeta SIM. Se reiniciará su dispositivo para buscar la tarjeta SIM”

tarjeta-sim-extraida

El cartel nos obliga a pulsar en el botón de Reiniciar, sin poder realizar ninguna otra acción. Tras el reinicio, nuestro Galaxy S4 vuelve a funcionar con normalidad, hasta que vuelva a aparecer otro error de “Tarjeta SIM extraída”.

Al principio este mensaje aparece de vez esporádicamente pero, poco a poco, la frecuencia de aparición se incrementa. Al final, el cartel aparecerá varias veces al día, haciendo que nuestro flamante Galaxy S4 sea prácticamente inusable.

Existen varios motivos por los que puede aparecer este cartel, tales como una tarjeta SIM defectuosa, o un problema de software o de hardware. Pero en la mayoría de los casos el culpable es la pieza que aloja la tarjeta SIM.

Si este es vuestro caso, afortunadamente, es posible reparar este error reemplazando esta pieza, que cuesta unos 2€ (gastos de envío incluidos) en vendedores internacionales de AliExpress o en Ebay. Simplemente buscar “galaxy s4 sim replacement” en cualquiera de estas dos páginas.

galaxy-s4-sim-pieza-reemplazo

La reparación en sí no es complicada, pero requiere abrir el Galaxy S4 y manipular ciertas piezas muy delicadas, por lo que deberemos tener un cuidado extremo y medir la fuerza que aplicamos, o podemos dañar nuestro terminal.

La reparación de un móvil es una operación delicada que requiere de cierta experiencia y habilidad. No nos hacemos responsables de ningún daño que podáis causar a vuestro dispositivo durante el proceso de reparación.


Reparando el error “Tarjeta SIM extraída”

Una vez que hayamos recibido nuestra pieza de reemplazo, podemos comenzar con la reparación del Galaxy S4.

Galaxy-s4-tarjeta-sim-extraida-0

Comenzamos retirando la carcasa trasera y la batería.

Galaxy-s4-tarjeta-sim-extraida-1

A continuación, retiramos los tornillos señalados en la siguiente imagen.

Galaxy-s4-tarjeta-sim-extraida-2

Ahora llega la delicada parte de separar la carcasa intermedia de la delantera. Ayudándonos de alguna herramienta, hacemos suavemente palanca en la junta, a lo largo del contorno. Ser extremadamente cuidadosos en este paso, pues es fácil romper alguna de las delgadas partes de plástico.

Galaxy-s4-tarjeta-sim-extraida-3

Una vez hayamos retirado la carcasa intermedia, veremos los componentes internos del Galaxy S4. Para retirar la pieza que aloja la SIM, comenzamos desconectando el cable que lo conecta a la placa base.

Galaxy-s4-tarjeta-sim-extraida-4

La pieza se encuentra fijada al resto del móvil únicamente mediante adhesivo. Retiramos suavemente la pieza, con mucho cuidado de no dañar la pieza a la que va pegado.

Galaxy-s4-tarjeta-sim-extraida-5

Ahora, en la pieza de reemplazo que hemos comprado, retiramos el plástico que protege el adhesivo.

Galaxy-s4-tarjeta-sim-extraida-6

Colocamos la pieza, prestando atención a que quede en la misma posición que la anterior. Una vez instalada, volvemos a conectar el cable que une la pieza con el resto del móvil.

Galaxy-s4-tarjeta-sim-extraida-7

Finalmente, volvemos a cerrar la carcasa, con cuidado de no dañar ningún componente y prestando especial atención a que los botones laterales encajen correctamente.

Galaxy-s4-tarjeta-sim-extraida-8

Arrancamos nuestro Galaxy S4 y, si hemos tenido suerte y la reparación ha sido correcta, podremos olvidarnos del mensaje de “Tarjeta SIM extraída”.

Aún siendo muy probable, no es totalmente seguro que la avería de vuestro móvil se deba a este componente. Si el mensaje os sigue apareciendo, podéis probar a restaurar el móvil a condiciones de fábrica o probar con otra tarjeta SIM.

Qué son y cómo usar interrupciones en Arduino

$
0
0
arduino-interrupciones

Las interrupciones son un mecanismo muy potente y valioso en procesadores y autómatas. Arduino, por supuesto, no es una excepción. En esta entrada veremos qué son las interrupciones, y como usarlas en nuestro código.

Para entender la utilidad y necesidad de las interrupciones, supongamos que tenemos Arduino conectado a un sensor, por ejemplo encoder óptico que cuenta las revoluciones de un motor, un detector que emite una alarma de nivel de agua en un depósito, o un simple pulsador de parada.

Si queremos detectar un cambio de estado en esta entrada, el método que hemos usado hasta ahora es emplear las entradas digitales para consultar repetidamente el valor de la entrada, con un intervalo de tiempo (delay) entre consultas.

Este mecanismo se denomina “poll”, y tiene 3 claras desventajas.

  • Suponer un continuo consumo de procesador y de energía, al tener que preguntar continuamente por el estado de la entrada.
  • Si la acción necesita ser atendida inmediatamente, por ejemplo en una alerta de colisión, esperar hasta el punto de programa donde se realiza la consulta puede ser inaceptable.
  • Si el pulso es muy corto, o si el procesador está ocupado haciendo otra tarea mientras se produce, es posible que nos saltemos el disparo y nunca lleguemos a verlo.

Para resolver este tipo de problemas, los microprocesadores incorporan el concepto de interrupción, que es un mecanismo que permite asociar una función a la ocurrencia de un determinado evento. Esta función de callback asociada se denomina ISR (Interruption Service Rutine).

Cuando ocurre el evento el procesador “sale” inmediatamente del flujo normal del programa y ejecuta la función ISR asociada ignorando por completo cualquier otra tarea (por esto se llama interrupción). Al finalizar la función ISR asociada, el procesador vuelve al flujo principal, en el mismo punto donde había sido interrumpido.

Como vemos, las interrupciones son un mecanismo muy potente y cómodo que mejora nuestros programas y nos permite realizar acciones que no serían posibles sin el uso de interrupciones.

Para usar interrupciones en dispositivos físicos (como pulsadores, sensores ópticos, … ) debemos antes eliminar el efecto “rebote”, como podéis ver en la entrada Aplicar debounce al usar interrupciones en Arduino.

INTERRUPCIONES EN ARDUINO

Arduino dispone de dos tipos de eventos en los que definir interrupciones. Por un lado tenemos las interrupciones de timers (que veremos en su momento al hablar de temporizadores. Por otro lado, tenemos las interrupciones de hardware, que responden a eventos ocurridos en ciertos pines físicos.

Dentro de las interrupciones de hardware, que son las que nos ocupan en esta entrada, Arduino es capaz de detectar los siguientes eventos.

  • RISING, ocurre en el flanco de bajada de LOW a HIGH.
  • FALLING, ocurre en el flanco de subida de HIGH a LOW.
  • CHANGING, ocurre cuando el pin cambia de estado (rising + falling).
  • LOW, se ejecuta continuamente mientras está en estado LOW.

Los pines susceptibles de generar interrupciones varían en función del modelo de Arduino.

En Arduino y Nano se dispone de dos interrupciones, 0 y 1, asociados a los pines digitales 2 y 3.El Arduino Mega dispone de 6 interrupciones, en los pines 2, 3, 21, 20, 19 y 18 respectivamente. Arduino Due dispone de interrupciones en todos sus pines.

Modelo INT0 INT1 INT2 INT3 INT4 INT5
UNO 2 3
Nano 2 3
Mini Pro 2 3
Mega 2 3 21 20 19 18
Leonardo 3 2 0 1 7
Due En todos los pines

LA FUNCIÓN ISR

La función asociada a una interrupción se denomina ISR (Interruption Service Routines) y, por definición, tiene que ser una función que no recibe nada y no devuelva nada.

Dos ISR no pueden ejecutarse de forma simultánea. En caso de dispararse otra interrupción mientras se ejecuta una ISR, la función ISR se ejecuta una a continuación de otra.

LA ISR, CUANTO MÁS CORTA MEJOR

Al diseñar una ISR debemos mantener como objetivo que tenga el menor tiempo de ejecución posible, dado que mientras se esté ejecutando el bucle principal y todo el resto de funciones se encuentran detenidas.

Imaginemos, por ejemplo, que el programa principal ha sido interrumpido mientras un motor acercaba un brazo para coger un objeto. Una interrupción larga podría hacer que el brazo no para a tiempo, tirando o dañando el objeto.

Frecuentemente la función de la ISR se limitará a activar un flag, incrementar un contador, o modificar una variable. Esta modificación será atendida posteriormente en el hilo principal, cuando sea oportuno.

No empleéis en una ISR un proceso que consuma tiempo. Esto incluye cálculos complejos, comunicación (serial, I2C y SPI) y, en la medida de lo posible, cambio de entradas o salidas tanto digitales como analógicas.

LAS VARIABLES DE LA ISR COMO “VOLATILES”

Para poder modificar una variable externa a la ISR dentro de la misma debemos declararla como “volatile”. El indicador “volatile” indica al compilador que la variable tiene que ser consultada siempre antes de ser usada, dado que puede haber sido modificada de forma ajena al flujo normal del programa (lo que, precisamente, hace una interrupción).

Al indicar una variable como Volatile el compilador desactiva ciertas optimizaciones, lo que supone una pérdida de eficiencia. Por tanto, sólo debemos marcar como volatile las variables que realmente lo requieran, es decir, las que se usan tanto en el bucle principal como dentro de la ISR.

EFECTOS DE LA INTERRUPCIÓN Y LA MEDICIÓN DEL TIEMPO

Las interrupciones tienen efectos en la medición del tiempo de Arduino, tanto fuera como dentro de la ISR, porque Arduino emplea interrupciones de tipo Timer para actualizar la medición del tiempo.

Efectos fuera de la ISR

Durante la ejecución de una interrupción Arduino no actualiza el valor de la función millis y micros. Es decir, el tiempo de ejecución de la ISR no se contabiliza y Arduino tiene un desfase en la medición del tiempo.

Si un programa tiene muchas interrupciones y estas suponen un alto tiempo de ejecución, la medida del tiempo de Arduino puede quedar muy distorsionada respecto a la realidad (nuevamente, un motivo para hacer las ISR cortas).

Efectos dentro de la ISR

Dentro de la ISR el resto de interrupciones están desactivadas. Esto supone:

  • La función millis no actualiza su valor, por lo que no podemos utilizarla para medir el tiempo dentro de la ISR. (sí podemos usarla para medir el tiempo entre dos ISR distintas)
  • Como consecuencia la función delay() no funciona, ya que basa su funcionamiento en la función millis()
  • La función micros() actualiza su valor dentro de una ISR, pero empieza a dar mediciones de tiempo inexactas pasado el rango de 500us.
  • En consecuencia, la función delayMicroseconds funciona en ese rango de tiempo, aunque debemos evitar su uso porque no deberíamos introducir esperas dentro de una ISR.

CREAR INTERRUPCIONES EN ARDUINO

Para definir una interrupción en Arduino usamos la función:

attachInterrupt(interrupt, ISR, mode);

Donde interrupt es el número de la interrupción que estamos definiendo, ISR la función de callback asociada, y mode una de las opciones disponibles (Falling, Rising, Change y Low)

No obstante, es más limpio emplear la función digitalPinToInterrupt(), que convierte un Pin a la interrupción equivalente. De esta forma se favorece el cambio de modelo de placa sin tener que modificar el código.

attachInterrupt(digitalPinToInterrupt(pin), ISR, mode);

Otras funcionas interesantes para la gestión de interrupciones son:

  • DetachInterrupt(interrupt ), anula la interrupción.
  • NoInterrupts(), desactiva la ejecución de interrupciones hasta nueva orden. Equivale a sli()
  • Interrupts(), reactiva las interrupciones. Equivale a cli()

Probando las interrupciones en Arduino

Para probar las interrupciones en Arduino, vamos a emplear una salida digital de Arduino para emular una señal digital. En el mundo real, sería otro dispositivo (un sensor, otro procesador…) el que generaría esta señal, y nosotros la captaríamos con Arduino.

Conectamos mediante un cable el pin digital 10 al pin digital 2, asociado a la interrupción 0.

arduino-interrupciones-ejemplo

Haciendo parpadear un LED a través de interrupciones

En el siguiente código definimos el pin digital 10 como salida, para emular una onda cuadrada de periodo 300ms (150ms ON y 150ms OFF).

Para visualizar el funcionamiento de la interrupción, en cada flanco activo del pulso simulado, encendemos/apagamos el LED integrado en la placa, por lo que el LED parpadea a intervalos de 600ms (300ms ON y 300ms OFF)

Puede que a estas alturas ver parpadear un LED no parezca muy espectacular, pero no es tan simple como parece. No estamos encendiendo el LED con una salida digital, si no que es la interrupción que salta la que enciende y apaga el LED (el pin digital solo emula una señal externa).

const int emuPin = 10;

const int LEDPin = 13;
const int intPin = 2;
volatile int state = LOW;

void setup() {
	pinMode(emuPin, OUTPUT);
	pinMode(LEDPin, OUTPUT);
	pinMode(intPin, INPUT_PULLUP);
	attachInterrupt(digitalPinToInterrupt(intPin), blink, CHANGE);
}

void loop() {
	//esta parte es para emular la salida
	digitalWrite(emuPin, HIGH);
	delay(150);
	digitalWrite(emuPin, LOW);
	delay(150);
}

void blink() {
	state = !state;
	digitalWrite(LEDPin, state);
}

Contando disparos de una interrupción

El siguiente código empleamos el mismo pin digital para emular una onda cuadrada, esta vez de intervalo 2s (1s ON y 1s OFF).

En cada interrupción actualizamos el valor de un contador. Posteriormente, en el bucle principal, comprobamos el valor del contador, y si ha sido modificado mostramos el nuevo valor.

Al ejecutar el código, veremos que en el monitor serie se imprimen números consecutivos a intervalos de dos segundos.

const int emuPin = 10;

const int intPin = 2;
volatile int ISRCounter = 0;
int counter = 0;


void setup()
{
	pinMode(emuPin, OUTPUT);
	
	pinMode(intPin, INPUT_PULLUP);
	Serial.begin(9600);
	attachInterrupt(digitalPinToInterrupt(intPin), interruptCount, LOW);
}

void loop()
{
	//esta parte es para emular la salida
	digitalWrite(emuPin, HIGH);
	delay(1000);
	digitalWrite(emuPin, LOW);
	delay(1000);


	if (counter != ISRCounter)
	{
		counter = ISRCounter;
		Serial.println(counter);
	}
}

void interruptCount()
{
	ISRCounter++;
	timeCounter = millis();
}

Lógicamente, nuestro objetivo es emplear interrupciones de hardware no solo con otros dispositivos digitales, si no también con dispositivos físicos como pulsadores, sensores ópticos…

Sin embargo, como hemos adelantado, estos dispositivos generan mucho ruido en los cambios de estado, lo que provoca que las interrupciones se disparen múltiples veces. Este fenómeno se denomina “rebote” y aprenderemos a eliminarlo en la siguiente entrada.

Mientras tanto, si te ha gustado esta entrada y quieres leer más puedes consultar el resto de tutoriales de Arduino

Leer un pulsador con Arduino con interrupciones y debounce

$
0
0
arduino-debounce

En la entrada anterior vimos qué son las interrupciones y cómo usarlas para responder a eventos de hardware en pins.

También dejamos claro que los dispositivos físicos, como pulsadores, detectores ópticos, etc, presentan un efecto rebote que interfiere con el uso de interrupciones, y que necesitamos eliminarlo o no podremos usar interrupciones con estos dispositivos.

El proceso de eliminación de este rebote se llama “debounce”. En esta entrada aprenderemos qué es el rebote y aprenderemos a eliminarlo con debounce por hardware y por software.

¿Qué es el debounce?

Los dispositivos electrónicos al cambiar de estado generan una señal que, sin ser perfectamente cuadrada, en general es más o menos “limpia”. Veamos, por ejemplo, la señal que genera Arduino al cambiar el estado de una salida digital de HIGH a LOW.

arduino-sin-rebote

Sin embargo el mundo real no es tan bonito. Muchos dispositivos físicos habitualmente generan ruido en los flancos de señal. Como ejemplo, veamos la variación de tensión que ocurre cuando el cambio de estado se genera por un pulsador.

arduino-rebote

Observar la cantidad de ruido ocurrido tras el flanco. En esencia, en el rango de unos microsegundos la señal es puro ruido. Todos esos picos pueden provocar disparos múltiples de una interrupción.

PROBANDO EL REBOTE

Para probar el rebote, simplemente vamos a emplear un cable para conectar el Pin 2 y Ground (también podéis usar un pulsador o un interruptor).

arduino-debounce-esquema

Activamos la resistencia interna de Pull UP en el Pin 2 y definimos una interrupción al evento de bajada en el PIN, y en la función ISR asociada simplemente incrementamos un contador.

En el bucle principal, comprobamos si el contador, y si este ha sido modificado mostramos su valor por el puerto de serie.

const int intPin = 2;
volatile int ISRCounter = 0;
int counter = 0;


void setup()
{
	pinMode(intPin, INPUT_PULLUP);
	Serial.begin(9600);
	attachInterrupt(digitalPinToInterrupt(intPin), debounceCount, LOW);
}

void loop()
{
	if (counter != ISRCounter)
	{
		counter = ISRCounter;
		Serial.println(counter);
	}
}

void debounceCount()
{
	ISRCounter++;
}

Al probar nuestro montaje y poner en contacto el PIN 2 a GROUND, esperaríamos que la variable se incrementara de uno en uno. Pero veremos que en realidad salta varios números cada vez (incluso varias decenas).

Este es el efecto del rebote. El ruido de la señal está generando múltiples interrupciones cada vez que conectamos el cable.

Eliminando el rebote

Disponemos de dos formas de aplicar el debounce. Añadiendo dispositivos electrónicos que filtren la señal (debounce por hardware) o modificando nuestro código para eliminar el rebote (debounce por hardware).

Debounce por hardware

Aplicar un debounce por hardware tiene la ventaja de no incrementar el tiempo de ejecución de nuestro código. Además, en general, es una solución más robusta. Por contra, tiene la desventaja de aumentar la complejidad de nuestro montaje.

La forma más sencilla de aplicar un debounce por hardware es colocar un condensador en paralelo con el dispositivo (pulsador, interruptor, sensor…). Un condensador del orden de 1uF debería ser suficiente para filtrar la mayoría del ruido.

El esquema de conexión es el siguiente.

arduino-debounce-hardware

En general siempre es conveniente añadir un filtro por hardware cuando empleamos entradas físicas con interrupciones.

Debounce por software

El debounce por software tiene la ventaja de no requerir componentes adicionales. Resolvemos el rebote únicamente modificando el código de nuestro programa.

Como desventaja, incrementa levemente el tiempo de ejecución y la complejidad del código. Además, si no aplicamos el código correctamente podemos ignorar interrupciones “verdaderas”.

La forma más sencilla de aplicar un debounce por software es comprobar el tiempo entre disparos de la interrupción. Si el tiempo es inferior a un determinado umbral de tiempo (threshold) simplemente ignoramos la interrupción. En definitiva, hemos definido una “zona muerta” en la que ignoramos las interrupciones generadas.

Para aplicar el debounce por software, modificamos la función ISR de la siguiente forma.

const int timeThreshold = 150;
const int intPin = 2;
volatile int ISRCounter = 0;
int counter = 0;
long timeCounter = 0;


void setup()
{
	pinMode(intPin, INPUT_PULLUP);
	Serial.begin(9600);
	attachInterrupt(digitalPinToInterrupt(intPin), debounceCount, FALLING);
}

void loop()
{
	if (counter != ISRCounter)
	{
		counter = ISRCounter;
		Serial.println(counter);
	}
}

void debounceCount()
{
	if (millis() > timeCounter + timeThreshold)
	{
		ISRCounter++;
		timeCounter = millis();
	}
}

Un tiempo de 100-200ms es correcto para un pulsador pero en otros casos deberemos ajustar el tiempo de forma que eliminemos el rebote, pero no ignoremos dos posibles eventos cercanos “verdaderos”.

En un montaje real, lo mejor es emplear una combinación de ambos sistemas, a la vez que ajustamos correctamente el valor del condensados y los tiempos del filtro por software para adaptarlos a nuestro sistema.

Si te ha gustado esta entrada y quieres leer más puedes consultar el resto de tutoriales de Arduino

Como solucionar el brillo bajo de pantalla en Windows 10

$
0
0
brillo-pantalla-windows-10

Una de las cosas que más me sorprendió tras la actualización de mi Tablet a Windows 10 fue una marcada disminución del brillo de pantalla.

La mayoría de Tablets y móviles disponen de un sensor de luz, para adaptar de forma automática el brillo de la pantalla al nivel de luz del entorno.

El nivel de luz final depende de cada dispositivo, pero en dos de mis Tablet el nivel de luz que proporciona el brillo automático es excesivamente bajo, incluso en el nivel máximo.

Y, aunque sea cierto que un brillo bajo ayuda a conservar la vista, de poco sirve si me la tengo que dejar intentando leer lo que pone en la ventana.

Afortunadamente es sencillo desactivar el brillo adaptativo de la pantalla en Windows 10, y así volver a controlar manualmente el nivel de luz.

Para ello entramos en “Opciones de energía”, pulsando con el botón derecho sobre el icono de batería de área de notificaciones.

Seleccionamos “Cambiar configuración del Plan” y en la siguiente ventana en “Configuración avanzada”

windows-10-brillo-pantalla

Finalmente, navegamos hasta “Pantalla / Habilitar brillo adaptativo” y marcamos ambas opciones en “Desactivado”

windows-10-opciones-energia

Ya está. A partir de ahora podemos controlar manualmente el brillo de la pantalla, y dejar de dejarnos los ojos intentando escudriñar en las ventanas.

El bus SPI en Arduino

$
0
0
arduino-spi

En esta entrada vamos a ver el bus SPI, una de las principales formas de comunicación disponibles en Arduino. En entradas anteriores ya vimos el puerto de serie, y en la próxima entrada veremos el bus I2C.

El bus SPI tiene interés como medio de comunicación porque una gran variedad de sensores y dispositivos comerciales disponen de un interfaz SPI como medio de comunicación.

El bus SPI

El bus SPI (Serial Peripheral Interface) fue desarrollado por Motorola en 1980. Sus ventajas respecto a otros sistemas han hecho que se convierta en un standard de facto en el mundo de la electrónica y automatización.

El bus SPI tiene una arquitectura de tipo maestro-esclavo. El dispositivo maestro (master) puede iniciar la comunicación con uno o varios dispositivos esclavos (slave), y enviar o recibir datos de ellos. Los dispositivos esclavos no pueden iniciar la comunicación, ni intercambiar datos entre ellos directamente.

En el bus SPI la comunicación de datos entre maestros y esclavo se realiza en dos líneas independientes, una del maestro a los esclavos, y otra de los esclavos al maestro. Por tanto la comunicación es Full Duplex, es decir, el maestro puede enviar y recibir datos simultáneamente.

Otra característica de SPI es que es bus síncrono. El dispositivo maestro proporciona una señal de reloj, que mantiene a todos los dispositivos sincronizados. Esto reduce la complejidad del sistema frente a los sistemas asíncronos.

Por tanto, el bus SPI requiere un mínimo de 3 líneas.

arduino-spi-esquema-basico

  • MOSI (Master-out, slave-in) para la comunicación del maestro al esclavo.
  • MISO (Master-in, slave-out) para comunicación del esclavo al maestro.
  • SCK (Clock) señal de reloj enviada por el maestro.

Además, se requiere una línea adicional SS (Slave Select) para cada dispositivo esclavo conectado, para seleccionar el dispositivo con el que se va a realizar la comunicación.

arduino-spi-esquema

Sin embargo, esto tiene la desventaja de requerir una línea por cada dispositivo esclavo. En caso de disponer muchos dispositivos esclavos esto puede no ser práctico, por lo que es posible adoptar una conexión en cascada, donde cada esclavo trasmite datos al siguiente.

arduino-spi-esquema-cascada

Por contra, en esta configuración la información debe llegar a todos los esclavos para que la comunicación sea finalizada por lo que, en general, la velocidad de respuesta del bus es menor.

Funcionamiento del bus SPI

El funcionamiento del bus SPI es sencillo.

arduino-spi-funcionamiento

Por defecto el maestro mantiene en estado HIGH todas las líneas SS. Cuando el maestro quiere establecer comunicación con esclavo pone a LOW la línea SS correspondiente, lo que indica al esclavo que debe iniciar la comunicación.

En cada pulso de la señal de reloj, normalmente en el flanco de subida, el dispositivo maestro envía un bit del esclavo y a la vez que recibe un bit del esclavo seleccionado.

La trama (los datos enviados) no sigue ninguna regla, es decir, podemos enviar cualquier secuencia arbitraria de bits. Esto hace que los dispositivos conectados necesiten tener pre-acordado la longitud y significado de los que van a enviar y recibir.

La electrónica requerida para implementar el bus SPI es sencilla y barata, incluso un único registro de desplazamiento puede ser suficiente. Además, como la señal de reloj es proporcionada por el maestro, los esclavos ni siquiera necesitan disponer de un reloj propio.

Ventajas y desventajas del SPI

Ventajas

  • Alta velocidad de trasmisión (hasta 8 Mhz en Arduino) y Full Duplex
  • Los dispositivos necesarios son sencillos y baratos, lo que hace que esté integrado en muchos dispositivos.
  • Puede mandar secuencias de bit de cualquier tamaño, sin dividir y sin interrupciones.

Desventajas

  • Se requiere 3 cables (SCK, MOSI y MISO) + 1 cable adicional (SS) por cada dispositivo esclavo.
  • Solo es adecuado a corta distancias (unos 30cm)s
  • No se dispone de ningún mecanismo de control, es decir, no podemos saber si el mensaje ha sido recibido y menos si ha sido recibido correctamente.
  • La longitud de los mensajes enviados y recibidos tiene que ser conocida por ambos dispositivos.

El bus SPI en Arduino

Hardware

Arduino dispone de soporte SPI por hardware vinculado físicamente a ciertos pines. También es posible emplear cualquier otro grupo de pines como bus SPI a través de sofware, pero en ese caso la velocidad será mucho menor.

Los pines asociados a SPI varían de un modelo a otro. La siguiente tabla muestra la disposición en alguno de los principales modelos. Para otros modelos, consultar el esquema de patillaje correspondiente.

MODELO SS MOSI MISO SCK
Uno 10 11 12 13
Nano 10 11 12 13
Mini Pro 10 11 12 13
Mega 53 51 50 52

El pin SS por hardware se emplea al usar Arduino como esclavo. En caso de usar Arduino como maestro, podemos usar cualquier pin como SS, o varios en caso de disponer de varios esclavos.

Software

Para usar el puerto SPI en Arduino el IDE Standard proporciona la librería “SPI.h” que contiene las funciones necesarias para controlar el hardware integrado de SPI.

Asimismo, el entorno de programación de Arduino define las constantes SCK, MOSI, MISO, y SS para los pines de SPI. Usar estos “alias” en nuestro código hace que sea más fácil de intercambiar programas entre modelos placas.

Las funciones básicas para hacer funcionar el bus SPI son las siguientes:

SPI.begin();            // Inicia el bus SPI
SPI.transfer(c);        // Envía un byte
SPI.attachInterrupt();	// Activar la interrupción para recibir datos

También se dispone de otras funciones para configurar las opciones del bus SPI. Para cambiar el orden de los bit enviados, disponemos de la función setBitOrder.:

setBitOrder (LSBFIRST);   // least significant bit first
setBitOrder (MSBFIRST);   // more significant bit first

Para cambiar la polaridad y la fase del reloj tenemos la función SPI.setDataMode:

setDataMode (SPI_MODE0);  // clock normalmente LOW, muestreo en flanco subida
setDataMode (SPI_MODE1);  // clock normalmente LOW, muestreo en flanco bajada
setDataMode (SPI_MODE2);  // clock normalmente HIGH, muestreo en flanco subida
setDataMode (SPI_MODE3);  // clock normalmente HIGH, muestreo en flanco bajada

Finalmente, podemos cambiar la velocidad del bus con la función SPI.setClockDivider() divisores de 2 a 128. La frecuencia del bus será la velocidad de reloj dividido por el divisor elegido.

setClockDivider(SPI_CLOCK_DIV2);   //8 MHz (considerando un modelo de 16 Mhz)
setClockDivider(SPI_CLOCK_DIV4);   //4 MHz
setClockDivider(SPI_CLOCK_DIV8);   //2 MHz
setClockDivider(SPI_CLOCK_DIV16);  //1 MHz
setClockDivider(SPI_CLOCK_DIV32);  //500 KHz
setClockDivider(SPI_CLOCK_DIV64);  //250 KHz
setClockDivider(SPI_CLOCK_DIV128); //125 KHz

Sin embargo, estas funciones están obsoletas desde la versión de Arduino 1.6.0., prefiriéndose la función beginTransaction, como muestra el siguiente ejemplo.

SPI.beginTransaction (SPISettings (2000000, MSBFIRST, SPI_MODE0));  // 2 MHz clock, MSB first, mode 0

No obstante, al ser la trama de datos específica de cada dispositivo, lo más frecuente es que no usemos directamente estas funciones, y que nuestro uso del bus SPI se realice de forma indirecta a través de la librería del componente.

En próximas entradas cómo conectar dos Arduino mediante puerto I2C, e introduciremos el bus I2C. Mientras tanto, si te ha gustado esta entrada y quieres leer más puedes consultar el resto de tutoriales de Arduino

El bus I2C en Arduino

$
0
0
arduino-bus-i2c

En esta entrada veremos el bus I2C, uno de los sistemas de comunicación disponible en Arduino. En entradas anteriores ya hemos visto el puerto de serie y el bus SPI que, junto al bus I2C, integran los principales sistemas de comunicación.

El bus I2C tiene interés porque, de forma similar a lo que pasaba con el bus SPI, una gran cantidad de dispositivos disponen conexión mediante I2C, como acelerómetros, brújulas, displays, etc.

El bus I2C

El estándar I2C (Inter-Integrated Circuit) fue desarrollado por Philips en 1982 para la comunicación interna de dispositivos electrónicos en sus artículos. Posteriormente fue adoptado progresivamente por otros fabricantes hasta convertirse en un estándar del mercado.

I2C también se denomina TWI (Two Wired Interface) únicamente por motivos de licencia. No obstante, la patente caducó en 2006, por lo que actualmente no hay restricción sobre el uso del término I2C.

El bus I2C requiere únicamente dos cables para su funcionamiento, uno para la señal de reloj (CLK) y otro para el envío de datos (SDA), lo cual es una ventaja frente al bus SPI. Por contra, su funcionamiento es un poco más complejo, así como la electrónica necesaria para implementarla.

arduino-bus-i2c-esquema

En el bus Cada dispositivo dispone de una dirección, que se emplea para acceder a los dispositivo de forma individual. Esta dirección puede ser fijada por hardware (en cuyo caso, frecuentemente, se pueden modificar los últimos 3 bits mediante jumpers o interruptores) o totalmente por software.

En general, cada dispositivo conectado al bus debe tener una dirección única. Si tenemos varios dispositivos similares tendremos que cambiar la dirección o, en caso de no ser posible, implementar un bus secundario.

El bus I2C tiene una arquitectura de tipo maestro-esclavo. El dispositivo maestro inicia la comunicación con los esclavos, y puede mandar o recibir datos de los esclavos. Los esclavos no pueden iniciar la comunicación (el maestro tiene que preguntarles), ni hablar entre si directamente.

Es posible disponer de más de un maestro, pero solo uno puede ser el maestro cada vez. El cambio de maestro supone una alta complejidad, por lo que no es algo frecuente.

El bus I2C es síncrono. El maestro proporciona una señal de reloj, que mantiene sincronizados a todos los dispositivos del bus. De esta forma, se elimina la necesidad de que cada dispositivo tenga su propio reloj, de tener que acordar una velocidad de transmisión y mecanismos para mantener la transmisión sincronizada (como en USART)

El protocolo I2C prevé resistencias de Pull-UP de las líneas a Vcc. En Arduino veréis que frecuentemente no se instalan estas resistencias, ya que la librería Wire activa las resistencias internas de Pull-UP. Sin embargo las resistencias internas tienen un valor de entre 20-30kOhmnios, por lo que son unas resistencias de Pull-UP muy blandas.

Usar unas resistencias blandas implica que los flancos de subida de la señal serán menos rápidas, lo que implica que podremos usar velocidades menores y distancias de comunicación inferiores. Si queremos emplear velocidades o distancias de transmisión superiores, deberemos poner físicamente resistencias de Pull-UP de entre 1k a 4K7.

Funcionamiento del bus I2C

Para poder realizar la comunicación con solo un cable de datos, el bus I2C emplea una trama (los datos enviados) amplia. La comunicación costa de:

  • 7 bits a la dirección del dispositivo esclavo con el que queremos comunicar.
  • Un bit restante indica si queremos enviar o recibir información.
  • Un 1 bit de validación
  • Uno o más bytes son los datos enviados o recibidos del esclavo.
  • Un bit de validación

arduino-bus-i2c-funcionamiento

Con estos 7 bits de dirección es posible acceder a 112 dispositivos en un mismo bus (16 direcciones de las 128 direcciones posibles se reservan para usos especiales)

Este incremento de los datos enviados (18bits por cada 8bits de datos) supone que, en general, la velocidad del bus I2C es reducida. La velocidad estándar de transmisión es de 100Mhz, con un modo de alta velocidad de 400Mhz.

El estándar I2C define otros modos de funcionamiento, como un envío de dirección de 8,10 y 12bits, o velocidades de transmisión de 1Mbit/s, 3.4Mbit/s y 5Mbit/s. No suelen ser empleados en Arduino.

VENTAJAS Y DESVENTAJAS DEL SPI

Ventajas

  • Requiere pocos cables
  • Dispone de mecanismos para verificar que la señal hay llegado

Desventajas

  • Su velocidad es media-baja
  • No es full duplex
  • No hay verificación de que el contenido del mensaje es correcto

El bus I2C en Arduino

Arduino dispone de soporte I2C por hardware vinculado físicamente a ciertos pines. También es posible emplear cualquier otro grupo de pines como bus I2C a través de sofware, pero en ese caso la velocidad será mucho menor.

Los pines a los que está asociado varían de un modelo a otro. La siguiente tabla muestra la disposición en alguno de los principales modelos. Para otros modelos, consultar el esquema de patillaje correspondiente.

MODELO SDA SCK
Uno A4 A5
Nano A4 A5
Mini Pro A4 A5
Mega 20 21

Para usar el bus I2C en Arduino, el IDE Standard proporciona la librería “Wire.h”, que contiene las funciones necesarias para controlar el hardware integrado.

Algunas de las funciones básicas son las siguientes

Wire.begin()  // Inicializa el hardware del bus
Wire.beginTransmission(address); //Comienza la transmisión
Wire.endTransmission(); // Finaliza la transmisión
Wire.requestFrom(address,nBytes);  //solicita un numero de bytes al esclavo en la dirección address
Wire.available();  // Detecta si hay datos pendientes por ser leídos
Wire.write();  // Envía un byte
Wire.read();   // Recibe un byte

Wire.onReceive(handler); // Registra una función de callback al recibir un dato
Wire.onRequest(handler); // Registra una función de callback al solicitar un dato

Existen otras librerías más avanzadas que Wire.h para manejar el bus I2C, como por ejemplo I2Cdevlib o I2C library.

Escáner de I2C

En un mundo ideal sabríamos la dirección de dispositivo que compramos. Pero en algunas ocasiones, sobre todo al comprar en vendedores chinos, el fabricante no nos facilita la dirección del dispositivo o incluso lo proporciona de forma incorrecta.

Esta es una circunstancia común y nada preocupante. Para eso disponemos de un sketch llamado “Scanner I2C” que realiza un barrido por todas las posibles direcciones del bus, y muestra el resultado en caso de encontrar un dispositivo en la dirección.

De esta forma podemos determinar cómodamente las direcciones de los dispositivos desconocidos.

El sketch scanner I2C está disponible en este enlace, o podéis usar la siguiente versión reducida y traducida.

#include "Wire.h"

extern "C" { 
    #include "utility/twi.h"
}

void scanI2CBus(byte from_addr, byte to_addr, void(*callback)(byte address, byte result) ) 
{
  byte rc;
  byte data = 0;
  for( byte addr = from_addr; addr <= to_addr; addr++ ) {
    rc = twi_writeTo(addr, &data, 0, 1, 0);
    callback( addr, rc );
  }
}

void scanFunc( byte addr, byte result ) {
  Serial.print("addr: ");
  Serial.print(addr,DEC);
  Serial.print( (result==0) ? " Encontrado!":"       ");
  Serial.print( (addr%4) ? "\t":"\n");
}


const byte start_address = 8;
const byte end_address = 119;

void setup()
{
    Wire.begin();

    Serial.begin(9600);
    Serial.print("Escaneando bus I2C...");
    scanI2CBus( start_address, end_address, scanFunc );
    Serial.println("\nTerminado");
}

void loop() 
{
    delay(1000);
}

En una próxima entrada veremos como conectar dos placas Arduino por bus I2C. Mientras, si te ha gustado esta entrada y quieres leer más puedes consultar el resto de tutoriales de Arduino


Conectar un display LCD Hitachi con Arduino por el bus I2C

$
0
0
arduino-lcd-i2c

¿Qué es un controlador LCD I2C?

El controlador de LCD I2C es un dispositivo que nos permite controlar una pantalla a través del bus I2C, usando únicamente dos cables.

En esta entrada aprendimos a manejar un display LCD Hitachi con controlador HD44780, una familia de pantallas barata y sencillas de emplear.

Pero usar esta pantalla directamente desde Arduino requería emplear una gran cantidad de pines de Arduino, lo que supone un enorme desperdicio de recursos, que deberían estar ocupados en cosas mucho más importantes que encender un simple display.

Una alternativa recomendable es usar un controlador que permita acceder al LCD a través del bus I2C. Este controlador LCD I2C puede conectarse a cualquier LCD Hitachi HD44780 y reduce la cantidad de cables necesarios a dos.

Internamente el controlador LCD I2C es una variación del extensor de entradas y salidas digitales PCF8574, especialmente adaptado para pantallas LCD Hitachi HD44780. Incluso incorporan un potenciómetro para regular el backlight del LCD.

El controlador LCD I2C normalmente se entrega por separado, en cuyo caso tendremos que soldarlo al display LCD.

Precio

El controlador I2C para un LCD Hitachi es un componente barato. Podemos encontrarlo por 0.60€, en vendedores internacionales de AliExpress o eBay.

arduino-i2c-lcd-controlador

También es posible comprarlo de forma conjunta con el LCD. No hay ahorro significativo en comprarlos de forma conjunta, por lo que el precio resulta la suma del LCD + controlador.

Por tanto, el precio final de un LCD I2C de 16 caracteres y dos líneas 16×2 (LCD1602) queda en torno de 1.70€, y el de 20×4 (LCD2004) uno de 20 caracteres y 4 lineas unos 4.20€.

arduino-i2c-lcd-componente

Esquema eléctrico

La conexión es sencilla, simplemente alimentamos el módulo desde Arduino mediante GND y 5V y conectamos el pin SDA y SCL de Arduino con los pines correspondientes del controlador LCD I2C.

arduino-lcd-i2c-esquema

Mientras que la conexión vista desde el lado de Arduino quedaría así.

arduino-lcd-i2c-conexion

En Arduino Uno, Nano y Mini Pro, SDA es el pin A4 y el SCK el pin A5. Para otros modelos de Arduino consultar el patillaje correspondiente.

Ejemplos de código

Para poder usar una pantalla LCD I2C emplearemos la librería LiquidCrystal_I2C, disponible en este enlace.

El uso es similar a la librería LiquidCrystal convencional. El siguiente sketch muestra el uso de las funciones de la librería para mostrar los textos “Linea 1” y “Linea 2” en una pantalla de 16×02.

#include  
#include 

LiquidCrystal_I2C lcd(0x27, 16, 2);  // Inicia el LCD en la dirección 0x27, con 16 caracteres y 2 líneas

void setup()
{
	lcd.init();                      
	lcd.backlight();
	lcd.setCursor(0, 0);
	lcd.print("Linea 1");
	lcd.setCursor(0, 1);
	lcd.print("Linea 2");
	delay(2500);
	lcd.clear();
}

void loop()
{
}

Si te ha gustado esta entrada y quieres leer más puedes consultar el resto de tutoriales de Arduino

Controlar motores de corriente continua con Arduino y L298N

$
0
0
arduino-l298n

¿Qué es un L298N?

El L298N es un controlador (driver) de motores, que permite encender y controlar dos motores de corriente continua desde Arduino, variando tanto la dirección como la velocidad de giro.

Como comentamos frecuentemente Arduino, y en general todos los autómatas, no disponen de potencia suficiente para mover accionadores. De hecho, la función de un procesador no debe ser ejecutar acciones si no mandar ejecutar acciones a drivers que realicen el “trabajo pesado”.

El L298N también puede controlar un único motor de paso a paso aunque, en general, preferiremos usar dispositivos específicamente diseñados para motores paso a paso.

La intensidad máxima que el L298N puede suministrar a los motores es de 2A por salida (hasta 3A de pico), con una tensión de alimentación de 3V a 35V.

El L298N incorpora protecciones contra efectos que pueden producirse al manejar motores de corriente continua. Dispone de protecciones contra sobre intensidad, sobre temperatura, y diodos de protección contra corrientes inducidas (flyback).

El controlador L298N es ampliamente usado en proyectos electrónico y robótica, por su sencillez de uso, bajo coste, y buena calidad precio.

Precio

Es controlador L298N es un componente barato, podemos encontrarlo por 1,40€ en vendedores internacionales de AliExpress o eBay.

arduino-l298n-componente

¿Cómo funciona un L298N?

Básicamente un L298N consiste en dos puentes-H, uno para la salida A y otro para la salida B.

Un puente-H es un componente ampliamente utilizado en electrónica para alimentar una carga de forma que podemos invertir el sentido de la corriente que le atraviesa.

Internamente un puente-H es una formación de 4 transistores, conectados entre Vcc y GND, con la carga a alimentar entre ellos. Dibujado en esquema el conjunto tiene forma de “H”, de la que recibe su nombre su nombre.

arduino-l298n-puenteH

Actuando sobre los 4 transistores, activando los transistores opuestos en diagonal de cada rama, podemos variar el sentido en el que la corriente atraviesa la carga

arduino-l298n-puenteH-funcionamiento

Conectando simultáneamente los transistores superiores o inferiores, podemos poner la carga Vcc o Gnd respectivamente, configuración que usaremos como freno.

Por último, nunca debemos encender ambos transistores de un mismo ramal (izquierda o derecha), ya que estaremos provocando un cortocircuito entre Vcc y GND.

La placa L298N incorpora electrónica que simplifica la conexión al puente H, agrupando las conexiones en 3 pines accesibles (por cada salida) y eliminando la posibilidad de generar un cortorcuito.

arduino-l298n-funcionamiento

Dos de estos pines, IN1 y IN2 (IN3 y IN4 para la salida B), controlan el encendido de los transistores de cada una de las dos ramas, encendiendo el ramal superior o inferior de la misma.

El tercer pin (IEA/IEB) desactiva simultáneamente todos los transistores del puente-H, desconectando la carga por completo.

Esquema eléctrico

La placa de conexión del L298N incorpora una entrada de voltaje, una serie de jumpers para configurar el módulo, dos salidas A y B, y los pines de entrada que regulan la velocidad y el sentido de giro.

arduino-l298n-esquema

La entrada de tensión proporciona el voltaje que alimentará a los motores. El rango de entrada admisible es de 3V a 35V y se suministra mediante los 2 terminales izquierdos de la clema de conexión entrada.

El tercer terminal de la clema de conexión, Vlógico, está conectado con la electrónica del L298N y es necesario que tenga un valor entre 4.5 y 5.5V para que la placa funcione correctamente.

Para ello el módulo incorpora un regulador de voltaje que suministra la tensión necesaria en Vlógico. Este regulador puede desactivarse quitando el jumper de la placa. Desactivaremos el regulador cuando la tensión de alimentación sea inferior a 5V o superior a 15V.

Por tanto:

  • Si el regulador está activado (jumper cerrado) Vlógico es una salida de 5V que podemos emplear para alimentar otros dispositivos.
  • Si el regulador está desactivado (jumper abierto), Vlógico es una entrada a la que tendremos que proporcionar un voltaje de 4.5 a 5.5V.

No debemos introducir corriente en Vlógico con el regulador activado (jumper conectado) o podemos dañar el módulo.

Por otro lado, tenemos las dos clemas de conexión A y B que suministran la salida a los motores.

Por último, tenemos los pines de entrada que controlan la dirección y velocidad de giro.

  • Los pines IEA, IN1 e IN2 controlan la salida A.
  • Los pines IEB, IN3 e IN4 controlan la salida B.

Los pines IN1, IN2, y IN3 e IN4, controlan la dirección de giro, respectivamente, de la salida A y B.

Los pines IEA y IEB desactivan la salida. Podemos conectarlos permanentemente mediante el uso de un jumper, o conectar una señal PWM para controlar la velocidad de giro.

En el caso de querer usar ambas fases, y poder elegir tanto el sentido de giro como la velocidad, y alimentar desde una fuente de 12V, el esquema de conexión a Arduino sería el siguiente.

arduino-l298n-conexion

Mientras que la conexión, vista desde el lado de Arduino, sería la siguiente.

arduino-l298n-montaje

La alimentación de Arduino en este caso podría realizarse desde la fuente de 12V al pin Vin de Arduino (usando el regulador de voltaje de Arduino), o desde el pin Vlogico del L298N al pin 5V de Arduino (usando el regulador del L298N).

Siempre que uséis más de una fuente de tensión recordar poner en común todos los GND incluido el de Arduino.

Ejemplos de código

Para controlar los dos motores, debemos activar correctamente las salidas digitales conectadas a los pines IN1 y IN2 (salida A), o los pines IN3 e IN4 (salida B).

Las posibles combinaciones son:

Adelante Atrás Freno
IN1 (o IN3) HIGH LOW LOW
IN2 (o IN4) LOW HIGH LOW

Respecto a los pines IEA y IEB, usaremos una salida PWM para controlar la velocidad de giro.

El siguiente código mueve hacia adelante el motor de la salida A al 80% de velocidad.

const int pinENA = 6;
const int pinIN1 = 7;
const int pinIN2 = 8;

const int speed = 200;		//velocidad de giro 80% (200/255)

void setup()
{
	pinMode(pinIN1, OUTPUT);
	pinMode(pinIN2, OUTPUT);
	pinMode(pinENA, OUTPUT);
}

void loop()
{
	digitalWrite(pinIN1, HIGH);
	digitalWrite(pinIN2 LOW);
	analogWrite(pinENA, speed);
	delay(1000);
}

El código necesario para controlar el L298N no es complicado pero si no somos limpios puede crecer rápidamente de tamaño, lo cuál será un problema cuando lo integremos en proyectos más grandes, como vehículos o robots.

Por tanto resulta conveniente agrupar y reutilizar el código en funciones que simplifiquen su uso.

El siguiente código enciende ambos motores en un sentido, a continuación en sentido contrario, y finalmente los para por completo, para después volver a iniciar el ciclo.

const int pinENA = 6;
const int pinIN1 = 7;
const int pinIN2 = 8;
const int pinIN3 = 9;
const int pinIN4 = 10;
const int pinENB = 11;

const int waitTime = 2000;	//espera entre fases
const int speed = 200;		//velocidad de giro

const int pinMotorA[3] = { pinENA, pinIN1, pinIN2 };
const int pinMotorB[3] = { pinENB, pinIN3, pinIN4 };

void setup()
{
	pinMode(pinIN1, OUTPUT);
	pinMode(pinIN2, OUTPUT);
	pinMode(pinENA, OUTPUT);
	pinMode(pinIN3, OUTPUT);
	pinMode(pinIN4, OUTPUT);
	pinMode(pinENB, OUTPUT);
}

void loop()
{
	moveForward(pinMotorA, 180);
	moveForward(pinMotorB, 180);
	delay(waitTime);

	moveBackward(pinMotorA, 180);
	moveBackward(pinMotorB, 180);
	delay(waitTime);

	fullStop(pinMotorA);
	fullStop(pinMotorB);
	delay(waitTime);
}

void moveForward(const int pinMotor[3], int speed)
{
	digitalWrite(pinMotor[1], HIGH);
	digitalWrite(pinMotor[2], LOW);

	analogWrite(pinMotor[0], speed);
}

void moveBackward(const int pinMotor[3], int speed)
{
	digitalWrite(pinMotor[1], LOW);
	digitalWrite(pinMotor[2], HIGH);

	analogWrite(pinMotor[0], speed);
}

void fullStop(const int pinMotor[3])
{
	digitalWrite(pinMotor[1], LOW);
	digitalWrite(pinMotor[2], LOW);

	analogWrite(pinMotor[0], 0);
}

Como vemos, con las funciones que hemos hecho resulta sencillo mover un robot adelante y atrás, e incluso es sencillo usarlas para hacer que gire o haga trayectorias. En un proyecto complejo, funciones similares estuvieran integradas dentro de nuestro modelo de objetos.

Usaremos el controlador de motores L298N frecuentemente en nuestros proyectos, y dentro de poco veremos algún proyecto como robots o vehículos que hacen uso del L298N.

Mientras tanto, si te ha gustado esta entrada y quieres leer más puedes consultar el resto de tutoriales de Arduino

Desactivar Windows Defender permanentemente en Windows 10

$
0
0
desactivar-windows-defender

Windows 10 vino con muchas sorpresas bajo el brazo. Algunas de ellas fueron agradables pero otras, como sus problemas de privacidad o la obligatoriedad de las actualizaciones, muy polémicas para el usuario.

Una de las más molestas es el alto consumo de procesador que se genera incluso sin estar ejecutando ningún proceso. Resulta frecuente encontrar la carga del procesador entre el 20 al 40%, incluso estando el ordenador parado.

Investigando un poco más con el explorador de procesos descubrimos que una parte importante de este consumo de procesador es debido a Windows Defender, el antivirus integrado de Windows.
Podemos detener el escaneo en tiempo real pero, entre las sorpresas que Microsoft ha tenido a bien regalarnos, Windows Defender vuelve a activarse automáticamente.

Si encontráis este consumo de procesador molesto, es posible desactivar Windows Defender de forma permanente modificando una clave del registro de Windows.
Para ello tenemos que modificar (o añadir si no existe) la siguiente clave DWORD

HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\DisableAntiSpyware

Los posibles valores son:

  • 0 = Para tener activo Windows Defender
  • 1 = Para desactivar permanentemente Windows Defender

Mientras la esta clave exista y tenga valor 1, Windows Defender estará permanentemente desactivado y no podrá ser activado, ni siquiera de forma temporal.

Esto supone un riesgo de seguridad para vuestro equipo, que pasa a no tener ningún tipo de protección antispyware. Por lo tanto, corre a vuestra responsabilidad desactivarlo.

No obstante, siempre es posible volver a activarlo, o instalar otro Software Antivirus que sea menos intrusivo con el uso de vuestro procesador.

Detector de obstáculos con sensor infrarrojo y Arduino

$
0
0
arduino-detector-obstaculos-infrarrojos

¿Qué es un detector de obstáculos IR?

Un detector de obstáculos infrarrojo es un dispositivo que detecta la presencia de un objeto mediante la reflexión que produce en la luz. El uso de luz infrarroja (IR) es simplemente para que esta no sea visible para los humanos.

Constitutivamente son sensores sencillos. Se dispone de un LED emisor de luz infrarroja y de un fotodiodo (tipo BPV10NF o similar) que recibe la luz reflejada por un posible obstáculo.

arduino-detector-obstaculos-infrarrojos-funcoinamiento

Los detectores de obstáculo suelen proporcionarse con una placa de medición estándar con el comparador LM393, que permite obtener la lectura como un valor digital cuando se supera un cierto umbral, que se regula a través de un potenciómetro ubicado en la placa.

Este tipo de sensores actúan a distancias cortas, típicamente de 5 a 20mm. Además la cantidad de luz infrarroja recibida depende del color, material, forma y posición del obstáculo, por lo que no disponen de una precisión suficiente para proporcionar una estimación de la distancia al obstáculo.

Pese a esta limitación son ampliamente utilizados para la detección de obstáculos en pequeños vehículos o robots. Su bajo coste hace que sea frecuente ubicarlos en el perímetro, de forma que detectemos obstáculos en varias direcciones.

También son útiles en otro tipo de aplicaciones como, por ejemplo, detectar la presencia de un objeto en una determinada zona, determinar una puerta está abierta o cerrada, o si una máquina ha alcanzado un cierto punto en su desplazamiento.

Precio

Los sensores de obstáculos infrarrojos son realmente baratos. Podemos encontrar detectores infrarrojos, incluida la placa de medición, por 0,30€ en vendedores internacionales de eBay y AliExpress.

arduino-detector-de-obstaculos-infrarrojos-componente

Al ser un sensor sencillo también podemos montarlo nosotros mismos. En general no merece la pena ya que sólo los componentes nos costarían más, sin contar el tiempo necesario y la calidad que podríamos obtener, por lo que lo normal es que usemos un modelo comercial.

Esquema eléctrico

El montaje es sencillo. Alimentamos el módulo a través de Vcc y GND conectándolos, respectivamente, a la salida de 5V y GND en Arduino.

arduino-detector-de-obstaculos-infrarrojos-conexion

Finalmente, conectamos la salida digital del sensor a una entrada digital para leer el estado del sensor.

arduino-detector-de-obstaculos-infrarrojos-esquema

Opcionalmente, calibramos el umbral de disparo acercando un objeto al detector de obstáculos y regulando la salida digital con el potenciómetro. Si queréis saltaros este paso, dejar el potenciómetro en un valor medio.

Ejemplos de código

El código es igualmente sencillo. Simplemente leemos el estado de la entrada digital, tal y como vimos en la entrada Entradas digitales en Arduino.

Si el sensor se dispara, ejecutamos las acciones necesarias.

const int sensorPin = 9;

void setup() {
  Serial.begin(9600);   //iniciar puerto serie
  pinMode(pin, INPUT);  //definir pin como entrada
}
 
void loop(){
  int value = 0;
  value = digitalRead(sensorPin );  //lectura digital de pin
 
  if (value == HIGH) {
      Serial.println("Detectado obstaculo");
  }
  delay(1000);
}

Si te ha gustado esta entrada y quieres leer más puedes consultar el resto de tutoriales de Arduino

También podemos leer el estado del sensor mediante el uso de interrupciones. Para más información consultar la entrada Qué son y cómo usar interrupciones en Arduino y Leer un pulsador con interrupciones en Arduino

Controlar un servo con Arduino

$
0
0
arduino-servo

¿Qué es un servo?

Un servo es un tipo de accionador ampliamente empleado en electrónica. A diferencia de otros tipos de motores en los que controlamos la velocidad de giro, en un servo indicamos directamente el ángulo deseado y el servo se encarga de posicionares en este ángulo.

Típicamente los servos disponen de un rango de movimiento de entre 0 a 180º. Es decir, no son capaces de dar la vuelta por completo (de hecho disponen de topes internos que limitan el rango de movimiento)

Internamente un servo frecuentemente consta de un mecanismo reductor. Por tanto proporcionan un alto par y un alto grado de precisión (incluso décimas de grado). Por contra, las velocidades de giro son pequeñas frente a los motores de corriente continua.

Los servos se admiten una tensión de alimentación entre 4,8V a 7,2V, siendo el valor más adecuado es 6V. Con tensiones inferiores el motor tiene menos fuerza y velocidad. Con tensiones superiores a 6,5V los servos empiezan a oscilar demasiado, lo cual los hace poco útiles.

Los servos son cómodos de emplear, ya que ellos mismos realizan el control de posición, que con otro tipo de motores debe hacerse de forma externa. Por este motivos son ampliamente empleados en proyectos de robótica, como brazos robóticos, robots con patas, controlar el giro de torretas, u orientar sensores como sensores de ultrasonidos o sensores de temperatura a distancia.

Precio

Existe una gran variedad de servos, que varían en tamaño, fuerza, velocidad, y precisión. Los servos que emplearemos en nuestros proyectos cuestan unos pocos euros pero, incluso dentro del campo de los hobbies podemos encontrar servos de 100-150€, y de miles de euros en el ámbito industrial.

Para nuestros proyectos caseros usaremos principalmente dos tamaños de servo. Dentro de los distintos modelos destacaremos tres por su calidad/precio. Podéis encontrarlos fácilmente en vendedores internacionales de eBay o AliExpress.

SG90

Es el servo de tamaño “pequeño” estándar dentro de los proyectos de electrónica. Es un servo pequeño, ligero, y barato, que dispone de engranajes de plástico. Muchos dispositivos, como torretas y partes de robots, están diseñados para instalar servos de este tamaño.

  • Torque: 1.4 kg/cm
  • Velocidad: 0.1s / 60º (4.8V) y 0.08s/60º (6V)
  • Dimensiones: 21.5mm x 11.8 x 22.7
  • Peso: 9g
  • Precio: 1.20€

arduino-servo-sg90

MG90S

El MG90S es similar al SG90 pero dispone de engranajes y el acoplamiento metálicos. A cambio pesa un poco más y es más caro. Físicamente es compatible con los accesorios del SG90.

Usaremos este servo como sustituto del SG90 cuando tengamos una aplicación en la que realmente necesitemos ejercer fuerza, y las partes de plástico podrían ceder y quedarse “redondas”.

  • Torque: 1.8 kg/cm
  • Velocidad: 0.1s / 60º (4.8V) y 0.08s/60º (6V)
  • Dimensiones: 22.8 x 12.2 x 28.5mm
  • Peso: 13.4g
  • Precio: 2€

arduino-servo-mg90s

M996R

Este es el servo de tamaño “grande” que usaremos frecuentemente. Este tipo de servos es ampliamente utilizado en proyectos de robótica. Igual que con el SG90, muchos dispositivos y kits como brazos robóticos, hexápodos, están diseñados para instalar este tamaño de servo.

  • Torque: 13kg/cm (4.8V) a 15kg/cm (6V)
  • Velocidad: 0.17seg / 60º (4.8V) y 0.13 seg/60º (6V)
  • Dimensiones: 40x19x43mm
  • Peso: 56g
  • Precio: 3.70€

arduino-servo-mg996r

Conviene aclarar que estos servos, sobre todos los comprados en china, destacan por su calidad/precio. Pero, lógicamente, son modestos en sus características. Veréis en comparativas que otros modelos más caros también son más rápidos y precisos.

Pero cuando hagamos proyectos como hexápodos o robots bípedos, que requieren entre 18 a 24 servos, la diferencia de usar servos de 1.2€-3.7€ a servos de 80-100€ supone pasar de un coste de 40-60€ por proyecto, a 2000-2400€, que es una diferencia enorme.

Por otro lado, usar servos baratos nos supondrá más problemas en calibración, repetibilidad, pruebas y trabajo adicional. Pero después de todo, hacer robots es sencillo, lo difícil es hacerlos baratos :D.

¿Cómo funciona un servo?

Internamente un servo está constituido por un motor de corriente continua, acoplado a un reductor para reducir la velocidad de giro, junto con la electrónica necesaria para controlar su posición.

arduino-servo-interior

Frecuentemente simplemente se dispone de un potenciómetro unido al eje del servo, que permite al servo para conocer la posición del eje. Esta información es tratada por un controlador integrado que se encarga de ajustar actuar sobre el motor para alcanzar la posición deseada.

La comunicación de la posición deseada se realiza mediante la transmisión de un señal pulsada con periodo de 20ms. El ancho del pulso determina la posición del servo.

arduino-servo-funcionamiento

La relación entre el ancho del pulso y el ángulo depende del modelo del motor. Por ejemplo, algunos modelos responden con 0º a un pulso de 500 ms, y otros a un pulso de 1000 ms

En general, en todos los modelos:

  • Un pulso entre 500-1000 us corresponde con 0º
  • Un pulso de 1500 ms corresponde con 90º (punto neutro)
  • Un pulso entre 2000-2500us corresponde con 180º

Por tanto, variando la señal en microsegundos podemos disponer de una precisión teórica de 0.18-0.36º, siempre que la mecánica del servo acompañe.

Esquema de montaje

Conectar un servo a Arduino es sencillo. El servo dispone de tres cables, dos de alimentación (GND y Vcc) y uno de señal (Sig).

El color de estos cables suele tener dos combinaciones:

– Marrón (GND), Rojo (Vcc) y Naranja (Sig)

– Negro (GND), Rojo (Vcc) y Blanco (Sig)

Por un lado, alimentamos el servo mediante el terminal GND ( Marrón / Negro) y Vcc (Rojo).

arduino-servo-montaje

En general, la alimentación a los servos se realizará desde una fuente de tensión externa (una batería o fuente de alimentación) a una tensión de 5V-6.5V, siendo 6V la tensión idónea.

Arduino puede llegar a proporcionar corriente suficiente para encender un servo pequeño (SG90), suficiente para hacer unos cuantos proyectos de prueba.

Sin embargo no dispone de corriente suficiente para actuar un servo grande (MG996R). Incluso varios servos pequeños, o hacer excesiva fuerza con ellos puede exceder la capacidad de corriente de Arduino, provocando su reinicio.

Por otro lado, finalmente, para el control conectamos el cable de señal (naranja / blanco) a cualquier pin digital de Arduino.

arduino-servo-esquema

Al usar una fuente externa recordar poner SIEMPRE en común todos los GND.

Ejemplos de código

El control de servos en Arduino es muy sencillo, ya que el IDE Standard proporciona la librería “servo.h”, que permite controlar simultáneamente hasta 12 servos en Arduino Uno/Nano y hasta 48 servos en Arduino Mega.

Entre los ejemplos típicos para ilustrar el funcionamiento de servos tenemos el Sketch “Sweep”, que realiza un barrido continuo con el servo.

Para ello incrementa el ángulo de 0 a 180º a razón de 1º cada 15ms, posteriormente realiza la operación contraria de 180º a 0º, para finalmente reiniciar el bucle.

#include 

Servo myservo;  // crea el objeto servo

int pos = 0;    // posicion del servo

void setup() {
	myservo.attach(9);  // vincula el servo al pin digital 9
}

void loop() {
	//varia la posicion de 0 a 180, con esperas de 15ms
	for (pos = 0; pos <= 180; pos += 1) 
	{
		myservo.write(pos);              
		delay(15);                       
	}

	//varia la posicion de 0 a 180, con esperas de 15ms
	for (pos = 180; pos >= 0; pos -= 1) 
	{
		myservo.write(pos);              
		delay(15);                       
	}
}

Si te ha gustado esta entrada y quieres leer más puedes consultar el resto de tutoriales de Arduino

Hacer un encoder óptico con un optointerruptor y Arduino

$
0
0
arduino-encoder-optointerruptor

¿Qué es un optointerruptor?

Un optointerruptor es un sensor con forma de “U” que permite detectar un objeto que atraviesa el dispositivo por la ranura interior.

arduino-optointerruptor

Los optointerruptores son sensores sencillos. Uno de los extremos contiene un diodo emisor de infrarrojos, mientras que el otro contiene un fototransitor que recibe la señal. Cuando un objeto pasa por la ranura interrumpe el rayo de luz infrarroja, lo que es detectado por el fototransitor.

Los optointerruptores son muy empleados como encoder para detectar la velocidad de giro y posición del eje de un motor. Para ello se emplea un disco con ranuras acoplado al eje. También es posible emplear una lámina transparente sobre la que se imprimen franjas negras, algo que encontramos frecuentemente en impresoras.

arduino-encoder

Además de como encoder, un optointerruptor puede ser empleado para detectar cualquier tipo de objecto que interrumpa el rayo como, por ejemplo, para detectar el cierre de una puerta, o como fin de carrera óptico en el desplazamiento de una máquina.

Otro sensor ampliamente empleado para realizar encoders y tacómetros es un sensor hall, como vimos en la entrada Detectar cambos magnéticos con Arduino y sensor hall A3144

Precio

Podemos encontrar placas con optoacoplador por unos por 0,60€ en vendedores internacionales de eBay y AliExpress.

No son componentes fáciles de encontrar porque cada vendedor le pone un nombre diferente y las traducciones de estas páginas son bastante malas. Probar buscando “photo interrupter” o “sensor velocidad arduino” o “sensor ranurado arduino”

arduino-encoder-optointerruptor-componente

También podemos encontrar optointerruptores en montajes de 2 o 4 canales. En general suelen ser más caros que comprarlos sueltos y no hay ninguna ventaja en tenerlos en un mismo dispositivo así que, en general, no son recomendables.

arduino-encoder-optointerruptor-multicanal

Al ser un sensor sencillo también podemos montarlo nosotros mismos. En general no merece la pena ya que sólo los componentes nos costarían más, sin contar el tiempo necesario y la calidad que podríamos obtener, por lo que lo normal es que usemos un modelo comercial.

Ensamblar nuestro propio sensor solo tiene sentido cuando, por la ubicación en la que tenga que ser montado el sensor, no dispongamos de espacio para alojar una placa comercial y nos veamos obligados a integrar el componente.

Esquema eléctrico

Si usáis una placa comercial, que como hemos dicho en general es recomendable, el montaje de un optointerruptor a Arduino es realmente sencillo. Alimentamos el módulo a través de Vcc y GND conectándolos, respectivamente, a la salida de 5V y GND en Arduino.

arduino-encoder-optointerruptor-esquema

Por otro lado conectamos la salida digital del sensor a una entrada digital para leer el estado del sensor.

arduino-encoder-optointerruptor-montaje

Si os decidís por hacer todo el montaje vosotros mismos, el esquema eléctrico tampoco es complicado. Simplemente necesitamos alimentar el módulo correctamente, respetando el esquema del componente. Como véis, el sentido de alimentación de ambas ramas suele estar invertido. Consultar el Datasheet de vuestro optoacoplador para verificar su patillaje.

arduino-optointerruptor-funcionamiento

Alimentamos al fotodiodo a través de una resistencia para limitar su corriente, como vimos en Encender un Led con Arduino. En la rama del fototransistor empleamos una resistencia de pull-down para leer el estado del sensor, como vimos en Leer un pulsador con Arduino

Ejemplos de código

Tenemos varias opciones para leer un optointerruptor con Arduino. Si estamos detectando la presencia de un objeto, simplemente leemos el estado de la entrada digital, tal y como vimos en la entrada Entradas digitales en Arduino.

Cuando el sensor se dispara, ejecutamos las acciones necesarias, cómo incrementar un contador, o medir el tiempo entre disparos.

const int sensorPin = 9;

void setup() {
  Serial.begin(9600);   //iniciar puerto serie
  pinMode(pin, INPUT);  //definir pin como entrada
}
 
void loop(){
  int value = 0;
  value = digitalRead(sensorPin );  //lectura digital de pin
 
  if (value == LOW) {
      Serial.println("Optointerruptor activado");
  }
  delay(1000);
}

Sin embargo, en el caso de usar el optointerruptor como encoder lo normal es que empleemos las interrupciones de Arduino, lo que nos simplificará considerablemente el código. El punto negativo es que tendremos que hacer debounce a las entradas y que Arduino UNO y Nano solo tenemos dos interrupciones externas, lo cuál en algunos vehículos se nos quedará corto.

Usaremos este tipo de sensores frecuentemente en nuestros proyectos de robótica y vehículos con Arduino. Mientras, si te ha gustado esta entrada y quieres leer más sobre Arduino puedes consultar el resto de tutoriales de Arduino

Medir distancias con Arduino y sensor Sharp GP2Y0A02YK0F

$
0
0
arduino-sharp-GP2Y0A02YK0F1
arduino-sharp-GP2Y0A02YK0F1

¿Qué es un sensor Sharp GP2Y0A02YK0F?

El Sharp GP2Y0A02YK0F es un sensor de distancia óptico. Está compuesto por un LED infrarrojo junto con dispositivo detector de posición (PSD) y un procesador integrado encargado de realizar el cálculo de la distancia.

El sensor escanea de forma continua los objetos ubicados en frente suyo y proporciona la salida mediante una referencia de tensión analógica, por lo que podemos emplear las entradas analógicas de Arduino para leer el valor de la distancia.

El rango de medición es de 20 a 150 cm, manteniendo un grado de precisión elevado en todo el intervalo. La tensión de alimentación es de 4.5 a 5.5V y el consumo de corriente de 33mA. El intervalo de refresco entre mediciones es de unos 80ms.

El GP2Y0A02YK0F es un dispositivo sencillo de conectar y usar. Sin embargo hay que tener en cuenta que incorpora un conector JST (Japanese Solderless Terminal) para su conexión, por lo que tendremos que emplear un conector de este tipo o soldar directamente los terminales en la placa.

El sensor es poco sensible al color y reflectividad del objeto detectado, ni a la temperatura ambiente. Sin embargo, sí puede ser afectado por luz ambiente si recibe un alto grado de luminosidad de forma directamente, en especial al usarlo en exterior. También pueden proporcionar mediciones incorrectas al detectar objetos transparentes o muy brillantes, especialmente vidrios y espejos.

El sensor Sharp es más preciso que los sensores de ultrasonidos como el HC-SR04, especialmente en distancias medias y largas, donde los sensores de ultrasonidos ven afectadas sus mediciones por los rebotes y ecos que producen las geometrías del entorno.

Sin embargo no puede operar en distancias cortas (<20cm) donde el HC-SR04, aunque con baja precisión, al menos puede realizar mediciones.

Cuando montéis estos sensores en un vehículo o robot intentarlos montarlos en la parte trasera del mismo, aunque la primera tendencia sea montarlos en la delantera. Así ganáis el ancho del vehículo como distancia, y podréis medir distancias inferiores.

Por otro lado, el sensor Sharp tiene una zona de medición más estrecho que el HC-SR04, lo cual permite obtener mayores para mediciones en frente del objeto. Por contra, ignorar objetos que el HC-SR04 si detectaría por su mayor ángulo de medición (por ejemplo, las patas de una mesa).

Finalmente, al emplear más de un sensor pueden producirse interferencias entre las mediciones si ambos haces interfieren. Sin embargo, el problema es mucho menor que al combinar sensores HC-SR04, donde podemos tener interferencias incluso sin que los haces interfieran, por los rebotes y ecos secundarios originados por el propio HC-SR04.

Podemos usar el GP2Y0A02YK0F en nuestros robots para medición de distancias en rangos medios y largos en un haz estrecho. Dadas sus diferentes características, podemos combinarlos con sensores ultrasonido tipo HC-SR04 para rangos cortos o amplios, o sensores de detección de obstáculos para distancias muy cortas.

El sensor Sharp también tiene puede ser empleado en otro tipo de aplicaciones como, por ejemplo, sistemas Touch-Less, control de iluminación, sensores de posición, fines de carrera o detección de objetos en un determinada zona.

Precio

El sensor Sharp GP2Y0A02YK0F es más caro que un sensor de ultrasonidos HC-SR04. Podemos encontrar sensores Sharp GP2Y0A02YK0F por 3.70€ en vendedores internacionales de eBay o AliExpress.

arduino-sharp-GP2Y0A02YK0F1-componente

¿Cómo funciona el Sharp GP2Y0A02YK0F?

El emisor LED infrarrojo emite un haz de luz pulsada infrarroja con una longitud de onda de 850nm +/-70nm. Se envía una luz pulsada para minimizar la influencia de la luz ambiente y del color del objeto en la medición.

El detector de posición PSD (position sensitive detection) es en realidad es un pequeño sensor CCD lineal que recibe la luz reflejada en cualquier objeto en la trayectoria del rayo. El sensor emplea triangulación para determinar la distancia del sensor a los objetos ubicados frente al rayo.

arduino-sharp-GP2Y0A02YK0F1-funcionamiento

La salida analógica tienen un valor de 2.5V a 20 cm, y de 0.4 a 150cm. Sin embargo, como hemos mencionado, la respuesta es no lineal por lo que es necesario interpolar el valor para obtener un nivel de precisión adecuado.

arduino-sharp-GP2Y0A02YK0F1-precision

Esquema de montaje

El esquema de montaje es sencillo. Por un lado, alimentamos el sensor mediante Vcc y GND conectándolos, respectivamente, a 5V y GND de Arduino.

arduino-sharp-GP2Y0A02YK0F1-esquema

Finalmente, conectamos el pin de señal a una de las entradas analógicas de Arduino.

arduino-sharp-GP2Y0A02YK0F1-conexion

Ejemplos de código

El siguiente código realiza la medición de la salida del sensor empleando las entradas analógicas de Arduino. A continuación, realiza la interpolación para obtener la distancia en centímetros.

Finalmente, muestra los valores por pantalla empleando el puerto de serie. En un montaje real, usaríamos esta zona para hacer las acciones necesarias, como detener un robot o activar un mecanismo.

const int sensorPin = A0;
const long referenceMv = 5000;

void setup() {
	Serial.begin(9600);
	pinMode(ledPin, OUTPUT);
}

void loop() {
	//lectura de la tensión
	int val = analogRead(sensorPin);
	int mV = (val * referenceMv) / 1023;
	int cm = getDistance(mV);

	
	//mostrar valores por pantalla
	Serial.print(mV);
	Serial.print(",");
	Serial.println(cm);

	delay(1000);
}

//interpolación de la distancia a intervalos de 250mV
const int TABLE_ENTRIES = 12;
const int INTERVAL  = 250;
static int distance[TABLE_ENTRIES] = {150,140,130,100,60,50,40,35,30,25,20,15};

int getDistance(int mV) {
	if (mV > INTERVAL * TABLE_ENTRIES - 1)      return distance[TABLE_ENTRIES - 1];
	else {
		int index = mV / INTERVAL;
		float frac = (mV % 250) / (float)INTERVAL;
		return distance[index] - ((distance[index] - distance[index + 1]) * frac);
	}
}

Si te ha gustado esta entrada y quieres leer más sobre Arduino puedes consultar la sección Tutoriales de Arduino

Detector de líneas con Arduino y sensor TCRT5000L

$
0
0
arduino-detector-lineas-TCRT5000L
arduino-detector-lineas-TCRT5000L

¿Qué es un TCRT5000L?

Un TCRT5000L es un tipo de sensor óptico reflectivo que detecta la diferencia de color en un objeto mediante la reflexión de la luz en el mismo.

El TCRT5000L es un sensor sencillo. Dispone de un LED emisor de luz infrarroja, y de un fototransitor que recibe la luz reflejada por un posible obstáculo. La cantidad de luz recibida depende del color y reflectividad del objeto, por lo que podemos distinguir entre zonas y oscuras de un objeto.

Estos sensores suelen proporcionarse con una placa de medición estándar con el comparador LM393, que permite obtener la lectura como un valor digital cuando se supera un cierto umbral, que se regula a través de un potenciómetro ubicado en la placa. Podemos capturar esta señal con las entradas digitales de Arduino.

El rango de medición del sensor varía entre 0.2 a 15mm, siendo la distancia óptima 2.5mm. Por tanto es un sensor de muy corta distancia.

La cantidad de luz infrarroja tiene una fuerte dependencia con el color, material, forma y posición del obstáculo, por lo que no disponen de precisión suficiente para proporcionar una estimación de la distancia a un objeto, simplemente es capaz de su detección.

Los sensores TCRT5000L son ampliamente utilizados para hacer robots seguidores de líneas, aunque también pueden emplearse para detectar cualquier otro tipo de objeto. Por ejemplo, son empleados en impresoras para saber cuando se ha agotado el papel.

Precio

Los TCRT5000L son realmente baratos. Podemos encontrarlos en montaje con la placa de medición por 0,65€ en vendedores internacionales de eBay o AliExpress.

arduino-detector-lineas-TCRT5000L-componente

Al ser un sensor sencillo también podemos montarlo nosotros mismos. En general no merece la pena ya que sólo los componentes nos costarían más, sin contar el tiempo necesario y la calidad que podríamos obtener, por lo que lo normal es que usemos un modelo comercial.

Ensamblar nuestro propio sensor realmente solo tiene sentido cuando, por la ubicación en la que tenga que ser montado el sensor, no dispongamos de espacio para alojar una placa comercial y nos veamos obligados a integrar el componente.

Esquema de montaje

Si usáis una placa comercial, que como hemos dicho en general es recomendable, el montaje de un TCRT5000L a Arduino es realmente sencillo. Alimentamos el módulo a través de Vcc y GND conectándolos, respectivamente, a la salida de 5V y GND en Arduino.

arduino-detector-lineas-TCRT5000L-esquema

Por otro lado conectamos la salida digital del sensor (DO) a una entrada digital para leer el estado del sensor.

arduino-detector-lineas-TCRT5000L-conexion

Si os decidís por hacer todo el montaje vosotros mismos el esquema eléctrico tampoco es complicado. Simplemente necesitamos alimentar el módulo correctamente a través de las resistencias adecuadas, respetando el esquema del componente.

arduino-detector-lineas-TCRT5000L-funcionamiento

Ejemplos de código

Para detectar cuando el TCRT5000L pasa por encima de una zona oscura simplemente leemos el estado de la entrada digital, tal y como vimos en la entrada Entradas digitales en Arduino.

Cuando el sensor se dispara tomaremos las acciones oportunas, como detener o variar la dirección de un robot.

const int sensorPin = 9;

void setup() {
  Serial.begin(9600);   //iniciar puerto serie
  pinMode(pin, INPUT);  //definir pin como entrada
}
 
void loop(){
  int value = 0;
  value = digitalRead(sensorPin );  //lectura digital de pin
 
  if (value == LOW) {
      Serial.println("TCRT5000L activado");  //zona oscura
  }
  delay(1000);
}

Otra forma de atender al TCRT5000L es emplear interrupciones, lo que nos simplificará el código. Sin embargo, en un robot seguidor de líneas frecuentemente usaremos de tres a cinco detectores de líneas, mientras que Arduino UNO y Nano solo tenemos dos interrupciones externas.

Para más información sobre interrupciones consultar la entrada Qué son y cómo usar interrupciones en Arduino y Leer un pulsador con interrupciones en Arduino
Si te ha gustado esta entrada y quieres leer más sobre Arduino puedes consultar la sección Tutoriales de Arduino

Salidas de mayor potencia con Arduino y transistor BJT

$
0
0
arduino-transistor-bjt
arduino-transistor-bjt

En entradas anteriores hemos visto como usar las salidas digitales y las salidas analógicas PWM de Arduino para realizar acciones en el mundo.

Sin embargo, las salidas en Arduino están limitadas tanto en tensión como en intensidad. La tensión máxima que pueden suministrar será la tensión de alimentación (5V o 3,3V en función del modelo). Por su parte, la intensidad máxima admisible es 40mA, siendo recomendado un valor inferior a 20mA.

Más allá de encender una pequeña carga o ejecutar unos cuantos programas de ejemplo, lo cierto es que en el mundo real esto no es suficiente para hacer funcionar la mayoría de cargas, ni siquiera un pequeño motor DC o un relé.

Este comportamiento es habitual, en general, en todos los autómatas. La función de un autómata no es proporcionar intensidad suficiente para realizar acciones. Su función es leer entradas, realizar cálculos, comunicarse con otros autómatas y comandar acciones.

Recordar, el procesador es el “cerebro” de una máquina, no el músculo.

Para realizar las acciones los procesadores delegan en etapas de amplificación o controladores (drivers), que actúan como adaptadores entre el nivel de potencia empleado en el controlador y el requerido por el actuador.

Una de las formas más simples y habituales de realizar esta adaptación es el empleo de transistores. Existen dos grandes familias de transistores. Los transistores BJT (bipolar junction transistor), que fueran los primeros en aparecer, y los transistores FET (field effect transistor).

En esta entrada aprenderemos a usar transistores BJT para manejar cargas mayores a las que podemos manejar con las salidas digitales o analógicas Arduino.

En la próxima entrada veremos cómo hacer esto con transistores MOSFET, unas sub familia de transistores FET.

¿QUÉ ES UN TRANSISTOR BJT?

Los transistores son dispositivos electrónicos que constituyen la base de la electrónica moderna. De forma muy resumida encontramos dos aplicaciones o modos de funcionamiento distintos.

  • Amplificar una señal eléctrica
  • Actuar como interruptor controlado de forma eléctrica

Existe multitud de modelos de transistores, cada uno con diferentes características eléctricas, para atender a las distintas necesidades de nuestros circuitos eléctricos. Por tanto, una parte importante de la fase de diseño al usar un transistor es la elección del modelo adecuado.

Externamente un mismo transistor puede fabricarse en distintos encapsulados standard. Normalmente, los encapsulados con mayor tamaño permiten disipar mejor el calor y, por tanto, soportan mejor intensidades superiores.

arduino-transistor-bjt-componente

Los encapsulados que usaremos más frecuentemente en nuestros proyectos son el TO-92 y TO-220.

Por tanto, no es posible distinguir de forma sencilla las características de un transistor simplemente de forma visual. Deberemos mirar el número de modelo, grabado sobre el mismo, y consultar su correspondiente Datasheet.

¿Cómo funciona un transistor BJT?

Los transistores son dispositivos relativamente complejos, y se requiere conocimientos de electrónica para entenderlos en profundidad. Por tanto, en lugar de realizar un análisis detallado, nos limitaremos a dar una serie de pautas para entender sus fundamentos y que nos permita emplearos en nuestros montajes.

Si necesitáis más información podéis consultar con cualquier libro de electrónica, o sentiros libres de dejar un comentario preguntando lo que queráis.

Una buena forma de entender el funcionamiento de un transistor es mirar a su “abuelo” en la electrónica, la válvula de vacío.

arduino-transistor-bjt-funcionamiento

Una válvula de vacio es un componente eléctrico que dispone de tres terminales en el interior de un tubo en el que se ha hecho vacio. Uno de los terminales actúa como cátodo y otro como ánodo. El tercer terminal está conectado a una rejilla metálica ubicada entre ambos.

Al aplicar electricidad en el terminal de la rejilla se genera un campo eléctrico que “arranca” corriente eléctrica desde el cátodo. Los electrones atraviesan el vacio, pasan sin chocar con la rejilla, y finalmente llegan al ánodo.

El resultado es que tenemos un “contacto eléctrico” entre los terminales de cátodo y ánodo, en el que podemos regular la cantidad de electricidad que fluye entre ambos actuando sobre la rejilla (el tercer terminal). Con esto conseguimos un amplificador eléctrico.

En los transistores BJT, la ampolla de vidrio y los terminales son sustituidos por uniones de semiconductores con diferentes grados de dopado (de ahí su nombre, bipolar junction), formando un integrado sólido. Esto permite hacerlos mucho más pequeños y duraderos que las válvulas de vacío.

En un transistor también tenemos tres terminales, denominados Emisor, Colector, y Base. El “contacto eléctrico” que nos interesa se realiza entre el emisor y el colector, mientras que la base es el elemento que controla la cantidad de electricidad que atraviesa el componente.

Modos de funcionamiento en un BJT

arduino-transistor-bjt-curvas

Un transistor BJT tiene tres modos de funcionamiento.

  • Corte: En este modo el transistor se comporta como si el colector y el emisor estuvieran desconectados, por lo que decimos que es similar a tener un circuito abierto
  • Saturación: En este modo, el transistor se comporta como si el colector y el emisor estuvieran conectados por un diodo de pequeña tensión. Por eso decimos que es similar a tener un cortocircuito, con una cierta caída de tensión
  • Activo: En este modo, la corriente entre el colector y el emisor es proporcional a la intensidad de la base

El modo activo es el modo empleado para amplificar señales (por ejemplo, para hacer un amplificador de audio). En esta entrada no emplearemos este modo.

Los modos corte y saturación puede emplearse de forma conjunta para formar un “interruptor” controlado eléctricamente. Son estos dos modos los que usaremos para encender y apagar nuestra carga, consiguiendo un efecto similar a emplear un interruptor físico, con la diferencia de que este “interruptor” estará controlado por una salida de Arduino.

El estado en que funciona un transistor BJT depende de la corriente que circula por su base. Por ese motivo se dice que un transistor BJT es un dispositivo controlado por intensidad (por contra, las válvulas de vacío y los transistores FET son dispositivos controlados por tensión)

ESQUEMA DE CONEXIÓN

Existe más de un forma de realizar la conexión del transistor. En esta entrada emplearemos la configuración de emisor común, por ser la más simple para hacer conmutar el transistor.

Existen dos sub familias de transistores BJT, el tipo PNP y el tipo NPN. La diferencia entre ambos es el tipo de uniones y semiconductores que se ha empleado en su fabricación.

arduino-transistor-bjt-esquema

Regla nemotécnica: Podéis usar la palabra “Pincha” (que abreviaremos como “PN”), imaginando que la flecha es una aguja que pincha o no el interior del transistor. Si la flecha “Pincha” es PNP. Si “No Pincha” es NPN

Ambos tipos de transistores, PNP y NPN, son similares en funcionamiento (o tienen unas diferencias realmente leves), pero sí que influye en la ubicación en la que tenemos que disponer el transistor BJT el montaje.

arduino-transistor-bjt-montaje

Regla nemotécnica: El transistor PNP (P) se pone en la parte “Positiva” del circuito. El transistor NPN (N) se pone en la parte “Negativa” del circuito

La resistencia de la base sirve para regular la intensidad que atraviesa la base del transistor, y la elección de su valor es crítica para el correcto funcionamiento del circuito. Calcularemos el valor de esta resistencia a continuación.

No todos los modelos de transistor y todos los encapsulados asignan los mismos terminales a cada pin. Por tanto, tendréis que consultar el patillaje en el Datasheet del dispositivo antes de realizar el montaje.

CALCULO DEL TRANSITOR BJT

Podéis realizar todos estos cálculos que aparecen en esta sección automáticamente mediante la Calculadora de transistor BJT como interruptor

Para usar el transistor como conmutador vamos a usar las zonas de corte y saturación del transistor, por lo que no tenemos que realizar cálculos en la región activa.

De esta forma, el cálculo se simplifica y se reduce a calcular la resistencia de base necesaria para que en el punto de trabajo deseado el transistor conmute entre corte y saturación.

En un transistor BJT, la intensidad que atraviesa el colector Ic es proporcional a la intensidad en su base Ib. Esta relación se denomina hFe (a veces Beta). Valores típicos son entre 100 a 200.

Por otro lado, en saturación, el transistor se comporta como un diodo entre colector y emisor de tensión Vce, y un diodo entre base y emisor de tensión Vbe.

Por ejemplo, supongamos que queremos alimentar una carga de 200mA con una tensión nominal de 12V, con un determinado transistor de cuyo Datasheet hemos obtenido que

  • hFe(min) = 100
  • Vce(sat) = 0.2
  • Vbe = 0.7
En el ejemplo asumiremos una hFe constante, pero en el mundo real la relación hFe varía entre un transistor y otro del mismo modelo, debido a diferencias en el proceso fabricación. Además, tiene dependencia con la temperatura de trabajo y con el punto de trabajo. Por tanto en los Datasheet del componente observaréis curvas de dependencia de este factor.

Aplicando la ley de Ohm al dispositivo, calculamos que su equivalente es una resistencia de 60 Ohm.

Por tanto, podemos calcular la intensidad que circula por el colector.

I_c = \frac{V_{cc}-V_{ce}}{R_{load} } = \frac{12-0.2}{60} = 0.196 mA

La intensidad requerida en la base es la intensidad de colector reducida a un factor de hFe(min, por lo que

I_b = \frac{I_c}{h_{FE}} = \frac{0.196A}{100} = 0.00196 A

Por tanto, la resistencia de base necesaria es inferior a

R_b = \frac{V_{in}-V_{be}}{I_b} = \frac{5 - 0.7}{0.00196} = 2196 \Omega

Elegimos la resistencia normalizada inferior y comprobaríamos mirando las curvas del Datasheet que la tensión de base es suficiente para llevar al transistor a saturación.

Otra forma para asegurar la saturación del transistor es mayorar un poco la corriente de base. En el ejemplo, Arduino tiene que proporcionar menos de 2 mA al transistor, por lo que tenemos margen para aumentar un poco la corriente.

R_b = \frac{V_{in}-V_{be}}{I_b} = \frac{5 - 0.7}{0.00196 \cdot 3} = 732 \Omega

Elegiríamos la resistencia normalizada más cercana. En este ejemplo, en el que no disponemos de más detalles sobre el transistor, una resistencia de base de 1k sería razonable.

Podéis elegir la resistencia normalizada más cercana con la Calculadora de resistencias normalizadas

Por último, debemos comprobar que todos los elementos del sistema son capaces de soportar la intensidad y potencia que los atraviesa (incluidas las resistencias y el propio transistor)

P_{transistor} = I_c \cdot V_{ce}

P_b = I_b \cdot V_b

Algunos modelos de transistores permiten disipar potencias mayores acoplando un disipador externo.

Modelos de BJT en Arduino

Existe una gran variedad de transistores BJT que podemos usar en nuestros montajes de Arduino. En general son componentes muy baratos. Su precio varía en función del modelo y características, pero un precio habitual es 0.01 – 0.02€.

Entre los muchos modelos disponibles, algunos habituales son el N2222, el BC337, el BC556 o el TIP41C.

CONECTAR CARGAS INDUCTIVAS

Al conectar cargas inductivas, bobinas, electroimán, motores, relés, debemos poner un dispositivo de protección adicional, el diodo de Flyback.

Las cargas inductivas presentan una oposición a variaciones en la corriente que los atraviesa, para lo cual generan una corriente inducida que se opone a las variaciones de intensidad. Estas corrientes inducidas pueden dañar el transistor o incluso el pin de Arduino.

El diodo de flyback proporciona un camino de baja resistencia que permite disipar las corrientes inducidas por las cargas inductivas, protegiendo el resto de dispositivos.

arduino-flyback

Por tanto, en el caso de cargas inductivas el montaje quedaría de la siguiente forma.

arduino-transistor-bjt-montaje-flyback

PAR DARLINGTON

Para obtener relaciones de amplificación mayores a las de un BJT podemos usar un par Darlington, un dispositivo basado en los transistores BJT, ampliamente empleado en electrónica.

En esencia, un par Darlington es un conjunto formado por dos BJT en un único integrado.

arduino-transistor-par-darlington

El comportamiento global de un par Darlington es similar a un BJT en el que los hFE se multiplican, llegando a valores de 5000-20000.

Por contra, la tensión de base se suma por lo que los valores típicos de Vce son en torno a 1.4V.

Igualmente, existen múltiples modelos de par Darlington. Su precio es superior al de un transistor BJT, pero siguen siendo dispositivos baratos. El rango habitual es de 0,10 a 0,20€.

Entre los muchos modelos disponibles, algunos habituales son el TIP140, el BC317, y el integrado ULN2003, que dispone de 7 par Darlington en un único integrado.

TRANSISTORES BJT EN PWM

Los transistores BJT son apropiados para salidas PWM, por lo que pueden ser controlados con las salidas analógicas (PWM) de Arduino.

El resultado será una onda pulsada entre Vcc y GND, con la misma frecuencia que el PWM.

Únicamente deberemos comprobar que la frecuencia de conmutación del transistor elegido es superior a la frecuencia del PWM que apliquemos.

EJEMPLO DE CÓDIGO

El código a emplear es exactamente el mismo que el que vimos al ver las salidas digitales y salidas analógicas PWM en Arduino, por lo que os referimos a los ejemplos de estas entradas.

La etapa de transistor únicamente nos permite adaptar la tensión y la corriente de salida a valores superiores a los que podríamos proporcionar directamente con las salidas de Arduino.

Si te ha gustado esta entrada y quieres leer más sobre Arduino puedes consultar la sección Tutoriales de Arduino

Medir temperatura de líquidos y gases con Arduino y DS18B20

$
0
0
arduino-ds18b20
arduino-ds18b20

¿Qué es un sensor DS18B20?

El DS18B20 es un sensor de temperaturas fabricado por la compañía Maxim Integrated. Proporciona la salida mediante un bus de comunicación digital que puede ser leído con las entradas digitales de Arduino.

Originalmente el sensor DS18B20 era fabricado por la empresa Dallas Semiconductor, que fue comprada por Maxim Integrated en 2001. Por ese motivo aún encontraréis referirse a este dispositivo como Dallas DS18B20, así como en Sketch y librerías.

El sensor DS18B20 es un sensor barato y, sin embargo, bastante avanzado. Dispone de un rango amplio de medición de -55ºC a +125ºC y una precisión superior a ±0.5°C en el rango –10°C de +85°C.

Una de las ventajas del DS18B20 es que se comercializa tanto en un integrado TO-92 como en forma de sonda impermeable, lo que permite realizar mediciones de temperatura en líquidos y gases.

El DS18B20 emplea un bus de comunicación denominado 1-Wire propietario de la empresa Maxim Integrated, aunque podemos usarlo sin tener que pagar por ninguna tasa (es parte del precio del dispositivo).

La principal ventaja del bus 1-Wire es que necesita un único conductor para realizar la comunicación (sin contar el conductor de tierra). Los dispositivos pueden ser alimentados directamente por la línea de datos, o mediante una línea adicional con una tensión de 3.0 a 5.5V.

Dentro del mismo bus 1-Wire podemos instalar tantos sensores como deseemos. Además, el bus 1-Wire permite emplear cables más largos que otros sistemas antes de que se deteriore la comunicación.

El DS18B20 también dispone de un sistema de alarma que permite grabar en la memoria no volátil del DS18B20 los limites inferiores y superiores. El bus 1-Wire permite consultar si algún dispositivo conectado ha activado una alarma.

El DS18B20 es un gran sensor para la medición de temperatura, tanto en ambientes domésticos como industriales. Sus características permiten crear redes con gran número de sensores para controlar, por ejemplo, la climatización o el sistema HVAC de un edificio comercial.

Precio

El DS18B20 es un sensor barato y excelente en calidad / precio. Podemos encontrarlo en su versión integrado TO-92 por 0.45€, y por 1€ en la versión sumergible, buscando en vendedores internacionales en eBay y AliExpress.

arduino-ds18b20-componente

¿Cómo funciona el DS18B20?

Como hemos dicho, internamente el sensor DS18B20 es más complicado de lo que en principio podríamos creer. Está formado por un procesador con múltiples módulos, que se encargan de controlar la comunicación, medir la temperatura, y gestionar el sistema de alarmas.

arduino-ds18b20-funcionamiento

Una de las principales ventajas de DS18B20 es su bus de comunicación 1-Wire que le permite realizar la transmisión empleando únicamente un cable de datos. Para ello, 1-Wire está basado en un complejo sistema de timings en la señal, entre el dispositivo emisor y el receptor.

La señal de comunicación empleada en 1-Wire, así como sus timings, son realmente largas y complejas. Para más información, consultar el Datasheet del dispositivo.

La mayor desventaja del sistema 1-Wire es que requiere un código complejo, lo que a su vez supone una alta carga del procesador para consultar el estado de los sensores. El tiempo de adquisición total de una medición de 750ms.

El dispositivo 1-Wire permite que todos los dispositivos conectados al bus se alimenten a través de la línea de datos. Para ello, disponen de un condensador que almacena energía mientras la línea de datos está en HIGH. Este modo se denomina “modo parásito”. En caso de no usar el modo parásito, los dispositivos deberán ser alimentados a una tensión entre 3.0V y 5.5V.

En cualquier caso, el bus 1-Wire requiere una resistencia de pull-up de 4k7 entre Vcc y Vq para que funcione correctamente.

Para poder dispone de múltiples dispositivos en un bus 1-Wire cada sensor dispone de una memoria ROM que es grabada de fábrica con un número de 64 bits. Los 8 primeros bits corresponden a la familia (0x28 para el DS18B20). Los siguiente 48 bits son el número de serie único. Los últimos 8 bits son un código CRC.

arduino-ds18b20-one-wire

Esto significa que potencialmente podríamos llegar a tener 2^48 (más de 218 billones) de DS18B20 conectados en una misma red 1-Wire, además de otros tantos dispositivos de otras familias (2^28, unos 268 millones de familias de dispositivos posibles). A efectos prácticos, esto supone infinitos dispositivos.

La resolución del DS18B20 es configurable a 9, 10, 11 o 12 bits, siendo 12 bits el modo por defecto. Esto equivale a una resolución en temperatura de 0.5°C, 0.25°C, 0.125°C, o 0.0625°C, respectivamente.

Que el DS18B20 disponga de una resolución por defecto de 0.0625ºC, no significa que esa sea su precisión. Sin embargo, el DS18B20 es considerablemente preciso en todo el rango –10°C de +85°C. Podéis consultar las desviaciones medias a 3 sigma en la siguiente gráfica.

arduino-ds18b20-precision

Esquema de montaje

Los dispositivos 1-Wire disponen de tres terminales

  • Vq, la línea de datos
  • Vdd, línea de alimentación
  • GND, línea de tierra

En la siguiente imagen figura la posición de estos pines en ambos formatos del sensor, como integrado y como sonda impermeable.

arduino-ds18b20-patillaje

Hemos comentado que el bus 1-Wire necesita una resistencia de pull-up de 4K7, y que podemos alimentar el sensor directamente a través del pin Vdd o usar el modo “parásito” y alimentarlo con la propia línea de datos.

Por tanto, el esquema más simple de conexión se muestra en la siguiente imagen, donde podemos conectar el sensor a cualquier entrada digital de Arduino.

arduino-ds18b20-esquema

Si representamos el mismo montaje, añadiendo la disposición que ocuparían los sensores adicionales (en caso de necesitarlos) observamos más claramente la estructura del bus 1-Wire.

arduino-ds18b20-montaje

Finalmente, si quisiéramos emplear el modo parásito, simplemente tenemos que conectar Vdd de todos los dispositivos a GND. De esta forma, los sensores tomarán su alimentación de la línea de datos Vq. El montaje con el modo parásito quedaría así.

arduino-ds18b20-montaje-parasito

Ejemplos de código

Para poder leer las temperaturas del DS18B20, necesitamos usar la librería 1-Wire y la librería Dallas Temperature.

En el primer ejemplo, leeremos un único sensor ubicado en el pin digital 5.

#include 
#include 

const int oneWirePin = 5;

OneWire oneWireBus(oneWirePin);
DallasTemperature sensor(&oneWireBus);

void setup() {
	Serial.begin(9600);
	sensor.begin(); 
}

void loop() {
    Serial.println("Leyendo temperaturas: ");
	sensor.requestTemperatures();

	Serial.print("Temperatura en sensor 0: ");
	Serial.print(sensor.getTempCByIndex(0));
	Serial.println(" ºC");

	delay(1000); 
}

Al usar la función getTempCByIndex, el indice es el número del sensor. Con esta función podemos leer más de un sensor instalado en un bus, pero tendríamos problemas para saber qué sensor es qué índice.

Por tanto, en caso de tener múltiples sensores lo normal es que accedamos directamente por la dirección de 64 bits del dispositivo. Para saber esta dirección, tenemos que usar el siguiente sketch, que escanea el bus 1-Wire y muestra en la pantalla su dirección en hexadecimal (agrupada en 8 números de dos dígitos).

#include 

const int oneWirePin = 5;
OneWire oneWireBus(oneWirePin);

void setup(void) {
  Serial.begin(9600);
  discoverOneWireDevices();
}

void discoverOneWireDevices(void) {
  byte i;
  byte present = 0;
  byte data[12];
  byte addr[8];
  
  Serial.println("Buscando dispositivos 1-Wire");
  while(ds.search(addr)) {
    Serial.println("Encontrado dispositivo 1-Wire en direccion");
    for( i = 0; i < 8; i++) {
      Serial.print("0x");
      if (addr[i] < 16) {
        Serial.print('0');
      }
      Serial.print(addr[i], HEX);
      if (i < 7) {
        Serial.print(", ");
      }
    }
    if ( OneWire::crc8( addr, 7) != addr[7]) {
        Serial.print("Error en dispositivo, CRC invalido!\n");
        return;
    }
  }
  Serial.println("Búsqueda finalizada")
  ds.reset_search();
  return;
}

void loop(void) {
  // nada que hacer aqui
}

Una vez que tengamos las direcciones de los dispositivos, podríamos realizar la lectura de múltiples sensores en el mismo bus 1-Wire.

En el siguiente ejemplo realizamos la lectura de dos sensores de los cuales ya hemos obtenido su dirección, uno en el interior y otro en el exterior de una vivienda, accediendo a través de su dirección.

#include 
#include 

const int oneWirePin = 5;

OneWire oneWireBus(oneWirePin);
DallasTemperature sensors(&oneWireBus);

DeviceAddress insideThermometer = { 0x28, 0x94, 0xE2, 0xDF, 0x02, 0x00, 0x00, 0xFE };
DeviceAddress outsideThermometer = { 0x28, 0x6B, 0xDF, 0xDF, 0x02, 0x00, 0x00, 0xC0 };

void setup(void)
{
  Serial.begin(9600);
  sensors.begin();
  sensors.setResolution(insideThermometer, 10);
  sensors.setResolution(outsideThermometer, 10);
}

void printTemperature(DeviceAddress deviceAddress)
{
  float tempC = sensors.getTempC(deviceAddress);
  if (tempC == -127.00) {
    Serial.print("Error getting temperature");
  } else {
    Serial.print(tempC);
	Serial.println(" ºC");
  }
}

void loop(void)
{ 

  Serial.println("Leyendo temperaturas");
  sensors.requestTemperatures();
  
  Serial.print("Temperatura interior: ");
  printTemperature(insideThermometer);
  Serial.print("Temperatura exterior: ");
  printTemperature(outsideThermometer);
  Serial.println("-------");
  
  delay(2000);
}

Si te ha gustado esta entrada y quieres leer más sobre Arduino puedes consultar la seccióntutoriales de Arduino

Detector de llama con Arduino y sensor infrarrojo

$
0
0
arduino-sensor-llama
arduino-sensor-llama

¿Qué es un sensor de llama infrarrojo?

Un sensor de llama óptico es un dispositivo que permite detectar la existencia de combustión por la luz emitida por la misma. Esta luz puede ser detectada por un sensor óptico, y ser capturado por las entradas digitales y las entradas analógicas de Arduino.

La llama es un fenómeno de emisión de luz asociado a los procesos de combustión. La combustión es un proceso que desprende grandes cantidades de energía en forma de calor. Durante la reacción se generan compuestos intermedios que liberan parte de su energía mediante la emisión de luz.

El espectro de emisión de llama depende de los elementos que intervienen en la reacción. En el caso de combustión de productos con carbón en presencia del oxígeno tenemos dos picos característicos en ultravioleta en longitudes de onda de 185nm-260nm y en infrarrojo en longitudes de onda 4400-4600nm.

arduino-sensor-llama-espectro

Los sensores de llama son ampliamente utilizados en la industria. Muchas máquinas ejecutan procesos susceptibles de generar llamas, como por ejemplo procesos de mecanizado o de electroerosión. Frecuentemente se realizan en presencia de elementos combustibles como aceite o viruta.

Por este motivo se incorporan sensores de llaman como dispositivo de seguridad, permitiendo detener el proceso en caso de detectar cualquier indicio de combustión. Estos dispositivos se ajustan a las longitudes de onda características de la aparición de la llama y normalmente combinan las señales ultravioleta y de infrarrojo.

En el campo de los hobbies podemos encontrar sensores de llama baratos. Frecuentemente estos sensores constan únicamente de un sensor infrarrojo ajustado a 760-1100 nm. El ángulo de detección es de 60º, y la distancia de detección entre 0.40 m a 0.80.

Este tipo de sensores de llama infrarrojos suelen incorporar una placa de medición estándar con el comparador LM393, que permite obtener la lectura tanto como un valor analógico como de forma digital cuando se supera un cierto umbral, que se regula a través de un potenciómetro ubicado en la placa.

arduino-sensor-llama-sensitividad

Como vemos, las longitudes de onda de estos sensores baratos poco tienen que ver con las emisiones características de las llamas y de los sensores industriales. De hecho, son afectados incluso por la iluminación interior, dando lugar a numerosos falsos positivos.

Por tanto, la sensibilidad y fiabilidad de estos detectores baratos no son suficientes para considerarlos un auténtico dispositivo de seguridad, aunque pueden ser interesantes en pequeños proyectos de electrónica y con fines didácticos, como por ejemplo hacer sonar una alarma o activando un LED al detectar la llama de un mechero.

No empleéis sensores sin las certificaciones oportunas en montajes de los cuales dependan la seguridad de personas o equipamientos.

Precio

Los sensores de llama infrarrojos caseros son dispositivos baratos. Podemos encontrarlos, incluida la placa de medición, por 0,65€ en vendedores internacionales de Ebay y Aliexpress.

arduino-sensor-llama-componente

Esquema de montaje

El esquema eléctrico es sencillo. Alimentamos el módulo conectando GND y 5V a los pines correspondientes de Arduino.

Ahora si queremos usar la lectura digital, conectamos la salida DO a una de las entradas digitales de Arduino.

arduino-sensor-llama-esquema

Mientras que la conexión vista desde Arduino quedaría así,

arduino-sensor-llama-montaje

Si quisiéramos emplear el valor analógico, simplemente conectaríamos la salida AO del sensor a una entrada analógica de Arduino.

Ejemplos de código

El código necesario es igualmente sencillo. Si estamos empleando la señal digital, empleamos una entrada digital para leer el estado. En el ejemplo mostramos un mensaje por la pantalla, pero en un caso real ejecutaríamos las acciones oportunas.

const int sensorPin = 9;

void setup()
{
   Serial.begin(9600);
   pinMode(sensorPin, INPUT);
}

void loop()
{
   int humedad = digitalRead(sensorPin);

   //mandar mensaje a puerto serie en función del valor leido
   if (humedad == HIGH)
   {
      Serial.println("Detección");   
      //aquí se ejecutarían las acciones
   }
   delay(1000);
}

Si estamos empleando la señal analógica AO, leemos el valor mediante la entrada analógica, y usamos el puerto de serie para mostrar el valor por pantalla. En un caso real, este valor se emplearía para ejecutar acciones, en lugar de mostrar el valor.

const int sensorPin = A0;

void setup() {
   Serial.begin(9600);
}

void loop() 
{
   int measure = analogRead(sensorPin);
   Serial.println(measure);
  
   if(measure < 500)
   {
      Serial.println("Detección");  
      //hacer las acciones necesarias
   }
   delay(1000);
}

Si te ha gustado esta entrada y quieres leer más sobre Arduino puedes consultar la seccióntutoriales de Arduino

Medir campos magnéticos con Arduino y sensor Hall lineal 49E

$
0
0
arduino-sensor-hall-49e
arduino-sensor-hall-49e

¿Qué es un sensor Hall?

Un sensor Hall es un dispositivo que nos permite realizar mediciones de campo magnético.

Los sensores Hall son ampliamente utilizados. Por ejemplo, en la industria del automóvil se usan para funciones tan dispares como para el accionamiento de los cinturones de seguridad, o la medición de la posición del árbol de levas. También se usan para medir velocidades de fluidos, detección de metales, factores de inducción, entre otras muchas aplicaciones.

Una ventaja importante de los sensores Hall es que realizan la medición a distancia, sin necesidad de contacto físico. Aunque su alcance es limitado (típicamente pocos centímetros) esto supone que apenas presentan desgaste mecánico. Además son inmunes a ruidos y polvo. Esto los convierte en sensores fiables y duraderos.

En general, encontramos dos tipos de sensores Hall:

  • Analógicos. Generan una salida proporcional a la intensidad del campo magnético. Empleados para medir la intensidad de un campo magnético
  • Digitales. Proporcionan un valor Alto en presencia de campo magnético, y bajo en ausencia del mismo. Por tanto, son empleados para detectar la existencia de campos magnéticos. A su vez se dividen en,
    • Switch, se activan al acercar el polo, y se desactivan al retirar el polo
    • Latch, se activan al acercar un polo, y mantienen su valor hasta que se acerca un polo contrario

En esta entrada emplearemos un sensor Hall 49E, de tipo analógico. Podemos emplear este sensor para detectar la presencia de un objeto, al que previamente habremos colocado un pequeño imán, o para fabricar tacómetros (contadores de revoluciones) simplemente acoplando un pequeño imán de neodimio al eje.

Precio

Los sensores Hall 49E son realmente baratos. Podemos encontrar 10 dispositivos A49E por 0.90€ en vendedores internacionales en eBay o AliExpress.

arduino-sensor-hall-49e-componente

¿Cómo funciona un sensor Hall?

Su principio de funcionamiento es el efecto Hall, denominado así por su descubridor Edwin Herbery Hall, en 1849.

Al hacer circular una corriente eléctrica a lo largo de un semiconductor en presencia de un campo magnético, los electrones son desviados por efecto del campo magnético, dando lugar a una tensión perpendicular a la corriente y al campo magnético.

efecto-hall

Midiendo esta tensión originada por el efecto Hall podemos conseguir construir sensores y medidores de campos magnéticos.

La familia de sensores Hall 49E incorporan la electrónica necesaria para dar una respuesta de tensión lineal en el rango de -100 a 100 mT. Los circuitos están diseñados para minimizar el ruido de la señal, por lo que no es necesario filtrado externo.

arduino-sensor-hall-49e-funcionamiento

El rango operativo de temperaturas es de -40 a 85ºC, y tiene poca influencia en la medición. La sensibilidad típica a 25ºC es de 0.18 mV/mT

arduino-sensor-hall-49e-curva

Interpolando en la gráfica anterior obtenemos la siguiente expresión para la respuesta en tensión respecto al flujo magnético medido por el sensor Hall 49E,

V = 0.180 \cdot B + 2.5

O equivalentemente, invirtiendo la ecuación, llegamos a la ecuación necesaria para poder obtener la densidad de flujo magnético a partir de la respuesta del sensor,

B = 53.33 \cdot V - 133.3

Esquema eléctrico

El esquema eléctrico que necesitamos es el siguiente.

arduino-sensor-hall-49e-esquema

Por lo que el esquema de conexión con Arduino quedaría así.

arduino-sensor-hall-49e-montaje

El esquema y valores de resistencias mostrador corresponden con el sensor 49E. Otros sensores hall requieren otros esquemas de montaje. Consultar su datasheet correspondiente si vuestro componente es distinto.

Montaje

Mientras que el montaje en una protoboard sería el siguiente.

arduino-sensor-hall-49e-montaje

Ejemplo de código

Para poder calcular el campo magnético a partir de la medición, en primer lugar medimos el voltaje mediante una entrada analógica de Arduino. A continuación convertimos el voltaje en densidad de flujo magnético usando la fórmula que hemos interpolado anteriormente.

const int pinHall = A0;

void setup() {
  pinMode(pinHall, INPUT);
  Serial.begin(9600);
}

void loop() {

  //media de 10 medidas para filtrar ruido
  long measure = 0;
  for(int i = 0; i < 10; i++){
      int value = 
      measure += analogRead(pinHall);
  }
  measure /= 10;
  
  //calculo del voltaje en mV
  float outputV = measure * 5000.0 / 1023;
  Serial.print("Output Voltaje = ");
  Serial.print(outputV);
  Serial.print(" mV   ");
  
  //interpolacion a densidad de flujo magnético
  float magneticFlux =  outputV * 53.33 - 133.3;
  Serial.print("Magnetic Flux Density = ");
  Serial.print(magneticFlux);
  Serial.print(" mT");
  
  delay(2000);
}

Si te ha gustado esta entrada y quieres leer más sobre Arduino puedes consultar la sección Tutoriales de Arduino

Aprendemos a medir campos magnéticos con Arduino y el sensor Hall Lineal 49E

Viewing all 1123 articles
Browse latest View live