TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: zonadjarn en 21 de Enero de 2008, 11:01:15

Título: Utilizacion del ADC del pic en CCS
Publicado por: zonadjarn en 21 de Enero de 2008, 11:01:15
Bueno voy con el tema, estoy usando un LM335 para medir la temperatura, y lo que quiero es que el PIC me de un aviso cuando supere un determinado voltaje "este se supone que sera la temperatura maxima a la que puede estar en este caso mi invernadero", lo que pasa que a la hora de decirle con alguna funcion de ver si es igual no me lo compra bien, alguien me podria decir como compararlo?.
Esta tarde os coloco el trozo de codigo que tengo echo, mientras a ver si alguien me puede echar un cable.....Saludos
Título: Re: Utilizacion del ADC del pic en CCS
Publicado por: Nocturno en 21 de Enero de 2008, 13:30:53
Comparar dos variables es muy sencillo con if, aunque imagino que tu problema es más complicado que eso:
if (a>b)
   alarma;
Título: Re: Utilizacion del ADC del pic en CCS
Publicado por: zonadjarn en 21 de Enero de 2008, 13:43:19
Comparar dos variables es muy sencillo con if, aunque imagino que tu problema es más complicado que eso:
if (a>b)
   alarma;

Asi es, te pongo como habia echo el codigo pero la comparacion no me funciona:

#include <16f877.h>
#device ADC=8
#fuses XT,NOWDT,NOPROTECT,NOLVP,PUT,BROWNOUT
#use delay(clock=4000000)
#use standard_io(b)
#byte port_c = 7  // Identificador asociado al registro de dirección 7

long valor;
long tempmax=11001000;
long tempmin=01010000;
void toma_adc_temperatura(void){
set_adc_channel(0); // Lectura del canal 0
delay_ms(1);  //para que se estabilice
valor=read_adc(); //Se guarda en la Variable Valor en valor convertido de Analogico en Digital
delay_ms(1); //para que se estabilice
}
void main() {
set_tris_a(0xff);
set_tris_b(0x00);
set_tris_c (0x00);
setup_adc(ADC_CLOCK_INTERNAL); //configura el converso
setup_adc_ports(RA0_analog); //entrada 0 como analogica
port_c=0;
do {
toma_adc_temperatura();
output_b(valor);
if (valor=0xa2){
port_c=1;
}
}while(true);
}

Lo que nose es como hacer lo de la comparacion de lo que me da cuando cojo lo del ADC con la temp maxima y minima que tengo para que me salte la alarma.
Lo bueno seria que la compararcion me la haria cuando es igual o mayor, me imagino que igual hay que poner lo de 0xa2 entre comillas o algo por el estilo...Saludos
Título: Re: Utilizacion del ADC del pic en CCS
Publicado por: Nocturno en 21 de Enero de 2008, 13:48:33
Te digo algunas cosas que veo raritas.

Utilizas tipos long para variables de 8 bits. Será mejor que utilices el tipo int8.

Utilizas asignaciones en binario sin utilizar la sintaxis correcta, que sería:
int8 tempmax=0b11001000;
int8 tempmin=0b01010000;

Una de las cosas menos intuitivas del C es que el signo = se puede usar de dos maneras. Si pones sólo uno (a=5) estás asignando el valor de la derecha a la variable de la izquierda. Si pones dos signos (a==5) estás comparando ambas partes.
Tú has usado if (valor=0xa2){ y tendrías que haber usado if (valor==0xa2){


De todas formas, yo te aconsejo utilizar el símbolo > porque así saltará la alarma con ese valor y con cualquier superior.
Título: Re: Utilizacion del ADC del pic en CCS
Publicado por: PalitroqueZ en 21 de Enero de 2008, 20:02:54
...
Una de las cosas menos intuitivas del C es que el signo = se puede usar de dos maneras. Si pones sólo uno (a=5) estás asignando el valor de la derecha a la variable de la izquierda. Si pones dos signos (a==5) estás comparando ambas partes.
...

eso también es válido en los operadores logicos

Título: Re: Utilizacion del ADC del pic en CCS
Publicado por: zonadjarn en 22 de Enero de 2008, 08:00:50
Una pregunta, como saber por ejemplo me tiene que saltar por temperatura maxima cuando pase por ejemplo de 3.10 V, como seria su converion en Digital?, nose si el proteus melo hara muy bien como quedaria la converion en digital?...SAludos


P.D-->Alguien me puede ayudar con la conversion de la temperatura  del LM335, esque lo tenfo conectado con una resistencia 2k2 para saber mas o menos la tabla de variacion de temperatura.
Título: Re: Utilizacion del ADC del pic en CCS
Publicado por: Nocturno en 22 de Enero de 2008, 08:16:38
Si no cambias la Vref, entonces el máximo será Vdd = 5V y el mínimo GND=0V.
Eso significa que a 3.10V haciendo una simple regla de tres le corresponden una lectura de x = 3.10*255/5 = 158
Título: Re: Utilizacion del ADC del pic en CCS
Publicado por: zonadjarn en 22 de Enero de 2008, 08:46:15
Si no cambias la Vref, entonces el máximo será Vdd = 5V y el mínimo GND=0V.
Eso significa que a 3.10V haciendo una simple regla de tres le corresponden una lectura de x = 3.10*255/5 = 158

Muchas gracias, hoy empezare con el motaje, si tengo alguna dudilla mas ya te coemtare......Saludos
Título: Re: Utilizacion del ADC del pic en CCS
Publicado por: zonadjarn en 29 de Enero de 2008, 08:47:11
Bueno pues sigo con mis pruebas, decir que el ADC por la pata RA0 ya me funciona, pero ahroa tengo problemas con hacer lo mismo por la RA1, ya que el medidor para el invernadero es de Luz y de Temperatura, a ver si me echas una mano ya que pongo RA0_RA1_analog y me da error el ccs, otra cosa es dentro del codigo como saber que toma de cada una de las patillas es....SAludos
Título: Re: Utilizacion del ADC del pic en CCS
Publicado por: Nocturno en 29 de Enero de 2008, 08:58:43
Si miras el 16F877.H verás que las únicas combinaciones válidas para configurar el conversor analógico son estas:
// Constants used in SETUP_ADC_PORTS() are:
#define NO_ANALOGS                           7    // None
#define ALL_ANALOG                           0    // A0 A1 A2 A3 A5 E0 E1 E2
#define AN0_AN1_AN2_AN4_AN5_AN6_AN7_VSS_VREF 1    // A0 A1 A2 A5 E0 E1 E2 VRefh=A3
#define AN0_AN1_AN2_AN3_AN4                  2    // A0 A1 A2 A3 A5
#define AN0_AN1_AN2_AN4_VSS_VREF             3    // A0 A1 A2 A5 VRefh=A3
#define AN0_AN1_AN3                          4    // A0 A1 A3
#define AN0_AN1_VSS_VREF                     5    // A0 A1 VRefh=A3
#define AN0_AN1_AN4_AN5_AN6_AN7_VREF_VREF 0x08    // A0 A1 A5 E0 E1 E2 VRefh=A3 VRefl=A2
#define AN0_AN1_AN2_AN3_AN4_AN5           0x09    // A0 A1 A2 A3 A5 E0
#define AN0_AN1_AN2_AN4_AN5_VSS_VREF      0x0A    // A0 A1 A2 A5 E0 VRefh=A3
#define AN0_AN1_AN4_AN5_VREF_VREF         0x0B    // A0 A1 A5 E0 VRefh=A3 VRefl=A2
#define AN0_AN1_AN4_VREF_VREF             0x0C    // A0 A1 A5 VRefh=A3 VRefl=A2
#define AN0_AN1_VREF_VREF                 0x0D    // A0 A1 VRefh=A3 VRefl=A2
#define AN0                               0x0E    // A0
#define AN0_VREF_VREF                     0x0F    // A0 VRefh=A3 VRefl=A2
#define ANALOG_RA3_REF         0x1         //!old only provided for compatibility
#define A_ANALOG               0x2         //!old only provided for compatibility
#define A_ANALOG_RA3_REF       0x3         //!old only provided for compatibility
#define RA0_RA1_RA3_ANALOG     0x4         //!old only provided for compatibility
#define RA0_RA1_ANALOG_RA3_REF 0x5         //!old only provided for compatibility
#define ANALOG_RA3_RA2_REF              0x8   //!old only provided for compatibility
#define ANALOG_NOT_RE1_RE2              0x9   //!old only provided for compatibility
#define ANALOG_NOT_RE1_RE2_REF_RA3      0xA   //!old only provided for compatibility
#define ANALOG_NOT_RE1_RE2_REF_RA3_RA2  0xB   //!old only provided for compatibility
#define A_ANALOG_RA3_RA2_REF            0xC   //!old only provided for compatibility
#define RA0_RA1_ANALOG_RA3_RA2_REF      0xD   //!old only provided for compatibility
#define RA0_ANALOG                      0xE   //!old only provided for compatibility
#define RA0_ANALOG_RA3_RA2_REF          0xF   //!old only provided for compatibility

Yo probaría con esta, a ver si va bien: AN0_AN1_AN3
Título: Re: Utilizacion del ADC del pic en CCS
Publicado por: zonadjarn en 29 de Enero de 2008, 09:51:46
Si miras el 16F877.H verás que las únicas combinaciones válidas para configurar el conversor analógico son estas:
// Constants used in SETUP_ADC_PORTS() are:
#define NO_ANALOGS                           7    // None
#define ALL_ANALOG                           0    // A0 A1 A2 A3 A5 E0 E1 E2
#define AN0_AN1_AN2_AN4_AN5_AN6_AN7_VSS_VREF 1    // A0 A1 A2 A5 E0 E1 E2 VRefh=A3
#define AN0_AN1_AN2_AN3_AN4                  2    // A0 A1 A2 A3 A5
#define AN0_AN1_AN2_AN4_VSS_VREF             3    // A0 A1 A2 A5 VRefh=A3
#define AN0_AN1_AN3                          4    // A0 A1 A3
#define AN0_AN1_VSS_VREF                     5    // A0 A1 VRefh=A3
#define AN0_AN1_AN4_AN5_AN6_AN7_VREF_VREF 0x08    // A0 A1 A5 E0 E1 E2 VRefh=A3 VRefl=A2
#define AN0_AN1_AN2_AN3_AN4_AN5           0x09    // A0 A1 A2 A3 A5 E0
#define AN0_AN1_AN2_AN4_AN5_VSS_VREF      0x0A    // A0 A1 A2 A5 E0 VRefh=A3
#define AN0_AN1_AN4_AN5_VREF_VREF         0x0B    // A0 A1 A5 E0 VRefh=A3 VRefl=A2
#define AN0_AN1_AN4_VREF_VREF             0x0C    // A0 A1 A5 VRefh=A3 VRefl=A2
#define AN0_AN1_VREF_VREF                 0x0D    // A0 A1 VRefh=A3 VRefl=A2
#define AN0                               0x0E    // A0
#define AN0_VREF_VREF                     0x0F    // A0 VRefh=A3 VRefl=A2
#define ANALOG_RA3_REF         0x1         //!old only provided for compatibility
#define A_ANALOG               0x2         //!old only provided for compatibility
#define A_ANALOG_RA3_REF       0x3         //!old only provided for compatibility
#define RA0_RA1_RA3_ANALOG     0x4         //!old only provided for compatibility
#define RA0_RA1_ANALOG_RA3_REF 0x5         //!old only provided for compatibility
#define ANALOG_RA3_RA2_REF              0x8   //!old only provided for compatibility
#define ANALOG_NOT_RE1_RE2              0x9   //!old only provided for compatibility
#define ANALOG_NOT_RE1_RE2_REF_RA3      0xA   //!old only provided for compatibility
#define ANALOG_NOT_RE1_RE2_REF_RA3_RA2  0xB   //!old only provided for compatibility
#define A_ANALOG_RA3_RA2_REF            0xC   //!old only provided for compatibility
#define RA0_RA1_ANALOG_RA3_RA2_REF      0xD   //!old only provided for compatibility
#define RA0_ANALOG                      0xE   //!old only provided for compatibility
#define RA0_ANALOG_RA3_RA2_REF          0xF   //!old only provided for compatibility

Yo probaría con esta, a ver si va bien: AN0_AN1_AN3

Muchas gracias, eso me lo has resuelto, ahora mi pregunta es como hacer para tener dos mediciones en el codigo que he pasado anteriormente....Saludos
Título: Re: Utilizacion del ADC del pic en CCS
Publicado por: zonadjarn en 29 de Enero de 2008, 10:00:21
Parece que he conseguido solucionar el programa con lo que me has dicho, ahora a ver si me puedes ayudar en ver como poder separar las medidas de tension que me entren por RA0 y RA1, ya que una es la de la alarma de temperatura y la otra la alarma de la Luminosidad....Saludos
Título: Re: Utilizacion del ADC del pic en CCS
Publicado por: Rodricity en 29 de Enero de 2008, 12:00:04
 Simplemente haces una conversion la almacenas en una variable, haces la otra medicion y la almacenas en otra variable...
Título: Re: Utilizacion del ADC del pic en CCS
Publicado por: Jorge_ en 29 de Enero de 2008, 12:03:34
Con la función set_adc_channel(x), seleccionas el pin que quieres leer.
Título: Re: Utilizacion del ADC del pic en CCS
Publicado por: zonadjarn en 29 de Enero de 2008, 17:29:43
Con la función set_adc_channel(x), seleccionas el pin que quieres leer.

Ok,muchas gracias, me imaginaba que seria segun el canal que seleccionas, pero queria asegurame, probare mañana a ver que tal va...Saludos
Título: Re: Utilizacion del ADC del pic en CCS
Publicado por: zonadjarn en 04 de Marzo de 2008, 08:41:25
A ver si me podeis ayudar porque no consiguo que me funcione para dos mediciones. Este es el codigo:

#include <16f876.h>
#device ADC=8
#fuses XT,NOWDT,NOPROTECT,NOLVP,PUT,BROWNOUT
#use delay(clock=4000000)
#use standard_io(b)
#use RS232(baud=4800,xmit=PIN_C6,rcv=PIN_C7)
#byte port_a = 5   // Identificador asociado al registro de dirección 5
#byte port_b = 6   // Identificador asociado al registro de dirección 6
#byte port_c = 7  // Identificador asociado al registro de dirección 7
#byte port_d = 8  // Identificador asociado al registro de dirección 8

long valor,valor2,desactivaralarma;
int8 tempmax=0b11001000;
int8 tempmin=0b01010000;
int8 lummax=0b11001000;
int8 lummin=0b01010000;
int alarma;
char rec;
void toma_adc_temperatura(void){
set_adc_channel(0); // Lectura del canal 0
delay_ms(1);  //para que se estabilice
valor=read_adc(0); //Se guarda en la Variable Valor en valor convertido de Analogico en Digital
delay_ms(1); //para que se estabilice
}

void toma_adc_luminosidad(void){
set_adc_channel(01; // Lectura del canal 0
delay_ms(1);  //para que se estabilice
valor2=read_adc(1); //Se guarda en la Variable Valor en valor convertido de Analogico en Digital
delay_ms(1); //para que se estabilice
}

void temperatura_maxima_alcanzada(void){ //Entra en la Funcion cunado se porduce una bajada de la temperatura por debajo del Límite Recomendado.
if ((alarma==1) && (desactivaralarma=='n')){
   printf("a");
   alarma=0;
   port_c=2;
}
}
void temperatura_minima_alcanzada(void){ //Entra en la Funcion cunado se porduce una bajada de la temperatura por debajo del Límite Recomendado.
if ((alarma==1)&&(desactivaralarma=='n')){
   printf("b");
   alarma=0;
   port_c=1;
}
}

void luminosidad_maxima_alcanzada(void){ //Entra en la Funcion cunado se porduce una bajada de la luminosidad por debajo del Límite Recomendado.
if ((alarma==1) && (desactivaralarma=='n')){
   printf("j");
   alarma=0;
   port_c=2;
}
}
void temperatura_minima_alcanzada(void){ //Entra en la Funcion cunado se porduce una bajada de la luminosidad por debajo del Límite Recomendado.
if ((alarma==1)&&(desactivaralarma=='n')){
   printf("k");
   alarma=0;
   port_c=1;
}
}

void main() {
printf("c");
port_c=0;
alarma=1;
desactivaralarma='n';
set_tris_a(0xff);
set_tris_b(0x00);
set_tris_c (0x00);
setup_adc(ADC_CLOCK_INTERNAL); //configura el converso
setup_adc_ports(All_analog); //entrada 0 como analogica
do {
toma_adc_temperatura();
output_b(valor);
toma_adc_luminosidad();
output_b(valor2);
if (valor>tempmax){
      temperatura_maxima_alcanzada();
}
if (valor<tempmin){
      temperatura_minima_alcanzada();
}
if ((valor>tempmin)&&(valor<tempmax)){
if (alarma==0){
alarma=1;
printf("c");
port_c=0;
}
}

if (valor>tempmax){
      temperatura_maxima_alcanzada();
}
if (valor<tempmin){
      temperatura_minima_alcanzada();
}
if ((valor>tempmin)&&(valor<tempmax)){
if (alarma==0){
alarma=1;
printf("c");
port_c=0;
}
}
if (valor2>lummax){
      luminosidad_maxima_alcanzada();
}
if (valor2<tempmin){
      luminosidad_minima_alcanzada();
}
if ((valor2>lummin)&&(valor2<lummax)){
if (alarma==0){
alarma=1;
printf("h");
port_c=0;
}
}
}while(true);
}


Título: Re: Utilizacion del ADC del pic en CCS
Publicado por: Micro23 en 04 de Marzo de 2008, 11:06:01
Citar
valor=read_adc(0); //Se guarda en la Variable Valor en valor convertido de Analogico en Digital
Citar
valor2=read_adc(1); //Se guarda en la Variable Valor en valor convertido de Analogico en Digital

Cuando utilizas esta funcion no debes pasarle el canal, ponela asi:

valor=read_adc();
valor2=read_adc();

antes de llamar a esta funcion debes seleccionar el canal a leer con set_adc_channel(0) y set_adc_channel(1). Fijate que en tu codigo pusiste set_adc_channel(01

Saludos y Suerte
Título: Re: Utilizacion del ADC del pic en CCS
Publicado por: huichoman en 04 de Marzo de 2008, 11:46:14
Hola Zonadjarn.

Mira voy de salida a la escuela, vi tu post de manera rápida, en cuanto regrese te ayudo.
La semana pasada nos dejaron una practica, utilizar el adc para leer un lm35, desplegar la temperatura en dos displays de 7 segmentos y que encendiera un led cuando llegara a cierta temperatura, te paso el código del programa, para que lo cheques espero que te sea utili, en cuanto regrese te paso la simulacion. Saludos.

Código: [Seleccionar]

#include <18F4525.h>
#device adc=8
#FUSES NOWDT, HS, NOBROWNOUT, NOPUT, NOCPD, NODEBUG, NOWRT, NOWRTD,MCLR, NOLVP
#use delay(clock=20000000)
#include <stdlib.h>


void main()
{
   int x=0, temp=0, digito1=0,digito2=0;
   float vadc=0;
   
   byte const display[10] =  {0b00111111,  //0
                              0b00000110,  //1
                              0b01011011,  //2
                              0b01001111,  //3
                              0b01100110,  //4
                              0b01101101,  //5
                              0b01111101,  //6
                              0b00000111,  //7
                              0b01111111,  //8
                              0b01100111}; //9

   
   setup_adc(ADC_CLOCK_DIV_32);
   setup_adc_ports(AN0|VSS_VREF);
   set_adc_channel(0);
   
   output_low(PIN_B0);
 
  while(1)
  {
     
   output_d(display[digito1]);
   delay_us(100);
   output_c(0b00000010);
   delay_us(100);
   output_c(0b00000000);
     
   vadc=read_adc();
   temp=(int) ((vadc * 391) / 1000);
   digito1=(temp/10);
   digito2=temp%10;
   
   output_d(display[digito2]);
   delay_us(100);
   output_c(0b00000001);
   delay_us(100);
   output_c(0b00000000);
   delay_us(100);
   
   if(temp>=30)
      output_high(PIN_B0);
   else   
   output_low(PIN_B0);
 
  }

}


GAMBARIMASU

Título: Re: Utilizacion del ADC del pic en CCS
Publicado por: huichoman en 04 de Marzo de 2008, 16:21:47
Hola amigo, del codigo anterior, puedes quitar la parte del display de 7 segmentos.
Te quedaría algo parecido a esto.

Lo que hace es leer el adc, despues convierte el valor del adc a temperatura en grados centigrados. Despues solo comparas con la temperatura que deseas que se dispare la alarma, en este caso activa un led conectado al B0.

Código: [Seleccionar]
#include <18F4525.h>
#device adc=8
#FUSES NOWDT, HS, NOBROWNOUT, NOPUT, NOCPD, NODEBUG, NOWRT, NOWRTD,MCLR, NOLVP
#use delay(clock=20000000)

void main()
{
   temp=0;
   float vadc=0; 
   
   setup_adc(ADC_CLOCK_DIV_32);
   setup_adc_ports(AN0|VSS_VREF);
   set_adc_channel(0);
   
   output_low(PIN_B0);
 
  while(true)
  {             
   vadc=read_adc();
   temp=(int) ((vadc * 391) / 1000);
   delay_ms(5)
 
   if(temp>=30)
      output_high(PIN_B0);
   else   
   output_low(PIN_B0); 
  }
}

GAMBARIMASUUUUU
 :mrgreen:
Título: Re: Utilizacion del ADC del pic en CCS
Publicado por: cyberpablis en 24 de Agosto de 2012, 11:20:20
Muchachos, no hace falta utilizar la definición preformateada de pines que incluye el CCS para declarar los pines a leer con el ADC.

Se puede usar, por ejemplo, la siguiente instrucción

setup_adc_ports(sAN1 | sAN2 | sAN6 | sAN7 | VSS_VDD);

En esta instrucción, la combinación de pines involucrados se define a voluntad.

Un abrazo.