miércoles, 26 de noviembre de 2014

Resistencias pull-up y pull-down

Hola de nuevo,


Después de unas entregas de toma de contacto, es hora de avanzar un paso más. Hasta ahora, hemos conseguido que nuestra placa haga lo que le hemos dicho, pero no ha habido interactuación. Le cargamos un programa, y desde el momento que lo recibe lo ejecuta indefinidamente, hasta que la desconectamos de la alimentación. Es decir, no podemos decidir cuándo ejecutar o parar la aplicación.
En esta entrada veremos cómo comunicarnos con el Arduino a través de unos pulsadores.

Pero antes de nada… sí exacto, un poco de teoría.

Cuando queremos comunicarnos a través de un pulsador, lo que acaba recibiendo nuestra placa son “0” ó “1”.  Pero conseguir esto no es tan sencillo como conectar un pulsador entre la alimentación y nuestra entrada, puesto que cuando no estuviese pulsado nuestro Arduino no recibiría un “0”, sino un estado indeterminado que lo haría inestable e impredecible.


Por lo tanto, necesitamos fijar un valor en la entrada digital para tener un valor por defecto. Para tal fin se usan dos tipos de montaje.

La resistencia “pull-up”, que establece un nivel alto (1) en reposo. Veamos el montaje:



En este caso, con el pulsador abierto, no hay paso de corriente y la entrada digital ve directamente la fuenta de alimentación, es decir los 5V (1).
Cuando pulsamos el interruptor, cerramos el circuito y por tanto la entrada digital está directamente conectada a masa (0). La resistencia es necesaria en este montaje para no cortocircuitar la fuente.


La resistencia “pull-down”, que establece un nivel bajo (0) en la entrada digital en estado de reposo y un nivel alto (1) cuando pulsamos. Este es el montaje más habitual. Un ejemplo:



El funcionamiento en reposo, con el interruptor abierto no hay paso de corriente, por tanto no hay caída de potencial en la resistencia y la entrada digital “ve” masa, es decir está a “0”. Cuando pulsamos y cerramos el circuito, se produce una caída de tensión en R1 por el paso de la corriente. Esta caída de tensión , que son los 5V directos de la fuente es lo que ve nuestra entrada digital, y por tanto estará a “1” mientras esté pulsado.

En este tipo de montajes se suele usar resistencias de 10K para controlar el consume de corriente del circuito.


El pulsador es una chapa metálica, que al pulsarla flexa y toca los contactos cerrando el circuito. Pero al liberarlo normalmente se producen unos rebotes, que en aplicaciones de precisión puede provocar “falsos positivos”. Para estos casos, se mejora el circuito añadiendo un pequeño condensador entre la entrada y masa. De esta forma:





En este montaje el condensador se carga cuando pulsamos, y al dejar de pulsar “filtra” los rebotes del contacto metálico. El inconveniente es que deberá descargarse el condensador para que el Arduino pueda obedecer a otra pulsación.

Se puede considerar que la entrada estará otra vez a un nivel 0, después de 5 veces la constante de tiempo de descarga del condensador. Si usamos una R de 10K y un condensador de 100nF, sería:


T = R x C = 10.000 x 0.00000001 = 0,1 ms Constante de carga

                5 T = 0,5 ms  Tiempo necesario entre pulsaciones


Obviamente, 0,5 milisegundos entre pulsaciones es un tiempo más que aceptable y que podemos dar por válido.


De todas maneras para nuestros ejemplos no montaremos ningún condensador, puesto que los tiempos de ejecución del programa superan el posible transitorio producido por el rebote del pulsador.

En la próxima entrada programaremos el Arduino para leer entradas.

sábado, 22 de noviembre de 2014

Uso de bucles. La instrucción for

Ejemplo 1_2

En esta entrada quiero explicar un tipo de bucle muy típico en programación. Se trata del bucle
for.
Este tipo de recurso se usa cuando queremos repetir n  número de veces un evento dentro del programa. Repetirlo a base de copiar el mismo código n veces cómo el día anterior tiene varios inconvenientes:
-        Es muy pesado, efectivamente, y aunque uses el clásico copiar y pegar,
-        También es ineficiente desde un punto de vista de programación, puesto que hace el código más largo, y la memoria de nuestro Arduino está muy limitada.
¿Cómo quedaría la secuencia de encendido, nuestro  void loop, con este recurso? Primero un vistazo al código anterior:


void loop()
{
  digitalWrite(2,HIGH);
  delay(d);
  digitalWrite(2,LOW);
  digitalWrite(3,HIGH);
  delay(d);
  digitalWrite(3,LOW);
  digitalWrite(4,HIGH);
  delay(d);
  digitalWrite(4,LOW);
  digitalWrite(5,HIGH);
  delay(d);
  digitalWrite(5,LOW);
}


Y ahora usando el for,  el ejemplo completo:




//Ejemplo1.2 versión para explicar el uso del for para realizar procesos repetitivos
//sobre el ejemplo anterior de "la ola ". La declaración de entradas y salidas es la misma
//el cambio será a la hora de encenderlas que lo haremos usando la instrucción for

int d=1000; // constante de tipo integer, que define el tiempo de delay

void setup()

{
  pinMode(2,OUTPUT); //Pin 2 conectado al led 1, definido como salida
  pinMode(3,OUTPUT); //Pin 3 conectado al led 2, definido como salida
  pinMode(4,OUTPUT); //Pin 4 conectado al led 5, definido como salida
  pinMode(5,OUTPUT); //etc...
}

Void loop()
{
For ( int a = 2;  a < 6; a++)
{
digitalWrite(a,HIGH);
delay (d);
digitalWrite(a,LOW);
delay (d);
}
}
                 
Analicemos el bucle:
for ( int a = 2; a < 6 ; a++ )
   {
digitalWrite(a, HIGH);
delay(d);
digitalWrite(a, LOW);
delay(d);
   }
}



Detrás de la instrucción for, entre paréntesis expresamos las condiciones del bucle.
Primero definimos una variable, a, y le asignamos un valor inicial.  Seguidamente le decimos cual es la condición que debe cumplir esa variable para salir del bucle, que sea más pequeña que 6, y cuanto tiene que incrementar en cada repetición, en este caso contar de 1 en 1, a++.
Después entre corchetes se encuentra las acciones que se realizarán todas las veces que se ejecute el bucle. Cómo tenemos los leds conectados entre los pines 2 y 6 lo que hacemos es dar una variable, el valor inicial de 2 e ir incrementándolo hasta llegar al último. Este código es equivalente al anterior, pero se aprecia rápidamente que incrementar el nº de leds es muchísimo más sencillo. También observamos que incrementar el número de salidas no incrementa la longitud del código.

El ejemplo para descarga, lo tienes en el enlace. Como siempre, intenta teclearlo tú:

Ejercicio 1.2 de arduino práctico

Los bucles también se pueden definir para realizar una cuenta regresiva. En ese caso utilizaremos el valor a--. En nuestro ejemplo, el bucle podría quedar de la siguiente manera:


for ( int a = 6; a <  2 ; a-- )
   {
digitalWrite(a, HIGH);
delay(d);
digitalWrite(a, LOW);
delay(d);
   }
}

Esta versión la tienes disponible en el siguiente enlace:

Ejercicio 1.2b de Arduino práctico

En este caso, los leds describirían la secuencia en sentido inverso, y con la sentencia a— en cada paso restaremos 1, hasta llegar a 2.

Pincha en el video para apreciar la diferencia:

lunes, 17 de noviembre de 2014

Uso de variables


Hoy usaremos el mismo montaje de la anterior entrada e intentaremos dar una vuelta de tuerca al ejemplo del día anterior y de paso avanzar un poco en técnicas de programación.

El otro día definimos un retraso de 1 segundo entre cada orden de encendido. ¿Qué pasaría si quisiéramos modificar este valor? Podemos hacer cómo el primer ejemplo, y modificarlo en cada parte del programa que aparezca, o usar una variable.
Veamos como quedaba el otro día el void loop:


{
  digitalWrite(2,HIGH);// Encendemos el Led 1 poniendo su salida en 1, HIGH
  delay(1000); //Espera de un segundo
  digitalWrite(2,LOW);//Apagamos el Led 1 poniendo su pina a 0, o LOW
  digitalWrite(3,HIGH);//Repetimos los mismo pasos hasta el led 4
  delay(1000);
  digitalWrite(3,LOW);
  digitalWrite(4,HIGH);
  delay(1000);
  digitalWrite(4,LOW);
  digitalWrite(5,HIGH);
  delay(1000);
  digitalWrite(5,LOW);
}


En esta caso tendría que ir a modificar cada línea de forma individual, o tener una variable con un valor, y modificando tan solo ese valor, automáticamente se cambiaría en todos los puntos que se use. Quedaría algo así el sketch completo:



//Ejemplo1.1 versión para explicar el uso de variables para parámetros repetitivos
//sobre el ejemplo 1
int d=1000; // variable de tipo integer, que define el tiempo de delay

void setup()

{
  pinMode(2,OUTPUT); //Pin 2 conectado al led 1, definido como salida
  pinMode(3,OUTPUT); //Pin 3 conectado al led 2, definido como salida
  pinMode(4,OUTPUT); //Pin 4 conectado al led 5, definido como salida
  pinMode(5,OUTPUT); //etc...
}
void loop()
{
  digitalWrite(2,HIGH);// Encendemos el Led 1 poniendo su salida en 1, HIGH
  delay(d); //Espera de un segundo
  digitalWrite(2,LOW);//Apagamos el Led 1 poniendo su pina a 0, o LOW
  digitalWrite(3,HIGH);//Repetimos los mismo pasos hasta el led 4
  delay(d);
  digitalWrite(3,LOW);
  digitalWrite(4,HIGH);
  delay(d);
  digitalWrite(4,LOW);
  digitalWrite(5,HIGH);
  delay(d);
  digitalWrite(5,LOW);
 //final del Loop, ahora volverá al incicio del bucle,
 //y se repetirá indefinidamente
}


Ahora, cambiando en el código el valor de d, cambiaría en todo el programa a la vez. En este caso hemos usado una variable del tipo int o integer. Este tipo de variable puede contener un número entero comprendido entre -32.768 y 32.767. Modificar ahora el tiempo de destello es mucho más sencillo.

En el video se puede observar como cada cambio, del valor de d se aplica inmeditamente en todo el programa:



Ya iremos profundizando en el tipo y uso de variables conforme vayamos avanzando. De momento conserva este montaje, que mañana intentaremos mejorarlo un poco más.

viernes, 14 de noviembre de 2014

Ejemplo 1_1. “La ola”

Para el siguiente montaje usaremos unos Leds como salida de nuestro circuito. Un led es un tipo de semiconductor pasivo que emite luz al paso de una corriente. LED, es la abreviación del inglés de Light-emitting diode. El símbolo que se usa en electrónica para representarlo es el siguiente:



El diodo led no puede ir conectado directamente a la salida del arduino, pues aunque es da baja potencia, lo acabaría fundiendo. Por lo tanto se ha interponer una resistencia para limitar la corriente que lo atraviesa. Haremos el cálculo sencillo del valor de la resistencia, y de paso repasamos un poco la ley de Ohm.
Para un diodo standard , supondremos una caída de potencial entre el ánodo y el cátodo de 1,7V. La corriente máxima admisible dependerá también del modelo, para este caso utilizaremos un valor inferior a los 20mA, en concreto 15mA.
La caída de tensión en la resistencia será por tanto :
Vr = Vcc-Vled = 5 - 1.7= 3.3V
Si tenemos el valor de la caída de tensión y la corriente que atraviesa la malla, despejando la R, de la fórmula V=IxR, quedaría:
R= V/I = 3,3/0.15 = 220Ω
En este caso, como coincide con un valor normalizado, usaremos para el montaje resistencias de 220Ω.
¡Qué coincidencia! Son justamente las que tengo en casa. Bueno en cualquier caso, podemos usar “cualquier valor” por encima de los 220Ω, con la única limitación del brillo que emitirá el led, pero ser razonables, no pongáis resistencias de 100kΩ, y preguntéis por qué no se enciende el led si hemos seguido el montaje al dedillo.
Valores por debajo, son contraproducentes, porque elevarán el consumo de nuestro diseño, y fundirán leds constantemente.
Está bien, una vez hemos explicado el por qué de los valores que hemos escogido pasaremos a definir el proyecto de hoy.



Encendido secuencial de leds. “La ola”

Este proyecto es un ejercicio muy común de inciación. Pero nos debería ayudar a planificar como enfrentarnos a cualquier proyecto a partir de ahora, con unas pautas que facilitarán enormemente el conseguir el objetivo final.

  •      Definir un objetivo. Es básico saber qué queremos conseguir. Cualquier modificación sustancial        durante la ejecución del proyecto seguramente nos obligue a volver al punto 1, y alargue el plazo y    aumente los costes. A lo mejor sólo es tu hobby, pero aplica todos los aspectos de la vida.

  •    .     Escribe tu algoritmo. No confundir con escribir el código del programa. El algoritmo son las   instrucciones que deberá seguir el flujo del programa, paso a paso. Intenta en este punto contemplar   todas las incidencias posibles.

  •       Selecciona el hardware necesario, ahora ya sabes cuantas entradas y salidas necesitas y cómo        puedes conectarlas.

  •     Escribe el código. Ahora ya puedes transformar tu algoritmo en el programa. El algoritmo viene a     ser como un boceto de un dibujo, y el programa el arte final.

  •      Crea el circuito, conecta todos los elementos de tu hardware con tu Arduino    

  •          Puesta en marcha y depuración de fallos. ¿Funciona tal y cómo esperabas? ¿No? Es momento de localizar los errores en el hardware o la programación.


Volviendo a nuestro proyecto de hoy. ¿Qué queremos conseguir? El encendido y apagado de 4  leds de manera secuencial.

El algoritmo podría ser algo parecido:

  1.- Encender el led 1
  2.- Esperar 1 segundo, y apagarlo
  3.- Encender el led 2
  4.- Esperar 1 segundo, y apagarlo
  5.- Continuaría así hasta el led 4 , momento en que saltaríamos al led 1
  6.- Repetir el bucle indefinidamente.

El hardware necesario:  

  •     4 leds de colores
  •     4 resistencias de 220Ω
  •     Una protoboard y cablecillo rígido
  •     Un arduino y su cable USB

Siguiente paso, escribir nuestro código:


  
// Ejemplo 1 - Secuencia de ON-OFF de 4 Leds "La ola"
// Definimos las salidas de nuestro proyecto en el setup

void setup()
{
  pinMode(2,OUTPUT); //Pin 2 conectado al led 1, definido como salida
  pinMode(3,OUTPUT); //Pin 3 conectado al led 2, definido como salida
  pinMode(4,OUTPUT); //Pin 4 conectado al led 5, definido como salida
  pinMode(5,OUTPUT); //etc...
}
void loop()
{
  digitalWrite(2,HIGH);// Encendemos el Led 1 poniendo su salida en 1, HIGH
  delay(1000); //Espera de un segundo
  digitalWrite(2,LOW);//Apagamos el Led 1 poniendo su pina a 0, o LOW
  digitalWrite(3,HIGH);//Repetimos los mismo pasos hasta el led 4
  delay(1000);
  digitalWrite(3,LOW);
  digitalWrite(4,HIGH);
  delay(1000);
  digitalWrite(4,LOW);
  digitalWrite(5,HIGH);
  delay(1000);
  digitalWrite(5,LOW);
 //final del Loop, ahora volverá al incicio del bucle,
 //y se repetirá indefinidamente
}



Seguidamente tocará cablear nuestro prototipo, siguiendo el siguiente esquema:



Una propuesta para el conexionado en la protoboard podría ser esta, donde minimizamos la cantidad de cable a emplear.


Podéis hacer copy-paste sobre el programa y pegarlo en Arduino. De todas maneras yo recomiendo entrarlo a mano e ir aprendiendo de nuestros errores. Por si algo os falla, os dejo un enlace directo al sketch ya depurado y comprobado.

Programa Ejemplo 1_1

Deberíais obtener un resultado similar al que muestra el video del siguiente enlace.


La modificación del sketch corresponde a la siguiente entrada, así que no desmontéis el circuito, que lo usaremos en la siguiente entrada. 


martes, 11 de noviembre de 2014

Empezando con Arduino

Éste es el primero de una serie de posts que irán descubriendo poco a poco el uso de microcontroladores para realizar diferentes tareas. Éstas irán creciendo en dificultad y/o complejidad progresivamente, con la idea de ir consolidando el conocimiento  de manera gradual, y sobre todo práctica.
¿Es necesario tener  conocimientos previos de electrónica? Sí, o al menos recomendable. Aunque trataré de explicar en algunos montajes ciertas propiedades sobre los componentes nuevos que vayan apareciendo, no profundizaré en ello, con lo que puede que queden algunas lagunas. En cualquier caso se admiten preguntas para aclarar cualquier duda.
¿Y de programación? Estamos en el mismo caso que antes, tener ciertas nociones de programación orientada a objetos no vendría mal. El lenguaje del microcontrolador que usaré para los ejemplos, el Arduino, es muy similar al Lenguaje C de programación. Intentaré ser todo lo descriptivo posible con el código, e id añadiendo la dificultad paulatinamente.
¿Necesitaré algo más a parte del Arduino? Sí, pero es barato. Yo te recomendaría que aparte de hacer con un surtido de leds, microinterruptores, pulsadores, motores, etc. comprases una placa de pruebas “protoboard o breadboard” en inglés. Este componente de facilitará enormemente el montaje de los prototipos. Puedes contemplar la idea de hacerte con un kit.
¿Y el hexacóptero-nuclear-radio controlado-GSM-GPS-APSC-ABS con junta de trócola galvanizada en qué capítulo vendrá? Lo siento, de momento no pretendo llegar a los superusers. Todo se andará, pero hay cientos de foros y webs con proyectos muy avanzados, casi todas en inglés, para ese menester. La idea de este sitio es aprender desde un nivel básico hasta…. El tiempo lo dirá. ¡Comencemos!

¿Qué es Arduino?
Es un pequeño microcontrolador “open source” que integra varias entradas y salidas para intercomunicarse con el exterior. Aquí podremos conectar interruptores, leds, motores, etc. Dispone también de un puerto USB, que puede servir de alimentación, y que hace las funciones de comunicación con el ordenador.
El lenguaje que utiliza es el Processing Language (www.processing.org), y el software que utiliza es el IDE (integrated development environment), que deberemos instalar en nuestro ordenador, desde su web (www.arduino.cc). Este software se distribuye para Windows, OSX y Linux.
El Arduino lo podemos conseguir de muchos sitios. Aunque el nombre de Arduino está reservado para los creadores, podemos encontrar clones compatibles con otras denominaciones normalmente acabadas en “duino”.
¿Merece la pena comprar un kit? Sí y no. Por precio posiblemente no, pero a cambio suelen venir con una serie de componentes, resistencias, leds, transistores, etc. que ayudan a completar muchos ejemplos. Lo dicho, si tienes alguna tienda de electrónica en tu barrio, prueba primero allí. (Luego nos quejaremos cuando busquemos un potenciómetro, esa tienda haya cerrado y esperemos un mes a que venga de China).
Una vez hechas las presentaciones, y si ya has pasado por caja, tendrás una placa con un aspecto parecido a este:



Como puedes observar, a parte del microcontrolador, tenemos el puerto USB; una entrada externa de alimentación, varios componentes que facilitan la comunicación con el PC, y las entradas y salidas.
Si ya has instalado el programa , (recuerda si no lo puedes descargar desde aquí), es momento de lanzar el programa, y conectar la placa por USB.
Como primera experiencia y para comprobar el correcto funcionamiento del arduino, cargaremos uno de los programas de ejemplo de lo que dispone el programa. Ejecutaremos el ejemplo Blink.
Archivo > Ejemplos > 01.Basics > Blink
Este programa hace parpadear el led que se encuentra en la propia placa base. Este led está conectado al puerto 13.
Demos un vistazo al código del programa. Para ello usaré una traducción del texto en inglés:

Int led = 13;                                       Definimos una constante integer con un nombre fácilmente identificable. Aprovechamos para darle un valor, en este caso el nº 13, que es el puerto donde está conectado el led de prueba.

void setup() {                                   Comenzamos la declaración de los puertos de entrada/salida,
pinMode(led, OUTPUT);            en este caso, con esta sentencia declaramos el pin led (puerto
}                                                             13), como salida (OUTPUT)

void loop() {                                      Comienza la rutina en bucle del programa. En este caso se
  digitalWrite(led, HIGH);             repetería indefinidamente. Con digitalWrite ponemos el pin
  delay(1000);                                    definido como led, a “1”, o nivel alto. Esto hará que el led se
  digitalWrite(led, LOW);              encienda. Aplicamos un retardo de 1 segundo y lo apagamos.
  delay(1000);                                    Es decir, escribimos en el pin led un “0”, o nivel bajo, y
}                                                             volvemos a aplicar un retardo de 1 segundo.


En este punto, y después de transferir el programa al Arduino, el led de la placa, debería comenzar a parpadear a intervalos de 1 segundo.
Podemos empezar a jugar un poco, y modificar el valor del delay para obtener velocidades de parpadeo diferentes, y no necesariamente simétricas. Es decir, podemos definir valores diferentes para el apagado y el encendido. No debemos olvidar transferir el programa después de cada modificación, para observar el resultado.

En este video, explico como configurar el puerto serie en el programa Arduino, como cargar y transferir el sketch. Cómo modificar los valores para cambiar el tiempo de retardo, etc



Resumiendo
·         Todo lo que pongamos en el programa o sketch, comprendido entre los signos :
/* texto
Explicativo*/
Será obviado por el compilador. De todas maneras esto facilita que el programa sea inteligible por los demás y por nosotros mismos.
Lo mismo sucede con lo que aparece en cada línea después de dos barras //.
·         Podemos definir constantes y variables antes de ejecutar el programa. Los nombres que les pongamos ayudarán a comprender el programa. Existen muchos tipos de variables, que ya iremos definiendo.
·         Digitalwrite (nº de pin, Estado) , pone a 0 ó 1 el pin seleccionado
o   Nº de pin, puede ser un número , constante o variable definida previamente, que no puede ser mayor que el número de puertos de nuestro Arduino, y que se debe corresponder con una salida real (sea un led, relé, altavoz, etc)
o   Estado, que puede tener dos valores, HIGH para encendido o 1, y LOW para apagado o 0.
·         Delay (tiempo),que puede ser número, constante o variable, aplica un retardo en el flujo del programa. El Arduino no pasará a la siguiente instrucción, hasta que cuente hasta ese número. Con la base de tiempos del Arduino UNO, 1000 equivale a 1 segundo.