Go Down

Topic: problema velocidad de lectura arduino (Read 2005 times) previous topic - next topic

tauro0221

Hi,
El buffer no esta en el IDE esta en el mantenimiento de la computadora. Ve a mantenimiento seleccionas el puerto que usas ,selecciona el  puerto de usb que estas  usando ,selecciona el setting del puerto y abajo hay una seleccion que dice advance y la selecciona y veras que tiene dos buffers uno de RX y otro de TX y selecciona el max. El problema que yo tengo es que computadora esta en ingles y seme hace dificil cambiar los nombres al espanol.

surbyte

#31
Jul 14, 2020, 04:28 am Last Edit: Jul 14, 2020, 04:33 am by surbyte
No. Hablo del ADC.
Me corrijo, no es free wheeling sino free-running.
Code: [Select]
const byte adcPin = 0;
volatile int adcReading;
volatile boolean adcDone;
boolean adcStarted;

void setup ()
{
  Serial.begin (115200);
  // set the analog reference (high two bits of ADMUX) and select the
  // channel (low 4 bits).  this also sets ADLAR (left-adjust result)
  // to 0 (the default).
  ADMUX = bit (REFS0) | (adcPin & 0x07);

}  // end of setup

// ADC complete ISR
ISR (ADC_vect)
  {
  byte low, high;
  
  // we have to read ADCL first; doing so locks both ADCL
  // and ADCH until ADCH is read.  reading ADCL second would
  // cause the results of each conversion to be discarded,
  // as ADCL and ADCH would be locked when it completed.
  low = ADCL;
  high = ADCH;

  adcReading = (high << 8) | low;
  adcDone = true;  
  }  // end of ADC_vect
  
void loop ()
{
  // if last reading finished, process it
  if (adcDone)
    {
    adcStarted = false;

    // do something with the reading, for example, print it
    Serial.println (adcReading);
    delay (500);

    adcDone = false;
    }
    
  // if we aren't taking a reading, start a new one
  if (!adcStarted)
    {
    adcStarted = true;
    // start the conversion
    ADCSRA |= bit (ADSC) | bit (ADIE);
    }    
  
  // do other stuff here

}  // end of loop

Un ejemplo de Nick Gammon


alonsol

#32
Jul 15, 2020, 05:33 pm Last Edit: Jul 15, 2020, 05:34 pm by alonsol

Hi,
El buffer no esta en el IDE esta en el mantenimiento de la computadora. Ve a mantenimiento seleccionas el puerto que usas ,selecciona el  puerto de usb que estas  usando ,selecciona el setting del puerto y abajo hay una seleccion que dice advance y la selecciona y veras que tiene dos buffers uno de RX y otro de TX y selecciona el max. El problema que yo tengo es que computadora esta en ingles y seme hace dificil cambiar los nombres al espanol.
Hola Tauro, gracias por responder.
He estado buscando en mi notebook donde podría encontrarse lo que me mencionaste de los buffer y no he tenido éxito... Lo único que pille y que me dejo ruido es la siguiente imagen, en la cual se puede ver que se puede limitar el limite de bds que se transmiten a mi ordenador. Sin embargo, esta estaba predeterminada a 9600 bps.. sería extraño que al hacer funcionar al arduino a mayor velocidad, este me entregue la información a pesar de que esta entrada este configurada a menor bps. Ademas, su limite de transferencia es de 128000 como se puede ver en la imagen.








No. Hablo del ADC.
Me corrijo, no es free wheeling sino free-running.
Hola surbyte, gracias por responder.
Tengo muchas dudas sobre el código que me dejaste, así que me estoy enfocando en leer y aprender sobre este, pero tengo una pregunta que me surge de lo que comento soyvega anteriormente.. Mi duda es que si al lograr que el arduino funcione en modo free running, los datos que me entregue serán precisos..


tauro0221

Hi,
Segun la imagen tu tienes el buffer al maximo. Todo esta bien.Pregunta porque en vez de enviar la data a medida que los va leyendo, lee los puntos y los almacena en un array y despues que los lees entonces los envias serial. Esto te va dar mas velocida leyendolos. No se si te ya lo habian recomendado.

PeterKantTropus

Tu problema no es el tiempo de medición de datos, el arduino puede medir unos 60000 datos por segundos con el simple programa que tienes , lo de:  free running, toma asincrónica de datos, no es un problema que tengas que plantearte ahora (tal vez si complicas mucho el programa de arduino lo necesites ).
El diseño de tu "artefacto" es tomar datos uno a uno y enviarlos, entonces el cuello de botella es la velocidad de transmisión  de datos.
Son tres factores los que pueden influir al enviar datos errados: El buffer del arduino, ruido de la linea (empeora con la la velocidad de transmisión) y el buffer del PC.
El buffer del arduino, con la condición de enviar el dato cuando el buffer este vacío,  con el if (Serial.available() == 0) { estaría solucionado y solo enviás la cantidad de  datos que permite la velocidad de transmisión.
El fuffer del PC, esto ya lo pusiste al máximo, por lo tanto los errores estarían después de tomar muchos datos .
 Ruido de la linea, probablemente lo mas complicado de solucionar y teniendo en cuenta que los errores los estas teniendo cuando solo efectuaste unas pocas mediciones, es muy probable que sea la causa de tu problema.  Un cable largo y no apantallado puede ser el problema, pero también puede ser ruido eléctrico y  el mismo montaje de medición. Puedes trabajar  en dos campos: el de hardware, con cables apantallados, cortos, reducción de ruidos, etc. O con software, trasmitiendo bytes con comprobación de integridad.

Otra forma de hacerlo es tomar una serie de datos, almacenarlos y luego enviarlos por la comunicación serie a baja velocidad, pero eso dependería de la realidad física a medir. También hay librerías para efectuar transformadas de Fourier en el arduino y solo enviar el resultado.
Tal vez deberías describir un poco mas lo que estas haciendo (realidad física)






//-----------------------******------------------------
if (Codigo_con_delay==True) {
Proyecto=Fracaso;
 } 
//-----------------------******-----------------------

tauro0221

Hi,
Adjunto un sketch en linea con el consejo  de PeterKantTropus para que lo corras para ver que sucede. El sketch lee 300 veces el punto , almazena el resultado y despues te envia los  resultados en serial.{ruebalo para ver que sucede. La lecturas las estoy sumulando con un valor de 150.

Code: [Select]
[code]
unsigned int lecturas[301];//leer 300 veces el mismo puerto
byte puerto = A0;
int cnt;
//***********************************************
void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  Serial.println("Initializing");
}
//***********************************************
void loop() {
  // put your main code here, to run repeatedly:
  Serial.println("Scanner corriendo");
  for (cnt = 0; cnt <=300; cnt++) {
    lecturas[cnt] = 150 ;//analogRead(puerto) * (5.0 / 1024.0);
  }
  Serial.println("Enviando los valores ");
  for (cnt = 0; cnt <= 300; cnt++) {
    if (Serial.available() == 0) {
      // acá todo el código  de medición y salida serial
    }
    Serial.print ("Lectura = "); Serial.print (cnt);
    Serial.print("  Valor = "); Serial.println(lecturas[cnt]);
  }
  Serial.println("final de scaneando");
  delay(1000);
}
//*************************************************
[/code]

alonsol

#36
Jul 16, 2020, 07:19 pm Last Edit: Jul 16, 2020, 07:22 pm by alonsol
Hola a todos, y muchas gracias por sus respuesta, no saben cuando las agradezco.

Escribiré dos respuestas para hacer mas ordenada y sencilla la lectura.

Hi,
Segun la imagen tu tienes el buffer al maximo. Todo esta bien.Pregunta porque en vez de enviar la data a medida que los va leyendo, lee los puntos y los almacena en un array y despues que los lees entonces los envias serial. Esto te va dar mas velocida leyendolos. No se si te ya lo habian recomendado.
Hola tauro,
Creo que no me lo habían recomendado, así que le daré una vuelta para ver si lo puedo implementar,  dado que no me interesa que me entregue los datos al instante con tal que después me entregue todos..



Hi,
Adjunto un sketch en linea con el consejo  de PeterKantTropus para que lo corras para ver que sucede. El sketch lee 300 veces el punto , almazena el resultado y despues te envia los  resultados en serial.{ruebalo para ver que sucede. La lecturas las estoy sumulando con un valor de 150.

Muchas gracias por el código, ya lo corrí y me arroja los 300 resultados. Sin embargo haciendo correr el programa varias veces me siguio arrojando el mismo error de que al inicio en la consola me entrega datos de mediciones anteriores. Luego edite el código iniciando el loop con un "if (Serial.available() == 0) {...." con el fin de verificar si se evitaban estos errores, pero sigue ocurriendo. (adjunto codigo por si no se entiende)

Code: [Select]

unsigned int lecturas[301];//leer 300 veces el mismo puerto
byte puerto = A0;
int cnt;
//***********************************************
void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  Serial.println("Initializing");
}
//***********************************************
void loop() {
  // put your main code here, to run repeatedly:
  if (Serial.available() == 0) {
  Serial.println("Scanner corriendo");
  for (cnt = 0; cnt <=300; cnt++) {
    lecturas[cnt] = 150 ;//analogRead(puerto) * (5.0 / 1024.0);
  }
  Serial.println("Enviando los valores ");
  for (cnt = 0; cnt <= 300; cnt++) {
    if (Serial.available() == 0) {
      // acá todo el código  de medición y salida serial
    }
    Serial.print ("Lectura = "); Serial.print (cnt);
    Serial.print("  Valor = "); Serial.println(lecturas[cnt]);
  }
  Serial.println("final de scaneando");
  delay(1000);
}
}


Una conclusión que puedo obtener de estos datos que me aparecen en consola, es que es si o si resultados de el codigo corrido anteriormente. Adjunto foto de la consola al correr el programa varias veces.



Algo que me causo inquietud es que yo para parar el programa, por lo general desconecto el Arduino del computador directamente

tauro0221

Hi,
Tu comentario acerca 
Quote
es que es si o si resultados de el codigo corrido anteriormente
aqui lo que pasa es que  el programa sigue corriendo y  los resultados van estar almacenados en el buffer de la computadora. Para ver si corre bien entonces ponle un delay de como 1 minuto al final del programa para que pueda vaciar el serial buffer. Si le desconecta el usb el print out va a  seguir hasta que vacie el buffer.

alonsol

#38
Jul 16, 2020, 07:58 pm Last Edit: Jul 16, 2020, 07:59 pm by alonsol
Ruido de la linea, probablemente lo mas complicado de solucionar y teniendo en cuenta que los errores los estas teniendo cuando solo efectuaste unas pocas mediciones, es muy probable que sea la causa de tu problema.  Un cable largo y no apantallado puede ser el problema, pero también puede ser ruido eléctrico y  el mismo montaje de medición. Puedes trabajar  en dos campos: el de hardware, con cables apantallados, cortos, reducción de ruidos, etc. O con software, trasmitiendo bytes con comprobación de integridad.

Hola Peter,

Utilizo el cable que supongo que venía con Arduino, ya que me lo pasaron así. Adjunto fotos sobre el cable y las conexiones que utilizo para el fotodiodo con la placa.





En la segunda imagen aparece el fotodiodo conectado a una resistencia, la cual pongo y saco dependiendo la luz incidente en este, debido a que para hacer pruebas con luz ambiental sin enfocarla a ninguna emisión directa, la corriente generada es muy pequeña. Sin embargo, estoy a la espera de que me lleguen unos amplificadores operacionales para poder aumentar la tensión de esta y conectarla de la siguiente forma.




Otra forma de hacerlo es tomar una serie de datos, almacenarlos y luego enviarlos por la comunicación serie a baja velocidad, pero eso dependería de la realidad física a medir. También hay librerías para efectuar transformadas de Fourier en el arduino y solo enviar el resultado.
Tal vez deberías describir un poco mas lo que estas haciendo (realidad física)


La idea principal es poder realizar mediciones de la corriente que genera el fotodiodo con la luz incidente que llegue a este con el Arduino. La idea es pasar esta información a MatLab, ya que ademas de realizar la transformada rápida de fourier, puedo generar distintos gráficos para visualizar las frecuencias de onda, la variación de intensidad en luces intermitentes, etc.. Algo así como un osciloscopio pero no en tiempo real, ya que necesito ir guardar los datos para posterior análisis. Adjunto el código que estaba utilizando para esto, que ademas de leer el pin A0, entrega la fecha y hora actual.

Code: [Select]

#include <RTClib.h>
RTC_Millis rtc;     //Reloj por software

void setup(void) {

  Serial.begin(2000000);
   //Para setear RTC con fecha y hora cuando se compila
   rtc.begin(DateTime(F(__DATE__), F(__TIME__)));
   //Para setear RTC a 21-MAR-2019 8:00:00
   //rtc.adjust(DateTime(2019, 3, 21, 8, 0, 0));
    DateTime hoy = rtc.now();  
    Serial.print(hoy.year());
    Serial.print('-');
    Serial.print(hoy.month());
    Serial.print('-');
    Serial.print(hoy.day());
    Serial.print(" (");
    Serial.print(hoy.hour());
    Serial.print(':');
    Serial.print(hoy.minute());
    Serial.print(':');
    Serial.print(hoy.second());
    Serial.println(")");  
}
 
void loop(void) {
  if (Serial.available() == 0) {
      int pinRead0 = analogRead(A0);
      float pVolt0 = (pinRead0 / 1024.0 * 5.0)*1000;
      Serial.print(millis());
      Serial.print("\t");
      Serial.println(pVolt0,0);
      t=millis();
}
}


En la actualidad me interesa hacer prender un led con la placa y leer la intensidad de luz con el fotodiodo de manera simultanea, con el fin de poder generar gráficos de estos en MatLab. He estado leyendo y probando distintos ejemplos, pero aun no logro algo efectivo. De echo uno de los primeros en revisar fue tu ejemplo de prender dos led de forma secuencial.. jajaja


tauro0221

#39
Jul 16, 2020, 08:32 pm Last Edit: Jul 16, 2020, 08:33 pm by tauro0221
Hi,
A mi parecer creo que el problema esta en tu computadora. Yo corro ese mismo programa sin un error = 0. Una sugerncia es que trates de conseguir otra computadora para simular el problema.Si corre bien sin problema entonces el problema esta en tu computadora. Yo le puse un delay de 100 al final del sketch y todavia corre sin errores.Otra cosa es que mi aduino es chino.

Go Up