TODOPIC
Microcontroladores PIC => Todo en microcontroladores PIC => Mensaje iniciado por: tito melli en 10 de Noviembre de 2018, 16:09:18
-
Hola!
Estoy usando el PIC 16F18326 para un proyecto, y tenía pensado hacer 3 schedules diferentes de la siguiente forma:
const int8 time_schedule_1_steps = 40; // Schedule #1: Number of 25ms steps to reach X seconds. 40 = 1 seconds
const int8 time_schedule_2_steps = 10; // Schedule #2: Number of 25ms steps to reach X seconds. 10 = 250 milliseconds
const int8 time_schedule_3_steps = 200; // Schedule #3: Number of 25ms steps to reach X seconds. 200 = 5 seconds
#int_timer2
void timer2_isr () {
timer2_count_25ms += 1; // Increase Schedule 25ms counter
timer2_count_sch1 += 1; // Increase Schedule#1 counter
timer2_count_sch2 += 1; // Increase Schedule#2 counter
timer2_count_sch3 += 1; // Increase Schedule#3 counter
if (timer2_count_sch1 == time_schedule_1_steps) { // Time to get schedule #1
timer2_sch1_ok_1 = 1; // Schedule#1 complete
timer2_sch1_ok_2 = 1; // Duplicated schedule #1 for different function
timer2_count_sch1 = 0; // Reset counter
}
if (timer2_count_sch2 == time_schedule_2_steps) { // Time to get Schedule #2
timer2_sch2_ok = 1; // Schedule#2 complete
timer2_count_sch2 = 0; // Reset counter
}
if (timer2_count_sch3 == time_schedule_3_steps) { // Time to get Schedule #3
timer2_sch3_ok = 1; // Schedule#3 complete
timer2_count_sch3 = 0; // Reset counter
}
TMR2IF = 0; // Clear flag before exit ISR
}
El problema es que he visto que cuando usaba el ADC para calcular el voltaje Vcc mediante uno de estos schedules, la medida era mucho menor. He visto que si sólo activo 1 la medida es correcta, y cuantos más activo menor es.
He probado a desactivar las interrupciones cuando entre en la función de lectura de voltaje, pero no ha funcionado.
¿Sabéis de alguna posible interferencia entre módulos, u os ha pasado algo similar alguna vez?
Gracias de antemano!
Saludos
-
Entonces el problema lo tenes en la lectura del ADC, y que seguramente no tenga el tiempo suficiente para que al cambiar de canales se logre el nivel correcto.
Supongo esto porque:
1 solo schedule, significaria leer una entrada y guardar el valor, y no cambiaria para nada el canal. Asi que mientras no convierte esta cargandose correctamente.
Ya 2, implica que vos cambies de canal para leer otra entrada, esperes el tiempo correcto de adquisicion y recien alli pases a convertir, sino vas a tener errores.
-
Hola KillerJC,
Probé incluso a duplicar el tiempo con delay_ms, pero no cambio nada la medida. El caso es que cuando ponía la función de medida antes del bucle while, o incluso directamente en el bucle, funcionaba siempre bien, pero cuando la meto en la condición del schedule, deja de tomar la medida correctamente.
Por eso supongo que no es tema del tiempo de adquisición (que por otro lado cumple con los mínimos del datasheet). No sé... :S
-
Los minimos segun la carga que tengas sobre el pin. No es lo mismo tener una resistencia de 10M sobre la entrada que 100k... En fin...
El codigo que pusiste no tiene nada de malo, asi que el problema no esta alli. Lo unico que hace el codigo es que cada tanto activar una de las flags para que luego vos lo leas y actues en consecuencia. Por ende esa parte no tiene nada de malo. Si queres poner la parte donde actua cada uno de esos schedules ( tareas ) seria mejor. Y como estas alimentando al pin analogico, como te comente antes, no es lo mismo hacerlo a traves de una resistencia pequeña que de una grande.
-
Hola KillerJC,
Sí, por eso me extraña tanto la forma que tiene de actuar. Esta tarde subo el código.
El ADC mide el voltaje del FVR, que está siempre activo, y no hay cambio de canal
Saludos
-
Hola de nuevo!
Estoy usando el PIC 18F26k22, y.. sorpresa! Vuelvo a tener errores en la medida del ADC!
Si pido que se mida dentro del schedule de 1 segundo, me mide 140mV, pero si lo saco de ahí y lo pongo directamente en el bucle while (1), me mide 260mV.
He tenido que incrementar el tiempo de adquisición de 8 TAD a 20 TAD para que mida correctamente.
Alguien sabe por qué puede ser?
Saludos
-
Como te habia comentado, eso depende de la carga que tenga el pin... pensa que tu pin analogico es un capacitor, y vos le tenes que dar el tiempo para que se cargue correctamente. Por eso mismo aumentandole el tiempo de adquisicion funciona bien.
-
Me parece que el problema que tenes es que tenes poca corriente circulando por los resistores divisores y por eso tarda en cargarse el capacitor del ADC. Eso se soluciona achicando el valor de esas resistencias manteniendo siempre la relación o con un buffer (seguidor de voltaje) con un amplificador operacional.
-
Como te habia comentado, eso depende de la carga que tenga el pin... pensa que tu pin analogico es un capacitor, y vos le tenes que dar el tiempo para que se cargue correctamente. Por eso mismo aumentandole el tiempo de adquisicion funciona bien.
Pero entonces debería ser al revés, no? Cuando está constantemente midiendo en el bucle while, la medida es correcta. Sin embargo, cuando lo meto dentro del schedule de 1s, va mal.
Por otro lado, no solo mido con ese pin, sino con 4 más. O sea, que en principio el condensador se carga entre medias con otros voltajes.
Me parece que el problema que tenes es que tenes poca corriente circulando por los resistores divisores y por eso tarda en cargarse el capacitor del ADC. Eso se soluciona achicando el valor de esas resistencias manteniendo siempre la relación o con un buffer (seguidor de voltaje) con un amplificador operacional.
Estoy usando un LM35. Creo que la única solución sería el seguidor de voltaje. A ver si puedo hacer una modificación del hardware...
-
Pero entonces debería ser al revés, no? Cuando está constantemente midiendo en el bucle while, la medida es correcta. Sin embargo, cuando lo meto dentro del schedule de 1s, va mal.
Por otro lado, no solo mido con ese pin, sino con 4 más. O sea, que en principio el condensador se carga entre medias con otros voltajes.
Acordate que para que se cargue correctamente deberias cambiar el canal en la interrupcion anterior.. Es decir:
- Entra interrupcion
- Lee ADC
- Cambia al canal siguiente
Asi cuando entra de nuevo ya paso 1s.
En el while podes poner un delay, en la interrupcion no. No se como es el codigo que probaste, pero eso lo unico que se me ocurre.
-
¿No estas reescribiendo en el puerto en algún momento?
-
Pero entonces debería ser al revés, no? Cuando está constantemente midiendo en el bucle while, la medida es correcta. Sin embargo, cuando lo meto dentro del schedule de 1s, va mal.
Por otro lado, no solo mido con ese pin, sino con 4 más. O sea, que en principio el condensador se carga entre medias con otros voltajes.
Acordate que para que se cargue correctamente deberias cambiar el canal en la interrupcion anterior.. Es decir:
- Entra interrupcion
- Lee ADC
- Cambia al canal siguiente
Asi cuando entra de nuevo ya paso 1s.
En el while podes poner un delay, en la interrupcion no. No se como es el codigo que probaste, pero eso lo unico que se me ocurre.
En principio con este PIC, la adquisición la hace automaticamente con el numero de TAD que le des en el registro ADCON2. En mi caso lo correcto era usar 8 TAD, pero he tendido que subirlo a 20 TAD. Por otro lado, el PIC cuenta también con 2 TAD automáticos de desconexión tras la medida, para descargar el condensador. Esto es lo raro..
¿No estas reescribiendo en el puerto en algún momento?
Sólo lo uso para leer el voltaje. Defino el TRIS al inicio del programa, y ya no vuelvo a tocarle nada :S
-
¿Tenes alguna resistencia de alto valor entre el lm35 y el ADC del pic?
-
¿Tenes alguna resistencia de alto valor entre el lm35 y el ADC del pic?
Tampoco. Está directamente conectado al pin..
-
Si tenes osciloscopio podrias poner una resistencia en serie de 1k y medir la señal en el pin de entrada del pic para ver si no se te esta reiniciando el puerto, sino tambien con un diodo y capacitor como detector de picos puede servir.
-
Definitivamente tiene pinta de ser el condensador, que no se descarga totalmente al realizar una medición, y al medir con el ultimo pin de la función, me viene cargado cuando vuelvo a entrar, y como el LM35 da voltajes pequeños, se ve muy afectado.
He probado a colocar en el codigo otro pin antes del pin_LM35, y cuando lo conecto a tierra me da un voltaje muy diferente a cuando lo conecto a Vdd. Esto se ve mitigado cuando incremento el tiempo de adquisición.
Además, estoy convencido de que, como dijiste, la intensidad que ofrece el LM35 es muy baja, con lo que hace que no se termine de cargar correctamente el condensador del PIC.
Ahora lo que toca es averiguar cómo descargarlo antes de cada medida, jaja.
Gracias por toda la ayuda! :)
-
si tenes un pin libre. ponelo a GND, y hace una lectura sin sentido a GND.
De todas formas 1segundos no se compara en nada a 20 TAD, asi que si cambias el canal luego de haber leido no deberias tener mas problemas. Si te esta afectando el TAD entonces es por que primero cambias de canal y luego lees.