TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: krin en 26 de Noviembre de 2004, 11:24:00
-
Hola. Necesito ayuda de como poder integrar una señal analogica de entrada que se mueve entre 0V y 5V en un intervalo de 10 segundos aprox. Alguien tiene idea de como poder hacer esto? Ayuda por favor
-
A qué te refieres exactamente con "integrar"?
Qué forma tiene esa señal?
-
Con la ayuda de un fototransistor recibo señales luminosas entre 0 y 5 volts. La idea de integrar es sumar todos los valores que me entrega el fototransistor en un determinado intervalo de tiempo, 10 segundos, y a partir del valor de la suma total, si es mayor o menor que ciertos numeros, ejecutar distintos tipos de instrucciones.
-
Tendras q pensar en cuantas muestras quieres capturar.A mas muestras,mas exacta será la media que obtengas. ¿quieres actuar en función de la suma total de todos los valores o en un valor medio?
-
Gracias por el interes Modulay.
En principio, la idea es actuar en funcion de la suma total, pero tambien puede ser en base al promedio. Cualquiera de las dos alternativas es buena. Algo de teoria he estado absorviendo, pero aun no entiendo como obtener los valores que el conversor A/D obtiene del fototransistor. Como podría saber que valores se acumularon en alguna variable que guarda la suma despues de pasado el tiempo de integración y que no sea a traves de una LCD? No entiendo tampoco una constante de resolucion que he visto en algunos programas del foro del tipo:
float const resoluc = 5/ 1024
Agradecería sugerencias por favor.
-
Si no dispones de un lcd para visualizar datos,ó recurres a displays 7 segmentos ó a diodos led,no se me ocurre otra cosa.Vendría bien q te manejaras con algún software de simulación,eso te simplificaría bastante las cosas.
¿que pic vas a usar?
Lo de la constante es simple:
El AD del pic va a convertir el valor de tensión analógica presente en el canal al que conectes el sensor en un número:
valor = read_adc()
... de 8 ó 10 bits,dependiendo de como lo configures y del tipo de pic que sea.Si tu sensor te va a dar entre 0 y 5V y configuras el AD del pic para que trabaje a 10 bits (1024 valores),obtendrás el valor de tensión que entrega el sensor multiplicando "valor" por la constante resoluc.
-
Hasta el momento voy a usar el PIC16F877. Otra alternativa sería el pic16F870. La verdad no cuento con una LCD y aprender a usarla sería mas complejo. Pero con LEDs si cuento...pero como se pueden visualizar los valores en ellos? La verdad yo solo quiero saber el valor de la integración para implementar rutinas con IF y While, es decir solo quiero saber el valor total de la suma para a partir de este resultado continuar con la ejecucion del programa. Por ejemplo: si la suma total es mayor que 100 entonces poner en High una salida del PIC. Si la suma total es mayor que 200, entonces poner en High otra salida del pic.
Voy a intentar a hacer un programa tentativo y lo subire al foro para ver como va y si me pueden dar una manito con el...
-
Echale un ojo a este hilo:
http://miarroba.com/foros/ver.php?foroid=46840&temaid=2307248
Quizá te pueda ayudar algo
Un saludo
-
Muy interesante Modulay. Gracias por el link... me da mas ideas de como implementar el programa. Por lo que se ve te manejas de las mil maravillas en esto de programar PIC en C...
-
Si necesitas ayuda sobre como hacer el programa del conversor, puedes usar la opción "buscar" que la tienes más arriba. En ejemplos para simular no sé si también había algo hecho, lo que sí te aseguro es que en el apartado de C hay muchos ejemplos hechos.
Respecto a mostrar el resultado de la suma puedes usar comunicación RS232 con el PC y que te la muestre en pantalla.
Lo dicho, lo mejor es que presentes el programa y nosotros te lo arreglamos para que puedas ver el resultado.
Un saludo
PD. Supongo que el programa PROTEUS de simulación no sabrás utilizarlo, para lo que quieres te vendría de perlas. Para otras cosas a veces falla.
-
Pocher ¿en qué cosas te suele fallar a tí proteus?
-
Pués lo último y no estoy muy seguro hasta que lo pruebe físicamente ha sido con una comunicación entre 3 PICs.
Otra cosa que recuerde fué una temporización con el TMR2, creía que no funcionaba la temporización pero sí lo hacía, el "único problemilla" era que en lugar de encender el LED cada segundo lo hacía cada 17 minutos.
Leer caracteres de la LCD me parece que támpoco se dejaba.
Hice una lista con cada cosa que me iba saliendo pero al final la tiré a la basura (habían unas cuantas cosillas).
Para los compañeros que esteis leyendo estas líneas, os he de decir que con el PROTEUS se aprende un montón, eso sí tienes que tener paciencia con los bugs, y cuando creas que lo estas haciendo bien y el PROTEUS lo saca mal hacer una prueba con componentes reales.
Un saludo
-
Eso es lo que me hizo fiarme poco al principio,pero hoy dia ya no puedo vivir sin él.El tema de las temporizaciones y encender y apagar leds en tiempo real a proteus no le va mucho,eso sí que lo he visto con mis propios ojos
-
Hola.
Acá escribi una version preliminar en C para el integrador. Se que le falta mucho aun, instrucciones que tal vez son necesarias y que no he considerado por inexperiencia, por ello no la he compilado (en PICC q es el que uso). Falta el como identificar los valores que definen un determinado nivel de voltaje que sirve de discriminacion en rutinas condicionales y eso no tengo idea como hacerlo (una alternativa es por prueba y error pero no se de donde empezar)... En el programa se describe mas detalladamente...
/////////////////////////////////////////////////////////////////////////////////////////////////////////
//// ////
//// integrador de voltaje entre 0 y 5 volts provenientes de ////
//// fototransistores. Los fototransistores se conectan al puerto A/D del ////
//// pic 16f877a. La integracion es por 10 segundos. la integracion es sobre ////
//// diferentes colores de papeles que daran a los fototransistores diferentes////
//// niveles de voltajes dependientes del color del papel. para cada color es ////
//// necsario fijar un valor de referencia para que el microprocesador ////
//// pueda identificar de que color se trata. ////
//// ////
////////////////////////////////////////////////////////////////////////////////////////////////////////
#include <16F877A.H>
#fuses XT,NOWDT,NOPROTECT //no se si esto está bien
#use delay(clock=4000000)
short cont;
const int escala = 255;
#device adc=8
//#device adc=10
#define INTS_PER_SECOND 15 //numero de desbordes del tmr0 por segundo 4000/(256*256*4)
BYTE segundos; //almacena segundos transcurridos desde empieza la cuenta
BYTE int_count; // contador de interrupciones
#int_rtcc // Esta funcion es llamada cada vez
void clock_isr() { // que el timer0 se desborda (255->0).
// Para la frecuencia de 4MHz es aprox.
if(--int_count==0) { // 15 veces por segundo
++segundos;
int_count=INTS_PER_SECOND;
}
}
void main() {
long sensor1 = 0; // tres salidas fototransistores conectados al porta A/D
long sensor2 = 0;
long sensor3 = 0;
long suma1; //variables que acumulan la suma de voltajes
long suma2;
long suma3;
set_tris_b(0); //puerto b como entrada
set_tris_c(1); //puerto c como salida
setup_adc_ports(ALL_ANALOG); //configuracion de entradas analogas
setup_adc(ADC_CLOCK_INTERNAL);
while (1)
{
cont=input(PIN_B2); // entradas de activacion del contador
if(cont==0)
{
int_count=INTS_PER_SECOND;
set_rtcc(0);
setup_counters( RTCC_INTERNAL, RTCC_DIV_256);
enable_interrupts(INT_RTCC);
enable_interrupts(GLOBAL);
}
if(segundos<=10)
{
set_adc_channel(0);
valor1=read_adc();
suma1 = suma1 + valor1;
delay_ms(200);
set_adc_channel(1);
valor2=read_adc();
suma2 = suma2 + valor2;
delay_ms(200);
set_adc_channel(2);
valor3=read_adc();
suma3 = suma3 + valor3;
delay_ms(200);
}
if(suma1>x&&suma1<y) // x e y serian la suma de voltajes
{ // que definen los niveles en que debe encontrar
output_bit(PIN_C1,1); // suma 1 para que corresponda al color rojo por
} //ejemplo
else
{
output_bit(PIN_C1,0);
}
if(suma2>z&&suma2<w) // idem para otro color
{
output_bit(PIN_C2,1);
}
else
{
output_bit(PIN_C2,0);
}
if(suma3<a) // idem para otro color
{
output_bit(PIN_C3,1);
}
else
{
output_bit(PIN_C3,0);
}
}
}
-----------------------------------------------
Agradezco comentarios...
-
Bueno,hay que pulir unos cuantos detalles.Si has intentado compilar el código te habrás dado cuenta de que contiene errores,tales como usar variables sin haberlas declarado.Ese tema se trata en el mircocursillo del enlace que te dí.Creo que debes leer un poco más sobre C para seguir adelante con tu proyecto.Te pongo otro enlace en el que podrás pillarte un código que usa el AD del pic para q te pueda servir un poco de guía:
http://miarroba.com/foros/ver.php?foroid=256746&temaid=1725528
-
Sí hay varios errores.
- set_tris_b(0xFF) //Entradas
- set_tris_b(0x00) //Salidas
- Los setup_counter(----), enable_int(....RTCC y enable_int(GLOBAL) definelos en el main no en el while
- Faltan declarar variables: x, y, z w
- Si te interesa ver los resultados de las sumas usa:
#use RS232(BAUD=9600,BITS=8,PARITY=N,XMIT=PIN_C6,RCV=PIN_C7) y abajo en el while:
printf("suma1=%lu suma2=%lu suma3=%lu",suma1,suma2,suma3);
De esta forma verías los resultados en el PC con el hiperterminal de Windows por ejemplo. Tienes para esto que establecer una comunicación con un MAX232 con el PC.
La otra vía para visualizar es la LCD.
Un saludo, pule el código y cuenta.
-
si las variabls x, y, z, w, a..... no las declare por que el programa es a modo de ejemplo...por eso no lo he compilado...Parece que la unica alternativa es ver los resultados a traves de una LCD o la otra alternativa como dice pocher...Una vez pula mas el programa lo subo... Gracias por la ayuda.
-
...y otra sería que te hicieras con Proteus o algún otro software de simulacion...
-
Hola.
Acá va la rutina compilada...el problema es que no hace nada...Tengo una LCD de 1x16 conectada al puerto D, conectado de la anera que sugiere la libreria lcd.c de PICC. Alguna ayuda de por qué no hace nada?
#include <16F877A.H>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#device adc=8
#use delay(clock=4000000)
#include <LCD.C>
#byte port_a=5
#byte port_b=6
#byte port_c=7
#byte port_d=8
short entrada; //detecta una entrada en el puerto b
short salida; // detecta salida en el puerto b
short cont; // inicializador del contador
const float escala = 0.019607; // = 5/255
#define INTS_PER_SECOND 15 //numero de desbordes del tmr0 por segundo 4000/(256*256*4)
BYTE segundos; //almacena segundos transcurridos desde q empieza la cuenta
BYTE int_count; // contador de interrupciones
#int_rtcc // Esta funcion es llamada cada vez
void clock_isr() { // que el timer0 se desborda (255->0).
// Para la frecuencia de 4MHz es aprox.
if(--int_count==0) { // 15 veces por segundo
++segundos;
int_count=INTS_PER_SECOND;
}
}
void borra_lcd()
{
lcd_putc("f"
;
}
void main() {
int sensor1; // fototransistor conectado a traves de un seguidor de voltaje
long suma1 = 0; //variable que acumula la integracion
set_tris_b(1); //entrada
set_tris_c(0); //salida
set_tris_d(0); //salida
setup_adc_ports(ALL_ANALOG); // A/D
setup_adc(ADC_CLOCK_INTERNAL);
setup_counters( RTCC_INTERNAL, RTCC_DIV_256);
enable_interrupts(INT_RTCC);
enable_interrupts(GLOBAL);
lcd_init();
while (1)
{
entrada=input(PIN_B0);
salida=input(PIN_B1);
cont=input(PIN_B2);
if(entrada==1||salida==1) //si hay algo en la entrada o salida se pone una
{ // pata del pic en uno. Esto es para otros propositos mas que integrar
output_bit(PIN_C0, 1);
}
else
{
output_bit(PIN_C0,0);
}
if(cont==1) // si entrada del contador se habilita, se hecha a andar el contador
{
int_count=INTS_PER_SECOND;
set_rtcc(0);
}
if(segundos<=10) // si han pasado menos de 10 seg va integrando (sumando) la entrada
{ // en suma 1 cada medio segundo.
set_adc_channel(0);
sensor1=read_adc();
suma1 = suma1 + sensor1;
delay_ms(500);
}
else
{
suma1=suma1*escala; // si han pasado mas de diez segundo muestra el resultado en la lcd
borra_lcd();
printf(lcd_putc,"suma1=%lu ",suma1);
}
}
}
-
Hola estimados...
Como este foro ha sido lo que mas me ha ayudado a aprender a programar en C, acá va un pedazo de una rutina más grande implementada, pero que da buena solución al problema de la integración de señales analógicas a la entrada del PIC. Con ejemplos es la forma mas facil de aprender a programar...Gracias por la ayuda...Ojalá esto le sirva a alguien...
#include <16F877A.H>
#fuses XT,NOWDT,NOPROTECT,NOLVP
//#device adc=8
#device adc=10
#use delay(clock=4000000)
#include <lcd.c>
#use standard_io(A)
#use standard_io(b)
#use standard_io(c)
#use standard_io(d)
#byte port_a=5
#byte port_b=6
#byte port_c=7
#byte port_d=8
short entrada; //detecta una entrada en el puerto b
short salida; // detecta salida en el puerto b
short cont; // inicializador del contador
#define INTS_PER_SECOND 15 //numero de desbordes del tmr0 por segundo 4000/(256*256*4)
int segundos; //almacena segundos transcurridos desde q empieza la cuenta
int int_count; // contador de interrupciones
#int_rtcc // Esta funcion es llamada cada vez que el timer0 se desborda (255->0).
void clock_isr()
{
// Para la frecuencia de 4MHz es aprox. 15 veces por segundo
if(--int_count==0) {
++segundos;
int_count=INTS_PER_SECOND;
}
}
void main()
{
long sensor1=0; // fototransistor conectado a traves de un seguidor de voltaje
long suma1=0; //variable que acumula la integracion
long sensor2=0;
long suma2=0;
long sensor3=0;
long suma3=0;
segundos=0;
int_count=INTS_PER_SECOND;
entrada=0;
salida=0;
cont=0;
setup_adc_ports(ALL_ANALOG); // A/D
setup_adc(ADC_CLOCK_INTERNAL);
setup_counters( RTCC_INTERNAL, RTCC_DIV_256);
// set_adc_channel(0);
set_rtcc(0);
disable_interrupts(INT_RTCC);
// enable_interrupts(INT_RTCC);
enable_interrupts(GLOBAL);
lcd_init();
printf(lcd_putc,"Ingrese
Billete"
;
while(1)
{
entrada=input(PIN_D1);
salida=input(PIN_D2);
cont=input(PIN_D0);
if(entrada==0||salida==0)
{
output_bit(pin_c0,1);
}
else
{
output_bit(pin_c0,0);
}
if(cont==0) // si entrada del contador se habilita, se hecha a andar el contador
{
enable_interrupts(INT_RTCC);
printf(lcd_putc,"fProcesan
do..."
;
delay_ms(10);
}
if(segundos>0&&segundos<=15) //integra dos señales de entrada en un
set_adc_channel(0); //intrvalo de tiempo de 15 seg
sensor1=read_adc();
suma1 = suma1 + sensor1;
delay_ms(1);
set_adc_channel(1);
sensor2=read_adc();
suma2 = suma2 + sensor2;
delay_ms(1);
}
if(segundos>0&&segundos<=16) //se ve en la pantalla el resultado de la integración
{ //cada medio segundo, pero no en volts (solo habría
printf(lcd_putc,"fA=%lu
V=%lu ",suma1,suma2);//que agregar un factor conversor)
delay_ms(500);
}
}
}