Ayuda al programar puerto Analogico

Buenas amigo. Necesito una ayuda de una lectura que me tiene loco.

Estoy programando en ccs compiler un programa para un cotrol de temperaturas de un horno y una llama. Pero tengo el problema que las mediciones de las llama son de un maximo de 1000°C y la medicion es muy rapida asi que una vez que lo muestra en el LCD no se logra ver bien como en el tester externo donde si logro ver bien, ya que cambia los grado cada unos 500ms y la lectura va saltando. La otra es que tengo el problema de que en el canal AN0 mido una temperatura de 500°C maximo pero lo necesito con precision y e visto que se habla de tomar varias medidas y sacar la mas compleja a la medida correcta.

Lo que necesito es que me corrijan como puedo hacer que las lectura sean mas lenta como de unos 500ms pero sin afectar el demas programa ya que con un delay lo estavilizo biem pero entonces los pulsadores lo tengo que pisar durante ese tiempo.
La otra es como puedo tomar varias muestra de una lectura como dicen en otros foros de tomar unas 100 lecturas luego las compara y muestra la mas conclusa.

Aca les dejo una parte del programa para que lo vean y me echen la mano.

#include <16f876.h>
#device adc=10
#fuses XT,NOWDT
#use delay(clock=4000000)
#include <internal_eeprom.c>
#include <LCD_portb.c>
#include <math.h>
#BYTE TRISA = 0x85
#BYTE PORTA = 0x05
#define up PIN_A2
#define down PIN_A3
#define up1 PIN_A4
#define down1 PIN_A5
#define ph PIN_C0
#define th PIN_C1
void main() {

int16 q;
float cupla_pcb,cupla_gpu,pre,top,c1,c2;

setup_adc_ports(AN0);
setup_adc(ADC_CLOCK_INTERNAL);

pre=read_float_eeprom(0x00);
top=read_float_eeprom(0x04);

while (TRUE){

set_adc_channel(0);
delay_ms(5);
q = read_adc();
c1 = 5.0 * t1 / 1023.0;
cupla_pcb = c1 * 200.0;
lcd_gotoxy(1,1);
printf(lcd_putc, "T=%01.0fC ", cupla_pcb);

set_adc_channel(1);
delay_us(100);
q = read_adc();
c2 = 5.0 * q / 1023.0; // Pasa binario a °C
cupla_gpu = c2 * 100;
lcd_gotoxy(10,1);
printf(lcd_putc, "T=%01.0fC ", cupla_gpu);

if(!input(up)){
delay_ms(10);
if(pre>=200)
pre=200;
else
pre+=1; }

if(!input(down)){
delay_ms(10);
if(pre<=90)
pre=90;
else
pre-=1;}

if(!input(up1)){
delay_ms(10);
if(top>=320)
top=320;
else
top+=1; }

if(!input(down1)){
delay_ms(10);
if(top<=130)
top=130;
else
top-=1;}

if(cupla_pcb>=pre){
output_low(ph); }
if(cupla_pcb<=pre){
output_high(ph); }

if(cupla_gpu>=top){
output_low(th); }
if(cupla_gpu<=top){
output_high(th); }

if(cupla_gpu<=130.0){
output_low(th); }

if(!input(up)){
output_high(buzer);
delay_ms(200);
output_low(buzer);}

lcd_gotoxy(1,2);
printf(lcd_putc, "A=%01.0fC ", pre);
write_float_eeprom(0x00, pre);
lcd_gotoxy(10,2);
printf(lcd_putc, "A=%01.0fC ", top);
write_float_eeprom(0x04, top);

}
}
 
Sugiero dos formas...
- Dentro de un conteo hasta cumplir 500ms aprox. por ejemplo...
Código:
word i;
for(i=0 ; ; i++){
    delay_ms(1);
    if(i > 500){
        // Lectura del ADC.
        break;
    }
    // Resto del codigo
}
// Resto del codigo
Tu calculas el tiempo que quieras (500 * 1ms = 500ms aprox.)

- Otra es que programar un timer y usarlo en interrupciòn y cada que sucede la interrupcion hacer la lectura del ADC..., puedes usar un contador dentro de la interrupcion para hacer tiemps mas largos.

Sobre tomar varias lecturas, primero revisa que tienes sufuciente RAM ya que està tecnica requiere guardar cada dato por decir en un array del tipo word (16bits); el tiempo en que hace cada lectura tu lo decides, el resto es fàcil... si quieres la media (sumas todo y divides entre la cantidad de tomas) o usar un algoritmo para buscar la captura mas alta o la màs frecuente para que sea un daro valido.

Busca un poco en el foro que vi este tema.

Saludos
 
Gracias amigo ByAxel por tu ayuda la verdad es que probe le occion de tomar varias lecturas unas 10 y luego las dividi y si me parese que esta biem de ese modo.

Ahora con determinar el tiempo de lectura en enpuerto AN0 no logro entender mucho el codigo que me dejaste. Disculpa mi ignorancia pero soy un poco nuevo en programacion. Te agradeceria mucho si me echas la mano o puedes editarlo en el programa que te deje y disculpa las molestia pero para eso estamos en el foro.

Saludos
 
Como has optado por tomar lecturas sucesivas (10) creo que no es necesario que uses ese mètodo...

la medicion es muy rapida asi que una vez que lo muestra en el LCD no se logra ver bien como en el tester externo donde si logro ver bien, ya que cambia los grado cada unos 500ms y la lectura va saltando

EL còdigo que puse era para tomar una lectura cada 500ms aprox. casi sin perjudicar al resto del codigo... lo que hace es dentro de un bucle (for en mi caso) contar 500 veces 1ms lo que hace 500ms aprox., cuando se cumple 500 recien hace la lectura...

PD: Dentro del bucle està el codigo principal

Saludos
 
Gracias amigo ByAxel la verdad es que no me da el resultado ya que me para todo el programa y los pulsadores del menu tengo que precionarlos por ese tiempo para que me pueda activar.

Asi es como lo hice

int16 i;

for(i=0 ; ; i++){
delay_ms(1);
if(i > 500){
set_adc_channel(1);
delay_us(100);
v = read_adc();
break; }
c2 = 5.0 * v / 1023.0; // Pasa binario a °C
cupla_gpu = c2 * 100; }


Y de este modo fue que saque el promedio de la lectura para que me estavilizara un poco.

set_adc_channel(0);
delay_ms(5);
q = read_adc();
set_adc_channel(0);
delay_ms(5);
q1 = read_adc();
set_adc_channel(0);
delay_ms(5);
q2 = read_adc();
set_adc_channel(0);
delay_ms(5);
q3 = read_adc();
set_adc_channel(0);
delay_ms(5);
q4 = read_adc();
set_adc_channel(0);
delay_ms(5);
q5 = read_adc();
set_adc_channel(0);
delay_ms(5);
q6 = read_adc();
set_adc_channel(0);
delay_ms(5);
q7 = read_adc();
set_adc_channel(0);
delay_ms(5);
q8 = read_adc();
set_adc_channel(0);
delay_ms(5);
q9 = read_adc();
set_adc_channel(0);
delay_ms(5);
q10 = read_adc();
t1 = q+q1+q2+q3+q4+q5+q6+q7+q8+q9+q10;
t2 = 5.0 * t1 / 1023.0;
cupla_pcb = t2 * 100.0;
cupla_pcb = cupla_pcb / 11;

No se que este haciendo mal o quisas todo pero bueno espero que me ayuden.
Graciass
 
Última edición:
Atrás
Arriba