Estructuras secuencial

Estructura secuenciales

Es aquella que permite la ejecución de un bloque de instrucciones de forma secuencial, es decir, una a continuación de la otra, respetando rigurosamente el orden establecido entre ellas de arriba a bajo y de izquierda a derecha.

Ejemplo

Realizar un programa para encender y apagar un diodo Led.



int pinLed=13; //Pin donde esta conectado el diodo led

void setup() // Función que se ejecuta una sola vez.
{
pinMode(pinLed, OUTPUT); // Inicializar el pin digital (pinLed) como salida.
}
void loop() // Función que se ejecuta una y otra vez, de forma ininterrumpida.
{
digitalWrite(pinLed, HIGH); // Encender el led, haciendo que el voltaje sea alto.
delay(1000); // Esperar un segundo
digitalWrite(pinLed, LOW); // Apagar el led, haciendo que el voltaje sea bajo.
delay(500); // Esperar un segundo
}

Entradas analógicas en Arduino

En esta entrada vamos a ver las entradas analógicas, su funcionamiento y características.

Son pines de entrada a los que podemos conectar periféricos que proporcionan señales eléctricas variables; por ejemplo un sensor de luz cuya tensión es proporcional a la cantidad de luz que recibe.

¿Qué es una señal analógica?

Una señal analógica es una magnitud que puede tomar cualquier valor dentro de un intervalo –Vcc y + Vcc. Por ejemplo, una señal analógica de tensión entre 0V y 5V podría valer 2,72V, o cualquier otro valor con cualquier número de decimales. Por contra, recordemos que una señal digital de tensión teórica únicamente podía registrar dos valores (en el ejemplo, 0V o 5V).

 Por norma general en los autómatas las entradas analógicas son más escasas, más lentas y más caras que las entradas digitales. En el caso de Arduino uno disponemos de un número variable de entradas analógicas, que en el caso de Arduino Uno y Mini Pro son 6 (A0, A1, A2, A3, A4, A5).

Precisión de la medición

 Para entender la precisión de una entrada analógica es necesario entender cómo funciona un conversor analógico digital (ADC), que es su componente fundamental. Un ADC es un dispositivo que convierte una medición analógica en una medición digital codificada con un número N de bits.

En el caso de Arduino Uno, Mini Pro, y Mega, las entradas analógicas disponen de 10 bits de resolución, lo que proporciona 1024 niveles digitales, lo que a 5V supone una precisión de la medición de +-2,44mV.

 Conexión de entradas analógicas en Arduino

Supongamos que dispongamos un sensor analógico que proporciona una señal analógica entre 0V a 5V.

El código para realizar la lectura es similar al que realizado para las entradas digitales. Simplemente realizamos la lectura mediante AnalogRead() y almacenamos el valor devuelto en una variable.

Ejemplo: Leer el valor de un sensor y mostrar en el monitor serie un mensaje en función del valor leído.

#define pinSensor 0; // seleccionar la entrada para el sensor A0
int valorSensor; // variable que almacena el valor (0 a 1023)

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

void loop()
{
valorSensor = analogRead(pinSensor); // realizar la lectura
//mandar mensaje al monitor serie en función del valor leído

if (valorSensor > 512)
{
Serial.println("Mayor que 2,5V");
}
else
{
Serial.println("Menor que 2,5V");
}
delay(1000);
}

 En la siguiente entrada se puede observar el uso de la utilización de las entradas analógicas para la lectura del valor devuelto por una LDR (Medidor de luz con LDR). 

Salidas analógicas PWM en Arduino

Son patillas que actúan como si fueran salidas analógicas hacia los periféricos.
Arduino Uno implementa por hardware salidas PWM en varios de sus pines, que aparecen identificados en la placa con el símbolo “~” junto al número del pin. Patillas: 11, 10, 9, 6 ,5 y 3.


En ocasiones necesitaremos proporcionar un valor analógico de tensión, por ejemplo, para regular la intensidad de iluminación de un LED, o variar la velocidad de un motor DC.

En esta entrada vamos a ver cómo utilizar una salida PWM para emular una señal analógica de tensión desde Arduino.

Lo primero que tenemos que entender es que la mayoría de automatismos (y Arduino no es una excepción) no son capaces de proporcionar una auténtica salida analógica. Ni siquiera pueden suministrar una salida analógica discretizada (es decir, a saltos) de tensión. Lo único que pueden proporcionar es una salida digital de -Vcc o Vcc. (por ejemplo, 0V y 5V).

Para salvar esta limitación y simular una salida analógica la mayoría de los automatismos emplean un “truco”, que consiste en activar una salida digital durante un tiempo y mantenerla apagada durante el resto. El promedio de la tensión de salida, a lo largo del tiempo, será igual al valor analógico deseado.

Existe más de una forma de hacer esta aproximación. Una de las más sencillas, y por ello muy empleada en automatización, es la modulación de ancho de pulso (PWM). En esta modulación se mantiene constante la frecuencia (es decir, el tiempo entre disparo de pulsos), mientras que se hace variar la anchura del pulso. 

Para generar una señal PWM en los pines digitales de la placa Arduino, hay que usar la función analogWrite(pin, valor).

Esta función nos permitirá emular una señal analógica a partir de una digital. Presenta dos variables:

Pin. Hace referencia al pin digital en el que vamos a producir la señal PWM. (pines, que aparecen identificados en la placa con el símbolo “~” junto al número del pin).
Valor. Es un número comprendido entre 0 y 255. El valor 0 corresponde a 0V de promedio y el valor 255 a 5V.

Ejemplo: Variar la intensidad de luz de un led

int pinLed=9; //Declaramos la variable donde se conectará el led

void setup()
{
pinMode(pinLed, OUTPUT);
}

void loop()
{
for( int n=0;n<256 n="" p="">{
analogWrite(pinLed,n);
delay(100);
}
 
PWM  no es una señal analógica


Es importante recordar en todo momento que en una salida PWM el valor de tensión realmente es Vcc. Por ejemplo, si estamos alimentando un dispositivo que necesita 3V, y usamos una señal pulsada, en realidad estaremos suministrando 5V durante un 60% del tiempo y 0V durante el 40%. Pero si el dispositivo, por ejemplo, soporta como máximo 3V, podemos dañarlo si lo alimentamos mediante un PWM. 

Una señal pulsada es suficiente para emular una señal analógica en muchas aplicaciones. Por ejemplo, podemos variar la intensidad luminosa en un LED mediante un PWM. El LED realmente se enciende y apaga varias veces por segundo, pero este parpadeo es tan rápido que el ojo no lo aprecia. El efecto global percibido es que el LED brilla con menor intensidad. 

Otro ejemplo, al variar la velocidad de un motor DC con un PWM, en la mayoría de los casos la inercia del motor se encargará de que el efecto del PWM sea despreciable. No obstante, en función de la frecuencia podemos notar vibraciones o ruidos, en cuyo caso podremos deberemos variar la frecuencia del PWM. 

Por otro lado, debemos tener en cuenta los efectos que supone la rápida conexión y desconexión de la señal pulsada puede suponer en el dispositivo alimentado. Por ejemplo, en el caso de cargas inductivas (motores, relés, o electroimanes) la desconexión supondrá la generación de voltaje inducido que puede dañar la salida digital o el propio dispositivo, por lo que será necesario disponer de las protecciones oportunas.

En cuanto a transistores, en general, los de tipo BJT resultan apropiados para funcionar como amplificación de señales PWM. Esto no suele ser así en los transistores MOS, donde los efectos capacitivos del mismo, unidos a la limitación de corriente de las salidas digitales, frecuentemente harán que necesitemos un driver de amplificación previo para evitar que el transistor trabaje en zona activa.

Sensor de ultrasonidos HC-SR04

El sensor de ultrasonidos se enmarca dentro de los sensores para medir distancias o superar obstáculos, entre otras posibles funciones.


Un sensor de ultra sonidos es un dispositivo para medir distancias. Su funcionamiento se base en el envío de un pulso de alta frecuencia, no audible por el ser humano. Este pulso rebota en los objetos cercanos y es reflejado hacia el sensor, que dispone de un micrófono adecuado para esa frecuencia

Los sensores de ultrasonidos son sensores baratos, y sencillos de usar. Este sensor en concreto tiene un rango de distancias sensible entre 1,7 cm y 4,5 m con una precisión de 3mm.

Los sensores de ultrasonidos son sensores de baja precisión. La orientación de la superficie a medir puede provocar que la onda se refleje, falseando la medición. Además, no resultan adecuados en entornos con gran número de objetos, dado que el sonido rebota en las superficies generando ecos y falsas mediciones. Tampoco son apropiados para el funcionamiento en el exterior y al aire libre. 

Pese a esta baja precisión, que impide conocer con precisión la distancia a un objeto, los sensores de ultrasonidos son ampliamente empleados. En robótica es habitual montar uno o varios de estos sensores, por ejemplo, para detección de obstáculos, determinar la posición del robot, crear mapas de entorno, o resolver laberinto.

Características
  • Dimensiones del circuito: 43 x 20 x 17 mm
  • Tensión de alimentación: 5 Vcc
  • Frecuencia de trabajo: 40 KHz
  • Rango máximo: 4.5 m
  • Rango mínimo: 1.7 cm
  • Duración mínima del pulso de disparo (nivel TTL): 10 μS.
  • Duración del pulso eco de salida (nivel TTL): 100-25000 μS.
  • Tiempo mínimo de espera entre una medida y el inicio de otra 20 mS.
¿Qué recibimos en el sensor?

El tiempo que transcurre entre el envío y la recepción de un pulso sonoro.

¿Cómo vamos a traducir dicho tiempo en distancia?

Aprovechando que la velocidad de dicho ultrasonido en el aire es de valor 340 m/s, o 0,034 cm/microseg (ya que trabajaremos con centímetros y microsegundos). Para calcular la distancia, recordaremos que v=d/t (definición de velocidad: distancia recorrida en un determinado tiempo).

De la fórmula anterior despejamos d, obteniendo d=v·t, siendo v la constante anteriormente citada y t el valor devuelto por el sensor a la placa Arduino.


También habrá que dividir el resultado entre 2 dado que el tiempo recibido es el tiempo de ida y vuelta.


Pines de conexión
  • Vcc.
  • Trig (Disparo ultrasonido).
  • Echo (Recepción de ultrasonido)
  • GND
 Montaje en una protoboard




Programa

Para activar el sensor necesitamos generar un pulso eléctrico en el pin Trigger (disparador) de al menos 10us. Previamente, pondremos el pin a Low durante 4us para asegurar un disparo limpio. 

Posteriormente usamos la función “pulseIn” para obtener el tiempo requerido por el pulso para volver al sensor. Finalmente, convertimos el tiempo en distancia mediante la ecuación correspondiente. 

Observar que intentamos emplear siempre aritmética de enteros, evitando usar números en coma flotante. Esto es debido a que las operaciones en coma flotante ralentizan mucho el procesador, y suponen cargar un gran número de librerías en memoria.

Empezamos a programar nuestro sketch, explicaremos paso a paso el código para sea más comprensible:

Primero configuramos los pines y la comunicación serial a 9600 baudios

const int EchoPin = 5;
const int TriggerPin =6;
long distancia;
long tiempo;

void setup(){

Serial.begin(9600);
pinMode(TriggerPin, OUTPUT); /*activación del pin 9 como salida: para el pulso ultrasónico*/
pinMode(EchoPin, INPUT); /*activación del pin 8 como entrada: tiempo del rebote del ultrasonido*/
}

Ahora en el bucle void loop() empezamos enviando un pulso de 5 us al Trigger del sensor para estabilizar el sensor:


digitalWrite(TriggerPin,LOW); /* Por cuestión de estabilización del sensor*/
delayMicroseconds(5);


A continuación enviaremos un pulso de 10 us al Trigger del sensor para al Trigger del sensor:


delayMicroseconds(10);
digitalWrite(TriggerPin, LOW);

Seguidamente recibimos el pulso de respuesta del sensor por el pin Echo, para medir el pulso usamos la función pulseIn(pin, value)

tiempo=pulseIn(EchoPin, HIGH); /* Función para medir la longitud del pulso entrante. Mide el tiempo que transcurrido entre el envío del pulso ultrasónico y cuando el sensor recibe el rebote, es decir: desde que el pin 12 empieza a recibir el rebote, HIGH, hasta que deja de hacerlo, LOW, la longitud del pulso entrante*/

La variable t, almacena el tiempo que tarda en llegar el eco del ultrasonido, el siguiente paso  es calcular la distancia entre el sensor de ultrasonidos y el objeto.


 Partimos de la siguiente formula:
Donde  Velocidad es la velocidad del sonido 340m/s, pero usaremos las unidades en cm/us pues trabajaremos en centímetros y microsegundos, tiempo es el tiempo que demora en llegar el ultrasonido al objeto y regresar al sensor, y la distancia recorrida es dos veces la distancia hacia el objeto, reemplazando en la formula tenemos:
Finalmente enviamos al monitor serie el valor de la distancia y terminamos estableciendo una pausa de 100ms, que es superior a los 60ms  recomendado por los datos técnicos del sensor.




const int EchoPin = 5;
const int TriggerPin =6;
long distancia;
long tiempo;

void setup(){

Serial.begin(9600);
pinMode(TriggerPin, OUTPUT); /*activación del pin 9 como salida: para el pulso ultrasónico*/
pinMode(EchoPin, INPUT); /*activación del pin 8 como entrada: tiempo del rebote del ultrasonido*/
}

void loop(){

digitalWrite(TriggerPin,LOW); /* Por cuestión de estabilización del sensor*/
delayMicroseconds(5);
digitalWrite(TriggerPin, HIGH); /* envío del pulso ultrasónico*/
delayMicroseconds(10);
digitalWrite(TriggerPin, LOW);

tiempo=pulseIn(EchoPin, HIGH); /* Función para medir la longitud del pulso entrante. Mide el tiempo que transcurrido entre el envío del pulso ultrasónico y cuando el sensor recibe el rebote, es decir: desde que el pin 12 empieza a recibir el rebote, HIGH, hasta que deja de hacerlo, LOW, la longitud del pulso entrante*/
distancia= tiempo/59; /*fórmula para calcular la distancia obteniendo un valor entero*/
/*Monitorización en centímetros por el monitor serial*/
Serial.println("Distancia ");
Serial.println(distancia);
Serial.println(" cm");
delay(100);
}

Para resumir el código y no tener que repetir tantas instrucciones cada vez que queramos realizar una medida vamos a escribir el sketch utilizando una función:

Vamos a crear una función medirDistancia(), la cual nos devolverá la distancia.

Como ejemplo práctico hemos diseñado un circuito que incorpora un sensor y su finalidad será la de controlar el funcionamiento de un motor, de tal manera que cuando se encuentre un objeto en una distancia menor a 20 cm del sensor, el motor dejará de girar, si la distancia es mayor de 20 cm el motor girará.

Circuito eléctrico


Sketch

#define E1 13 // Enable Pin para el motor 1
#define I1 12 // Control pin 1 para el motor 1
#define I2 11 // Control pin 2 para el motor 1

const int EchoPin = 2;
const int TriggerPin =3;
long distanciaAlObjeto;

void setup()
{
  pinMode (E1, OUTPUT);
  pinMode (I1, OUTPUT);
  pinMode (I2, OUTPUT);
  pinMode (EchoPin,INPUT);
  pinMode (TriggerPin,OUTPUT);
  Serial.begin(9600);
 }

void loop()
{
  distanciaAlObjeto=medirDistancia();
  if(distanciaAlObjeto>20)
  {
   girarMotor();
  }
  else
  {
    digitalWrite (E1, LOW); //Parar el motor 1
  }
}
long medirDistancia()
{
long distancia;
long tiempo;
digitalWrite(TriggerPin,LOW); /* Por cuestión de estabilización del sensor*/
delayMicroseconds(5);
digitalWrite(TriggerPin, HIGH); /* envío del pulso ultrasónico*/
delayMicroseconds(10);
digitalWrite(TriggerPin, LOW);
tiempo=pulseIn(EchoPin, HIGH); /* Función para medir la longitud del pulso entrante. Mide el tiempo que transcurrido entre el envío del pulso ultrasónico y cuando el sensor recibe el rebote, es decir: desde que el pin 12 empieza a recibir el rebote, HIGH, hasta que deja de hacerlo, LOW, la longitud del pulso entrante*/
distancia= tiempo/59; /*fórmula para calcular la distancia */
/*Monitorización en centímetros por el monitor serial*/
Serial.println("Distancia ");
Serial.println(distancia);
Serial.println(" cm");
return(distancia);
}

void girarMotor()
{
  digitalWrite (E1, HIGH); //Activar el motor 1
  digitalWrite (I1, HIGH);  //Iniciar el giro
  digitalWrite (I2, LOW);
}

Placa de pruebas (Protoboard)

El protoboard: Es una especie de tablero con orificios, en la cual se pueden insertar componentes electrónicos y cables para montar circuitos. Como su nombre lo indica, esta tableta sirve para experimentar con circuitos electrónicos, con lo que se asegura el buen funcionamiento del mismo.


Así pues, con una protoboard, nos olvidamos del trabajo de soldar, y sólo nos limitamos a introducir los terminales de nuestros componentes electrónicos en las perforaciones que trae.

Estas placas están agujereadas con conexiones internas dispuestas en hileras, de modo que forman una matriz de taladros a los que podemos directamente insertar componentes y formar el circuito deseado.


Como el nombre indica, se trata de montar prototipos, de forma eventual, por lo que probamos y volvemos a desmontar los componentes, quedando la protoboard lista para el próximo experimento. 

En estos tableros montaremos los circuitos formados por resistencias, condensadores, transistores, Leds, displays, pulsadores y circuitos integrados principalmente. Hay que tener en cuenta que para realizar las conexiones entre componentes utilizaremos cables, que tienen que ser de un hilo rígido de 0,5 a 0,75 mm de diámetro aproximadamente. Estos cables también se venden preparados para los protoboard. Se trata de unos cables de longitud fija, los cuales tienen en los extremos unos contactos que facilitan ese trabajo de “pinchar” en la placa.
Básicamente un protoboard se divide en tres partes:


La central: Es la región localizada en el medio ldel protoboard, se utiliza para colocar los circuitos integrados.

A los lados de la central: En ella van los buses y se localizan en ambos extremos del protoboard.

Parte exterior de la placa. Hay dos filas de contactos a cada lado de la placa para poner la alimentación del circuito.

  • La línea azul siempre sera negativo, también llamada: tierra

  • Por otro lado, la línea roja siempre será positivo.

Esta disposición de conexiones nos ayuda a la hora de organizarnos, siguiendo algunas premisas que nos llevarán a un diseño limpio, sin problemas y efectivo:

  • Emplearemos las conexiones laterales para la alimentación.

  • Utilizaremos cables de distintos colores para cada “canal” de alimentación, rojo para el positivo y negro para el negativo (GND).

  • Coloca los circuitos integrados en una sola dirección, de derecha a izquierda o viceversa.

  • Se deberá de utilizar cables lo más cortos posibles, evitando así interferencias/ruidos y/o resistencias inesperadas.
  • Procuraremos mantener siempre un orden dentro de lo posible. Un diseño bien organizado dice mucho más que una maraña de cables.
  • Por último, si necesitas más espacio, siempre puedes acoplar más protoboard por cualquiera de los 4 lados con las pestañas que trae.
  • Algunos protoboards tienen separada la parte media de los buses, es por eso que se realiza esta conexión para darle continuidad a la corriente.
Limitaciones
  • Estos prototipos que montemos no pueden trabajar a frecuencias mayores de 20 Mhz. ya que entre las filas para la inserción de componentes hay capacidades parásitas que nos afectarían el funcionamiento del circuito.
  • También hay que tener cuidado de no usar intensidades de corriente muy altas por las conexiones de la placa.

Ordinogramas

También denominados diagramas de flujo de programas. Son representaciones gráficas que muestran la secuencia lógica y detallada de las operaciones que se van a realizar en la ejecución de un programa.

Ejemplo:

Diseñar un algoritmo que calcule el área de un triángulo utilizando como método de representación el ordinograma.


El diseño de todo ordinograma debe de reflejar :
  • Un principio o inicio que marca el comienzo de ejecución del programa y que viene determinado por la palabra "INICIO"
  •  La secuencia de operaciones, lo más detallada posible y siguiendo siempre el orden en el que se deberán ejecutar ( de arriba-abajo y de izquierda-derecha).
  • Un fin que marca la finalización de ejecución del programa y que viene determinado por la palabra "FIN".
La simbología utilizada en la construcción de ordinogramas es la siguiente:






Las reglas que hay que seguir para la confección de un ordinograma son las siguientes:
  1. Todos los símbolos utilizados en el diseño deben estar conectados por medio de líneas de conexión o líneas de flujo de datos.
  2. Queda terminantemente prohibido el cruce de líneas de conexión, pues ello nos indica que el ordinograma no está correctamente diseñado.
  3.  A un símbolo de proceso pueden llegarle varias líneas de conexión o flujo, pero del él solo puede salir una.
  4.  A un símbolo de decisión puede llegarle varias líneas de conexión o flujo de datos, pero de él solo puede salir una línea de entra las dos posibilidades existentes (verdadero o falso).
  5. A un símbolo de inicio  de proceso no llega ninguna línea de conexión o flujo y de él solo puede partir una línea de conexión.
  6. A un símbolo de proceso o ejecución pueden llegar muchas líneas de conexión, pero de él no puede partir ninguna.
 Ejemplo



Robot con 2 motores de CC y L293D

Propuesta

Aprender a controlar motores de corriente continua utilizando controladores basados en puentes H.

Material necesario

  • Cables para protoboard

  • Plataforma para robot móvil


  • Arduino Uno o similar. Esta sesión acepta cualquier otro modelo de Arduino. 
  • Placa Protoboard.

Esquema eléctrico
l293d_arduino_bb 
   
Programa para conseguir que el móvil se desplace hacia delante durante 1 s.
 
#define E1 8 // Enable Pin for motor 1 
#define I1 9 // Control pin 1 for motor 1
#define I2 10 // Control pin 2 for motor 1
#define E2 7 //Enable Pin for motor 2 
#define I3 6 //Control sentido de giro motor 2
#define I4 5 //Control sentido de giro motor 2 


void setup()
{
    pinMode( E1,OUTPUT);
    pinMode( I1,OUTPUT);
    pinMode( I2,OUTPUT);
    pinMode( E2,OUTPUT);
    pinMode( I3,OUTPUT);
    pinMode( I4,OUTPUT);


 pinMode( i, OUTPUT);
  }
}

void loop()
{
digitalWrite(E1, HIGH); // Activamos Motor1
digitalWrite(I1, HIGH); // Arrancamos el motor 1 
digitalWrite(I2, LOW);

digitalWrite(E2, HIGH);  // Activamos Motor2
digitalWrite(I3, HIGH); //Arrancamos el motor 2
digitalWrite(I4, LOW);
delay(1000);

digitalWrite(E1, LOW); // Paramos Motor 1
digitalWrite(E2, LOW);  // Paramos Motor 1
delay(500); }