Departamento de Ingeniería Industrial
Instrumentación
Reportes de Prácticas con Sensores y
Comunicación Serial
Aquino Alvarado Miguel
Balbi González Michele Ramón
Jaramillo Cajica Ismael
Pacheco Zepeda Juan Rafael
Pineda Torres Julio Adolfo
Contenido
Medición de iluminación y comunicación serial PIC - PC...3
Medición de iluminación y comunicación serial PIC - PC
Aquino Alvarado Miguel
Balbi González Michele Ramón
Jaramillo Cajica Ismael
Pacheco Zepeda Juan Rafael
Pineda Torres Julio Adolfo
INTITUTO TECNOLÓGICO DE COLIMA
Departamento de Ingeniería Mecatrónica
Av. Tecnológico No.1. C.P. 28976. Villa de Álvarez, Col.
Tel/Fax (01 312) 3129920. 3140933 www.itcolima.edu.mx
INTRODUCCIÓN
El censado de la iluminación de un
espacio
puede
conseguirse
fácilmente implementando un circuito
con fotorresistencias, LDR, por sus
siglas en inglés. La obtención de esta
información puede permitir el
desencadenamiento de otras
acciones, siendo el ejemplo más
común el encendido de un bombillo
cuando la iluminación desciende de
cierto nivel.
La comunicación serial (RS232) es un
método de transmisión de
información muy utilizado en el
ámbito de los microcontroladores. El
intercambio se da a nivel de bytes.
Las interfaces en computadora para
controlar circuitos a distancia
representan el hoy y el mañana de
los sistemas de automatización. Una
interfaz facilita la interacción con
éstos, ya sea para envío y/o
recepción de información.
RESUMEN
El presente reporte muestra el trabajo
realizado con un circuito de censado
de iluminación implementando un
microcontrolador, así como la
transmisión de información a un
programa escrito en C# en ambos
sentidos, mediante comunicación
serial.
PLANTEAMIENTO DEL PROBLEMA
Diseñar y construir un circuito capaz
de indicar el nivel de iluminación y
transmitir y recibir información con
una interfaz en computadora.
MARCO TEÓRICO
Material
Protoboard: Tablero con orificios
conectados eléctricamente en una
configuración estándar. Se utiliza
para conectar y probar conexiones
de circuitos electrónicos sin tener
que soldar o montar de manera
permanente los componentes.
Cables
Potenciómetro de 5 KΩ: El
potenciómetro es un dispositivo de
resistencia variable mediante una
perilla.
Resistencias
La pantalla de cristal líquido o
LCD (Liquid Crystal Display) es
un dispositivo controlado de
visualización gráfico para la
representación de caracteres. En
este caso dispone de 2 filas de 16
caracteres cada una y cada
carácter dispone de una matriz de
5x7 puntos (pixeles), aunque los
hay de otro número de filas de
caracteres. Este dispositivo está
gobernado internamente por un
microcontrolador.
Se llama microcontrolador a un
sistema de microprocesador
incluido todo él en un chip. Dentro
de este chip están incluidos la CPU
del procesador, memoria y
elementos periférico de forma que
se pueda realizar todo un sistema
de
control
simplemente
conectando los elementos
exteriores. El PIC 16F877A de
Microchip pertenece a una gran
familia de microcontroladores de 8
bits (bus de datos), posee varias
características que hacen a este
un dispositivo muy versátil,
eficiente y práctico.
El LDR (Light Dependant Resistor)
es un componente electrónico cuya
resistencia disminuye con el
aumento de intensidad de luz
incidente.
Módulo de conexión bluetooth tipo
serial:
Permite
establecer
comunicación serial con el PIC de
manera inalámbrica conectándolo
a alimentación y sus pines TX y RX
a los pines RX y TX del PIC.
Desarrollo
Lo que se está simulando con este
circuito es un sistema de censado de
iluminación natural. Un operario sería
capaz de encender o apagar
manualmente la iluminación artificial.
La configuración de esta práctica en
la parte de hardware fue muy
parecida a la que se había llevado a
cabo anteriormente: se tiene un
circuito donde el microcontrolador
PIC 16F877A capta en su módulo
convertidor ADC un valor de voltaje
generado por la LDR.
En esta ocasión se genera una
equivalencia en porcentaje de
iluminación (donde el 100% inicia
siendo 1024 de valor, el máximo
teórico) que puede ser ajustada
después.
Lo que se quiere hacer es poder
transmitir este porcentaje del PIC a
un programa escrito en C# que se
está ejecutando en la computadora,
así como recibir otros datos del
programa de PC en el PIC, sobre
todo órdenes para que ejecute ciertas
rutinas, y al ejecutarlas nuevamente
envíe datos generados con esas
funciones.
Fueron creados dos programas (el
código se muestra en los anexo).
Cada uno cuenta con una parte
dedicada al envío de datos y otra que
se encarga de la recepción de los
mismos. La lógica es la siguiente:
1. Programa del PIC: Se dedica a captar
el valor de ADC y efectuar el cálculo
de porcentaje de iluminación. La
recepción de datos se realiza con una
interrupción (INT_RDA). La letra que
se reciba (“a”, “b”, “c”, etc) le dice al
PIC qué instrucciones ejecutar. En
este caso:
“a”:
Permite
encender
manualmente la iluminación
artificial.
“b”:
Permite
apagar
manualmente la iluminación
artificial.
“c”: Esta función está pensada
para calibrar el máximo de
iluminación que se presentará
en donde se instale el sensor.
Es evidente que un máximo de
1024 no siempre será correcto,
por lo que mediante estas
instrucciones se establece el
máximo al valor presente
actualmente en el convertidor
ADC del microcontrolador.
El envío de datos se realiza
mediante un printf(). En este caso
se pueden enviar cadenas de
varios caracteres. En este caso el
programa puede enviar dos tipos
de cadena:
Iniciada con “c”: Esto le indica al
receptor de la interfaz de
computadora que este valor
debe mostrarse como una
lectura normal de iluminación.
Iniciada con “m”: En este caso el
módulo de recepción del
programa de computadora sabe
que la lectura mandada es un
valor máximo nuevo.
2.Programa de computadora: Escrito en
Visual C# 2010 Express, tenemos
cuatro pestañas:
Conexión: Los botones permiten
iniciar la conexión serial
abriendo el puerto seleccionado
(botón azul) o terminarla
cerrándolo (botón rojo).
PIC a PC: En esta parte el
programa se encarga de
desplegar el porcentaje de
iluminación actual (las cadenas
codificadas con una “c” inicial
que envía el PIC).
PC a PIC: Mediante dos botones
se puede poner en estado alto o
bajo uno de los pines del PIC,
en este caso se trabaja con el
pin B1. Para la aplicación actual
se simula algún tipo de
iluminación extra que sería
necesario encender si la zona
está pobremente iluminada.
Bidireccional: En esta sección el
programa envía una instrucción
para que el PIC realice el
calibrado
de
máxima
iluminación, y entonces
despliega el valor máximo nuevo
(que se obtiene de una cadena
codificada con una “m” inicial
que envía el PIC).
Cabe mencionar que la comunicación
realizada fue de tipo serial, pero
sobre la tecnología bluetooth. Para
poder realizar esto se debe contar
con un adaptador bluetooth para el
PIC y un aparato con bluetooth, o en
su defecto, otro adaptador para la
computadora.
Conclusión
El circuito armado fue completamente
funcional, realizando la transferencia
de datos sin problemas de pérdida de
conexión u otros.
Con esta práctica se pudieron
constatar las facilidades y
funcionalidades que proporciona la
comunicación entre un PIC y una
computadora. Es realmente cómodo
poder tomar lectura de datos en un
punto remoto y ver desplegada la
medición en un lugar centralizado.
Anexos
Código fuente del PIC
#include <16F877A.h> //llamamos el header (libreria con instrucciones y funciones basicas) especifico para el desarrollo de codigo para el PIC 16F8777A
#device ADC=10 //resolucion ADC de 10 bits
#fuses XT,NOWDT,NOPROTECT,NOLVP //preparamos el PIC para que deshabilite el WatchDogTimer, XT es para indicar la presencia de un cristal de 4MHz o menos #use delay(clock=4000000) //velocidad de reloj a 4MHz
#use rs232 (baud=9600, xmit=pin_c6, rcv=pin_c7, parity=N, stop=1, bits=8) //configuramos la comunicacion serial para hacerse con un byte a la velocidad indicada con los pines indicados sin bit de paridad y 1 bit de paro
#include <lcd.c> //librería para manejar el lcd
//---VARIABLES---float lectura,conversion,maximo; //declaramos variables del programa
char recibidor; //VARIABLE CHAR 8 BITS
//---INT.SERIAL---#int_rda //la interrupción se disparará cada que haya datos para leer en el bufer serial
void serial() //función para ejecutar con la interrupción serial {
recibidor=getc(); //recibimos el byte y lo guardamos en recibidor
switch(recibidor) //entra a case para buscar opciones (puede ser con if`s) {
case 'a': //encender luz auxiliar mandando el pin B1 a estado alto output_high(PIN_B1);
delay_ms(200); //retardo de 200 ms break;
case 'b': //apagar luz auxiliar mandando el pin B1 a estado bajo output_low(PIN_B1);
delay_ms(200); break;
case 'c': //calibrar nivel maximo de iluminacion
set_adc_channel(0); //canal 0 del adc
delay_us(20); //tiempo de espera para lectura maximo = read_adc(); //guarda variable leida en lectura
delay_ms(200);
printf("m%.0f;",maximo); //mandamos por serial (al programa de C#) el nuevo maximo
break;
default:
disable_interrupts(int_rda); //interrupcion serial break;
};
}//fin de Interrupcion RS232
void main() //function principal del programa {
enable_interrupts(GLOBAL); //habilitar interrupciones globales enable_interrupts(int_rda); //interrupcion serial
setup_adc_ports(AN0); //abilitar canales del adc de acuerdo al pic que utilices setup_adc(ADC_CLOCK_INTERNAL); //timer interno del pic se carga al adc para el muestreo
lcd_init(); //inicializar el LCD
maximo=1024; //damos al maximo de iluminacion el valor de 1024 inicialmente
while(1) //ciclo infinito {
lcd_putc( "\f"); //limpia lcd
//---LECTURA DEL
set_adc_channel(0); //canal 0 del adc
delay_us(20); //tiempo de espera para lectura
lectura = read_adc(); //guarda variable leida en lectura
conversion=(lectura*100)/maximo; //factor de conversion de %
if(conversion>100) //si el máximo dará más de 100% aumentamos máximo para evitarlo
//y volvermos a calcular el % {
maximo=lectura;
conversion=(lectura*100)/maximo;
printf("m%.0f;",maximo); // si aumentamos el máximo, lo mandamos al programa de PC
}
printf(lcd_putc, "\f Iluminacion=%.0f", conversion); //imprimimos conversion en lcd
printf(lcd_putc, "\n maximo=%.0f", maximo); //imprimimos conversion en lcd
printf("c%.0f;",conversion); //enviamos por serial el % de iluminacion
delay_ms(200);//delay lcd
}
}
Código fuente del programa de PC
using System; //se importan automaticamente una serie de librerias using System.Collections.Generic;
using System.ComponentModel; using System.Data;
using System.Drawing; using System.Linq; using System.Text;
using System.Windows.Forms; using System.IO.Ports;
namespace WindowsFormsApplication1 {
public partial class Form1 : Form {
// declaramos las variables a utilizar string[] Puertos = new string[20];
string dato_in; char caracter_final;
{
InitializeComponent();
CheckForIllegalCrossThreadCalls = false;
pserie.ReadTimeout = 1000; //espera para leer pserie.WriteTimeout = 1500; //espera para escribir
//a continuación se limpia el combobox de puertos, se leen todos los disponibles y se despliegan
cpuertos.Items.Clear();
Puertos = SerialPort.GetPortNames();
for (int i = 0; i < Puertos.Length; i++) {
cpuertos.Items.Add(Puertos[i]); }
cpuertos.SelectedIndex = 0;
cpuertos.Focus();
//todo cambio en lblstatus.text indica información que se da al usuario
lblstatus.Text = "Puertos listos.";
//en las siguientes líneas se configura la conexión del puerto serie
pserie.DataReceived += new SerialDataReceivedEventHandler(pserie_DataReceived);
if (!pserie.IsOpen) // {
ldato_in.Text = "No hay comunicación con el PIC, debe iniciarla primero";
alinear(); }
lblmaximo.Text = "";
}
//estas instrucciones permiten leer las cadenas recibidas utilizando como carácter final un punto y coma
#region Recibir RS232
private void pserie_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
Try //permite intentar ejecutar una instruccion y hacer otra cosa si falla
{
dato_in = "";
//leemos byte por byte mientras no haya un punto y coma presente while (caracter_final != ';') { caracter_final = (char)pserie.ReadChar();
//salimos cuando recibimos el punto y coma if (caracter_final == ';')
break;
dato_in += caracter_final.ToString();
}
this.Invoke(new EventHandler(Actualizar_labels)); }
catch {
MessageBox.Show("Conexion perdida, intente conectar nuevamente", "Conexion:", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
//esta funcion envia al lugar adecuado la lectura, si es de conversion o si es de valor maximo, por los caracteres iniciales ‘c’ o ‘m’
private void Actualizar_labels(object s, EventArgs e) {
label8.Text = dato_in;
if (dato_in.Substring(0, 1) == "c") {
ldato_in.Text = dato_in.Substring(1,dato_in.Length-1) + " %"; barrailu.Value = Convert.ToInt32(dato_in.Substring(1,dato_in.Length-1));
}
else if (dato_in.Substring(0, 1) == "m") {
{
lblmaximo.Text = dato_in.Substring(1, dato_in.Length - 1); }
alinear(); }
}
//alineamos las etiquetas viendo los pixels libres a cada lado y con la ventana private void alinear()
{
ldato_in.Left = (tabpicapc.Size.Width - ldato_in.Size.Width) / 2; lblmaximo.Left = (tabbidireccional.Size.Width - lblmaximo.Size.Width) / 2;
}
#endregion
//el boton conectar abre el Puerto que esté seleccionado en el combobox de puertos
private void bconectar_Click(object sender, EventArgs e) {
lblstatus.Text = "Abriendo Puerto"; try
{
if (pserie.IsOpen) {
pserie.Close(); }
pserie.PortName = cpuertos.SelectedItem.ToString(); if (!pserie.IsOpen)
{
pserie.Open(); }
lblstatus.Text = "Puerto " + pserie.PortName + " abierto."; ldato_in.Text = "Esperando datos.";
lblmaximo.Text = "Esperando datos."; alinear();
}
catch (Exception) {
lblstatus.Text = "No se pudo abrir el puerto " + pserie.PortName + ".";
} }
//el boton desconectar Cierra la comunicacion
private void bdesconectar_Click(object sender, EventArgs e) {
try {
pserie.Close();
lblstatus.Text = "Puerto " + pserie.PortName + " cerrado.";
ldato_in.Text = "No hay comunicación con el PIC, debe iniciarla primero";
barrailu.Value=0; lblmaximo.Text = ""; ldato_in.Text = ""; alinear();
label8.Text = ""; }
catch (Exception) {
MessageBox.Show("No se pudo cerrar el puerto.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning);
} }
//tenemos un boton actualizar que vuelve a leer los puertos disponibles private void button4_Click(object sender, EventArgs e)
{
try {
cpuertos.Items.Clear();
Puertos = SerialPort.GetPortNames();
for (int i = 0; i < Puertos.Length; i++) {
cpuertos.Items.Add(Puertos[i]); }
cpuertos.SelectedIndex = 0;
cpuertos.Focus();
lblstatus.Text = "Puertos actualizados."; }
catch {
lblstatus.Text = "Primero se debe abrir el puerto."; }
}
//estas lineas se ejecutan si se Cierra el programa
private void Form1_FormClosing(object sender, FormClosingEventArgs e) {
if ((MessageBox.Show("¿Seguro que desea salir?", "Saliendo", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No))
{
e.Cancel = true; }
else {
pserie.Close(); e.Cancel = false; }
}
//para calibrar el maximo enviamos una “c”
private void bcalibrar_Click(object sender, EventArgs e) {
try {
pserie.Write("c");
lblstatus.Text = "Se calibró el nivel máximo de iluminación."; }
catch {
lblstatus.Text = "Primero se debe abrir el puerto."; }
}
//para encender el pin enviamos una “a”
private void button1_Click_1(object sender, EventArgs e) {
try {
pserie.Write("a");
lblstatus.Text = "Luz auxiliar encendida."; }
catch {
lblstatus.Text = "Primero se debe abrir el puerto."; }
}
//para apagar el pin enviamos una “b”
private void button2_Click(object sender, EventArgs e) {
try {
pserie.Write("b");
lblstatus.Text = "Luz auxiliar apagada."; }
catch {
lblstatus.Text = "Primero se debe abrir el puerto."; }
} } }
Medición de temperatura y comunicación serial PIC - PC
Aquino Alvarado Miguel
Balbi González Michele Ramón
Jaramillo Cajica Ismael
Pacheco Zepeda Juan Rafael
Pineda Torres Julio Adolfo
INTITUTO TECNOLÓGICO DE COLIMA
Departamento de Ingeniería Mecatrónica
Av. Tecnológico No.1. C.P. 28976. Villa de Álvarez, Col.
Tel/Fax (01 312) 3129920. 3140933 www.itcolima.edu.mx
INTRODUCCIÓN
Dispositivos como el integrado LM35
proporcionan una técnica simple para
medir temperatura y crear un
termómetro. Conocer el valor de la
temperatura es útil en sistemas
donde ésta variable se vuelve crítica
y es necesario mantenerla a cierto
nivel, accionando un ventilador, por
ejemplo.
La comunicación serial (RS232) es un
método de transmisión de
información muy utilizado en el
ámbito de los microcontroladores. El
intercambio se da a nivel de bytes.
Las interfaces en computadora para
controlar circuitos a distancia
representan el hoy y el mañana de
los sistemas de automatización. Una
interfaz facilita la interacción con
éstos, ya sea para envío y/o
recepción de información.
RESUMEN
Con la práctica que se resume en
este reporte se pretende medir la
temperatura de manera continua y
desplegar la información en una
interfaz de computadora creada
expresamente para este circuito.
PLANTEAMIENTO DEL PROBLEMA
Diseñar y construir un circuito capaz
de medir temperatura y transmitir y
recibir información con una interfaz
en computadora.
MARCO TEÓRICO
Material
conectados eléctricamente en una
configuración estándar. Se utiliza
para conectar y probar conexiones
de circuitos electrónicos sin tener
que soldar o montar de manera
permanente los componentes.
Cables
Potenciómetro de 5 KΩ: El
potenciómetro es un dispositivo de
resistencia variable mediante una
perilla.
Resistencias
La pantalla de cristal líquido o
LCD (Liquid Crystal Display) es
un dispositivo controlado de
visualización gráfico para la
representación de caracteres. En
este caso dispone de 2 filas de 16
caracteres cada una y cada
carácter dispone de una matriz de
5x7 puntos (pixeles), aunque los
hay de otro número de filas de
caracteres. Este dispositivo está
gobernado internamente por un
microcontrolador.
Se llama microcontrolador a un
sistema de microprocesador
incluido todo él en un chip. Dentro
de este chip están incluidos la CPU
del procesador, memoria y
elementos periférico de forma que
se pueda realizar todo un sistema
de
control
simplemente
conectando los elementos
exteriores. El PIC 16F877A de
Microchip pertenece a una gran
familia de microcontroladores de 8
bits (bus de datos), posee varias
características que hacen a este
un dispositivo muy versátil,
eficiente y práctico.
LM35: El LM35 es un sensor de
temperatura con una precisión
calibrada grados Celsius. Su rango
de medición abarca desde -55°C
hasta 150°C. La salida es lineal y
cada grado centígrado equivale a
10mV.
Módulo
de
conexión bluetooth tipo serial:
Permite establecer comunicación
serial con el PIC de manera
inalámbrica conectándolo a
alimentación y sus pines TX y RX a
los pines RX y TX del PIC.
Desarrollo
Lo que se está simulando con este
circuito termómetro que transmite su
lectura a una estación remota. Existe
un sistema de control que determina
si se enciende un ventilador dada una
temperatura máxima permitida. Un
operario sería capaz de encender o
apagar manualmente el ventilador o
de modificar la temperatura máxima
permitida.
La configuración de esta práctica en
la parte de hardware fue muy
parecida a la que se había llevado a
cabo anteriormente: se tiene un
circuito donde el microcontrolador
PIC 16F877A capta en su módulo
convertidor ADC un valor de voltaje
generado por el LM35.
Se quiere enviar la lectura del PIC a
un programa escrito en C# que se
está ejecutando en la computadora,
así como recibir otros datos del
programa de PC en el PIC, sobre
todo órdenes para que ejecute ciertas
rutinas, y al ejecutarlas nuevamente
envíe datos generados con esas
funciones.
Fueron creados dos programas (el
código se muestra en los anexos).
Cada uno cuenta con una parte
dedicada al envío de datos y otra que
se encarga de la recepción de los
mismos. La lógica es la siguiente:
1. Programa del PIC: Se dedica a captar
el valor de ADC y efectuar el cálculo
de temperatura. La recepción de
datos se realiza con una interrupción
(INT_RDA). La letra que se reciba
(“a”, “b”, “c”, etc) le dice al PIC qué
instrucciones ejecutar. En este caso:
a. “a”:
Permite
encender
manualmente el ventilador.
b. “b”:
Permite
apagar
manualmente el ventilador.
c. “c”: Se incrementa en 5°C el
límite de temperatura.
d. “c”: Se disminuye en 5°C el
límite de temperatura.
El envío de datos se realiza
mediante un printf(). En este caso
se pueden enviar cadenas de
varios caracteres. En este caso el
programa puede enviar dos tipos
de cadena:
Iniciada con “c”: Esto le indica al
receptor de la interfaz de
computadora que este valor
debe mostrarse como una
lectura normal de temperatura.
Iniciada con “m”: En este caso el
módulo de recepción del
programa de computadora sabe
que la lectura mandada es un
valor máximo nuevo.
2.Programa de computadora: Escrito en
Visual C# 2010 Express, tenemos
cuatro pestañas:
a. Conexión: Los botones permiten
iniciar la conexión serial
abriendo el puerto seleccionado
(botón azul) o terminarla
cerrándolo (botón rojo).
b. PIC a PC: En esta parte el
programa se encarga de
desplegar la temperatura actual
(las cadenas codificadas con
una “c” inicial que envía el PIC).
c. PC a PIC: Mediante dos botones
se puede poner en estado alto o
bajo uno de los pines del PIC,
en este caso se trabaja con el
pin B1. Para la aplicación actual
se simula un ventilador.
d. Bidireccional: En esta sección el
programa puede enviar una
instrucción para aumentar el
límite de temperatura o bajarlo y
entonces se despliega el valor
máximo nuevo (que se obtiene
de una cadena codificada con
una “m” inicial que envía el PIC).
Conclusión
El circuito armado fue completamente
funcional, realizando la transferencia
de datos sin problemas de pérdida de
conexión u otros.
Anexos
Código para el PIC 16F877A
#include <16F877A.h> //llamamos el header (libreria con instrucciones y funciones basicas) especifico para el desarrollo de codigo para el PIC 16F8777A
#device ADC=10 //resolucion ADC de 10 bits
#fuses XT,NOWDT,NOPROTECT,NOLVP //preparamos el PIC para que deshabilite el WatchDogTimer, XT es para indicar la presencia de un cristal de 4MHz o menos #use delay(clock=4000000) //velocidad de reloj a 4MHz
#use rs232 (baud=9600, xmit=pin_c6, rcv=pin_c7, parity=N, stop=1, bits=8) //configuramos la comunicacion serial para hacerse con un byte a la velocidad indicada con los pines indicados sin bit de paridad y 1 bit de paro
#include <lcd.c> //librería para manejar el lcd
//---VARIABLES---float lectura,conversion,maximo; //declaramos las variables que usaremos int forzar;
char recibidor;
//---INT.SERIAL---#int_rda //código ejecutado cuando hay datos en el bufer del serial void serial()
{
recibidor=getc(); //recibimos el byte y lo guardamos en recibidor
switch(recibidor) //entra a case para buscar opciones (puede ser con if`s) {
case 'a': //encender ventilador forzar=1;
output_high(PIN_B1);
printf(lcd_putc, "\f E manual."); delay_ms(1000);
break;
case 'b': //apagar ventilador forzar=0;
output_low(PIN_B1);
printf(lcd_putc, "\f A manual."); delay_ms(1000);
break;
case 'c':
printf(lcd_putc, "\f Temp ++"); maximo=maximo+5;
printf("m%.0f;",maximo); delay_ms(1000);
break;
case 'd':
printf(lcd_putc, "\f Temp --"); maximo=maximo-5;
printf("m%.0f;",maximo); delay_ms(1000);
break;
default:
disable_interrupts(INT_RDA); break;
//} };
}//fin de Interrupcion RS232
void main() {
enable_interrupts(GLOBAL);
enable_interrupts(INT_RDA); //INTERRUPCION SERIAL
setup_adc_ports(AN0); //habilitar canales del adc de acuerdo al pic que se usa setup_adc(ADC_CLOCK_INTERNAL); //timer interno del pic se carga al adc para el muestreo
lcd_init();
maximo=100;
while(1) {
lcd_putc( "\f"); //LIMPIA LCD
//---LECTURA DEL
set_adc_channel(0); //canal 0 del adc
delay_us(20); //tiempo de espera para lectura
lectura = read_adc(); //guarda variable leida en lectura
conversion=(lectura/2)-4; //factor de conversion de temperatura
if(conversion>maximo && forzar==0) {
output_high(pin_b1);
printf(lcd_putc, "\f ventilador encendido."); delay_ms(1000);
}
if(conversion<=maximo && forzar==0){ output_low(pin_b1);
printf(lcd_putc, "\f ventilador apagado."); //imprimimos conversion en lcd
delay_ms(1000); }
printf(lcd_putc, "\f temp=%.0f", conversion); //imprimimos conversion en lcd
printf(lcd_putc, "\n maximo=%.0f", maximo); //imprimimos conversion en lcd
//enviamos cadena de conversión con el carácter ‘c’ printf("c%.0f;",conversion);
delay_ms(1000);//DELAY LCD
}
}
Código del programa de PC
//se importan automaticamente una serie de librerias using System;
using System.Collections.Generic; using System.ComponentModel; using System.Data;
using System.Drawing; using System.Linq; using System.Text;
using System.Windows.Forms; using System.IO.Ports;
namespace WindowsFormsApplication1 {
public partial class Form1 : Form {
string[] Puertos = new string[20];
string dato_in; char caracter_final;
public Form1() //al abrir el programa se ejecuta lo siguiente {
InitializeComponent();
CheckForIllegalCrossThreadCalls = false;
pserie.ReadTimeout = 1000; //espera para leer pserie.WriteTimeout = 1500; //espera para escribir
//a continuación se limpia el combobox de puertos, se leen todos los disponibles y se despliegan
cpuertos.Items.Clear();
Puertos = SerialPort.GetPortNames();
for (int i = 0; i < Puertos.Length; i++) {
cpuertos.Items.Add(Puertos[i]); }
cpuertos.SelectedIndex = 0;
cpuertos.Focus();
//todo cambio en lblstatus.text indica información que se da al usuario lblstatus.Text = "Puertos listos.";
//en las siguientes líneas se configura la conexión del puerto serie
pserie.DataReceived += new SerialDataReceivedEventHandler(pserie_DataReceived);
lblstatus.Text = "Puertos listos.";
pserie.DataReceived += new SerialDataReceivedEventHandler(pserie_DataReceived);
if (!pserie.IsOpen) {
ldato_in.Text = "No hay comunicación con el PIC, debe iniciarla primero";
alinear(); }
//lblmaximo.Text = ""; lblref.Text = "";
}
//estas instrucciones permiten leer las cadenas recibidas utilizando como carácter final un punto y coma
#region Recibir RS232
private void pserie_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
try {
dato_in = "";
//leemos byte por byte mientras no haya un punto y coma presente while (caracter_final != ';')
{
caracter_final = (char)pserie.ReadChar();
//salimos cuando recibimos el punto y coma if (caracter_final == ';')
break;
dato_in += caracter_final.ToString();
}
this.Invoke(new EventHandler(Actualizar_labels)); }
catch {
MessageBox.Show("Conexion perdida, intente conectar nuevamente", "Conexion:", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
//esta funcion envia al lugar adecuado la lectura, si es de conversion o si es de valor maximo, por los caracteres iniciales ‘c’ o ‘m’
private void Actualizar_labels(object s, EventArgs e) {
label8.Text = dato_in;
ldato_in.Text = dato_in;
if (dato_in.Substring(0, 1) == "c") {
ldato_in.Text = dato_in.Substring(1, dato_in.Length - 1);
}
else if (dato_in.Substring(0, 1) == "m") {
{
lblref.Text = dato_in.Substring(1, dato_in.Length - 1); }
}
alinear();
}
//alineamos las etiquetas viendo los pixels libres a cada lado y con la ventana private void alinear()
ldato_in.Left = (tabpicapc.Size.Width - ldato_in.Size.Width) / 2; //lblmaximo.Left = (tabbidireccional.Size.Width -lblmaximo.Size.Width) / 2;
}
#endregion
//el boton conectar abre el Puerto que esté seleccionado en el combobox de puertos
private void bconectar_Click(object sender, EventArgs e) {
lblstatus.Text = "Abriendo Puerto"; try
{
if (pserie.IsOpen) {
pserie.Close(); }
pserie.PortName = cpuertos.SelectedItem.ToString(); if (!pserie.IsOpen)
{
pserie.Open(); }
lblstatus.Text = "Puerto " + pserie.PortName + " abierto."; ldato_in.Text = "Esperando datos.";
//lblmaximo.Text = "Esperando datos."; alinear();
}
catch (Exception) {
lblstatus.Text = "No se pudo abrir el puerto " + pserie.PortName + ".";
} }
//el boton desconectar Cierra la comunicacion
private void bdesconectar_Click(object sender, EventArgs e) {
try {
pserie.Close();
lblstatus.Text = "Puerto " + pserie.PortName + " cerrado.";
ldato_in.Text = "No hay comunicación con el PIC, debe iniciarla primero";
//lblmaximo.Text = ""; ldato_in.Text = ""; alinear();
label8.Text = ""; }
catch (Exception) {
MessageBox.Show("No se pudo cerrar el puerto.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning);
} }
//tenemos un boton actualizar que vuelve a leer los puertos disponibles private void button4_Click(object sender, EventArgs e)
{
try {
cpuertos.Items.Clear();
Puertos = SerialPort.GetPortNames();
for (int i = 0; i < Puertos.Length; i++) {
cpuertos.Items.Add(Puertos[i]); }
cpuertos.SelectedIndex = 0;
cpuertos.Focus();
lblstatus.Text = "Puertos actualizados."; }
catch {
lblstatus.Text = "Primero se debe abrir el puerto."; }
}
//estas lineas se ejecutan si se Cierra el programa
private void Form1_FormClosing(object sender, FormClosingEventArgs e) {
if ((MessageBox.Show("¿Seguro que desea salir?", "Saliendo", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No))
{
e.Cancel = true; }
else {
pserie.Close(); e.Cancel = false; }
}
//para encender el ventilador enviamos una “a”
private void button1_Click_1(object sender, EventArgs e) {
try {
pserie.Write("a");
lblstatus.Text = "Ventilador encendido."; }
catch {
lblstatus.Text = "Primero se debe abrir el puerto."; }
}
//para apagar el ventilador enviamos una “b”
private void button2_Click(object sender, EventArgs e) {
try {
pserie.Write("b");
lblstatus.Text = "Ventilador apagado."; }
catch {
lblstatus.Text = "Primero se debe abrir el puerto."; }
}
//para subir el límite de temperatura enviamos una “c”
private void bsubir_Click(object sender, EventArgs e) {
try {
pserie.Write("c"); }
catch {
lblstatus.Text = "Primero se debe abrir el puerto."; }
}
//para bajar el límite de temperatura enviamos una “d”
private void bbajar_Click(object sender, EventArgs e) {
try {
pserie.Write("d"); }
catch {
lblstatus.Text = "Primero se debe abrir el puerto."; }
} }
}