Quinta Unidad. Práctica 3.1
Enviar datos desde PC - PIC
Comunicación PC-PIC Temperatura y Luz
Oscar Hiram Álvarez Campos Monroy Guerrero José Carlos Jaime Moisés Benavides Chiñas Edgar Gilberto Vargas Contreras Jaime Flores Cisneros
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
Objetivos:
Diseñar una Interfaz Gráfica en C# para comunicar la PC con el PIC en ambas direcciones
Realizar la comunicación PIC-PC por medio de puerto serie.
Utilizar la interfaz del sensor de Temperatura y Luz para adaptarlo yenviar una señal desde la interfaz hacia el microcontrolador para que realice alguna acción.
Explicar como conectar el pic por el modulo Bluetooth RS232.
Introducción:
Primeramente definiremos los conceptos básicos para realizar la comunicación del PIC-PC, los cuales son RS232, UART y Comunicación Serial.
Comunicación Serial:
La comunicación serial es una interfaz de comunicaciones de datos digitales utilizado por computadoras y periféricos, donde la información es transmitida bit por bit, enviando solamente un bit a la vez.
Una analogía para comparar la comunicación serie con paralelo sería una carretera tradicional de un carril (comunicación serial) y una carretera de varios carriles (paralelo).
Fig. 1 Autopista 1 carril, solo puede circular un carro a la vez.
La comunicación serial solo puede enviar un bit a la vez uno tras otro.
Esto puede presentar un problema si por ejemplo queremos enviar un dato donde se repitan bits por ejemplo: 1101001.
¿Cómo sabe el ordenador si le llegaron dos 1’s o más?.
Es decir si pudiéramos visualizar el 1 como color rojo y el 0 como color blanco, si enviamos dos 1’s veríamos simplemente rojo no podríamos saber cuántos 1’s fueron. Es por ello que se utilizan señales de reloj.
Fig2. Señal de Reloj
Si se utiliza una señal de reloj (cambia de color rojo a blanco cada cierto tiempo), cuando mande un pulso el reloj (color rojo) es cuando recibe un bit el puerto serie, para el ejemplo del imagen el reloj tuvo que parpadear 8 veces para poder registrar el byte (8 bits). Esto es
precisamente el USART
(Universal Synchronous Receiver Transmitter) Transmisor Receptor
Universal Síncrono porque se sincroniza con una señal de reloj. Por otro lado el UART (Universal
Asynchronous Receiver
Transmitter) Transmisor Receptor Universal Asíncrono, no utiliza una señal de reloj utiliza bits de inicio y bits de paro. UART Toma bytes de datos y transmite bits
individuales de manera
secuencial, al llegar a su destino otro UART ensambla los bits para formar el byte original.
RS232
Recommended Estándar 232es una interfaz que designa una norma para el intercambio de una serie de datos binarios entre un DTE (Equipo terminal de datos) y un DCE (Equipo de comunicación de datos).
En RS232 Hay dos líneas de datos RX y TX donde una es transmisor y otro receptor.
Fig. 3 RS232
El conector más común RS232 Es la versión de 9 pines DE-9.
Fig4. Conector DE-9
Aunque para nuestras prácticas utilizaremos solo 4 pines Vcc (Voltaje de alimentación), GND, TX y RX.
´
Para la parte del interfaz es importante definir primeramente que la programación no es una programación estructurada como la utilizada para programar el PIC (la ejecución del programa se realiza línea por línea), para la interfaz se utilizará un lenguaje de programación orientado a objetos C#, en este tipo de lenguajes, cada objeto tiene una propiedad y una función o subrutina, estas subrutinas pueden ser llamadas por medio de botones, cuadros de texto, etiquetas, etc.
Fig. 5 Formulario con un botón en Visual C# con sus propiedades. El interfaz se realizará en Microsoft Visual C# Express. En la imagen se aprecia un formulario en Visual C# junto con un botón, este botón podría ser programado por ejemplo para escribir un mensaje en pantalla. Material:
1. Potenciómetros de 5k
Fig6. Potenciómetro 2. Protoboard.
Fig. 7 Protoboard
3. Cables de conexión Dupont. 4. Multímetro.
5. Microcontrolador Pic16f877a
Fig. 8 Pic16f877a 6. Display LCD 2x16.
Fig. 9 LCD 2X16 7. Programador de pic 8. Resistencias eléctricas 9. Dipswitch
10. Fotoresistencia (LDR) con un máximo de 5mOhms
Fig. 10 Diferentes LDR en el mercado.
11. Cristal de cuarzo a 4Mhz
Fig. 11 Cristal de Cuarzo.
12. Modulo Bluetooth Serial RS232
Fig. 12 Modulo Bluetooth
13. Sensor de Temperatura LM35
Fig. 13 LM35 Sensor de temperatura
Desarrollo de la práctica
Primero se realizó el interfaz en Visual C#, se recomienda investigar un poco sobre la programación Orientada a Objetos, sobre clases, etc. En el siguiente sitio Web existen muchos tutoriales al respecto: http://www.csharpya.com.ar/ También se recomienda empezar a visualizar las ventanas y propiedades de los objetos en el compilador para familiarizarse con el entorno.
1.- Insertaremos las etiquetas (labels) a utilizar, una etiqueta es un texto (ojo no es un cuadro de texto) que nos puede ayudar a identificar objetos poner mensajes o dar presentación al trabajo.
Fig. 14 Barra de herramientas VISUAL C#
Para insertar las etiquetas nos vamos hacia la parte superior derecha donde dice “cuadro de herramientas” (CTRL+W,X). Dentro del cuadro buscamos la sección “label” e insertamos las etiquetas deseadas.
Una vez insertada etiqueta nos damos clic en la sección “propiedades”.
Fig. 15 Barra de propiedades
Una vez seleccionado
“propiedades” damos clic al
“objeto” que deseamos
modificar, en este caso el label. Del lado derecho nos aparecerán
todas sus propiedades. Fig. 16 Propiedades del label
En este cuadro podemos apreciar todas las propiedades que podemos modificar a nuestro gusto por ejemplo:
Font: Tipo de letra, negrita, tamaño.
Forecolor: Color de la etiqueta. Location: Localización de la etiqueta por coordenadas.
Size: Tamaño de la etiqueta. Text: Texto de la etiqueta.
OJO: NO SE DEBE CONFUNDIR LA PROPIEDAD “TEXT” CON LA PROPIEDAD “NAME” .
La propiedad Text es el texto que aparece en la etiqueta, la opción name será el nombre de la etiqueta, si dentro de nuestra programación queremos utilizar esta etiqueta tendremos que referirnos siempre por su “name”.
Ahora insertaremos un
combobox, 2 buttons y 2 picturebox utilizando el mismo método que utilizamos para insertar el label.
Fig. 17 Cuadro de herramientas
De igual modo podemos modificar sus propiedades haciendo clic en propiedades y en el objeto.
Para lograr la apariencia que tiene la interfaz, se utilizaron las
propiedades de
BackgroundImage,
BackgroundColor,BackGroundIma geLayout y FlatStyle.
Fig. 18 Propiedades del boton
Se descargó la imagen que se quiere que tenga el botón y se da click en BackGroundImage, recurso local e importar la imagen.
Fig. 19 Importar imagen a boton
Por último en la ventana de propiedades añadiremos los objetos “ Serial port y status strip”.
Las propiedades del “Serial Port” se deben configurar de la siguiente manera:
Fig. 20 Propiedades puerto serie
Jugando con las propiedades del Form, de los botones y de los label se dio la siguiente apariencia a la interfaz:
Fig. 21 Interfaz
Nota los componentes quedaron así:
Labels:
“Comunicación serial”
“Puertos”
“Estado del pic”
“Led a ecender” “Abrir/cerrar” “Actualizar” Buttons:
Boton amarillo, verde y botones azules arriba-abajo.
Picturebox:
Abrir-cerrar bluetooth y actualizar.
Una vez terminada la parte gráfica pasamos a los anexos a ver la parte de la programación, es importante recalcar que para programar cada botón se debe hacer doble click en él e introducir el código que realizará o seleccionar el botón e ir hacia la parte “eventos” click:
Fig. 22 Evento click del boton
Es más rápido dar simplemente doble click pero a veces puede ocasionar errores.
Explicaremos un poco la parte de la programación del botón que se encarga de enviar la señal hacia el pic.
private void button4_Click_1(object sender, EventArgs e) //Botones de referencia /enviar dato a pic
{ try {
puerto_serie.Write("u"); // Se envia el caracter "u" por el puerto serie hacia el pic, este lo recibira con getc()
}
catch (Exception) {
toolStripStatusLabel1.Text = "Puerto cerrado hay que abrirlo";
} }
Como podemos observar, lo que este botón realiza es enviar debido al comando “Write” un carácter “u”(UP) , lo que nos indica que se debe aumentar la referencia
Para el sensor de Luz receptor=getc(); switch(receptor) { case 'u': lim=lim+5; delay_ms(10); break; case 'd': lim=lim-5; delay_ms(10); break; default:
disable_interrupts(INT_RDA); break; }
Para el sensor de temperatura
Get=getc(); switch(Get) { case 'u': lim=lim+(5*54/26.2); delay_ms(10); break; case 'd': lim=lim-(5*54/26.2); delay_ms(10); break; default: disable_interrupts(INT_RDA); //INTERRUPCION SERIAL break; }
Como se observa, el programa cada vez que se haga click en el botón de subir referencia se enviará una letra U y la referencia se aumentará un 5 para el sensor de luz y un 5° para el de temperatura. Por el contrario cuando se intenta disminuir se envía una letra d(down) y la referencia se disminuye en 5 para el sensor de luz y un 5° para el de temperatura.
CONEXIÓN BLUETOOTH
Para realizar la conexión por puerto serie debido a que la mayoría de las laptop no cuentan con entrada para puerto serie, es necesario utilizar otros métodos. Un método es utilizar el MAX232 y un adaptador Puerto serie a USB. En nuestras prácticas se utilizó el Módulo mencionado en la sección de Materiales.
La conexión física del Módulo se hace muy similar a la conexión en proteus.
Fig. 23 Conexión puerto serie proteus
En proteus se conecta el COMPIM Rx con Rx y Tx con Tx.
Físicamente el módulo tiene 6 terminales nosotros solo ocuparemos 4, TXD,RXD,VCC y GND.
Fig. 24 Modulo Bluetooth RS232
Se conecta Vcc a voltaje de alimentación (de 3.3 a 5v).
GND a tierra.
TXD, Al pin RXD del pic en la datasheet podemos ver que pin es, en el caso del PIC16F877a es la terminal 26.
RXD, al pin TXD del pic que es el pin 25.
En nuestro caso utilizamos el software Bluesoleil para configurar el Bluetooth, en la
pestaña de
“Herramientas/Mibluetooth
Dispositivo/UART/” se pone la siguiente configuración:
Fig. 25 Configuracion del bluetooth.
Esta configuración debe coincidir con la configuración del puerto serie en Visual C# y con la configuración del PIC en CSS.
ANEXOS
CODIGO DEL PROGRAMA
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; //Al igual que al principio del programa del pic
se definen las librerías, estas vienen por default.
using System.IO.Ports; //Esta librería se tiene que agregar Input/Output
Ports para poder utilizar los puertos de entrada y salida.
namespace Comunicacion_Serial {
public partial class serial_com : Form
{ // Declaramos las variables globales un vector string de 20 posiciones, una variable string y un caracter
#region Variables Globales string[] Puertos = new string[20];
string datos_entrantes; char caracter_final;
#endregion // Los #region son una manera
organizada de estructurar la programación, se puede prescindir de ellos
public serial_com() {
InitializeComponent();
//deshabilita excepciones en subprocesos (deshabilita la coordinación de subprocesos)
CheckForIllegalCrossThreadCalls = false;
puerto_serie.ReadTimeout = 1000; //tiempo de espera para leer (Equivalente a delay_ms)
puerto_serie.WriteTimeout = 1500; //tiempo de espera para escribir
Puertos = SerialPort.GetPortNames(); //Añadimos los puertos disponibles en el vector "puertos"
comboBox2.Items.Clear(); //Se limpia el combobox
for (int i=0; i<Puertos.Length;i++) //Con este ciclo se agregan los puertos al combobox para poder seleccionarlos
{
comboBox2.Items.Add(Puertos[i]);
}
comboBox2.Text=comboBox2.Items[0].ToString(); comboBox2.Focus();
toolStripStatusLabel1.Text="Conectado"; // Se pone un mensaje de "conectado" en la barra de estado
puerto_serie.DataReceived += new
SerialDataReceivedEventHandler(Puerto_Serial_DataRecived);
}
En esta parte del programa se reciben los datos
#region RecibirRS232
private void Puerto_Serial_DataRecived(object sender,
SerialDataReceivedEventArgs e) //Programamos la recepción de datos del pic
{
try // Un try es similar a un if, si no se puede realizar lo que hay dentro del try se va hacia el catch
{
datos_entrantes = ""; // Se limpia la cadena datos entrantes
caracter_final = (char)0;
while (caracter_final !=';') // Cuando el PIC envié un ";" quiere decir que termino de enviar el dato
{ // por lo tanto mientras que no se reciba un ";" el ciclo while estará leyendo
caracter_final = (char)puerto_serie.ReadChar(); // Se recibe en caracter_final el dato que envie el PIC por puerto serie
if (caracter_final == ';') // Si se recibe el ";" se sale del ciclo con un break
break;
datos_entrantes += caracter_final.ToString(); //A la cadena datos_entrantes se le suma cada char que se lee convertido a string
}
this.Invoke(new EventHandler(actualizar_labels)); // Se llama a la funcion actualizar_labels
} catch
{ // Si no se puede realizar el try se desplega el sieguiente mensaje, podemos cambiar el texto, el icono, el boton, etc.
MessageBox.Show("Conexión perdida, intente de nuevo","Error",MessageBoxButtons.OK,MessageBoxIcon.Error);
}
}
private void actualizar_labels(object s, EventArgs e) {
label1.Text = "Sensor:" + datos_entrantes; // Se le asgina a la etiqueta la palabra "sensor" + lo que contenga la cadena datos_entrantes
}
#endregion
private void abrir_Click(object sender, EventArgs e) //boton abrir puerto
{
toolStripStatusLabel1.Text = "Abriendo Puerto"; // Se pone el mensaje de "abriendo puerto" en la barra de estado
try {
if (puerto_serie.IsOpen) // Si un puerto estaba previamente abierto se cierra
{
puerto_serie.Close(); }
puerto_serie.PortName = comboBox2.SelectedItem.ToString(); // Se pone el nombre del puerto seleccionado en el combobox
if (!puerto_serie.IsOpen) {
puerto_serie.Open(); }
toolStripStatusLabel1.Text = "Puerto " + puerto_serie.PortName + " Abierto"; //Se pone en la barra de estado "Puerto"
//+ el nombre del puerto + "abierto"
}
catch(Exception) //Si no entra al try se despliega el siguiente mensaje en la barra de estado
{
toolStripStatusLabel1.Text = " No se pudo abrir " + puerto_serie.PortName;
} }
private void cerrar_Click(object sender, EventArgs e) //Cerrar puertos
{
try {
puerto_serie.Close(); //Se cierra e puerto que este abierto
toolStripStatusLabel1.Text= "Puerto " + puerto_serie.PortName + " cerrado"; // Se despliega en la barra de estado el puerto que cerro
}
catch(Exception) {
MessageBox.Show("No se pudo abrir el puerto", "Error",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
} }
private void refresh_Click(object sender, EventArgs e) //Boton actualizar
{
try {
Puertos = SerialPort.GetPortNames(); comboBox2.Items.Clear();
{
comboBox2.Items.Add(Puertos[i]); }
comboBox2.Text = comboBox2.Items[0].ToString(); comboBox2.Focus();
toolStripStatusLabel1.Text = "Puertos Actualizados"; }
catch(Exception) {
toolStripStatusLabel1.Text = "Puertos Cerrados abrelos"; }
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
//Este evento se activa cuando se da clic en la cruz para cerrar
{
if ((MessageBox.Show("¿Nos vas a abandonar :(?", "Saliendo RS-232", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)) {
e.Cancel = true; }
else {
puerto_serie.Close();
e.Cancel = false; // Se muestra un cuadro preguntando si se desea salir, si se da clic en YES, e.cancel = true y se cierra el form
} }
private void button1_Click(object sender, EventArgs e) //Encender un led/enviar dato a pic
{ try {
puerto_serie.Write("r"); // Se envia el caracter "r" por el puerto serie hacia el pic, este lo recibira con getc()
toolStripStatusLabel1.Text = "LED AMARILLO"; // Se escribe en la barra de texto "led amarillo"
}
catch(Exception) {
toolStripStatusLabel1.Text = "Puerto cerrado hay que abrirlo"; // Si no se cumple el try es porque no se ha abierto el puerto
}
}
private void button3_Click(object sender, EventArgs e) {
{
puerto_serie.Write("g"); // Se envia el caracter "g" por el puerto serie hacia el pic, este lo recibira con getc()
toolStripStatusLabel1.Text = "LED verde"; // Se escribe en la barra de texto "led verde"
}
catch (Exception) {
toolStripStatusLabel1.Text = "Puerto cerrado hay que abrirlo"; // Si no se cumple el try es porque no se ha abierto el puerto
} }
private void serial_com_Load(object sender, EventArgs e) {
}
private void button4_Click_1(object sender, EventArgs e) //Botones de referencia /enviar dato a pic
{
try {
puerto_serie.Write("u"); // Se envia el caracter "u" por el puerto serie hacia el pic, este lo recibira con getc()
}
catch (Exception) {
toolStripStatusLabel1.Text = "Puerto cerrado hay que abrirlo";
} }
private void button5_Click(object sender, EventArgs e) {
{
try {
puerto_serie.Write("d"); // Se envia el caracter "d" por el puerto serie hacia el pic, este lo recibira con getc()
}
catch (Exception) {
toolStripStatusLabel1.Text = "Puerto cerrado hay que abrirlo";
} }
private void button4_Click_2(object sender, EventArgs e) {
{
try {
puerto_serie.Write("u");
}
catch (Exception) {
toolStripStatusLabel1.Text = "Puerto cerrado hay que abrirlo";
} } }
private void button5_Click_1(object sender, EventArgs e) {
{
try {
puerto_serie.Write("d");
}
catch (Exception) {
toolStripStatusLabel1.Text = "Puerto cerrado hay que abrirlo";
} } }
private void button2_Click_1(object sender, EventArgs e) {
try {
puerto_serie.Write("a");
toolStripStatusLabel1.Text = "LED AZUL"; }
catch (Exception) {
toolStripStatusLabel1.Text = "Puerto cerrado hay que abrirlo";
}
}
private void sendChar(char c) {
char[] data = new Char[1]; data[0] = c;
try {
} catch {
MessageBox.Show("Error: sendByte - failed to send.\nIs the port open?");
} }
} }
CODIGO DEL PROGRAMA DEL PIC SENSOR DE LUZ
#include <16F877A.h> //Se insertan las librerías del pic 16f877a #device adc=10 //Se declara el Adc de 10 b
#fuses XT,NOWDT,NOPROTECT,NOLVP //Se declaran los fuses para poder reprogramar el pic
#use delay(clock=4M) // Se le asignan al reloj interno de 4Mhz #use rs232 (baud=9600, xmit=pin_c6, rcv=pin_c7, parity=N, stop=1, bits=8) #include <lcd.c> //Se incluye la librería del Lcd
#use standard_io(b) //Se utiliza la configuración estándar de los puertos B #define ROJO Pin_B1
#define BLANCO Pin_B2 #define AMARILLO Pin_B3 #define BOMBA Pin_B4 Char Get;
float lim; double x, temp; int j; #int_rda void serial() {
Get=getc();
switch(Get) {
case 'u':
lim=lim+(5*54/26.2); delay_ms(10);
break;
case 'd':
lim=lim-(5*54/26.2); delay_ms(10);
break;
default:
disable_interrupts(INT_RDA); //INTERRUPCION SERIAL break;
} }
void main(){ //se declara el programa Main
//se asignan las variables que serán utilizadas durante el programa
//se inicia el Lcs enable_interrupts(GLOBAL);
enable_interrupts(INT_RDA); //INTERRUPCION SERIAL
setup_adc_ports(RA0_RA1_RA3_ANALOG); //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(); lim=103;
while(1){ //While principal infinito lcd_putc( "\f");
set_adc_channel(0); //Sensor de Temperatura x=read_adc();
delay_us(20);
temp=x*26.2/54; //Leemos el valor que nos da el ADC printf(lcd_putc,"\fReferencia %2.2f",lim); // Imprmimos en la primer linea printf(lcd_putc,"\nTemp %2.2f ",x*26.2/54);
printf("%S""%.0f""%S;","Temp :",Temp," Grados"); // Imprimimos en la segunda linea segun la ecuacion
if (x>lim) { //La bandera se enciende al llegar a cierta temperatura
j=1;}
while (j==1) {
output_high(PIN_B0); //Se enciende el ventilador
x=read_adc(); //Leemos el valor que nos da el ADC printf(lcd_putc,"\fAlerta ! "); // Imprmimos en la primer linea
printf(lcd_putc,"\nTemp %2.2f ",x*26.2/54); //Se imprime la temperatura printf("%S""%.0f""%S;","Alerta! Temp :",Temp," Grados");
delay_ms(100);
if (x<lim-20) { //Se apaga cuando llega a cierta temperatura output_low(PIN_B0);
j=0;} } }}
CODIGO DEL PROGRAMA DEL PIC SENSOR TEMPERATURA
#include <16F877A.h> //Se insertan las librerías del pic 16f877a #device adc=10 //Se declara el Adc de 10 b
#fuses XT,NOWDT,NOPROTECT,NOLVP //Se declaran los fuses para poder reprogramar el pic
#use delay(clock=4M) // Se le asignan al reloj interno de 4Mhz #use rs232 (baud=9600, xmit=pin_c6, rcv=pin_c7, parity=N, stop=1, bits=8) #include <lcd.c> //Se incluye la librería del Lcd
#use standard_io(b) //Se utiliza la configuración estándar de los puertos B #define ROJO Pin_B1
#define BLANCO Pin_B2 #define AMARILLO Pin_B3 #define BOMBA Pin_B4
Char Get; float lim; double x, temp; int j;
#int_rda void serial() {
switch(Get) {
case 'u':
lim=lim+(5*54/26.2); delay_ms(10);
break;
case 'd':
lim=lim-(5*54/26.2); delay_ms(10);
break;
default:
disable_interrupts(INT_RDA); //INTERRUPCION SERIAL break;
} }
void main(){ //se declara el programa Main
//se asignan las variables que serán utilizadas durante el programa
//se inicia el Lcs
enable_interrupts(GLOBAL);
enable_interrupts(INT_RDA); //INTERRUPCION SERIAL
setup_adc_ports(RA0_RA1_RA3_ANALOG); //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();
lim=103;
while(1){ //While principal infinito lcd_putc( "\f");
set_adc_channel(0); //Sensor de Temperatura x=read_adc();
delay_us(20);
temp=x*26.2/54; //Leemos el valor que nos da el ADC printf(lcd_putc,"\fReferencia %2.2f",lim); // Imprmimos en la primer linea printf(lcd_putc,"\nTemp %2.2f ",x*26.2/54);
printf("%S""%.0f""%S;","Temp :",Temp," Grados"); // Imprimimos en la segunda linea segun la ecuacion
if (x>lim) { //La bandera se enciende al llegar a cierta temperatura
j=1;}
while (j==1) {
output_high(PIN_B0); //Se enciende el ventilador
x=read_adc(); //Leemos el valor que nos da el ADC printf(lcd_putc,"\fAlerta ! "); // Imprmimos en la primer linea
printf(lcd_putc,"\nTemp %2.2f ",x*26.2/54); //Se imprime la temperatura printf("%S""%.0f""%S;","Alerta! Temp :",Temp," Grados");
delay_ms(100);
if (x<lim-20) { //Se apaga cuando llega a cierta temperatura output_low(PIN_B0);
j=0;} }
}}