Pages: 1 ... 7 8 [9] 10   Go Down
Author Topic: Aumentar la frecuencia de muestreo (Solucionado)  (Read 19483 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 15
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Pues, tras varios intentos, creo que he conseguido lo que queria. Ahora, para comparar resultados, tengo 3 códigos:
 1- "no rápido: analogRead()
 2- "rápido:  ADLAR=1 Byte ADCH"
Estos códigos anteriores ya están puestos anteriormente
3- "rápido:  ADLAR=0 byte ADCL"
Éste último código es:

Code:
// *********************************
//  datos rápidos ADLAR=0 byte ADCL
// *********************************

#define mysize 40

unsigned long tStart;
unsigned long tEnd;
byte mydata[mysize];
unsigned int bytes_datos[mysize];

void setup()
{
  Serial.begin(115200);
  delay(200);

   
  //Prescaler
  //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
  //Configure to Prescaler=32
  bitWrite(ADCSRA,ADPS2,1); // sbi(ADCSRA, ADPS2);
  bitWrite(ADCSRA,ADPS1,0); // cbi(ADCSRA, ADPS1);
  bitWrite(ADCSRA,ADPS0,1); // sbi(ADCSRA, ADPS0);
 
 // Input Channel Selections
 
//  MUX3210    Single Ended Input
//     0000          ADC0
//     0001          ADC1
//     0010          ADC2
//     0011          ADC3
//     0100          ADC4
//     0101          ADC5
//     0110          ADC6
//     0111          ADC7
//     1000          ACD8

// Entrada A4
ADMUX=(0<<REFS1)|(1<<REFS0)|(0<<MUX3)|(1<<MUX2)|(0<<MUX1)|(0<<MUX0);//(1<<ADLAR)|

}

void loop()
{

  Serial.println("espero corte:");
  mydata[0] =analogReadFast();
  while (analogReadFast()>mydata[0]-10){};
  tStart=micros();
  for (int i=1; i<mysize;i++)
  {
     mydata[i]=analogReadFast();
  }
  tEnd=micros();
 
    for (int i=0; i<mysize;i++)
  {
    Serial.print(mydata[i],DEC); Serial.print(" ");

  }
  Serial.println("");
  Serial.println("NEW ACQUISITION");
  Serial.print("tStart=");
  Serial.println(tStart);
  Serial.print("tEnd=");
  Serial.println(tEnd);
  Serial.print("Tiempo: ");
  Serial.println(tEnd-tStart);
  Serial.print("nPoints=");
  Serial.println(mysize);
}

int analogReadFast()
{
ADCSRA|=(1<<ADSC); //  sbi(ADCSRA, ADSC);
// ADSC is cleared when the conversion finishes
while (bit_is_set(ADCSRA, ADSC));
        byte BAJO=ADCL;
        byte ALTO=ADCH;
        return BAJO;
}

La modificaciónes  aplicadas son: 
 - la línea que define el registro ADMUX, en la que he suprimido la parte que asigna 1 al byte ADLAR, por lo que ahora ADLAR = 0. Ésto es necesario para hacer un desplazamiento de 2 bits hacia la derecha

 - la función analogReadFast(), en la que, después de leer el byte bajo y el alto, envio solo el byte bajo(ADCL).  por lo que siempre que el valor del sensor sea < 255 la transmisión de datos será real y la rapidez mucho mayor como puede verse a continuación:

DATOS NO RAPIDOS
esperando corte...
196 181 173 166 158 147 130 108 89 74 61 50 40 34 32 33 35 40 44 52 60 67 77 93 113 134 150 162 174 185 192 195 196 195 196 196 196 195 196 195
NEW ACQUISITION
tStart=1601608
tEnd=1605976
Tiempo: 4368
nPoints=40
esperando corte...

Los resultado son correctos, pero la duración es grande debido a que la transmisión de cada dato ocupa 2 bytes.

DATOS RAPIDOS(ADLAR=1; ADCH)
espero corte:
49 39 38 38 37 37 36 35 35 34 33 32 31 30 29 28 27 26 25 24 23 22 22 21 20 19 18 18 17 16 16 15 14 14 13 12 12 11 11 10
NEW ACQUISITION
tStart=2872060
tEnd=2873156
Tiempo: 1096
nPoints=40
espero corte:

Los resultados tienen corta duración, pues cada dato ocupa 1 sólo byte, pero a consta de hacer un desplazamiento de 2 bytes a la izquierda, por que el valor es menor y hay una ligera disminución de la precisión

DATOS RAPIDOS(ADLAR=0; ADCL)
espero corte:
195 183 179 177 174 170 168 165 161 158 154 150 145 142 138 133 129 124 119 113 109 104 100 96 92 88 85 81 79 76 73 71 68 66 63 61 59 57 56 53
NEW ACQUISITION
tStart=2254152
tEnd=2255248
Tiempo: 1096
nPoints=40
espero corte:

Los datos se transmiten igual de rápidos que en el caso anterior, pues siguen ocupando 1 byte.  Ahora hay un desplazamienos de 2 bits a la derecha, y el valor es real(no se reduce su tamaño), coincidiendo con los de los primeros datos, siempre que no se supere el límite de ese byte, que es 255.
 
Gracias Igor R, ha sido un placer.


Logged

0
Offline Offline
Edison Member
*
Karma: 16
Posts: 1579
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Una pregunta.... que tipo de sensor estas usando? Si es una barrera, por que usas entrada analogica?  smiley-eek-blue



nota.- ni enyes ni acentos
Logged


Offline Offline
Newbie
*
Karma: 0
Posts: 15
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Pues estoy usando un emisor de luz infrarroja y un fototransistor para detección de gotas y fotografiar colisiones.  Con los datos de corte de la barrera hago gráficos que me ayudan a tomar decisiones.

Puede que la rapidez en los datos no sea tan importante para esta aplicación, pero también lo quiero aplicar a construir gráficos del destello de flashes fotográficos y hacer comparaciones.

Todas estas operaciones implican guardar los datos en un array antes de la transmisión serial. Si recien tomado un dato, lo enviara via serial, el cálculo de los tiempos sería diferente e incluiría un retardo por el tiempo de transmisión.

Además, guardando una matriz de datos de 1 sólo byte me ahorro memoria con respecto al método tradicional de 2 bytes.

 
Logged

0
Offline Offline
Edison Member
*
Karma: 16
Posts: 1579
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Lo decia porque si era una barrera para detecta solo 2 estados (ON/OFF) puedes usar una entrada digital que es mucho mas rapido.
Logged


Offline Offline
Newbie
*
Karma: 0
Posts: 15
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Igor R: "No sé exactamente que pasa cuando fuerzas un cast a un byte en:
 mydata[ i ]=analogRead(PINS_SENSOR_BARRIER);
No tienes más que probar, así que ya nos dirás... "


En los 2 últimos códigos, que usan la función analogReadFast(),  los tiempos de lecturas son mas rápidos, pero es debido a que incorporan lineas que modifican el preescaler(cambiando los bits ADPS0, ADPS1 Y ADPS2 del registro ADCSRA). Es decir, si quito del código estas lineas que modifican estos bits, el tiempo de lectura con analogRead() y con analogReadFast() tienen poca variación.

Con respecto al comentario del encabezamiento, he comprobado que hacer byte mydata[mysize]; y mydata=analogReadFast(); tiene el mismo efecto que poner ADLAR = 0 y hacer un desplazamiento a la derecha de 2 bits, cogiendo el byte ADCL, siempre que el valor del dato no supere a 255, y todo esto fue lo que incorporé al 3º código.

Por todo esto, de momento:
 - Seguiré usando analogRead() frente a analogReadFast()
 - No usaré ADLAR = 1, sino ADLAR = 0 que es el que tiene por defecto.
 - Limitaré la luz que llega al sensor para que no supere el valor máximo que puede tener 1 byte, es decir, 255
 - Y, por supuesto, seguiré modicando el preescaler para aumentar la velocidad de ADC
 

 - También estudiaré tu oferta de usar entradas digitales, aunque lo bueno de usar la entrada analógica es que puede establecer el límite de la barrera de forma fácil, y supongo que en una entrada digital tendría que añadir un circuito electrónico que me permita hacer el cambio de estado en distintos niveles.







Logged

0
Offline Offline
Edison Member
*
Karma: 16
Posts: 1579
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hola:

analogRead() frente analogFast() tienen que tener bastante diferencia en cuestión de tiempo, otra cosa es que sea suficiente para tu aplicación (no tienes más que comparar código).
En teoría, para trabajar con resolución de 10 bits, deberías configurar el prescaler como máximo a 200 kHz (según datasheet). Ese es el motivo de que se forzó a 8 bits,ya que se configuró a más velocidad.

Me refiero, el código es bastante sencillo he intentaba ir a la máxima velocidad posible incluyendo envio por serie para monitorizar en "tiempo real".
Ahora ya dependiendo de la aplicación de cada uno, puedes adaptarlo a tus necesidades.


Salu2


Igor R.
« Last Edit: January 02, 2012, 03:22:07 am by Igor R » Logged


Offline Offline
Newbie
*
Karma: 0
Posts: 15
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ufff.., lo siento Igor R, por querer usar tiempos pequeños no me di cuenta que sobrapasaba la frecuencia permitida (al forzar preescaler con 10 bits).

Tambíen supongo que si uso la función  analogFast() pero incorporando la lectura tanto del byte ADCL como del ADCH no debería haber diferencias con analogRead(), pues estoy leyendo 2 bytes.

Me tendré que resignar y perder resolución si quiero mas rapidez.

Gracias. Creo que todo me ha sido muy util para conocer mejor el funcionamiento del proceso.



Logged

0
Offline Offline
Edison Member
*
Karma: 16
Posts: 1579
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hola,

El amigo Juan, me ha pasado el link de su página con un programa creado en gambas usando lo que se ha comentado en este post.
http://www.seta43.netau.net/ardu_os.html


smiley-wink
Logged


0
Offline Offline
Sr. Member
****
Karma: 1
Posts: 341
UNO
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

pues he probado ese "osciloscopio" pero me aparece un error al intentar abrir el puerto....... ¿que sera?
Logged

Madrid
Offline Offline
Sr. Member
****
Karma: 5
Posts: 481
Life isn't about finding yourself, life is about creating yourself!!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

pues he probado ese "osciloscopio" pero me aparece un error al intentar abrir el puerto....... ¿que sera?

¿Te has dao' cuenta tú también, no?
Logged

Engineering is the art of
making what you want from
things you can get.

     

[SOLUCIONADO]

0
Offline Offline
Sr. Member
****
Karma: 1
Posts: 341
UNO
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

pues he probado ese "osciloscopio" pero me aparece un error al intentar abrir el puerto....... ¿que sera?

¿Te has dao' cuenta tú también, no?

¿A ti también te ha pasado?
o no entiendo lo que quieres decir...
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 2
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

buenos dias, estoy tratando de cambiar la velocidad de muestreo del adc de mi arduino due, pero no se como hacerlo, por lo que les agradeceria cualquier ayuda que me puedan brindar......
mi correo: davichi_89@yahoo.com
Logged

Loja
Offline Offline
Newbie
*
Karma: 0
Posts: 23
Solo se que nada se
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hola Amigos, tengo una duda con este TEMA de Frecuencia de Muestreo ?????????????????????????????????????????????????????????????' smiley-confuse

El código ADCSRA|= (1<<ADPS2)|(1<<ADPS1)|(0<<ADPS0)  se activa para todos los puertos analógicos o solo para uno, y si es así explíquenme como activar para todos juntos por favor

Y para el Arduino Mega 2560 la frecuencia de muestreo por defecto es 15.6kHz es decir (16MHz/1024=15.6kHz), pero esta frecuencia tengo que dividirla pata 13 ???? o no, si es así seria 1.2kHz, y es muy bajo para procesar señales,

es que necesito adquirir una señal eléctrica CA para calcular THD.. y para calcular THD es necesario aumentar la frecuencia o no?????


GRACIAS............
Logged

0
Offline Offline
Edison Member
*
Karma: 16
Posts: 1579
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

¿Como vas a calcular THD? ¿con Arduino?  ¿FFT? ¿tiene que ser a "tiempo real"?
¿Estamos hablando de Total Harmonic Distortion (THD)?

Así a primeras sin pensarlo mucho, suena a mucha caña para el micro del Arduino Mega....
Si vas a usar la librería FFT que hay de Arduino, me miraría primero las limitaciones que tiene... que son unas cuantas....No vaya a ser que no cumpla tus requerimientos.

Acerca del tema de la frecuencia del ADC, si la información tratada en los numerosos post de este tema no cubren tus dudas, lo mejor es que te descargues el datasheet del micro y eches un vistazo. Es la mejor fuente de información cuando necesitas estas cosas.


Saludos,


Igor R.
« Last Edit: September 11, 2013, 05:26:29 pm by Igor R » Logged


Loja
Offline Offline
Newbie
*
Karma: 0
Posts: 23
Solo se que nada se
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Exacto Total Harmonic Total (THD)..

Mi problema es que necesito definir la misma frecuencia de muestreo del ADC para todos los puertos analogicos.

Y si con la libreria FFT para arduino necesito resolverlo.

Esta es la libreria:
https://code.google.com/p/neuroelec/downloads/detail?name=ffft_Library.zip&can=2&q=

Saludos
Logged

Pages: 1 ... 7 8 [9] 10   Go Up
Jump to: