Puente levadizo controlado por Arduino

Se trata de idear, diseñar, planificar y construir una maqueta de un PUENTE LEVADIZO con diversos materiales disponibles, que cumpla las siguientes condiciones: 

CONDICIONES 

  • La elevación y descenso del tablero será suave.
  • Su accionamiento será eléctrico a 4,5V y su control:
    • El control será automático mediante Arduino y sensores de final de carrera.
    • El ajuste de piezas y acabado deberá ser preciso.
    • Las medidas máximas del conjunto no excederán de 300x200x150 mm
Solución adoptada

La solución final consiste en la construcción de una maqueta construida con listones de madera de samba y contrachapado.

Puente levadizo

Sistema de transmisión formado por un motor con reductora y un sistema de transmisión por correa.


El sistema de subida y bajada está formado por un torno fabricado con varilla roscada.


En la parte superior hemos colocado dos poleas de madera, para reducir rozamiento del cable.


Como elementos final de carrera se ha utilizado dos LDR, una para detectar la subida del tablero,


y otra para detectar la bajada del tablero


Por último el circuito de control está formado por una placa de Arduino Uno, un pulsador, dos LDRs  y  un driver L293D.


Circuito eléctrico
 

Programa

#define EA 9
#define I1 8
#define I2 10
#define pinPulsador 0  // Pin digital de entrada para el pulsador
int pinLDR_S = 0;      //A0, Pin analógico para LDR superior
int pinLDR_I = 1;     //A1,  Pin analógico para LDR inferior
int valorLDR_S = 0;
int valorLDR_I = 0;
int velocidad=200;
int estadoPulsador=HIGH;

 void subir()
{
 analogWrite(EA, velocidad);
 digitalWrite(I1, HIGH);
 digitalWrite(I2, LOW);
}

 void bajar()
 {
 analogWrite(EA, velocidad);
 digitalWrite(I1, LOW);
 digitalWrite(I2, HIGH);
}
 void parar()
{
 digitalWrite(I1, LOW);
 digitalWrite(I2, LOW);
 }
 void setup()
 {
  pinMode(EA, OUTPUT);
  pinMode(I1, OUTPUT);
  pinMode(I2, OUTPUT);
  pinMode (pinPulsador, INPUT);

}


void loop()
{
estadoPulsador = digitalRead(pinPulsador); //Leer estado del pulsador

valorLDR_S= analogRead(pinLDR_S);
valorLDR_I= analogRead(pinLDR_I);

if ( estadoPulsador == LOW && valorLDR_I>300)<300 br=""><300 300="">
<300 br="">{
while(valorLDR_S >300)
{
  subir();
  valorLDR_S= analogRead(pinLDR_S);
  delay(300);
}
parar();
}
if(estadoPulsador==LOW && valorLDR_S>300)
<300 br=""><350 br=""><350 br=""> {
<300 br=""><350 br=""><350 br=""> while(valorLDR_I >300)
  {
   bajar();
   valorLDR_I= analogRead(pinLDR_I);
   delay(300);
  }
   //parar motor
   parar();
  }
 }

Estructuras de control

Son utilizadas para controlar la secuencia de ejecución de un programa así como, determinados bloques de instrucciones.

Una clasificación podría ser la siguiente:
  • Estructura secuencial. 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. Leer más..

  • Estructuras alternativas. También llamadas estructuras condicionales, son aquellas que controlan la ejecución o la no ejecución de una o más instrucciones en función de que se cumpla o no una condición establecida. Leer más..

  • Estructuras repetitiva. Son aquellas instrucciones que nos permiten variar o alterar la secuencia normal de ejecución de un programa haciendo posible que un grupo de acciones se ejecuten más de una vez de forma consecutiva. Este tipo de instrucciones también reciben el nombre de bucles o lazos. Leer más..




Estructuras repetitivas


Estructuras repetitivas

Son aquellas instrucciones que nos permiten variar o alterar la secuencia normal de ejecución de un programa haciendo posible que un grupo de acciones se ejecuten más de una vez de forma consecutiva. Este tipo de instrucciones también reciben el nombre de bucles o lazos.

Estructura mientras (while)

La estructura mientras se caracteriza porque su diseño permite repetir un bloque de instrucciones mientras que se cumpla la condición establecida, en el caso que la condición sea falta, dicho bloque de instrucciones no se ejecutará ninguna vez.




Ejemplo: Realizar un programa que encienda un diodo led al presionar un pulsador y permanezca  encendido mientras esté presionado dicho pulsador.

 

 
int estadoPulsador;
int pinPulsador=8; // Declaramos la variable pinPulsador con el número del pin en qué está conectado

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

void setup() // Función que se ejecuta una sola vez.
{
   pinMode(pinPulsador, INPUT); // Inicializa el pin  8 como entrada
   pinMode(pinLed, OUTPUT); // Inicializar el pin digital (pinLed) como salida.
}

void loop() // Función que se ejecuta una y otra vez, de forma ininterrumpida.
{
estadoPulsador= digitalRead(pinPulsador); // Lee el valor del pin del pulsador y lo almacena en la variable estadoPulsador
while(estadoPulsador==LOW)
  {
    digitalWrite(pinDiodo, HIGH); // Si es así activa el diodo
    estadoPulsador= digitalRead(pinPulsador);
  }
 }


Estructura Para (for)

Este tipo de instrucciones repetitivas se caracterizan porque el número de veces que se repetirá el bloque de instrucciones general está fijado de antemano.


  • Vcont: Variable contador del bucle.
  • Vi: Valor inicial que toma Vcont ( es el valor inicial a partir del cual comienza la ejecución del bucle.
  • Vf: Valor final para Vcont (es el valor final que se toma como referencia para la finalización del bucle).
  • n: Cantidad en que se incrementa o decrementa (según sea el valor especificado positivo o negativo) la variable Vcont al final de cada vuelta del bucle. Por defecto, este valor es siempre 1.
El control del bucle se utiliza en aquellas ocasiones en las que se conoce previamente el número de veces que se van a efectuar las operaciones del bucle.


Ejemplo: Inicializar los pines digitales como entradas

int n;

void setup()
{
   for(n=0;n<13 n="" p="">    {
      pinMode(n,OUTPUT);
    }
}


Estructuras alternativas

Estructuras alternativas

También llamadas estructuras condicionales, son aquellas que controlan la ejecución o la no ejecución de una o más instrucciones en función de que se cumpla o no una condición establecida.

a) Alternativa simple

Ejemplo

Realizar un programa para encender un diodo Led en función del estado de un pulsador.




int pinPulsador=8; // Declaramos la variable pinPulsador con el número del pin en qué está conectado
int pinLed=13; //Pin donde esta conectado el diodo led
int estadoPulsador=0;

void setup() // Función que se ejecuta una sola vez.
{
pinMode(pinPulsador, INPUT); // Inicializa el pin  8 como entrada
pinMode(pinLed, OUTPUT); // Inicializar el pin digital (pinLed) como salida.
}

void loop() // Función que se ejecuta una y otra vez, de forma ininterrumpida.
{
estadoPulsador= digitalRead(pinPulsador); // Lee el valor del pin del pulsador y lo almacena en la variable estadoPulsador
if(estadoPulsador==LOW)
  {
    digitalWrite(pinDiodo, HIGH); // Si es así activa el diodo
    delay(1000); // Esperar un segundo
  } }


b) Alternativa doble

Ejemplo

Realizar un programa para encender o apagar un diodo Led en función del estado de un pulsador. ON el diodo led luce, OFF  el diodo led no luce.




int pinPulsador=8; // Declaramos la variable pinPulsador con el número del pin en qué está conectado
int pinLed=13; //Pin donde esta conectado el diodo led
int estadoPulsador=0;

void setup() // Función que se ejecuta una sola vez.
{
pinMode(pinPulsador, INPUT); // Inicializa el pin  8 como entrada
pinMode(pinLed, OUTPUT); // Inicializar el pin digital (pinLed) como salida.
}

void loop() // Función que se ejecuta una y otra vez, de forma ininterrumpida.
{
estadoPulsador= digitalRead(pinPulsador); // Lee el valor del pin del pulsador y lo almacena en la variable estadoPulsador
if(estadoPulsador==LOW)
{
digitalWrite(pinDiodo, HIGH); // Si es así activa el diodo
delay(1000); // Esperar un segundo
}
else
{
digitalWrite(pinLed, LOW); // Apagar el led, haciendo que el voltaje sea bajo.
delay(500); // Esperar un segundo
}
}

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.