Manejo de Entradas en un PIC16F877a usando lenguaje C

avatar
(Edited)

Luego de ver cómo se manejan las salidas usando Lenguaje C pudimos hacer nuestro primer programa para simular un semáforo. Ahora ha llegado el momento de ver cómo podemos configurar las entradas y crear un programa para que ciertas salidas se activen bajo algunas condiciones de las entradas.

Usaremos el condicional if y algunos operadores lógicos vistos en logica combinacional. Finalmente simularemos el control de nivel de un tanque mediante sensores discretos (suiches de nivel).

Parte del código que usaremos en C. Fuente: @electronico

Input(Pin) será la instrucción que nos permitirá verificar el estado de un pin específico y tomar decisiones basadas en su estado.

Donde dice Pin se debe reemplazar por el nombre del PIN deseado (PIN_Xn), debemos reemplazar X por la letra correspondiente al puerto; A,B,C,D u otro si existe y la letra n por el número del pin correspondiente a ese puerto. Si por ejemplo queremos consultar el Pin 0 del port C sería

input(PIN_C0)

Pero necesitamos establecer las condiciones para los posibles estados presentes para lo cual para efectos de este artículo nos apoyaremos en el condicional if() el cual consulta si se cumple la condición escrita dentro del paréntesis conteniendo un código que se ejecutará cuando sea el caso.

Luego está la instrucción else que se complementa con if, cuando no se cumple la condición en if entonces se ejecuta el código de else pero para efectos de este artículo por ahora no usaremos else.

Manejando entradas con input(PIN) en el condicional if()

Luego de haber escrito toda la estructura que define el microcontrolador a usar, fusibles, manejo de puertos (todo esto descrito en artículos anteriores) y estándo ya dentro de la rutina principal el manejo de una entrada puede usar el siguiente formato:

if(input(PIN) Operador condición)
{
código a ejecutar.
}

Operador puede representar una operación matemática o lógica en cuyo caso se reemplaza la palabra operador por el simbolo que representa la operación deseada y condición por el valor para el cual se cumplirá la condición.

En código a ejecutar se escriben las acciones que se deben seguir cuando se cumplan las condiciones dadas.

Es importante aclarar que if() no está limitado a un solo operador, se puede establecer una condición o una serie de condiciones dentro del parentesis, estás pueden ser matemáticas o lógicas.

Pero no vamos a complicarnos mucho porque nuestras entradas solo acetaran valores discretos o lógicos siendo posibles sólo 2 valores posibles.

Una vez se cumpla la condición o las condiciones se ejecutará lo que escribamos en código a ejecutar y generalmente usamos ese espacio para manipular las salidas.

Control discreto de nivel

Ahora nos apoyaremos en un pequeño ejercicio para explicar todo lo anterior a nivel de detalle.

Se requiere un programa para un microcontrolador que controle el nivel de almacenamiento de agua en un tanque. Se dispone de dos sensores discretos también conocidos como switchs de nivel de los cuales uno está en un lugar alto (switch de nivel alto) y otro en un lugar bajo (Switch de nivel bajo) y una bomba para el llenado del tanque

Si el nivel baja hasta cierto punto se activa el switch de nivel bajo, dicho evento debe mandar a activar la bomba para el llenado del tanque y encender un indicador para dar a conocer que la bomba se encuentra operando.

Una vez el tanque se ha llenado hasta el switch de nivel alto éste se activa y manda a desactivar la bomba y al mismo tiempo el indicador.

Si por alguna razón los switchs alto y bajo envían un 1 lógico de forma simultánea se debe activar un indicador de error ya que esta condición no es físicamente posible y su aparición representa que alguno de los switchs está en falla.

Adicionalmente se deben colocar dos pulsadores para control manual de la bomba, uno para encendido y uno para apagado, también se debe considerar que si el switch de nivel alto está activo y se quiere encender la bomba con el pulsador manual se encenderá el indicador de error impidiendo que la bomba encienda y rebose el tanque

Análisis del problema

Parece un problema exigente sin embargo es de los más simples. Lo primero que uno debe hacer es aplicar las partes correspondientes a un lazo de control electronico:

  • Identificamos la cantidad de dispositivos de entrada de dato y el tipo de dato que suministran.
  • Identificamos la cantidad de dispositivos de salida y el tipo de señal que requieren para activarse.
  • Intentamos comprender los requerimientos del solicitante y adaptarlos a los dispositivos que tenemos.
  • Diseñamos el programa de control basado en los análisis anteriores.

Si seguimos ese patrón tenemos 4 sensores de entrada que incluyen switch alto y switch bajo más dos pulsadores para arranque y parada manual de la bomba, todas las entradas brindan señales discretas.

Usaremos los siguientes pines para conexión de las entradas.

B0: Swich Bajo, B1: Swicth Alto, B2: Pulsador de arranque manual, B3: Pulsador de parada manual.

Tenemos 3 salidas que son dos luces indicadoras mas la bomba de llenado.

Usaremos los siguientes pines para controlar estas salidas.

D0: Bomba de llenado, D1: Indicador bomba operando, D2: Indicador de error.

Los requerimientos están en el enunciado e iremos cubriendolos durante la programación.

Escribiendo el código

Lo primero que hacemos es lo de siempre, definir el encabezado del programa con las configuraciones que hemos establecido como cómunes.

#include <16f877a.h>
#fuses HS,NOWDT,NOPUT,NOLVP,NOPROTECT,BROWNOUT
#use delay(clock=20)

Vamos a usar el PORTB como entrada y el PORTD como salida, nos apoyaremos en la directiva fast_io para establecer esas configuraciones.

#use fast_io(B)
#use fast_io(D)
void main()
{
set_tris_b(0xFF);
set_tris_d(0x00); //...

Siempre se deben limpiar las salidas para evitar la aparición de señales indeseadas. Usamos para ello la instrucción para manejo de salidas output_PORT(Valor) para establecer todas en 0

output_d(0x00);

Ahora creamos el bucle while para que nuestro código dentro de él se ejecute de forma constante.

while(true)
{

Dentro de este bucle establecemos la primera condición, en ella definimos cuando debe encenderse la bomba y sabemos que solo existen dos formas posibles de que ocurra, que el nivel sea bajo (Switch bajo es 1) o que el pulsador manual se active (pulsador de arranque manual es 1). Podemos establecer estas dos condiciones dentro del condicional if() usando un operador OR para escribir ambas condiciones a la vez.

Dentro del código a ejecutar encendemos la bomba (conectada en el pin D0 y el indicador de la bomba operando conectado en el pin D1)

  if(input(PIN_B0)  ==  1 ||  input(PIN_B2)  ==  1)
     {
     output_high(PIN_D0);
     output_high(PIN_D1);
     }

Las condiciones en las que se debe apagar la bomba y su indicador son cuando el swich alto sea 1 o el pulsador de parada sea 1, nos apoyamos en el mismo modelo de instrucción if() y operador or para establecer esta condición y en el código apagamos todas las salidas cuando se cumpla la condición.

  if(input(PIN_B1)  ==  1  ||  input(PIN_B3)  == 1)
     {
      output_d(0x00);
      }

Ahora vamos por la condición de error, está aparecerá si ambos switchs son 1 o si el swich de nivel alto es 1 y el pulsador de arranque manual es 1. Es decir, el error aparecerá bajo dos posibles condiciones.

Para abordar esto usamos dos condicionales if (uno para cada condición) y dentro de la condición usamos el operador AND para establecer que se cumplirá la condición solo cuando ambos estados definidos dentro de ella sean 1.

  if (input(PIN_B0)  == 1  && input(PIN_B1) ==1)
     {
     output_high(PIN_D2);
     }
  if (input(PIN_B1)  == 1  && input(PIN_B2) ==1)
     {
     output_high(PIN_D2);
     }

Con esto ya tenemos el programa que cumple todas las condiciones exigidas. Ahora vamos a implementarlo en nuestro simulador PROTEUS.

Simulando en Proteus

Para proteus usaremos dos switchs manuales que pueden hacer la función de los swichs de nivel y dos pulsadores que representan el control manual de la bomba.

Tenemos además un motor controlado por un transistor que representa la bomba y dos luces leds que representan los indicadores (verde operando y rojo error)

Se pueden notar algunas resistencias extras entre los pines de entrada y tierra, éstas se colocan para evitar que cuando las entradas reciban un 1 lógico lo retengan aun cuando el origen de la señal regrese a cero perturbando el funcionamiento del programa. Esto se puede omitir programando en ensamblador con la instrucción clrf que limpia las entradas. Tal vez en el futuro veamos como a hacerlo en C.

Diseño del programa en PROTEUS. Fuente: @electronico

Ahora vamos a simularlo y a grabarlo en un gif. Para nuestra simulación cerramos el swich de bajo nivel simulando un bajo nivel en el tanque y la bomba (motor) se deberá activar. Cuando se active el swich de alto se debe desactivar.

Luego simularemos los botones de arranque y parada manual y finalmente vamos a provocar la activación del indicador de error.


Simulación del programa en Proteus. Fuente: @electronico


Artículos relacionados.

Lecturas recomendadas

  • José M. Angulo Usategui, Ignacio Angulo Martínez, Microcontroladores PIC: Diseño práctico de aplicaciones (primera parte)
  • Ronald J. Tocci, Neal S. Widmer, Sistemas digitales: principios y aplicaciones
  • Albert Paul Malvino, Principios de electrónica, Sexta edición.
  • Robert L. Boylestad, Electrónica: Teoría de Circuitos.
  • Timothy J. Maloney, Electrónica Industrial, dispositivos y sistemas.



0
0
0.000
4 comments
avatar

Congratulations @electronico! You have completed the following achievement on the Hive blockchain And have been rewarded with New badge(s)

You published more than 50 posts.
Your next target is to reach 60 posts.

You can view your badges on your board and compare yourself to others in the Ranking
If you no longer want to receive notifications, reply to this comment with the word STOP

To support your work, I also upvoted your post!

Check out the last post from @hivebuzz:

HiveBuzz World Cup Contest - Round of 16 - Recap of Day 3
The Hive Gamification Proposal Renewal
Our Hive Power Delegations to the November PUM Winners
Support the HiveBuzz project. Vote for our proposal!
0
0
0.000
avatar

¡Enhorabuena!


Has recibido el voto de PROYECTO CHESS BROTHERS

✅ Has hecho un buen trabajo, por lo cual tu publicación ha sido valorada y ha recibido el apoyo de parte de CHESS BROTHERS ♔ 💪


♟ Te invitamos a usar nuestra etiqueta #chessbrothers y a que aprendas más sobre nosotros.

♟♟ También puedes contactarnos en nuestro servidor de Discord y promocionar allí tus publicaciones.

♟♟♟ Considera unirte a nuestro trail de curación para que trabajemos en equipo y recibas recompensas automáticamente.

♞♟ Echa un vistazo a nuestra cuenta @chessbrotherspro para que te informes sobre el proceso de curación llevado a diario por nuestro equipo.


Cordialmente

El equipo de CHESS BROTHERS

0
0
0.000
avatar

Thanks for your contribution to the STEMsocial community. Feel free to join us on discord to get to know the rest of us!

Please consider delegating to the @stemsocial account (85% of the curation rewards are returned).

Thanks for including @stemsocial as a beneficiary, which gives you stronger support. 
 

0
0
0.000
avatar

¡Felicitaciones!



Estás participando para optar a la mención especial de nuestra COMUNIDAD (Recompensa de 1 Hive), también has recibido 1 ENTROKEN.

1. Invierte en el PROYECTO ENTROPÍA y recibe ganancias semanalmente. Entra aquí para más información.

2. Contáctanos en Discord: https://discord.gg/hkCjFeb

3. Suscríbete a nuestra COMUNIDAD, apoya al trail de @Entropia y así podrás ganar recompensas de curación de forma automática. Entra aquí para más información sobre nuestro trail.

4. Creación de cuentas nuevas de Hive aquí.

5. Visita nuestro canal de Youtube.

Atentamente

El equipo de curación del PROYECTO ENTROPÍA

0
0
0.000