Lectura simultánea de varios pines analog in

Buenos días.

Tengo una duda que no sé cómo resolver. Tengo dos fuentes de tensión variable conectadas a A0 y A1, pines Analog In. Estoy intentando hacer un programa en Arduino que me permita la lectura simultánea de los valores de tensión que llegan a ambos pines, de modo que en el plotter se vean como señales diferentes. Además de eso, necesito hacer otro programa que me permita reflejarlo en vez de en señales diferentes, como una única señal; de modo que esta sea la suma de los valores que llegan por A0 y por A1.

El código para un pin individual es este, pero al meter más if para el otro pin (A1), no lo lee; ya que nunca sale del primer if:

void setup() {
  Serial.begin(115200);
}

void loop() {

  int valor_sensor0 = analogRead(A0);
  float volt0 = valor_sensor0 * 5.0 / 1024;
  if ((volt0) > 0) {
 
    Serial.println(volt0);
  }
}

Muchas gracias de antemano y un saludo.

¿Y por qué usas un if?


void setup() {
  Serial.begin(115200);
}

void loop() {
  float v1 = analogRead(A0)*5.0/1023.0;
  float v2 = analogRead(A1)*5.0/1023.0;
  Serial.print(v1);
  Serial.print(",");
  Serial.print(v2);
  Serial.print(",");
  Serial.println(v1+v2);
}

Tienes razón, pero es que así me imprime los datos en la misma función gráfica dentro del plotter y no por separado en diferentes gráficas. Gracias

Por ejemplo, este es el código que tengo:

void setup() {
  Serial.begin(2400);
  
}
void loop() {
  float v0 = analogRead(A0) * 5.0 / 1024;
  float v1 = analogRead(A1) * 5.0 / 1024;
  float vtotal = v0 + v1;
  
  if (vtotal>0) {

    Serial.println(v0);
    Serial.println(" ");
    Serial.println(v1);
  }
    }

Me sale este gráfico, todo del mismo color:

No sé por qué no me sale en gráficos separados. Gracias

Creo que tu problema viene a como entiendes que funciona el plotter. Si quieres enviar varias variables tienes usar print para enviar la variable, separando cada variable con un espacio por ejemplo. La última variable debe ser escrita usando println para que el plotter empiece a leer las variables de nuevo.

Por ejemplo este código:

void setup() {
  Serial.begin(2400);
  
}
void loop() {
  float v0 = analogRead(A0) * 5.0 / 1024;
  float v1 = analogRead(A1) * 5.0 / 1024;
  float vtotal = v0 + v1;
  
  Serial.print(v0);
  Serial.print(" ");    
	Serial.println(v1);
  
}

Da como resultado esto:

Como ves, en la parte superior derecha aparece la leyenda: azul primera variable, roja la siguiente y verde la última. En este caso la azul y roja casi se solapan pues tengo los pins del Arduino libres, sin nada, flotando. Pero como ves la verde es la suma de las dos.

Quizás no esté entendiendo bien lo que pretendes hacer con el plotter.

Perfecto gracias! Es justo lo que necesitaba.

Buenas tardes. Tengo un pequeño problema que no consigo resolver.

Para entenderlo, primero quiero exponer el caso del código simplificado:

Tengo dos variables volt0 y volt1 correspondientes con la entrada de datos de los pines analog in (A0) y (A1) respectivamente, correspondientes con la señal del voltaje generado por dos fuentes de corriente variable. Cuando la suma de los voltajes de A1 y A0 es mayor que 0, se imprimen los valores volt1 y volt2, dentro de un void loop; por ello siempre que sea mayor que 0, se imprimirán durante un tiempo "t":

void setup() {
  Serial.begin(9600);
  
}

void loop() {
  float v0 = analogRead(A0) * 5.0 / 1024;
  float v1 = analogRead(A1) * 5.0 / 1024;
  
  float vtotal = v0 + v1;
  
  if (vtotal>0) {
    Serial.print(v0);
    Serial.print(",");
    Serial.println(v1);
  }
    }

Esto provoca que el código se imprima de la siguiente forma:

De modo que a 9600 baudios obtengo 14 datos de A1 y A2 durante un tiempo "t", lo que se corresponde con 7 datos para A1 y otros 7 para A2.

AQUÍ VIENE LA DUDA:

Si en vez de tener 2 variables, tuviera 15 (desde A0 hasta A14); ¿Cómo podría hacer para obtener 7 datos por cada variable en el mismo tiempo "t"? La cosa es que solo obtengo durante ese tiempo "t" a 9600 baudios tres tomas de datos:
image

Una solución que se me ocurrió fue aumentar los baudios a 2000000, pero los recoge de forma menos precisa:

Para ver que la toma de datos no es la misma a pesar de aumentar los baudios dejo la comparativa de estos dos serial plotter, el primer a 9600 baudios para dos variables; y el segundo a 2000000 de baudio para 15 variables:


Como se puede ver, una es más precisa que la otra. ¿Existe alguna forma de solucionar esto?

Gracias de antemano y un saludo.

La lectura del ADC siempre dura lo mismo, unos 100uS. Si en vez de leer 2 veces (200uS) lees 15, la velocidad de lectura es de 1500uS (1.5mS). Ahí casi que no puedes hacer nada, si no es recurriendo a librerias de terceros como AnalogReadFast que reduce el tiempo a tan solo 21uS.

Hay algo que no entiendo:

Veamos que pasa:

  float v0 = analogRead(A0) * 5.0 / 1024;
  float v1 = analogRead(A1) * 5.0 / 1024;
  float vtotal = v0+v1;

Ahí realizas la lectura, dos veces en el ADC, obviamos lo que tarda en hacer la operación de multiplicar/dividir y la asignación. Aproximadamente serán 200 uS.

if ( vtotal = v0+v1 ) {
  Serial.print(v0);
  Serial.print(",");
  Serial.print(v1);
}

Ahí realizas el envio y eso tarda en ejecutarse un tiempo X. Este código va a tardar en ejecutarse lo mismo independientemente de la velocidad del puerto serie.

Cuando realizas una llamada a print lo que haces realmente es escrbir en el búfer de salida los bytes correspondientes y dar la orden de enviar. Luego el UART lo envia a la velocidad que tenga puesta.

Mira este código:

uint32_t a,b;
void setup() {
  Serial.begin(57600);
}

void loop() {
  a = micros();
  Serial.print(0.34);
  Serial.print(" ");
  Serial.println(0.43);
  b = micros();
  Serial.println(b-a);
  delay(1000);
}

En begin prueba con distintos valores de velocidad, veras que el tiempo que tarda en ejecutarse varia muy poco.

Es decir, tu tiempo siempre será el mismo: lectura del adc mas el print.

¿Qué tienes conectado de sensor?, las fluctuaciones en la entrada del ADC son dificiles de eliminar.

Hola Victor

Lo primero de todo gracias por tu ayuda.

Para entenderlo mejor, lo que estoy utilizando son diferentes pulsadores piezoeléctricos que generan un voltaje. En el primer caso uso 2, y el el otro caso utilizo 14.

De modo que a 9600 baudios obtengo 14 datos de A1 y A2 durante un tiempo "t", lo que se corresponde con 7 datos para A1 y otros 7 para A2.

Con esto me refiero a que para un tiempo t, que puede ser 500ms, por ejemplo; se imprimen solamente 14 valores. 7 correspondientes a la entrada A0 y otros 7 a A1. Obteniendo los valores correspondientes a las siguientes imágenes (monitor y plotter):

image

En este caso A1 esta siendo presionado, y A0 no; por eso marca 0.00 voltios.

La aplicación que realmente le busco a este programa, es hacer lo mismo pero para 14 pulsadores. Obteniendo la misma resolución. La cosa es que no la obtengo, ni si quiera con 2000000 baudios: (imagen 9600 baudios monitor/9600 plotter):

image

image

La señal se corresponde a A1, el resto de pulsadores no se están ejecutando.

Como se puede ver, la señal está mucho peor definida que cuando ejecuto el programa para dos pulsadores en vez de para los 14. Esto sigue ocurriendo si aumento los baudios a 2000000:

image

No se si se puede solucionar con AnalogReadFast(), pero he estado mirando y la verdad que no entiendo muy bien como instalarlo

Para instalar la libreria, ve al enlace que te puse. En la pestaña que poce "code" pulsa y se abrirá un desplegable, abajo del todo dale a "download zip".

Te descargaras un archivo llamado "avdweb_AnalogReadFast-master.zip". Al abrirlo con Winrar/Winzip/7zip dentro habrá una carpeta llamada "avdweb_AnalogReadFast-master".

Supongo que estas trabajando sobre Windows, así que tendrás que buscar la carpeta "Arduino" en "Documentos". Al abrirla verás otra carpeta que se llama "libraries". Abrela. Copia la carpeta "avdweb_AnalogReadFast-master" dentro. Por último, cambia el nombre de la carpeta eliminando "-master", quedándose solo una carpeta llamada "avdweb_AnalogReadFast.h".

Ya estará la libreria instalada.

He probado la libreria con este código:

#include <avdweb_AnalogReadFast.h>

int bufer[15];
int suma = 0;
int i;

void setup() {
   Serial.begin(9600);
}

void loop() {
  suma = 0;
  for (i=0; i<15; i++) {
    bufer[i]=analogReadFast(A0+i);
    suma += bufer[i];
  }
  if ( suma!=0 ) {
  for (i=0; i<14; i++) {
    Serial.print(bufer[i]);
    Serial.print(",");
  }
  Serial.println(bufer[i]);
  Serial.println(b-a);
  }
}

Y realmente reduce el tiempo de 1.6mS a unos 200uS de la lectura (en simulación, no tengo un Arduino Mega).

He utilizado un búfer para leer los pines y reducir un poco el código. También he obviado la conversión a voltage, para reducir el tiempo de cálculo.

Aún así no mejorarás mucho. La lectura es más rápida, pero el tiempo que va a tomar los "print" seguirá siendo elevado.

Encima envía 80 caracteres (bytes) hacia un buffer de 64 bytes, va a demorar más todavía ya que tiene que esperar que al menos se transmitan 16 bytes para poder continuar.

Saludos

Buenos días. He probado la librería y la verdad que sigo teniendo el mismo problema. Imagino que será por lo que dices de la velocidad de impresión. Gracias!

Podría existir alguna forma de reprogramar el código para que no ocurriera eso? Los pulsadores no se van a pulsar nunca exactamente en el mismo instante de tiempo, lo mismo puedo jugar con eso, para que imprima justo el que se ejecuta en el instante en el que se pulsa

La única forma en la que podemos aumentar la velocidad de transmisión es trabajar a nivel de byte, usando la función write en vez de print


#include <avdweb_AnalogReadFast.h>

int bufer[15];
int suma = 0;
int i;
uint32_t a, b;

void setup() {
   Serial.begin(9600);
}

void loop() {
  a = micros();
  suma = 0;
  for (i=0; i<15; i++) {
    bufer[i]=analogReadFast(A0+i);
    suma += bufer[i];
  }
  if ( suma!=0 ) {
    
    Serial.write((byte*)bufer, 30);
    
  }
  b = micros();
  Serial.println();
  Serial.println(b-a);
}

Este código resulta mucho más rápido, un poco mas de 30mS. Pero, me temo que el plotter no funciona con datos en bytes y no mostrará nada.

Tu aplicación final es un teclado con 14 teclas, pero ¿cúal es el objetivo de usar el plotter? Si no tienes que usar el plotter, tan solo que realice un "algo" cuando pulsas la tecla la velocidad no será tan crítica.

Realmente estoy usando el plotter para que sea más visual la explicación. Lo que si que necesito es que los valores queden registrados como ocurre con print, para volcarlos a excel

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.