TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: sancho25 en 08 de Febrero de 2012, 12:33:43
-
Hola buenas, he realizado el proyecto de un termostato donde la temperatura minima es de 20 y la maxima es de 25, estos parametros los cambio mediante el programa que es el siguiente:
#include <16f876A.h>
#device ADC=10
#fuses NOPROTECT,NOCPD,NOLVP,NOWDT,XT
#use fast_io (A)
#use fast_io (B)
//#use fast_io (C)
#use delay(clock=4000000)
#include <lcd2.c>
#include <ds1820.h>
float minimo=20;
float maximo=25;
void main()
{
lcd_init();
delay_ms(100);
SETUP_ADC_PORTS(NO_ANALOGS);
set_tris_a(0x3F);
set_tris_b(0x00);
while (1)
{
DS18S20_Convert_T(); //Obtiene la temperatura del DS18S20
Temp=make16(DS18S20_Buffer[1],DS18S20_Buffer[0]);//Lee el valor de 16 bits de la temperatura
if(bit_test(DS18S20_Buffer[1],7)) //Si es negativo...
{
Temp=~Temp+1; //Complementa a 2
Temperatura=Temp*-0.5; //Ajusta la parte fracionaria
}
else
Temperatura=Temp*0.5; //Ajusta la parte fraccionaria
lcd_enviar(LCD_COMANDO,LCD_CLEAR);
lcd_gotoxy(1,1);
printf(lcd_putc,"TEMP: %3.1f ", temperatura);
lcd_putc(223);
lcd_putc("C ");
lcd_gotoxy(1,2);
if (temperatura<=minimo)
{
printf(lcd_putc,"Frio! Calentando");
output_high(PIN_C5);
output_low(PIN_C6);
output_low(PIN_C7);
}
else if (temperatura>=maximo)
{
printf(lcd_putc,"Caliente!Enfriar");
output_low(PIN_C5);
output_high(PIN_C6);
output_low(PIN_C7);
}
else
{
printf(lcd_putc,"Temperatura OK ");
output_low(PIN_C5);
output_low(PIN_C6);
output_high(PIN_C7);
}
}
}
FIN
Me interesaria poder regular esos parametros desde un teclado, pero es que no tengo ni idea de como hacerlo... necesito ayuda, os lo agradezco mucho
mi correo es david_sancho25@hotmail.com
-
2 cosas a tener en cuenta, primero no es necesario repetir el mensaje en varios subforos y luego el mail esta demás, todo se comparte dentro del foro y no por privado ;-)
Saludos!
-
Hola.
Revisa la librería KBD.C del CCS para que te des una idea.
Saludos
-
Hola buenas, lo siento por escribirlo dos veces, pero es que no sabia donde postearlo, entonces decidi en los dos sitios, si alguien me puede ayudar lo agradeceria.
Ya he estado mirando pero es que no lo se... lo unico que quiero hacer es variar la temperatura mediante un teclado, si tener que volver a cargar el programa al pic
Un saludo y gracias
-
Hola.
... lo unico que quiero hacer es variar la temperatura mediante un teclado, sin tener que volver a cargar el programa al pic
Eso no se puede hacer ... si cambias el programa, debes volver a programarlo.
Saludos
-
Si eso es lo que quiero, volver a programarlo, que realize lo mismo que hace ahora, pero añadiendole el teclado para que nada mas encenderlo que me mande introducir la temperatura maxima y minima, pero no se como hacerlo...
-
Hola Sancho,
Como te dijo MLO debes usar la librería KBD.c, donde encontraras una función que es kbd_getc(c), donde te dirá que tecla se ha pulsado. Por lo tanto, puedes realizar un programa que al iniciar te pregunte por LCD que temperatura max quieres, introduzcas un numero que lo vas mostrando por el LCD y le des a # para confirmar o a * para borrar. Cuando se pulse # obtienes la información del LCD y lo guardas en tu variable de temperatura max. Lo mismo con la mínima.
-
Hola marqueses, gracias por contestar e intentar ayudarme, lo necesito :)
He leido la libreria, pero es que no se muy bien como hacerlo, el programa que e hecho es el que e adjuntado en el primer comentario, que tendria que declarar alguna variable y luego como modifico? para que nada mas encender que me pida directamente las temperaturas maxima y minimas.
gracias
-
Hola Sancho,
Las variables puedes definirlas y no declararles ningun valor, o darle algun valor como 0 para que se inicialicen en ese valor. Luego, usas éste codigo
printf(lcd_putc,"\fIntroduzca SP\n");
Tecla_pulsada();
rT=Valor_introducido ();
printf(lcd_putc,"\f SP = %f",rT);
delay_ms(1000);
//rT es global y tipo float
Esto lo colocas al comienzo de tu programa y ya asignarías el valor min(lo que yo nombro rT en mi codigo) y max de tus variables con los valores obtenidos mediante introducción de teclado. Todo antes del while.
Ten encuentra también que la librería que trae CCS es de teclados matriciales de 3x4 y no de 4x4. En caso de que tu teclado sea de 4x4 avísame y te mando una librería que encontré para usar estos teclados.
Te adjunto dos funciones que me cree en su dia para manejar el teclado y capturar valores introducidos que se mostraban en el LCD.
Saludos.
-
Hola, otra vez por ayudarme, verdaderamente lo necesitaba
haber estoy intentadolo ahora, he añadido la libreria de kbd.c
entonces antes de while, e añadido el codigo que me has pasado, y e definido arriba float rT=0;
con esto antes de emepzar a medir la temperatura ya defino los valores maximos y minimos?? o solo uno de ellos :? ando un poco verde la verdad en el tema del teclado
te adjunto las modificaciones:
#include <16f876A.h>
#device ADC=10
#fuses NOPROTECT,NOCPD,NOLVP,NOWDT,XT
#use fast_io (A)
#use fast_io (B)
//#use fast_io (C)
#use delay(clock=4000000)
#include <lcd2.c>
#include <ds1820.h>
#include <kbd.c>
float minimo;
float maximo;
float rT=0;
void main()
{
lcd_init();
delay_ms(100);
SETUP_ADC_PORTS(NO_ANALOGS);
set_tris_a(0x3F);
set_tris_b(0x00);
lcd_gotoxy(1,1);
printf(lcd_putc,"Control de temp.\n");
printf(lcd_putc,"de un motor c.c");
delay_ms(5000);
lcd_enviar(LCD_COMANDO,LCD_CLEAR);
printf(lcd_putc,"\fIntroduzca SP\n");
Tecla_pulsada();
rT=Valor_introducido ();
printf(lcd_putc,"\f SP = %f",rT);
delay_ms(1000);
while (1)
{
DS18S20_Convert_T(); //Obtiene la temperatura del DS18S20
Temp=make16(DS18S20_Buffer[1],DS18S20_Buffer[0]);//Lee el valor de 16 bits de la temperatura
if(bit_test(DS18S20_Buffer[1],7)) //Si es negativo...
{
Temp=~Temp+1; //Complementa a 2
Temperatura=Temp*-0.5; //Ajusta la parte fracionaria
}
else
Temperatura=Temp*0.5; //Ajusta la parte fraccionaria
lcd_enviar(LCD_COMANDO,LCD_CLEAR);
lcd_gotoxy(1,1);
printf(lcd_putc,"TEMP: %3.1f ", temperatura);
lcd_putc(223);
lcd_putc("C ");
lcd_gotoxy(1,2);
if (temperatura<=minimo)
{
printf(lcd_putc,"Frio! Calentando");
output_high(PIN_C5);
output_low(PIN_C6);
output_low(PIN_C7);
}
else if (temperatura>=maximo)
{
printf(lcd_putc,"Caliente!Enfriar");
output_low(PIN_C5);
output_high(PIN_C6);
output_low(PIN_C7);
}
else
{
printf(lcd_putc,"Temperatura OK ");
output_low(PIN_C5);
output_low(PIN_C6);
output_high(PIN_C7);
}
}
}
Me funciona todo como quiero, pero kiero añadirle lo de las funciones del teclado para no tener que cargar el programa para cambiar los valores minimos y maximos
un saludo gracias
-
Tu código debería ser
printf(lcd_putc,"\fIntroduzca Tº Minimo\n");
Tecla_pulsada();
minimo=Valor_introducido ();
printf(lcd_putc,"\fTº Minima = %f",minima);
delay_ms(1000);
printf(lcd_putc,"\fIntroduzca Tº Maxima\n");
Tecla_pulsada();
maximo=Valor_introducido ();
printf(lcd_putc,"\fTº Maxima= %f",maximo);
delay_ms(1000);
Cuando escribes el \f dentro del printf es como si hicieras lcd_enviar(LCD_COMANDO,LCD_CLEAR); , por lo que te lo podrias ahorrar.
Si lo tienes simulado en Proteus prueba a ver si funciona correctamente. Por otro lado, en caso de que quieras cambiar los valores en cualquier momento podrías incluir un pulsador asociado a una interrupción externa y colocar este código en la interrupción.
Saludos.
-
ok, ok, entonces tendria que introducir la libreria del teclado, y antes del while añadir ese codigo no? pues sinceramente pensaba que era muchisimo mas complicado :P , lo tengo montado en el trabajo, me funciona todo, pero queria incorporarle lo del teclado para no tener que volver a cargar el programa cada vez que quiera cambiar los parametros, muchisimas gracias enserio, mañana cuando lo prueba comento por aqui y subo fotos si quieres para compartirlo con la gente. Si tengo alguna duda te puedo comentar no?
un saludo
-
Si, antes del while, pero solo para inicializar los valores, pero si quieres cambiar los parametros en cualquier momento echale un vistazo a lo de la interrupcion externa. Ten encuenta tambien si tu teclado es 3x4 o 4x4 porque esa libreria es para los teclados de 3x4 solamente. Lo complicado para mi fue realizar las funciones que adjunté :D así que si te son de ayuda perfecto!.
Si tienes alguna duda ya mañana comentas, a ver que tal te va.
Saludos.
-
Para la interrupcion externa es para los pulsadores no? pero para el teclado vale con lo de antes? porque en el montaje en (orcad) he puesto un pulsador para resetear, entonces cada vez que quiera cambiar los valores solo tendria que pulsarlo. Pues el teclado no lo se... tengo 2 tipos de archivos para adjuntar que son para el teclado, añado los dos y me quito de problemas. Muchas gracias por los archivos y por la ayuda :)
Un saludo
-
Si si, a ver te explico. Si colocas un pulsador en B0 que es donde se encuentra la interrupción externa 0, cuando lo pulses habrá un cambio de estado en el pin, el micro se da cuenta y crea una interrupción en el programa. Es decir, cuando detecta un cambio de estado en el pin, deja lo que está haciendo y se va directamente a ejecutar el codigo de la función de la interrupción. Por lo tanto, si en la función de la interrupción escribes el mismo código del comienzo del programa (el que te indiqué anteriormente) cambiarías los valores de las variables sin tener que resetear el micro. Es solo una opción, si te sale mas rentable reiniciar, pues reinicia :P.
-
((:-)) muchas gracias por la explicacion, sinceramente no tenia ni idea, como ya e dixo ando un poco verde :)
practicamnte dejare el reset, xk ya tengo la placa montada jaja y habia hecho tambn el teclado para poder añadirlo cuando podria saber como se hace, pero gracias a tu ayuda ya lo se. Mañana lo pruebo y te comento por aqui haber que tal graciaaaas
Un saludo
-
Hola marqueses
He estado haciendo el programa, y al final e realizado con la ayuda de un compañero esto:
#include <16f876A.h>
#device ADC=10
#fuses NOPROTECT,NOCPD,NOLVP,NOWDT,XT
#use fast_io (A)
#use fast_io (B)
//#use fast_io (C)
#use delay(clock=4000000)
#include <lcd2.c>
#include <ds1820.h>
//#include <teclado.c>
#include <kbd2.c>
float minimo;
float maximo;
char tecla;
int cursor;
char nu;
char MAX1;
char MAX2;
char MIN1;
char MIN2;
char c;
int i;
float valor_introducido_maximo()
{
for(i=0;i<2;i++)
{
do
{
tecla=kbd_getc();
delay_ms(30);
}
while(tecla==0);
if(tecla=='0'||tecla=='1'||tecla=='2'||tecla=='3'||tecla=='4'||tecla=='5'||tecla=='6'||tecla=='7'||tecla=='8'||tecla=='9')
nu=tecla-48;
if (cursor==0)MAX1=nu;
if (cursor==1)MAX2=nu;
cursor++;
if (cursor==2) cursor=0;
}
return(tecla);
}
float valor_introducido_minimo()
{
for(i=0;i<2;i++)
{
do
{
tecla=kbd_getc();
delay_ms(30);
}
while(tecla==0);
if(tecla=='0'||tecla=='1'||tecla=='2'||tecla=='3'||tecla=='4'||tecla=='5'||tecla=='6'||tecla=='7'||tecla=='8'||tecla=='9')
nu=tecla-48;
if (cursor==8)MIN1=nu;
if (cursor==9)MIN2=nu;
cursor++;
if (cursor==10) cursor=8;
}
return(tecla);
}
void main()
{
lcd_init();
delay_ms(100);
SETUP_ADC_PORTS(NO_ANALOGS);
set_tris_a(0x3F);
set_tris_b(0x00);
lcd_gotoxy(1,1);
printf(lcd_putc,"Introduzca T Minimo\n");
//Tecla_pulsada();
//tecla=kbd_getc();
minimo=valor_introducido_minimo();
lcd_enviar(LCD_COMANDO,LCD_CLEAR);
printf(lcd_putc,"T Minimo = %f",minimo);
delay_ms(1000);
lcd_enviar(LCD_COMANDO,LCD_CLEAR);
printf(lcd_putc,"Introduzca T Maximo\n");
//Tecla_pulsada();
//tecla=kbd_getc();
maximo=Valor_introducido_maximo();
lcd_enviar(LCD_COMANDO,LCD_CLEAR);
printf(lcd_putc,"T Maximo= %f",maximo);
delay_ms(1000);
lcd_enviar(LCD_COMANDO,LCD_CLEAR);
while (1)
{
DS18S20_Convert_T(); //Obtiene la temperatura del DS18S20
Temp=make16(DS18S20_Buffer[1],DS18S20_Buffer[0]);//Lee el valor de 16 bits de la temperatura
if(bit_test(DS18S20_Buffer[1],7)) //Si es negativo...
{
Temp=~Temp+1; //Complementa a 2
Temperatura=Temp*-0.5; //Ajusta la parte fracionaria
}
else
Temperatura=Temp*0.5; //Ajusta la parte fraccionaria
lcd_enviar(LCD_COMANDO,LCD_CLEAR);
lcd_gotoxy(1,1);
printf(lcd_putc,"TEMP: %3.1f ", temperatura);
lcd_putc(223);
lcd_putc("C ");
lcd_gotoxy(1,2);
if (temperatura<=minimo)
{
printf(lcd_putc,"Frio! Calentando");
output_high(PIN_C5);
output_low(PIN_C6);
output_low(PIN_C7);
}
else if (temperatura>=maximo)
{
printf(lcd_putc,"Caliente!Enfriar");
output_low(PIN_C5);
output_high(PIN_C6);
output_low(PIN_C7);
}
else
{
printf(lcd_putc,"Temperatura OK ");
output_low(PIN_C5);
output_low(PIN_C6);
output_high(PIN_C7);
}
}
}
Lo que me pasa ahora, es que le meta le valor que le meta en el teclado, no salen los valores que introduzco por el teclado, si no que salen 48 o 53... yno tengo ni idea de porque; creo que puede ser que las variables MAX1 y MAX2 las tego que juntar en una para iguyalarlo a a el valor de tecla, para que haga la conversion a decimal y asi sacar el valor que introduzco.....
Igual me he hecho un lio... no se :(
un saludo
-
Tiene pinta de ser los caracteres ASCI, ¿has probado con el código que te propuse? Ademas, debes incluir la funcion kbd_init(); al inicio (lo mismo que haces con el LCD con lcd_init())
Prueba a ver este código y si te funciona ya vas probando tu código
void main()
{
lcd_init();
kbd_init();
delay_ms(100);
SETUP_ADC_PORTS(NO_ANALOGS);
set_tris_a(0x3F);
set_tris_b(0x00);
lcd_gotoxy(1,1);
printf(lcd_putc,"\fIntroduzca Tº Minimo\n");
Tecla_pulsada();
minimo=Valor_introducido ();
printf(lcd_putc,"\fTº Minima = %f",minima);
delay_ms(1000);
printf(lcd_putc,"\fIntroduzca Tº Maxima\n");
Tecla_pulsada();
maximo=Valor_introducido ();
printf(lcd_putc,"\fTº Maxima= %f",maximo);
delay_ms(1000);
while (1)
{
DS18S20_Convert_T(); //Obtiene la temperatura del DS18S20
Temp=make16(DS18S20_Buffer[1],DS18S20_Buffer[0]);//Lee el valor de 16 bits de la temperatura
if(bit_test(DS18S20_Buffer[1],7)) //Si es negativo...
{
Temp=~Temp+1; //Complementa a 2
Temperatura=Temp*-0.5; //Ajusta la parte fracionaria
}
else
Temperatura=Temp*0.5; //Ajusta la parte fraccionaria
lcd_enviar(LCD_COMANDO,LCD_CLEAR);
lcd_gotoxy(1,1);
printf(lcd_putc,"TEMP: %3.1f ", temperatura);
lcd_putc(223);
lcd_putc("C ");
lcd_gotoxy(1,2);
if (temperatura<=minimo)
{
printf(lcd_putc,"Frio! Calentando");
output_high(PIN_C5);
output_low(PIN_C6);
output_low(PIN_C7);
}
else if (temperatura>=maximo)
{
printf(lcd_putc,"Caliente!Enfriar");
output_low(PIN_C5);
output_high(PIN_C6);
output_low(PIN_C7);
}
else
{
printf(lcd_putc,"Temperatura OK ");
output_low(PIN_C5);
output_low(PIN_C6);
output_high(PIN_C7);
}
}
}
-
Hola marqueses, ya lo he solucionado, era la colocacion de los float y los char; he nombrado individualmente para cada temperatura maxima y minimo y dentro de ello. Ahora lo que quiero es que cuando me esta controlando la temperatura(cuando ya he elegido el min y el max) que dando al boton del teclado matricial (#) que mme vuelva a pedir la temperatura maxima y minima, e pensado hacerlo con de do while, pero no me sale... si sabrias hacerlo..
un saludo y gracias
-
Hola Sancho, me alegro que te funcionara finalmente! ((:-)) Lo que quieres hacer ahora es lo que te comenté en su día, si quieres cambiar la temperatura en cualquier momento, lo mas facil y eficaz es colocar una interrupción externa a través de un pulsador, ya que como me comentas que quieres hacer, el micro tiene que estar en cada ciclo del while comprobando que la tecla # está pulsada, y eso puede ocasionar problemas y perdida de tiempo.
En caso de que no puedas usar un pulsador y programar la interrupción externa, pues la opción que dices seria colocar un if (teclapulsada=#) --> ejecutas la función de introducir la temperatura, else --> sigues con el control normal. Esta forma de programar ya te digo que puede darte problemas, ya que si el programa es lento o rapido quizas no le de tiempo a darse cuenta de que la tecla esté pulsada o no. En fin, pruebalo y ya comentas ;-)