18F2550 ADC, Se puede hacer muestreo de tiempo constante?

Bueno, el asunto es la pregunta:

Usando el ADC del 18F2550, ¿se puede hacer que el tiempo de muestreo (el mas rapido posible) sea constante?

Estoy usando CCS C, con cristal 20mhz y el micro corriendo a 48mhz.

Por mas que pruebe las distintas variantes de configuracion del clock del ADC, obtengo en algunos casos que estoy haciendo la lectura antes que termine la anterior (a pesar de usar read_adc() con START_AND_READ) o sino obtengo tiempos mas o menos variables en el simulador. (Proteus 7.2)

Para determinar esto, estoy poniendo un breakpoint en la linea de read_adc() y verifico el tiempo entre una y la siguiente pasada por este breakpoint. (Es un loop cerrado para probar, las instrucciones son todas de tiempo constante)

Por ej:

Empiezo en el tiempo 10.005ms y el segundo read ocurre en 10.008ms. Sin embargo el tercero por ahi ocurre en 10.009ms y no en 10.012ms.

La señal es una senoidal de 1khz 5v pico a pico, offset 2.5v

¿Es posible hacerlo constante?
 
ese tiempo es configurable con el tiempo de adquisicion, de todas formas si estuvieras empezando una lectura antes de acabar la anterior el proteus te lanza un error o un warning. . lo estas recibiendo? de todas formas 3us no es un tiempo demasiado pequeño para el conversod adc. . . el tiempo minimo que permite es de 0,7us y tu lo estas triplicando. . .
Un saludo
 
Hola Pablet, gracias por contestar,

Si estoy recibiendo esos warnings pero solo en casos particulares.

¿Tendrias a mano un ejemplo de codigo para configurarlo con tiempo de sample minimo posible, pero que sea constante? Muchas gracias!
 
seaarg podes programar el módulo Captura o Comparación no recuerdo bien con un valor que determina el tiempo, cada vez que ese tiempo pasa (es constante y preciso) podes configurar al módulo para que no provoque una interrupción sino que lance una conversión AD. De este modo podes hacer conversiones AD cada un tiempo x siempre igual.

Saludos!
 
Dragongold,

Gracias por tu respuesta, pero si bien la "primera" parte de tu propuesta seria de tiempo fijo, la conversion AD finalizaria en un tiempo variable. Con lo cual el resultado es un sampleo de tiempo variable. (fijo+ad)

Estoy suponiendo que SE PUEDE hacer una conversion AD de un tiempo fijo, con el AD del pic, como los conversores AD comunes. ¿Sera asi?
 
seaarg vos estas seguro que el tiempo variable esta en la lectura del ADC y no en el resto de las instrucciones? Estas usando el reloj RC del ADC o usas un divisor aplicando la frecuencia del cristal del PIC?

Saludos
 
Segurisimo :p

#use delay(clock=48000000) // Frecuencia máxima de trabajo.
#use ADC=8 // ADC a 8 bits.
------------------
setup_adc_ports(AN0);
setup_adc(ADC_CLOCK_DIV_2); // Built-in A/D setup function
set_adc_channel(0); // Built-in A/D setup function
delay_us(10);
do {
data[pointer] = read_adc();
pointer++;
} while(pointer > 0);

Con esto, obtengo una lectura constante entre sample y sample, que dura 1.75us. De este tiempo una parte fija es la estructura de control y el incremento del indice del vector. La conversion y asignacion a la variable en si dura 1.25us

Con esto (que logre anoche recien) diria que esta "solucionado" mi problema ya que el tiempo es ahora constante.

En este momento, se leen los samples y se asignan a un vector de 256 posiciones. El maximo que me permite el compilador para este micro es 850 posiciones (y usa 98% de ram), pero requiere empezar a trabajar con variable de indice de 16bits con las demoras adicionales que eso conlleva.

Ahora bien, me pregunto si habra alguna forma de hacerlo MAS rapido, ya sea trabajando en el adc (ya no sabria como) o haciendo algun tipo de magia en C con malloc() punteros, etc.

¿Alguien sugiere algo?

Muchas gracias.
 
Última edición:
Te referías a hacer más rapido la captura de los datos del ADC y su puesta en el array pero trabajando con 16 bits (INT16)? Según la hoja de datos del 18F2550 le toma alrededor de 0.8uS la toma de la tensión y 11uS la conversión a binario, esto trabajando a lo máximo, no se si será correcto lo que estoy diciendo. Por lo que me parece que ya estas trabajando a esa velocidad lo que quedaría de ver si se puede aumentar es el grabado de esos 16bits en el array, con punteros sería una opción pero no creo que mejore la unica que te queda es evitar el uso de la matriz pero el programa se hace larguisimo haciendo así:

data1 = read_adc();
data2 = read_adc();
data3 = read_adc();
data4 = read_adc();
data5 = read_adc();
....

Esa sería la forma más rapida ya que se graba directamente en la variable y no se la busca en un array. Se puede saber para que es este proyecto? Un osciloscopio ? Voltimetro?

Saludos
 
0.8us puede ser, pero 11us creo que no, quiza sean los 11 TAD lo que leiste. (sino no podria estar yo tomando a 1.75us cada sample, con guardado en variable y todo) A menos que vos estes haciendo una cuenta de 1us por instruccion. En mi caso son 83.3ns por instruccion. (48mhz)

Tu idea de una linea por read me daria 83.3ns extras a la conversion nada mas... seria fantastico pero no creo que me alcance la ROM para 256 lineas de grabado + 256 lineas de lectura.

Sin embargo, tu idea me da una idea y es abrir un bloque ASM y tratar de imitar lo que hacia hace mucho tiempo en ASM con tablas.

Y si, es un osciloscopio pequeñito, portable pero estoy intentando superar los 100khz de ancho de banda usable. (esto es: al menos 10 samples x ciclo de una onda senoidal)

Hasta ahora logre 56khz a 10 puntos por ciclo. (Obvio en simulaciones, ni toque el hard todavia).

De ultima me metere en hacer oversampling, pero no me convence mucho porque solo funcionaria en señales periodicas constantes.

Todo este lio es porque me estoy queriendo ahorrar el conexionado de una SRAM+Contadores+ADC externo.
 
Haaa me parecia que por ahí venía la mano jaja. Yo estoy trabajando en uno pero no uso el ADC del PIC porque es algo lento, saqué un ADC de 16bits 14MSPS del scanner de una impresora multifuncion que ya no funcionaba. Para ello había pensado en usar un DSP pequeño de 18 pines pero poderosos nucleo de 40MIPS. De esta manera el trabajo es bastante rapido. Pero para lo que tu pretendes de un ancho de banda de 100KHz con este PIC debería alcanzar.
Pudiste medir señales de solo 56KHz? En teoría deberías poder medir señales de hasta 250KHz por lo menos si te toma 1.75uS cada conversion. Que ahora que me fijo mejor el tiempo mínimo que requiere el conversor AD es de 1.6us o se que solo te lleva 0.15uS guardar el resultado lo que es bastante rápido.
Ignoro cuanto mas lento podra ser el guardado en una variable de 16bits pero no creo que sea demasiado mayor, si lo sería si hablásemos de FLOAT.
Fijate bien porque como está ahora deberías poder medir hasta los 200KHz por lo menos.

Saludos
 
Que buena idea la del conversor del scanner.

Estrictamente, el metodo actual samplea a 571khz (1.75us por sample), pero eso lo divido en 10 porque me interesa tener 10 puntos por periodo. De nada sirve ver una senoidal de 500khz viendo solamente 1 punto por periodo en pantalla. Si fuera una cuadrada veria mas o menos hasta 114khz en mi teoria (viendo 5 puntos)

El guardado de la variable esta tomando mas o menos 11 instrucciones de 83.3ns, no recuerdo bien ahora.
 
Tenes razon, la única solución que veo es un micro mas rapido como un DSPic no creo que logres mas velocidad con este porque 1.75uS ya es un buen tiempo es apenas un poco mas del tiempo mínimo de conversión del ADC. No veo otra solucion que opinas?
 
Yo tampoco, a menos que haga lo que queria evitar que es poner un ADC externo (tengo de hasta 40msps y de hasta 80msps), controlar su clock con el clock del pic y leer el puerto y almacenar a toda velocidad. Esto me daria un tiempo de sample+conversion bastante mas rapido (83.3ns x cantidad de instrucciones requeridas para leer puerto y almacenar) pero complica el hard.

Hice una pequeña prueba en simulador recien.

Si hago algo que vos sugeriste:

data[0] = input_b();
data[1] = input_b();
data[2] = input_b();
data[3] = input_b();
......
data[255] = input_b();

Utilizando un ADC externo rapido. Cada linea son 2 instrucciones, o sea 0.167us Esto me da una frecuencia de sampleo de 5.988 Mhz ya mucho mas interesante. Seria samplear una frecuencia de hasta 598khz a 10 samples por periodo y sin utilizar memoria externa ni contadores, tan solo el ADC conectado derecho al pic.

Por supuesto que el ADC samplearia 4 veces mas rapido al estar conectado al clock del pic (no se si el PLL se refleja en OSCOUT) pero los samples perdidos no serian importantes.

En caso de que OSCOUT solo refleje la F del cristal, serian 20mhz, 4 veces mas samples de los que leo con el pic.

Se va poniendo interesante. Quiero adicionarle un display grafico de 128x64, hay que ver si me da la rom para tanto.
 
Última edición:
Si la salida del oscilador es multiplicada por el PLL según tengo entendido. Qué ADC externo estas usando? Donde conseguiste ADC de 40 y 80MSPS se ven interesantes. Y si con ese método es lo más rapido que hay y podés lograr mayor resolución aun si usas DSPic ya que nos vamos de los 12MIPS a 40MIPS como mínimo. Sigo atentamente el post se pone interesante :p.

Saludos!!

Edito: si no queres usar un ADC externo vienen unos 24F y algunos DSPic con ADC de hasta 5MSPS
 
Última edición:
Los ADC que tengo los consegui por pedido de samples:

TLC5540 (40msps)
ADS831 (80msps)

El primero es hasta un poquito mas facil de hacer interfaz con el PIC, tiene OE y algunas cosas interesantes. El segundo es mas rapido, pero en mi placa de prueba lo pude hacer andar a 40msps nada mas, mucho ruido.

Sobre otros pic, lo veo dificil, en cordoba conseguimos los mas "comunes" y como muy loco el 18f2550
 
Si eso es verdad pero podrías hacer un pedido a Elemon de Bs. As. que tiene muchos PICs a precios excelentes y te los trae a su sucursal a de Córdoba sin costo alguno fijate en su página web y contactalos por teléfono por mail suelen ser algo lentos. Porque con tantos MSPS no creo que se pueda con este PIC.

Saludos!!
 
Atrás
Arriba