Aumentar la frecuencia de muestreo (Solucionado)

Hola, soy muy nuevo en el manejo de esta increíble herramienta soy docente, he armado una barrera óptica con un viejo mouse para ser usada en un trabajo práctico de física, que consiste en calcular la velocidad de una flecha lanzada con una ballesta, lo he logrado a medias Midiendo la velocidad de una flecha con un Mouse viejo y el arduino – Espacio de Cesar
Quisiera que algún experimentado me oriente para que la velocidad de muestreo sea mayor, he logrado medir hasta 2 milisegundos lo que me parece mucho, en caso de querer usar el mismo dispositivo para medir la velocidad de un balín de rifle de aire comprimido por ejemplo.
El código que usé es este:
Seguramente para Uds esto será muy rústico y con errores sepan por favor disimular
/*
Barrera de luz
*/
// to the pins used:
const int analogInPin = A0; // acá entra el cable que viene del fototransistor
int sensorValue = 0; //
//int outputValue = 0; //
unsigned long time;
void setup() {
Serial.begin(115200);
}
void loop() {
// read the analog in value:
sensorValue = analogRead(analogInPin);
// print the results to the serial monitor:
//Serial.print(“Time: “);
time = millis();
Serial.print(time);
Serial.print(” “);
Serial.println(sensorValue);
}
Saludos
César

Yo usaria una interrupcion: se activa cuando sucede algo.

En mi blog (en mi firma) tienes un ejemplo de algo similar, pues busco detectar un paso por meta.

Yo el problema que veo es que menos que 2 milisegundos me resulta difícil teniendo en cuenta que la ejecución de las instrucciones necesita su tiempo. En el arduino no se cuanto tiempo necesita en ejecutar cada instrucción (tal vez salga en el datasheet), pero si es 1 milisegundo piensa que en tu bucle hay 5 instrucciones, asi que ejecutarlas te está comiendo el tiempo.

Hola,

Para algo tan concreto, lo mejor es que te mires cómo esta programada la función analogRead() de Arduino (Wiring). La conversión creo que dura unos 13 ciclos (25 si es la primera vez), por lo que tienes que mirar a cuanto han configurado el prescaler del módulo ADC. Lo mejor es tirar del datasheet del micro + ojear la función. Si bajas la resolución del ADC, puedes aumentar bastante la velocidad.

Puedes ojear http://interface.khm.de/index.php/lab/experiments/arduino-realtime-audio-processing/, que estan haciendo tratamiento de sonido a tiempo real. Muestrean a 15 kHz.

Por otro lado, usando sensores de barrera (salida digital) e interrupciones, para el tipo de aplicación que quieres, creo que será mucho mejor que algo analógico.

Saludos

Igor R.

yo lo haría con interrupciones, y que la función de interrupción sea que almacene la variable millis() en un array o variable, estamos hablando de que el reloj va a 16 Mhz o 20 mhz, 2 mseg a esta velocidad me parece muchísimo, si lo haces como te digo la función de la interrupción no gastara mucho tiempo ( en ensamblador seria un MOV de un registro a otro )

yo utilizaría entradas digitales, las analógicas tardan mucho en hacer la conversión , además como ya he comentado en otros post las entradas analógicas están multiplexadas, solo hay un conversor analógico, cuantas mas entradas analógicas se utilicen menor será la frecuencia que puedas utilizar. además al no ser el mismo tiempo de conversión de una vez que otra ( depende del nivel de la señal) tampoco puede calcular con exactitud la diferencia de tiempos entre una señal y otra.

yo utilizaria 2 interrupciones
1º que almacene el valor de millis() en variablesensor1
2ª que almacene el valor de millis() en variablesensor2

y por display o serie o como quieras que muestre el calculo de (espacio entre sensores)/(variablesensor2-variablesensor1)

quizás se me escape algo ...

Un saludo ¡

lo que dice Igor y SrDonGato pero utilizando micros en lugar de millis

http://www.arduino.cc/en/Reference/Micros

desconocía la función esa :smiley: pero claro está que cuanto mayor sea la resolucion de tiempo más precision en la medida tendrá :slight_smile:

El principal problema es cómo instalarlo. Si lo haces digital, la manera más sencilla sería construirte un cubo o similar, que tengas varias barreras ópticas a la entrada y a la salida, para asegurarte que cubres el area para captar la flecha y disparar a través de dicho cubo.

Luego medirlo en Arduino, se puede usar un timer del micro directamente (en vez de millis() o micros()) para tener la máxima precisión posible. Al final, la parte soft de Arduino, yo creo que es la más sencilla (analógica o digital). Ya habeis visto en link que hacen tratamiendo de sonido a tiempo real con el micro....

Cada manera tienes sus pros y contras, de manera analógica, posiblemente requiere menos instalación hardware (aunque requerirá etapa de adaptación de la señal, por ejemplo con Schmitt trigger o etapa amplificadora). Se me ocurre que con sensores de presión, micrófonos ó midiendo de manera inductiva (magnetizando la punta de la flecha), también se podría hacer.

¿Alguien sabe cómo miden los comerciales? Tipo a :

Hola y muchas gracias por las respuestas!! con Micros() he probado tal como esta pero no mejora, el cuello de botella esta por otro lado, yo soy muy novato y de programación casi nulo, he hecho todo en forma intuitiva. Esog voy a incursionar por tu web a ver si rescato algo de lo que me comentas, también veré el enlace de Igor R, yo hice tambié con el mismo código una interesante prueba calculando la frecuencia de resonancia de las cuerdas de una guitarra esta en mi blog http://anajesusa.wordpress.com/ pero claro estamos hablando de pocos Hz, 15Khz es palabra mayor.
Por favor tengan paciencia conmigo, estoy medio viejo y me cuesta un poco la parte de programación.
César

Prueba a configurar el prescaler del ADC (registro ADCSRA, bits 2:0). Al aumentar la frecuencia del módulo ADC disminuye la precisión. Atmel recomienda para 10 bits, que el reloj del ADC debe estar entre 50 kHz-200 kHz. Con un prescaler de 64, estarías un poco por encima pero cercano a lo recomendado para 10 bits (250 kHz). Si no me equivoco en las cuentas, la conversion cuesta 13 ciclos y el cristal es de 16Mhz, por lo que (16000/64)/13=19230 Hz, por lo que nuestro amigo Nyquist dice que podrías adquirir señales de hasta 8 kHz con esta configuración.

A parte, existe una modalidad del ADC, que te inicia la conversión cuando hay overflow, por ejemplo, del timer 0 ó 1 (se configura en el registro ADCSRB). Yo creo que te interesa ésto, para adquirir de forma periódica.

Otra cosa que puedes usar es sólo 8 bits, y de esta manera,sólo tienes que leer un registro (para aumentar velocidad al no tener que hacer operaciones al recoger el valor del conversor y por otro lado podrías aumentar más la frec del ADC).

Todo ésto lo tienes en el datasheet del micro, ya que el lenguaje Arduino no lo tiene implementado. Pero claro, estamos hablando de una cosa muy específica y que necesitas profundizar.

:wink:

Igor, discupla mi ignorancia como ingreso al prescaler, (estoy super verde :blush:)
Para DonGato, hay un solo sensor, lo que mide es la sombra de la flecha, la distancia es el largo del proyectil
He probado esto:
unsigned long tsombra; //declaro una variable, se usara como contador de bucles.

void setup() { //hay que ponerlo siempre, aqui se configura el asunto
pinMode(2, INPUT); // set the digital pin as input:
Serial.begin(115200); //lento pero llega, No se si es necesario definir los baudios
}

void loop(){ //hay que ponerlo siempre, este es le bucle de la chicha
digitalWrite(13, HIGH);
tsombra=0; //reseteamos contador

while (digitalRead(2)==1) {} //mientras el pin esta a 1 queda en bucle esperando sombra
while (digitalRead(2)==0) {tsombra++;} //mientras esta en oscuro incrementa "tsombra".

Serial.print("T. sombra= "); //envia resultado
Serial.println(tsombra);
}
pero hechas las pruebas no me convence, tal vez haya algo mal.
Igor vi en tu web la maqueta de control PID, me llamó la atención que usaran un resistor NTC para sensor de calor siendo los diodos 1n4148 tan lineales en esta función, mi primer trabajo con arduino fue adaptar una sonda hecha con este diodo para usarlo como termostato electrónico en una estufa para microbiología. La placa ARDUINO – Espacio de Cesar

Hola Cesar,

El principal motivo fue usar un sensor no lineal, y usar una tabla en memoria flash para linealizarlo y porque el precio de un termistor es casi similar al del diodo (hablando de comprar 1 unidad). Por añadir más cosillas didácticas, puedes ver que precisamente ésto, es uno de los objetivos del proyecto. Pero podría ser una modificación perfecta, si sólo se quiere focalizar en el PID.

Para cambiar el prescaler, tan sólo tienes que cambiar los bits del registro ADCSRA. Por ejemplo, puedes hacer:
ADCSRA|= (1<<ADPS2)|(1<<ADPS1)|(0<<ADPS0)
Si no entiendes que hace ésto, puedes mirarte los compound y bitwise operators de la página de Arduino.

Otra forma, es usar los macros predefenidos cbi y sbi (clear bit and set bit):
sbi(ADCSRA, ADPS2);
sbi(ADCSRA, ADPS1);
cbi(ADCSRA, ADPS0);

Aunque yo también me haría una nueva función analogReadFast(), optimizandola un poco (como sólo vas a mirar una entrada analógica, puedes quitar la parte que configura el multiplexador). Puedes mirar las "tripas" de Arduino (arduino\hardware\arduino\cores\arduino).En el archivo wiring_analog.c tienes cómo está creada la función analogRead().
También me haría un función de configuración del modulo ADC, en el cual configuraría el prescaler, sólo 8 bits (si quieres mayor velocidad), etc

Saludos

Igor R.

Ya veo, me quede pegado en tu blog Igor, lo de tabla guardada en la flash esta muy bueno, ya se me ocurrió algo con eso, tengo un medidor de vacío hecho con una PT100 (resistencia de platino) que no sigue ninguna función ya había solucionado eso con un arcaico código que por verguenza no pongo (aunque funciona :)) veré de hacer algo semejante a lo de tu proyecto.
Cuando llegue a casa pruebo colocar la linea para cambiar el prescaler, con ese valor queda en 256, el valor defecto es de 1024? con ese valor queda 4 veces mas rápido el reloj?
Si luego de hacer esto cargo otro código y no modifico el timer este queda configurado en ese valor o vuelve a 1024.

Descárgate el datasheet del microcontrolador que trae el Arduino, y contesta tu mismo a la pregunta del prescaler? :wink:
La respuesta viene el mismo, en forma de una tabla.
Si al leerlo tienes alguna duda, entonces seguimos hablando....je,je,je

Cuando cargues otro código, se te configurará con el valor por defecto de Arduino.

:stuck_out_tongue:

Ademas de docente soy bioquímico, asi que soy medio durazno para las hojas de datos, pero estudiaré XD, gracias Igor

je,je,je... por eso!! tiene que estar requetechupao para ti!! Ahora en serio, lo digo para forzarte un poco. Si después de mirarlo no lo tienes claro, lo volvemos a comentar.
Tienes que mirar la parte de "Analog-to-Digital Converter", dónde explica los registros del mismo y en concreto ADCSRA-ADC Control and Status Register A.
Tendrás una tabla como esta:

Table 23-4. ADC Prescaler Selections
ADPS2 - ADPS1 - ADPS0 - Division Factor
0 - 0 - 0 ->2
0 - 0 - 1 ->2
0 - 1 - 0 ->4
0 - 1 - 1 ->8
1 - 0 - 0 ->16
1 - 0 - 1 ->32
1 - 1 - 0 ->64
1 - 1 - 1 ->128

Ten en cuenta que ya estas empezando a meterte en cosas medio serias, y no queda más remedio que mirarse la documentación de microcontrolador. Es lo bonito de Arduino, que te crea la necesidad por aprender...

:wink:

Sospecho que aca esta bien explicado, Tinkering with Electronics...: Timer 2: Introducción ya había estado husmeando por ahí hoy donde esta la tablita esa, en el datasheet no logro verla.

Bueno, el concepto es parecido, pero ahi es la explicación para los timers (en concreto timer 2).
¿No lo encuentras en el datasheet? ¿Qué Arduino tienes, un UNO? Si es así, ¿estás mirando el datasheet del ATmega 328?

Es un Duemilanove, y el chip es atmega328p, el datasheet http://www.atmel.com/dyn/resources/prod_documents/8271S.pdf
Cuando veía tu recito termostatizado con un tapper me acordaba de uno que hice, pero mas robusto, ya que lo mantenía a 85°C, también en este caso un ventilador de pc para homogeneizar pero en el interior para que no mande aire frío desde afuera.

Eso es el resumen (summary) del datasheet. Mira esto => http://www.atmel.com/dyn/resources/prod_documents/doc8271.pdf

El taper aguanta bastante temperatura, es de plástico robusto de los que estan preparados para microondas, congelador, etc.
Esta muy bien, porque es fácil de mecanizar con una dremel.
Me gusto hacerlo así para que fuese transparente, rápido de mecanizar y sobretodo...muy barato!! Compre 10 por 1 euros!! je,je,je
En los ejemplos que tengo, los setpoints están alrededor de 60 grados, pero llega a mucha más temperatura sin problemas (más de 110ºC)... Los setpoints los elegí ahí, por el tema de no tener que esperar cuando lo enciendes por primera vez....

Es importante el recipiente, porque al principio recicle uno parecido, que venía hummus (que rico estaba!!) y se derritió nada más meterle caña.... :smiley:

Hay que tener en cuenta que es un proyecto de un finde (48 horas). Se puede mejor mucho, adaptarlo, etc. Estoy deseando que alguien lo mejore!!
La verdad que el resultado no está del todo mal, y se puede jugar (aprender) mucho con el tema de control, y lo montas por un precio más que asequible.

]:smiley: