SCADA
SCADA
ATLIXCO
INGENIERÍA MECATRÓNICA
Control de Procesos
Práctica 2
Atlixco, Puebla
Abril 2020
1
1. Introducción
El mundo físico que nos rodea, es realmente analógico, y en teoría, no hubiese cabida posible de la
tecnología actual, por su desarrollo alrededor de estructuras digitales; es por esto que, para que una
magnitud física en particular pueda ser controlada o modicada, se requiere una previa conversión,
mediante un transductor, al correspondiente valor de tensión analógico; de esta forma se posibilita
el procesamiento de una magnitud especíca, a través de un sistema electrónico, para obtener una
respuesta deseada.
Estos sistemas electrónicos son conocidos como Sistemas de Adquisición de Datos, los cuales per-
miten una integración de alta velocidad y control entre elementos centrales y periféricos, con el objeto
de obtener una representación digital lo más el posible a la señal analógica original.
2. Objetivo general
Diseñar y construir una tarjeta de uso general para la supervisión, control y adquisición de datos
mediante un microcontrolador PIC18F4550 y una interfaz gráca de usuario con el lenguaje de Python,
implementando la librería Tkinter.
3. Marco teórico
Las interfaces grácas son medios visuales, mucho más cómodos que una terminal de texto, a través
de las cuales nuestros usuarios pueden interactuar y realizar tareas grácamente. El módulo Tkinter
cuenta con una serie de componentes grácos llamados Widgets, gracias a los cuales podemos diseñar
nuestras interfaces. Los widgets deben seguir una jerarquía a la hora de añadirse a la interfaz. Por
ejemplo, un Marco (frame) forma parte del objeto raíz Tk. Y a su vez, un botón (button) puede for-
mar parte de un contenedor como la raíz o un marco.
Es una librería que proporciona a las aplicaciones de Python una interfaz de usuario fácil de pro-
gramar. Además, es un conjunto de herramientas GUI de Tcl/Tk (Tcl: Tool Command Language),
proporcionando una amplia gama de usos, incluyendo aplicaciones web, de escritorio, redes, adminis-
tración, pruebas y muchos más. Además de ser una interfaz a través de la cual el usuario interactúa
con dispositivos electrónicos como ordenadores, dispositivos portátiles y otros dispositivos. De igual
forma son intermediarios entre el programa y el usuario. Está compuesta por iconos, menús, botones
y cualquier representación gráca.[1]
Al igual que las extensiones de Python, Tcl / Tk se implementa como un paquete de biblioteca C
con módulos para admitir scripts o aplicaciones interpretados. La interfaz de Tkinter se implementa
como un módulo de Python, Tkinter.py, que está vinculado a una extensión C (_tkinter) que utiliza
estas mismas bibliotecas Tcl / Tk. En muchos casos, un programador de Tkinter no tiene que preo-
cuparse por la implementación de Tcl / Tk ya que Tkinter puede verse como una simple extensión de
Python.
2
3.1.2 Módulo image
El módulo Image proporciona una clase con el mismo nombre que se utiliza para representar una
imagen PIL. El módulo también proporciona una serie de funciones de fábrica, incluidas funciones para
cargar imágenes de archivos y crear nuevas imágenes.
3.1.2.1 Funciones: PIL.Image.open( fp , modo = 'r' )
Abre e identica el archivo de imagen dado. Esta es una operación perezosa; esta función identica
el archivo, pero el archivo permanece abierto y los datos de la imagen real no se leen del archivo hasta
que intente procesar los datos (o llame al load () método). Ver new ().
Parámetros:
• fp: un nombre de archivo (cadena), un objeto pathlib.Path o un objeto de archivo. El objeto de
archivo debe implementar read(), seek()y tell()métodos, y debe abrirse en modo binario.
• modo: el modo. Si se da, este argumento debe ser r".
3
3.1.2.3 Construyendo imágenes
También puede usar cualquier decodicador de píxeles compatible con PIL. Tenga en cuenta que
esta función solo decodica datos de píxeles, no imágenes completas. Si tiene una imagen completa en
una cadena, envuélvala en un objeto BytesIO y úsela open() para cargarla.
Parámetros:
• mode: el modo de imagen.
• tamaño: el tamaño de la imagen.
• data: un búfer de bytes que contiene datos sin procesar para el modo dado.
• decoder_name: qué decodicador usar.
• args: parámetros adicionales para el decodicador dado.
Devoluciones: Un objeto Image.
3.1.3 Widget
Los widgets son objetos de Python llenos de acontecimientos que tienen una representación en el
navegador, a menudo como un control como un control deslizante, un cuadro de texto, etc. Puede usar
widgets para crear GUI interactivas para sus computadoras portátiles. Para usar el marco de widgets,
debe importar ipywidgets. [2]
También puede usar widgets para sincronizar información con estado y sin estado entre Python y
JavaScript.
3.1.4 Toplevel
El widget Toplevel proporciona un contenedor separado para otros widgets, como un marco. Para
aplicaciones simples de una sola ventana, la raíz Toplevel creada cuando inicializa Tk puede ser el
único shell que necesita. Hay cuatro tipos de niveles superiores que se muestran en la gura 1.
1. El nivel superior principal, que normalmente se denomina raíz.
2. Un nivel superior, que actúa independientemente de la raíz, a menos que se destruya la raíz, en cuyo
caso el niño también se destruye.
3. Un nivel superior transitorio, que siempre se dibuja encima de su padre y se oculta si el padre es
cronicado o retirado.
4. Se puede crear un Toplevel que no esté decorado por el administrador de ventanas congurando el
indicador overrideredirect en un valor distinto de cero. Esto crea una ventana que no se puede cambiar
de tamaño o mover directamente.
3.1.5 Frame.
Los widgets de marco son contenedores para otros widgets. Aunque puede vincular eventos de mouse
4
Figura 1: Figura 1. Toplevel widgets.
y teclado a devoluciones de llamada, los marcos tienen opciones limitadas y ningún otro método que
las opciones de widget estándar.
Uno de los usos más comunes para un marco (frame) es como maestro, para un grupo de widgets que
serán manejados por un administrador de geometría. Esto se muestra en la gura 2. El segundo ejem-
plo de cuadro, que se muestra en la gura 3 a continuación, usa un cuadro para cada la de la pantalla.
Figura 3: Figura 3. Estilos de cuadros que combinan el tipo de relieve con diferentes anchos de borde.
Un uso común del tipo de relieve GROOVE es proporcionar un marco etiquetado (a veces llamado
panel) alrededor de uno o más widgets. Hay varias maneras de hacer esto; la gura 4 ilustra solo un
ejemplo, usando dos cuadros [2]. Tenga en cuenta que el marco externo utiliza el administrador de
geometría Placer para colocar el marco interno y la etiqueta. Los widgets dentro del marco interno
usan el administrador de geometría de Packer.
5
Figura 4: Figura 4. Uso de un widget de marco para construir un panel.
3.1.6 Label Label widgets se utilizan para mostrar texto o imágenes. Las etiquetas pueden contener
texto que abarca varias líneas, pero solo puede usar una sola fuente. Puede permitir que el widget rompa
una cadena de texto que se ajuste al espacio disponible o puede incrustar caracteres de salto de línea
en la cadena para controlar los saltos [3]. Varias etiquetas se muestran en la gura 5.
Aunque las etiquetas no están destinadas a interactuar con los usuarios, puede vincular eventos de
mouse y teclado a devoluciones de llamada. Esto puede usarse como un botón "barato"para ciertas
aplicaciones.
En la tabla 1, se muestran las opciones más utilizadas para este widget. Estas opciones se pueden
usar como pares clave-valor separados por comas.
6
Figura 6: Tabla 1. Parámetros para Label.
7
3.1.7 Checkbutton
Los widgets del botón de vericación se utilizan para proporcionar selecciones de encendido / apa-
gado para uno o más elementos. A diferencia de los botones de radio, no existe interacción entre los
botones de vericación. Puede cargar botones de vericación con texto o imágenes. Los botones de
vericación normalmente deben tener una variable (IntVar) asignada a la opción variable que le per-
mite determinar el estado del botón de vericación. Además (o alternativamente) puede vincular una
devolución de llamada al botón que se llamará cada vez que se presione el botón.
Tenga en cuenta que la apariencia de los botones de vericación es bastante diferente en UNIX y
Windows; UNIX normalmente indica selección usando un color de relleno, mientras que Windows usa
una marca de vericación. El formulario de Windows se muestra en la gura 6.
3.1.8 Entry
Los widgets de entrada son los widgets básicos que se utilizan para recopilar datos de un usuario.
También pueden usarse para mostrar información y pueden deshabilitarse para evitar que un usuario
cambie sus valores.
Los widgets de entrada están limitados a una sola línea de texto que puede estar en una sola fuente.
Un widget de entrada típico se muestra en la gura 7. Si el texto ingresado en el widget es más largo
que el espacio de visualización disponible, el widget desplaza el contenido. Puede cambiar la posición
visible con las teclas de echa. También puede usar los métodos de desplazamiento del widget para
vincular el comportamiento de desplazamiento al mouse o a su aplicación [2].
8
3.1.9 Grid
El administrador de geometría de cuadrícula (grid) coloca los widgets en una tabla bidimensional.
El widget maestro se divide en varias las y columnas, y cada çelda.en la tabla resultante puede conte-
ner un widget. Este administrador de geometría organiza los widgets en una estructura similar a una
tabla en el widget principal [4]. La sintaxis de la cuadrícula (grid) es: widget.grid( grid_options ).
A continuación, se muestra lista de posibles opciones:
• column: la columna para colocar el widget; predeterminado 0 (columna más a la izquierda).
• columnpan: cuántas columnas ocupan widgeto; por defecto 1.
• ipadx, ipady: cuántos píxeles debe rellenar el widget, horizontal y verticalmente, dentro de los bordes
del widget.
• padx, pady: cuántos píxeles debe rellenar el widget, horizontal y verticalmente, fuera de los bordes
de v.
• la: la la para colocar el widget; predeterminado la primera la que todavía está vacía.
• Rowspan: Cuántas las ocupa el widget; por defecto 1.
• pegajoso: qué hacer si la celda es más grande que el widget. Por defecto, con sticky = , el widget
está centrado en su celda. pegajoso puede ser la concatenación de cadena de cero o más de N, E, S,
W, NE, NW, SE y SW, las direcciones de la brújula que indican los lados y las esquinas de la celda a
la que se adhiere el widget.
3.2 PIC
Un microcontrolador es un circuito integrado que en su interior contiene una unidad central de pro-
cesamiento (CPU), unidades de memoria (RAM y ROM), puertos de entrada y salida y periféricos.
Estas partes están interconectadas dentro del microcontrolador, y en conjunto forman lo que se le
conoce como microcomputadora. Se puede decir con toda propiedad que un microcontrolador es una
microcomputadora completa encapsulada en un circuito integrado [5].
3.2.1 PIC18F4550
Este pequeño gigante de 8 bits es el PIC18F4550 de Microchip, este microcontrolador cuenta con una
gran cantidad de memoria RAM, diferentes módulos de comunicación, una gran cantidad de pines de
entrada y salida y algunas otras grandes cualidades. Este microcontrolador tiene soporte nativo para
el puerto USB, tecnología nano Watt que reduce el consumo de energía durante la operación, por estas
razones este microcontrolador se convierte en la opción ideal para cualquier sistema embebido que se
quiera construir [6]. En la gura 8 se observa el datasheet del microcontrolador.
Características:
• Rango de voltaje operación: 2 V 5.5 V
• Timer0: Timer/Counter de 8 o 16 bits
• Timer1: Timer/Counter de 16 bits
• Timer2: Timer de 8 bits
• Timer3: Timer/Counter de 16 bits
• 35 Pines I/O (Entrada/Salida)
• Máxima Frecuencia de trabajo: 48 MHz
• Instrucciones: 35
• Familia de controladores / Serie: PIC18
• Tamaño del núcleo: 8 bit
• Tamaño de la memoria EEPROM: 256 Byte
• Tamaño de la memoria RAM: 2 KB
• Velocidad de CPU: 48 MHz
• Tipo de oscilador: externa, interna
• CMOS: Antiestático
• Marca: Microchip
• Modelo: PIC18F4550-I/P
• Encapsulado DIP
• 40 Pines.
9
Figura 9: Figura 8. Datasheet del PIC18F4550.
10
Figura 10: Figura 9. Registro de control y status del transmisor.
4. Metodología
4.2Diseñar una interfaz gráca de usuario en el lenguaje Python implementando la librería Tkinter
y considerando exactamente el número de elementos que se muestran en la gura 12, 5 salidas digita-
11
Figura 12: Figura 11. Registro de control del Baud-Rate.
les (5 LEDs), 5 entradas digitales (5 botones), 3 canales analógicos (voltaje, temperatura y humedad
relativa), y el envío de un mensaje de texto (ver gura 13). La interfaz debe conectar con el microcon-
trolador mediante comunicación serial.
4.3Programar el microcontrolador para permitir una comunicación entre la interfaz gráca me-
diante USB y responder correctamente a las solicitudes desde la interfaz y/o desde el hardware (ver
gura 14).
Nota: Puede emplear la librería de RS232 para microcontroladores o cualquiera que permita la comu-
nicación serial en el microcontrolador que esté empleando.
5. Resultados
12
13
Figura 15: Figura 13. Diagrama estructural general de la interfaz gráca de usuario, la cual se comunica
mediante USB con el hardware a través de una comunicación serial.
14
Figura 16: Figura 14. Diagrama estructural general de la programación del hardware para la interfaz
utilizando un microcontrolador PIC18F4550, que se comunica mediante USB con la PC a través de
una comunicación serial.
15
Figura 17: Figura 15. Montado nal del hardware implementando el microcontrolador PIC18F4550.
Figura 18: Figura 16. Diseño nal de la interfaz gráca de usuario realizada mediante el lenguaje de
programación Python, utilizando la librería Tkinter.
16
Figura 19: Figura 17. En esta gura se puede apreciar la comparación en modo manual, es decir,
mediante la pulsación de los botones físicos, el funcionamiento sincronizado de la interfaz y el hardware.
En la interfaz se observan todos los LEDs apagados al igual que en el hardware.
17
Figura 20: Figura 18. En esta gura se puede apreciar la comparación en modo manual, es decir,
mediante la pulsación de los botones físicos, el funcionamiento sincronizado de la interfaz y el hardware.
En la interfaz se observan todos los LEDs prendidos al igual que en el hardware. Asimismo, se aprecia
la lectura de los canales analógicos en la interfaz a través de los potenciómetros del hardware.
18
Figura 21: Figura 19. En esta gura se puede apreciar la comparación en modo manual, es decir,
mediante la pulsación de los botones físicos, el funcionamiento sincronizado de la interfaz y el hardware.
En la interfaz se observa escrito HOLA MUNDO al igual que en el LCD del hardware.
19
Figura 22: Figura 20. En esta gura se puede apreciar la comparación en modo digital, es decir,
mediante la pulsación de los Check Buttons de la interfaz, el funcionamiento sincronizado de la interfaz
y el hardware. En la interfaz se observan todos los Check Buttons seleccionados y todos los LEDs
prendidos al igual que en el hardware. Asimismo, se aprecia la lectura de los canales analógicos en la
interfaz a través de los potenciómetros del hardware. En la interfaz se observa escrito HOLA MUNDO
al igual que en el LCD del hardware.
20
Figura 23: Figura 21. En esta gura se puede apreciar la comparación en modo digital, es decir,
mediante la pulsación de los Check Buttons de la interfaz, el funcionamiento sincronizado de la interfaz
y el hardware. En la interfaz se observan todos los Check Buttons no seleccionados y todos los LEDs
apagados al igual que en el hardware. Asimismo, se aprecia la lectura de los canales analógicos en la
interfaz a través de los potenciómetros del hardware. En la interfaz se observa escrito HOLA MUNDO
al igual que en el LCD del hardware.
21
6. Conclusiones
Esta práctica se pudo demostrar que es posible crear nuestra propia tarjeta entrenadora con el
PIC 18F4550 siempre y cuando se tenga un correcto de las características de los componentes y de la
conguración que se desee desarrollar, como bien se puede una tarjeta con los elementos básicos, así
como una tarjeta más detallada y sosticada según los requerimientos de quien la vaya a utilizar.
7. Referencias
[7] Cruz, E. (2020). Comunicación serial UART, USART, RS232 con el PIC18F4550.
MakerElectronico. [En línea]. Disponible en:
https://www.makerelectronico.com/comunicacion-serial-uart-usart-rs232-pic18f4550/. [Accedido: 16-abril-
2020].
8. Anexos
import os
import time
import serial
from tkinter import *
from PIL import Image, ImageTk
class App():
def __init__(self):
self.ser = serialInterface()
self.root = Tk()
self.root.title("INTERFACE by NZURU")
self.root.config(bg="white")
self.root.resizable(0,0)
22
self.myframe = Frame()
self.myframe.pack(fill="both",expand="True")
self.myframe.config(bg="white")
self.myframe.config(width="650",height="500")
self.myframe.config(bd=35)
self.myframe.config(relief="groove")
self.myframe.config(cursor="hand2")
self.sensorString1 = StringVar()
self.sensorString2 = StringVar()
self.sensorString3 = StringVar()
self.sentString = StringVar()
self.b1 = IntVar()
self.b2 = IntVar()
self.b3 = IntVar()
self.b4 = IntVar()
self.b5 = IntVar()
self.controlType = IntVar()
self.B1 = Checkbutton(self.first_frame,text="Button1",fg="red",variable=self.b1)
self.B1.grid(row=2,column=1,sticky="e",padx=50,pady=20)
self.B2 = Checkbutton(self.first_frame,text="Button2",fg="red",variable=self.b2)
self.B2.grid(row=2,column=2,sticky="e",padx=50,pady=20)
self.B3 = Checkbutton(self.first_frame,text="Button3",fg="red",variable=self.b3)
self.B3.grid(row=2,column=3,sticky="e",padx=50,pady=20)
self.B4 = Checkbutton(self.first_frame,text="Button4",fg="red",variable=self.b4)
self.B4.grid(row=2,column=4,sticky="e",padx=50,pady=20)
self.B5 = Checkbutton(self.first_frame,text="Button5",fg="red",variable=self.b5)
self.B5.grid(row=2,column=5,sticky="e",padx=50,pady=20)
23
self.led1 = 0
self.led2 = 0
self.led3 = 0
self.led4 = 0
self.led5 = 0
self.on = Image.open('off.png')
self.ON = ImageTk.PhotoImage(self.on)
self.off = Image.open('on.png')
self.OFF = ImageTk.PhotoImage(self.off)
self.logo = Image.open('NZURU.png')
self.LOGO = ImageTk.PhotoImage(self.logo)
self.LOG_V = Label(self.zero_frame,image=self.LOGO)
self.LOG_V.grid(row=0,column=3,padx=50,pady=20)
24
self.labelSensor1.config(bd=10)
self.labelSensor1.config(relief="groove")
self.labelSent = Entry(self.four_frame,textvariable=self.sentString,bg="white")
self.labelSent.grid(row=0,column=1,padx=10,pady=40)
self.labelSent.config(fg="red",justify="center")
self.labelSent.config(bd=10)
self.labelSent.config(relief="groove")
self.root.after(3,self.connect_push)
self.root.mainloop()
def close(self):
self.ser.close_Serial()
def connect_push(self):
while True:
data = self.ser.data_read()
if self.controlType.get():
self.led1 = int(self.b1.get())
self.led2 = int(self.b2.get())
self.led3 = int(self.b3.get())
self.led4 = int(self.b4.get())
self.led5 = int(self.b5.get())
if self.led1:
self.LED1.configure(image=self.ON)
else:
self.LED1.configure(image=self.OFF)
if self.led2:
self.LED2.configure(image=self.ON)
else:
self.LED2.configure(image=self.OFF)
if self.led3:
self.LED3.configure(image=self.ON)
25
else:
self.LED3.configure(image=self.OFF)
if self.led4:
self.LED4.configure(image=self.ON)
else:
self.LED4.configure(image=self.OFF)
if self.led5:
self.LED5.configure(image=self.ON)
else:
self.LED5.configure(image=self.OFF)
else:
self.led1 = int(data[0])
self.led2 = int(data[1])
self.led3 = int(data[2])
self.led4 = int(data[3])
self.led5 = int(data[4])
if self.led1:
self.LED1.configure(image=self.ON)
else:
self.LED1.configure(image=self.OFF)
if self.led2:
self.LED2.configure(image=self.ON)
else:
self.LED2.configure(image=self.OFF)
if self.led3:
self.LED3.configure(image=self.ON)
else:
self.LED3.configure(image=self.OFF)
if self.led4:
self.LED4.configure(image=self.ON)
else:
self.LED4.configure(image=self.OFF)
if self.led5:
self.LED5.configure(image=self.ON)
else:
self.LED5.configure(image=self.OFF)
self.sensorString1.set(data[5])
self.sensorString2.set(data[6])
self.sensorString3.set(data[7])
s = self.sentString.get()
data = "\t{}{}{}{}{}{}\n{}".format(int(self.controlType.get()),self.led1,self.led2,self.l
self.ser.send_data(data)
self.root.update()
class serialInterface():
def __init__(self):
26
self.encoding = 'Ascii'
self.port = '/dev/ttyUSB0'
self.bauds = 115200
self.picSerial = serial.Serial(self.port,self.bauds)
time.sleep(2)
def data_read(self):
data = self.picSerial.readline()
data_str = data.decode(self.encoding)
data_sensors = self.get_values(data_str)
data_split = data_sensors.split(',')
data_int = []
for value in data_split:
data_int.append(float(value))
return data_int
def send_data(self,data):
data = data.encode()
self.picSerial.write(data)
def find_character(self,data,character):
index = 0
while index < len(data):
if data[index] == character:
return index
index += 1
return -1
def get_values(self,data):
j = self.find_character(data,"\t")
if j != -1:
w = self.find_character(data[j+1:],"\n")
return data[j+1:w+1]
def close_Serial(self):
self.picSerial.close()
self.picSerial.close()
if __name__=='__main__':
app = App()
app.close()
os.system ("clear")
#include <18f4550.h>
#device ADC =10
#include <stdint.h>
#include <stdlib.h>
#fuses HSPLL, NOWDT, NOPROTECT, NOLVP, NODEBUG, PLL2, CPUDIV1, VREGEN, NOMCLR INTRC_IO, USBDIV
#use delay (clock=48M,crystal=4000000)
#include<MLCD.c>
#use rs232(uart1,baud=115200,parity=N)//Frecuencia del reloj del pic
#define encender output_high //DEFIINIMOS LAS SALIDAS EN 1 COMO ENCENDE
#define apagar output_low //DEFINIMOS LAS SALIDAS EN 0 CONO APAGAR
27
#define led1 PIN_D7
#define led2 PIN_D6
#define led3 PIN_C0
#define led4 PIN_C1
#define led5 PIN_C2
int b1=0;
int b2=0;
int b3=0;
int b4=0;
int b5=0;
uint16_t AU[3]={0};
float AF[3]={0.0};
char buffer[30];
void readAnalogs();
char ch_recv;
char recv[10];
char lcd_buffer_f[16];
char lcd_buffer_s[16];
int i=0;
int j=0;
int first = 0;
int second = 0;
#int_RDA
void RDA_isr(){
ch_recv=getc(); //Captura el dato recibido del PIC 1
if(first==1){
recv[i] = ch_recv;
i++;
}
else if(second==1){
if(j<16)
lcd_buffer_f[j] = ch_recv;
else
lcd_buffer_s[j-16] = ch_recv;
j++;
}
if(ch_recv=='\t'){
i=0;
first = 1;
second = 0;
}
else if(ch_recv=='\n'){
j=0;
first = 0;
second = 1;
}
}
28
//HAbilita interrupcion por puerto serial
for(int l=0;l<10;l++)
recv[l] = '0';
for(int k=0;k<16;k++){
lcd_buffer_f[k] = ' ';
lcd_buffer_s[k] = ' ';
}
disable_interrupts(GLOBAL);
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
lcd_init(); //Se inicializa la LCD
while(true){
b1=input(pin_b0);
b2=input(pin_b1);
b3=input(pin_b2);
b4=input(pin_b3);
b5=input(pin_b4);
readAnalogs();
sprintf(buffer "\t%d,%d,%d,%d,%d,%.2f,%.2f,%.2f\n",b1,b2,b3,b4,b5,AF[0],AF[1],AF[2]);
printf(buffer);
if(recv[0]=='1'){
if(recv[1]=='1')
encender(led1);
else
apagar(led1);
if(recv[2]=='1')
encender(led2);
else
apagar(led2);
if(recv[3]=='1')
encender(led3);
else
apagar(led3);
if(recv[4]=='1')
encender(led4);
else
apagar(led4);
if(recv[5]=='1')
encender(led5);
else
apagar(led5);
}
else{
b1=input(pin_b0);
if(input(pin_b0)==1)
encender(led1);
else
apagar(led1);
b2=input(pin_b1);
if(input(pin_b1)==1)
encender(led2);
else
apagar(led2);
b3=input(pin_b2);
29
if(input(pin_b2)==1)
encender(led3);
else
apagar(led3);
b4=input(pin_b3);
if(input(pin_b3)==1)
encender(led4);
else
apagar(led4);
b5=input(pin_b4);
if(input(pin_b4)==1)
encender(led5);
else
apagar(led5);
}
lcd_gotoxy(1,1);
printf(lcd_putc,lcd_buffer_f);
lcd_gotoxy(1,2);
printf(lcd_putc,lcd_buffer_s);
}
}
void readAnalogs(){
set_adc_channel(0);
delay_us(20);
AU[0] = read_adc();
AF[0] = (5.0*AU[0])/1024.0;
set_adc_channel(1);
delay_us(20);
AU[1] = read_adc();
AF[1] = (5.0*AU[1])/1024.0;
set_adc_channel(2);
delay_us(20);
AU[2] = read_adc();
AF[2] = (5.0*AU[2])/1024.0;
}
30