Error de valores "inf" y "nan"

Muy buenas a todos, soy nuevo en el foro y en esto de arduino, estoy trabajando con un ATMEGA2560 que me han prestado en el insti y resulta que tengo un problema con la visualizacion de resultados.
Estoy trabajando en un pulsioximetro que tiene que hacer ciclos de mediciones con una fotocelula de un led rojo y un led IR. Creo que eso lo hace correctamente pero el fallo viene al ver los resultados que me da un valor “inf” y otro valor “nan” y no se exactamente que significa. He buscado info pero solo he encontrado cosas en ingles muy tecnico y me pierdo puesto que soy nuevo en el mundillo. Os dejo el codigo y una imagen con el error.

Con la opcion de imagenes no se muestra pero os dejo aqui el link del “error”: Imagen

int LED_R = 12; // LED ROJO conectado en el PIN 12
int LED_IR = 11; // LED IR conectado en el PIN 11
int SENSOR_R = 6; // SENSOR rojo conectado en el PIN analogico 6
int SENSOR_IR = 7; // SENSOR infrarrojo conectado en el PIN analogico 7
float SENSOR_VALOR_R = 0; // Lectura del sensor para luz roja encendida
float SENSOR_VALOR_IR = 0; // Lectura del sensor para luz infrarroja encendida
int INTERRUPTOR_R = 10; // Controla el interruptor rojo por el PIN 10
int INTERRUPTOR_IR = 9; // Controla el interruptor infrarrojo por el PIN 9
int CICLOS = 0; // Contador de milisegundos
int NUM_MUESTRAS = 0;
float MEDIA = 0;
float SENSOR_VALOR_R_ANT = 0;
float SENSOR_VALOR_IR_ANT = 0;
float MAXIMO_R_PROV = 0;
float MINIMO_R_PROV = 0;
float MAXIMO_R = 0;
float MAXIMO_IR = 0;
float MINIMO_R = 0;
float MINIMO_IR = 0;
float TIEMPO_INI_PULSO_PROV = 0;
float TIEMPO_INI_PULSO = 0;
float TIEMPO_INI_PULSO_ANT = 0;
float NUM_MAXIMOS = 0;
float MEDIA_PERIODOS = 0;
float AMPLITUD_R = 0;
float AMPLITUD_IR = 0;
float MEDIA_AMPLITUD_R = 0;
float MEDIA_AMPLITUD_IR = 0;
float PERIODO = 0;
float PULSO_CARD = 0;
int BUSCA_MAXIMO = 1;
int BUSCA_MINIMO = 1;
float dA_R = 0;
float dA_IR = 0;
float RATIO = 0;
float RATIO_PROV = 0;
float MEDIA_RATIO = 0;
float SAO2 = 0;

void setup() {
pinMode (LED_R, OUTPUT); // Configuración del PIN LED_R como salida
pinMode (LED_IR, OUTPUT); // Configuración del PIN LED_IR como salida
pinMode (SENSOR_R, INPUT); // Configuración del PIN SENSOR rojo como entrada
pinMode (SENSOR_IR, INPUT); // Configuración del PIN SENSOR infrarrojo como entrada
pinMode (INTERRUPTOR_R, OUTPUT); // Configuración del PIN INTERRUPTOR_R como salida
pinMode (INTERRUPTOR_IR, OUTPUT); // Configuración del PIN INTERRUPTOR_IR como salida
analogReference (DEFAULT); // Configuración de la tensión de referencia por defecto (5 V)
Serial.begin (9600); // Configuración para la transmisión de los datos por el puerto serie
}

void loop() {
// Cálculo de la media de la señal durante 2 segundos
for (CICLOS = 0; CICLOS <= 50; CICLOS++) {
digitalWrite (LED_R, HIGH); // Encendido del LED rojo
delayMicroseconds (10); // Espera para encendido completo del LED
digitalWrite (INTERRUPTOR_R, HIGH); // Cierre del interruptor rojo
delayMicroseconds (960); // Espera para estabilización de señal
SENSOR_VALOR_R = analogRead (SENSOR_R); // Lectura del pin analógico del sensor rojo
digitalWrite (INTERRUPTOR_R, LOW); // Apertura del interruptor rojo
delayMicroseconds (10); // Espera para apertura completa del interruptor
digitalWrite (LED_R, LOW); // Apagado del LED rojo
delayMicroseconds (20);
digitalWrite (LED_IR, HIGH); // Encendido del LED infrarrojo
delayMicroseconds (10); // Espera para encendido completo del LED
digitalWrite (INTERRUPTOR_IR, HIGH); // Cierre del interruptor infrarrojo
delayMicroseconds (960); // Espera para estabilización de señal
SENSOR_VALOR_IR = analogRead (SENSOR_IR); // Lectura del pin analógico del sensor infrarrojo
digitalWrite (INTERRUPTOR_IR, LOW); // Apertura del interruptor infrarrojo
delayMicroseconds (10); // Espera para apertura completa del interruptor
digitalWrite (LED_IR, LOW); // Apagado del LED infrarrojo
delayMicroseconds (20);
}
CICLOS = 0; // Se reinicia el contador de ciclos
NUM_MUESTRAS = NUM_MUESTRAS+1; // Se coge una muestra cada 200 milisegundos
// Los valores del pulso y de la saturación de oxígeno se calculan y se muestran cada 7 segundos
if (NUM_MUESTRAS <= 70) {
MEDIA = (MEDIA*(NUM_MUESTRAS-1) + SENSOR_VALOR_R)/NUM_MUESTRAS;
// Durante los primeros 3 segundos sólo se ha calculado la media de la señal roja
// Si han pasado los 3 primeros segundos, empezamos a buscar los cruces por la media y a calcular el ratio
if (NUM_MUESTRAS > 30) {
// Igualamos al valor medio las variables del máximo y mínimo provisional
if (NUM_MUESTRAS == 31) {
MAXIMO_R_PROV = MEDIA;
MINIMO_R_PROV = MEDIA;
}
// Siempre que estemos por encima de la media, actualizamos el valor del máximo provisional si encontramos un valor superior
// También almacenamos el momento en que ocurre de forma provisional
if (SENSOR_VALOR_R >= MAXIMO_R_PROV && SENSOR_VALOR_R > MEDIA) {
MAXIMO_R_PROV = SENSOR_VALOR_R;
TIEMPO_INI_PULSO_PROV = millis ();
}
// Siempre que estemos por debajo de la media, actualizamos el valor del mínimo provisional si encontramos un valor inferior
if (SENSOR_VALOR_R <= MINIMO_R_PROV && SENSOR_VALOR_R < MEDIA) {
MINIMO_R_PROV = SENSOR_VALOR_R;
}
// Se detecta un cruce por la media de arriba a abajo y se estaba buscando un máximo
if (SENSOR_VALOR_R_ANT > MEDIA && SENSOR_VALOR_R < MEDIA && BUSCA_MAXIMO == 1) {
MAXIMO_R = MAXIMO_R_PROV; // Almacenamos el valor del máximo encontrado
MAXIMO_R_PROV = MEDIA; // Reiniciamos el máximo provisional al valor de la media
MAXIMO_IR = SENSOR_VALOR_IR; // Almacenamos el valor del máximo infrarrojo (se produce a la vez que el máximo rojo)
TIEMPO_INI_PULSO = TIEMPO_INI_PULSO_PROV; // Almacenamos el momento en que se produjo el máximo
TIEMPO_INI_PULSO_PROV = 0;
// Si es el primer máximo encontrado
if (NUM_MAXIMOS == 0) {
TIEMPO_INI_PULSO_ANT = TIEMPO_INI_PULSO;
}
// A partir del segundo máximo encontrado
if (NUM_MAXIMOS >= 1) {
// Se calcula el período entre este máximo y el anterior
PERIODO = TIEMPO_INI_PULSO - TIEMPO_INI_PULSO_ANT;
TIEMPO_INI_PULSO_ANT = TIEMPO_INI_PULSO;
// Se calcula una media entre los períodos encontrados hasta el momento
MEDIA_PERIODOS = (MEDIA_PERIODOS*(NUM_MAXIMOS-1) + PERIODO)/NUM_MAXIMOS;
}
NUM_MAXIMOS = NUM_MAXIMOS+1;
BUSCA_MINIMO = 1; // Pasamos a buscar un mínimo
BUSCA_MAXIMO = 0; // Dejamos de buscar un máximo
}
// Se detecta un cruce por la media de abajo a arriba y se estaba buscando un mínimo
if (SENSOR_VALOR_R_ANT < MEDIA && SENSOR_VALOR_R > MEDIA && BUSCA_MINIMO == 1) {
MINIMO_R = MINIMO_R_PROV; // Almacenamos el valor del mínimo encontrado
MINIMO_R_PROV = MEDIA; // Reiniciamos el mínimo provisional al valor de la media
MINIMO_IR = SENSOR_VALOR_IR; // Almacenamos el valor del mínimo infrarrojo (se produce a la vez que el mínimo rojo)
BUSCA_MAXIMO = 1; // Pasamos a buscar un máximo
BUSCA_MINIMO = 0; // Dejamos de buscar un mínimo
// Al encontrar un mínimo, calculamos las amplitudes siempre que previamente hayamos encontrado algún máximo
if (NUM_MAXIMOS >= 1) {
AMPLITUD_R = MAXIMO_R - MINIMO_R; // Cálculo de amplitud roja
AMPLITUD_IR = MAXIMO_IR - MINIMO_IR; // Cálculo de amplitud infrarroja
// Cáclulo de las medias de las amplitudes encontradas hasta el momento
MEDIA_AMPLITUD_R = (MEDIA_AMPLITUD_R*(NUM_MAXIMOS-1)+AMPLITUD_R)/NUM_MAXIMOS;
MEDIA_AMPLITUD_IR = (MEDIA_AMPLITUD_IR*(NUM_MAXIMOS-1)+AMPLITUD_IR)/NUM_MAXIMOS;
}
}
}
}
else {
//Calculamos y mostramos por pantalla los valores de pulso y saturación de oxígeno
PULSO_CARD = 60000/MEDIA_PERIODOS;
MEDIA_RATIO = MEDIA_AMPLITUD_IR/MEDIA_AMPLITUD_R;
SAO2 = 115-(30*MEDIA_RATIO);
Serial.print ("Pulso cardiaco = ");
Serial.println (PULSO_CARD);
Serial.print ("Saturacion de oxigeno = ");
Serial.println (SAO2);
Serial.println ();
NUM_MUESTRAS = 0;
MEDIA = 0;
SENSOR_VALOR_R_ANT = 0;
MAXIMO_R_PROV = 0;
MINIMO_R_PROV = 0;
MAXIMO_R = 0;
MAXIMO_IR = 0;
MINIMO_R = 0;
MINIMO_IR = 0;
TIEMPO_INI_PULSO_PROV = 0;
TIEMPO_INI_PULSO = 0;
TIEMPO_INI_PULSO_ANT = 0;
NUM_MAXIMOS = 0;
MEDIA_PERIODOS = 0;
AMPLITUD_R = 0;
AMPLITUD_IR = 0;
MEDIA_AMPLITUD_R = 0;
MEDIA_AMPLITUD_IR = 0;
PERIODO = 0;
BUSCA_MAXIMO = 1;
BUSCA_MINIMO = 1;
MEDIA_RATIO = 0;
RATIO = 0;
RATIO_PROV = 0;
SAO2 = 0;
}
}

Creo que tengo un problema con la recepcion de la señal, no se si es que no me llega bien la señal analogica o que puede estar pasando :sob: :sob: :sob:

Gracias de antemano.

pulsioximetro.jpg

Moderador: Editado para visualicion de imagen y agregado de etiqueta de enlace.

inf es infinito

int surge de operaciones asi

float tmp = 1.0 / 0.0;    // inf!
Serial.println (tmp);

dara un inf

en cambio Nan aparece cuando calculas un número imaginario

float temp = sqrt (-1);    // NaN!

o i en notación matemática o número complejo puro.

Muchas gracias por la info. Entiendo que si alguna de las señales que tiene que recibir no me llega bien puede dar lugar a un fallo en el calculo y que por eso me salga el inf y el nan?

Exacto. Ahora un consejo, no uses mayúsculas en los códigos. Realmente me costó leerlo.

Entiendo que el LED esta en D12; el IR en D11 y dos sensores: una foto celular en A6 y el lector IR en A7.

Para que usas D9 y D10 ?

Para el mando de unos interruptores electornicos que dan paso a la señal al mismo ritmo que se encienden el led rojo o el led IR. digamos que tengo un circuito de generacion de señal que es la fotocelula y dos de salida, el de Rojo e IR. entonces dependiendo de cual este encendido doy paso a una señal de salida u otra.

He descubierto algo pero la verdad es que no me aclaro mucho, porque la programacion la cogi del proyecto de otra persona ya que no tengo apenas conocimientos de arduino. Resulta que llega un punto que los valores me dan 0.00 y creo que por eso me da fallo al final. Siento que este en mayuscula, ya digo no lo programe yo, pero he puesto varios print para ver los resultados en el monitor y me sale esto:

PERIODO = 0.00 TIEMPO_INI_PULSO = 0.00 TIEMPO_INI_PULSO_ANT = 0.00 MEDIA_PERIODOS = 0.00 MAXIMO_R_PROV = 697.00 SENSOR_VALOR_R = 697.00 TIEMPO_INI_PULSO_PROV = 3837.00 PERIODO = 0.00 TIEMPO_INI_PULSO = 0.00 TIEMPO_INI_PULSO_ANT = 0.00 MEDIA_PERIODOS = 0.00 MINIMO_R_PROV = 693.00 PERIODO = 0.00 TIEMPO_INI_PULSO = 0.00 TIEMPO_INI_PULSO_ANT = 0.00 MEDIA_PERIODOS = 0.00 PERIODO = 0.00 TIEMPO_INI_PULSO = 0.00 TIEMPO_INI_PULSO_ANT = 0.00 MEDIA_PERIODOS = 0.00 MINIMO_R_PROV = 688.00

¿Alguien sabria decirme porque? Muchas gracias de antemano.

Aca veo un error en el código, algo que tu agregaste que deliberadamente alguien lo hizo para confundir.

// Cálculo de la media de la señal durante 2 segundos
for (CICLOS = 0; CICLOS <= 50; CICLOS++) {
     digitalWrite (LED_R, HIGH); // Encendido del LED rojo
     delayMicroseconds (10); // Espera para encendido completo del LED
     digitalWrite (INTERRUPTOR_R, HIGH); // Cierre del interruptor rojo
     delayMicroseconds (960); // Espera para estabilización de señal
     SENSOR_VALOR_R = analogRead (SENSOR_R); // Lectura del pin analógico del sensor rojo
     digitalWrite (INTERRUPTOR_R, LOW); // Apertura del interruptor rojo
     delayMicroseconds (10); // Espera para apertura completa del interruptor
     digitalWrite (LED_R, LOW); // Apagado del LED rojo
     delayMicroseconds (20);
     digitalWrite (LED_IR, HIGH); // Encendido del LED infrarrojo
     delayMicroseconds (10); // Espera para encendido completo del LED
     digitalWrite (INTERRUPTOR_IR, HIGH); // Cierre del interruptor infrarrojo
     delayMicroseconds (960); // Espera para estabilización de señal
     SENSOR_VALOR_IR = analogRead (SENSOR_IR); // Lectura del pin analógico del sensor infrarrojo
     digitalWrite (INTERRUPTOR_IR, LOW); // Apertura del interruptor infrarrojo
     delayMicroseconds (10); // Espera para apertura completa del interruptor
     digitalWrite (LED_IR, LOW); // Apagado del LED infrarrojo
     delayMicroseconds (20);
}

si miras este ciclo for empieza y termina sin hacer nada mas que entregarte las ultimas muestras a SENSOR_VALOR_R y a SENSOR_VALOR_IR

O sea no sirve para nada, no toma muestras, no calcula.
Por eso todo esta en 0.

Si miras ahora acá

ciclos = 0; // Se reinicia el contador de ciclos
  num_muestras = num_muestras+1; // Se coge una muestra cada 200 milisegundos
  // Los valores del pulso y de la saturación de oxígeno se calculan y se muestran cada 7 segundos
  if (num_muestras <= 70) {

se ve que se requiren 2x70 segundos para tener datos.
El 1er for dice demorar 2 segundos algo que dudo pero basado en eso, 2 x 70 muestras son 140 segundos o sea 140/60 = 2min 20 seg recién tendrías valores distintos de 0.

Muchas gracias! Voy a seguir probando, ahora tengo un problema con los switch y m creo que tengo que usar millis() pero no se muy bien como.