variable se incrementa sin tener porque

Hola de nuevo,

estoy comprobando que que el valor de una variable este dentro de un rango determinado con un if y un else, y contabilizando los aciertos y errores, algo sencillo. Pues no se porque razon el contador de errores se va incrementando sin tener porque. Puesto que visualizo los datos por pantalla y los valores se encuetran dentro del rango valido, por lo tanto se incrementan los aciertos, pero los errores tambien, algo muy raro no??

////////// VERIFICACION PERIODO CH1 ////////////////

//if(Tch1){

  if(Tch1 > 15.60 && Tch1 < 16.10)
  {
     pulsos_giro++;
  }
  else
  {
    Error_pulsos_giro++;

  }
  
//}
///////////////////////////////////////////////////

Error_pulsos_giro no para de incrementarse, cuando el valore de Tch1 esta dentro del rango indicado.

Tch1 ¿está definido como float?

Si, claro es un float.

Haber los valores correctos oscilan entre 15,95(aveces 15,94 o 15,93) y 16,02 mas o menos.

He probado a plantearlo de otra manera y consigo que deje de incrementarse la variable que registra los errores, y ahora fuerzo a que haya algun error de vez en cuando y no los registra. :frowning:

if(Tch1 > 15.95 && Tch1 < 16.10)// se comprueba que hay un periodo valido
  {
    pulsos_giro ++; //se cuentan pulsos
  }
  else if(Tch1 < 15.95 || Tch1 > 16.10)
  {
    Error_pulsos_giro ++;
  }

He puesto un par de variables para ver cuando entra en el " if "o “else” y que se actualicen en cada vuelta y cambian la primera vez, luego se quedan fijas.

estado inicial:

pulsoOK = 0;
pulsoMalo = 1;

en cada buclelas reinicio, pero nada, no cambian.

Me pasan unas cosas mas raras que el copon !!! :o

 if(Tch1 > 15.90 && Tch1 < 16.10)// se comprueba que hay un periodo valido
  {
    pulsoOK = 1;
    pulsos_giro ++; //se cuentan pulsos
  }
  else //if(Tch1 < 15.90 || Tch1 > 16.10)
  {
    pulsoMalo = 0;
    Error_pulsos_giro ++;
  }

Sube tu sketch completo para ver qué más podría estar afectando tu código.

dos formas de hacerlo
Metodo1: transformar cada consulta float en una booleana

 if((Tch1 > 15.90) && (Tch1 < 16.10)) { // se comprueba que hay un periodo valido
      pulsoOK = 1;
    pulsos_giro ++; //se cuentan pulsos
  }
  else  {
    pulsoMalo = 0;
    Error_pulsos_giro ++;
 }

Metodo 2: Valor absoluto

if(abs(Tch1 - 16.0)< 0.1) {// se comprueba que hay un periodo valido
    pulsoOK = 1;
    pulsos_giro ++; //se cuentan pulsos
}
else {
    pulsoMalo = 0;
    Error_pulsos_giro ++;
}

Surbyte probe el primer metodo y nada, con el segundo veo que las variables pulsook y pulsomalo si cambian pero tampoco funciona correctamente :frowning: .

gepd, aqui adjunto todo el sketch.

const int Pin_in_ch1 = 2; // Pin entrada ch1 (direccion)
const int Pin_in_ch2 = 3; // Pin entrada ch2 (traccion)

char giro = 0;
char giro_ant = 0;
float Duty_giro = 0.0;
float Tch1 = 0.0;
unsigned int Tini_giro = 0;
unsigned int Tini_giro_ant = 0;
unsigned int Tact_giro = 0;
int pulsos_giro = 0;
int Error_pulsos_giro = 0;
unsigned long duty_ch1_OK;
unsigned long Error_duty_ch1;
boolean ch1_ok = 0;
int pulsoOK = 0;
int pulsoMalo = 1;


char trac = 0;
char trac_ant = 0;
float Duty_trac = 0.0;
float Tch2 = 0.0;
unsigned int Tini_trac = 0;
unsigned int Tini_trac_ant = 0;
unsigned int Tact_trac = 0;

unsigned long tini_loop = 0;
unsigned long tact_loop = 0;
unsigned long totalT_loop = 0;

int numLoops=0;


void setup() {

  Serial.begin(9600);
  pinMode(Pin_in_ch1,INPUT);

  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1 = 0;
  TCCR1B = _BV(CS10) | _BV(CS11); // pre-esca 64 , nuevo perido del micro 4e-6
}

void loop() {
  
  pulsoOK =0;
  pulsoMalo=1;
  tini_loop = micros();
  
  Leer_Canal1();
  Leer_Canal2();
  Comprobar_Ch1();
  
 
  
  
  tact_loop = micros();
  totalT_loop = tact_loop - tini_loop;
  
  if (++numLoops >= 2000) // representacion espaciada de datos para evitar saturar buffer serial
  {
    //Serial.print ("DUTY GIRO : ");
    //Serial.println (Duty_giro);
    Serial.print ("PERIODO GIRO: ");
    Serial.println (Tch1);
    Serial.println("----------------------------------  ");

    //Serial.print ("PULSOS GIRO: ");
    //Serial.println (pulsos_giro);
    
    Serial.print ("PULSOS Ok: ");
    Serial.println (pulsoOK);
    
    Serial.print ("PULSO MALO: ");
    Serial.println (pulsoMalo);
    
    /*
    Serial.println("----------------------------------  ");
    Serial.print ("DUTY TRACCION : ");
    Serial.println (Duty_trac);
    Serial.print ("PERIODO TRACCION: ");
    Serial.println (Tch2);
    */
    /*
    Serial.println("----------------------------------  ");
    Serial.print(" Periodo LOOP : ");
    Serial.print("  ");
    Serial.println(totalT_loop);
    */
    
   // Serial.println("----------------------------------  ");
   // Serial.print ("PERIODO OK GIRO : ");
   // Serial.println (pulsos_giro);
   // Serial.print ("DUTY OK GIRO: ");
   // Serial.println (duty_ch1_OK);
    
   // Serial.println("----------------------------------  ");
    //Serial.print ("ERROR DUTY GIRO : ");
    //Serial.println (Error_duty_ch1);
   
    Serial.print ("ERROR PERIODO GIRO: ");
    Serial.println (Error_pulsos_giro);
    /*
    Serial.println("----------------------------------  ");
    Serial.print ("GIRO OK : ");
    Serial.println (ch1_ok);
    */
    numLoops=0;
  }
  
  
}
void Leer_Canal1(){
  
  
  
  giro = digitalRead(Pin_in_ch1);
  
  if (giro != giro_ant)
  {
    if(giro)
    {
      Tini_giro = TCNT1;
      // se multiplica por 4e-3 en vez de 4e-6 por tema de representacion de datos en la consola
      Tch1 = (Tini_giro - Tini_giro_ant)*4e-3; // caluclo periodo ch1
    }
    else 
    {
      Tact_giro = TCNT1;
      Duty_giro = (Tact_giro - Tini_giro)*4e-3; //calculo duty-cycle ch1
    }
    giro_ant = giro;
  }

  Tini_giro_ant = Tini_giro;

}
void Comprobar_Ch1(){
  
////////// VERIFICACION PERIODO CH1 ////////////////7
//if(Tch1){
  if(Tch1 > 15.90 && Tch1 < 16.10)// se comprueba que hay un periodo valido
  {
    pulsoOK = 1;
    pulsos_giro ++; //se cuentan pulsos
  }
  else //if(Tch1 < 15.90 || Tch1 > 16.10)
  {
    pulsoMalo = 0;
    Error_pulsos_giro ++;
  }
//}
///////////////////////////////////////////////////


///////////// VEREFICIACION DUTY-CYCLE CH1 //////////////
  if(Duty_giro > 1.00 && Duty_giro < 2.00)   
  {
    duty_ch1_OK++;
  }
  else
  {
    Error_duty_ch1++;
  }
//////////////////////////////////////////////////////
/*
  if(pulsos_giro >= 10000) // espera un tiempo para validar el canal
  {
    ch1_ok = 1;
  }
  else
  {
    ch1_ok = 0;
  }
  */
}

Leer_Canal2 es igual que Leer_Canal1

Probé tu código levemente simplificado
Resultados correctos

float Tch1 		= 15.80;
int pulsos_giro 	= 0;
int Error_pulsos_giro 	= 0;

void setup() {
  Serial.begin(9600);
  Serial.println("Inicio float");
}

void loop() {
    char buffer[30];
    char a[10];

    Tch1 += 0.05;
    if (Tch1 > 16.20) {
    	Serial.println("Terminado");
        while(1);
    }
    dtostrf(Tch1, 5,2, a);
    
    if (Tch1 > 15.90 && Tch1 < 16.10) {
        pulsos_giro ++; 
    }
    else  {
        Error_pulsos_giro ++;
    }
    sprintf(buffer, "%s => Pgiro %d Egiro %d", a, pulsos_giro, Error_pulsos_giro);
    Serial.println(buffer);
    delay(1000);
}

Como este funciona solo haré el de valor absoluto porque confío en su funcionamiento.
Solo modifiqué la linea fundamental

if (abs(Tch1 - 16.0) < 0.1) {

todos funcionan.

Si puede ser que lo tuyo funcione surbyte, y es hasta descabellado pensar que tenga este tipo de problema, porque filtrar un rango de valores y contabilizar los aciertos y los errores no tiene ninguna dificultad. Pero no se que puede haber en el codigo que haga que las variables se incrementen pasandose por el forro las dos sentencias, porque lo que me aparace en pantalla me dice que el periodo esta bien calculado y veo con mis propios ojos que los valores entran dentro del rango de no errores.

Deje de usar las interrupciones para calcular el periodo y tener el programa mas simplificado y no tener ningun tipo de conflicto con la ejecucion de estas.

Y aun asi ocurren cosas muy raras, como por ejemplo esto que me esta pasando, la verdad es que me frustra bastante este tipo de problemas que no se ven de una forma clara. :(

Vale, creo que deberia de reformular el problema porque sigo probando y me he dado cuenta de que las sentencias “if y else” las hace bien junto con las variables pulsoOk y pulsoMalo he inicializado a cero las variables pulso_giro y Error_pulso_giro dentro de la funcion Comprobar_Ch1() y veo que si detecta los errores. Lo que como se ponen a cero en cada iteracion no puedo almacenar los incrementos

Vamos a ver, realmente el problema es que por lo menos la variable Error_pulso_giro se incrementa de una forma aleatoria, es como si cuando se lanzara el programa indepedientemente de lo que pase se incrementa.

void Comprobar_Ch1(){
  
   Error_pulsos_giro = 0;
   pulsos_giro = 0;
  
  //////// VERIFICACION PERIODO CH1 ////////////////7
if(Tch1 != 0.0){
  
  if(Tch1 > 15.97 && Tch1 < 16.10)// se comprueba que hay un periodo valido
  {
    pulsoOK = 1;
    pulsos_giro += 1; //se cuentan pulsos
  } 
  else //if(Tch1 < 15.90 || Tch1 > 16.10)
  {
    pulsoMalo = 0;
    Error_pulsos_giro += 1;
  }
}
///////////////////////////////////////////////////


///////////// VEREFICIACION DUTY-CYCLE CH1 //////////////
  if(Duty_giro > 1.00 && Duty_giro < 2.00)   
  {
    duty_ch1_OK++;
  }
  else
  {
    Error_duty_ch1++;
  }
//////////////////////////////////////////////////////

  if(pulsos_giro >= 10000)
  {
    ch1_ok = 1;
  }
  else
  {
    ch1_ok = 0;
  }

  
}

sin hacer esto nada mas abrir la consola ya aparacen valores adjunto un par de imagenes.

en la imagen 1 se ve que la variable que pulsos_giro toma el valor 1 cuando cumple la condicion y la variable Error_pulso_giro toma el valor uno cuando no cumple la candicion. como he dicho no se incrementa porq las tengo que poner a cero en cada iteracion para poder ver que realmente esta funcionando bien.

Y en la imagen 2 se ve que dichas variables no paran de incrementarse desde que abro la consola.

Como verás yo aisle el problema porque tu lo planteaste como que el condicional fallaba. Ahora esta claro que en algún otro momento las variables cambian de valor asi que presta atención a eso.

Las imagenes de antes las adjunto aqui que me habia dado error al cargarlas

Pictures.zip (130 KB)

Alguna sugerencia chicos??

¿De dónde obtienen los valores esas variables? Si posteas el sketch tal como lo estás usando se puede replicar para ver si da el mismo problema e intentar solucionarlo. Si lo que surbyte te envió no te sirve, habría que intentar hacerlo con las mismas condiciones que tu lo estás haciendo.

Te he preguntado por email si tienes resistencias de 10k entre el pin 2 y 3 a gnd.

Ya, lo he visto, te refieres a si tengo activadas las PULL-UP??

He probado activar tanto las PULL UP como las PULL DOWN y nada de nada, sigue funcionando igual de mal :(.

Otra cosa, aun teniendo el Joystick y el receptor apagados, las variables siguen incrementandose....ya nose que hacer

La variable de error se incrementan en cada ciclo.
Eso ocurre porque asi lo tienes programado.
No se si te entiendo pero cuando se da que el valor cae dentro del rango la variable se incrementa correctamente.
A eso te refieres?
Terminas teniendo como un contador de pulsos errados tal como esta escrita tu rutina.
Que quisieras que haga en su lugar?

void Comprobar_Ch1(){
   Error_pulsos_giro = 0;
   pulsos_giro = 0;
  //////// VERIFICACION PERIODO CH1 ////////////////7
if(Tch1 != 0.0){
  if(Tch1 > 15.97 && Tch1 < 16.10) {// se comprueba que hay un periodo valido
    pulsoOK = 1;
    pulsos_giro += 1; //se cuentan pulsos
  } 
  else //if(Tch1 < 15.90 || Tch1 > 16.10) {
    pulsoMalo = 0;
    Error_pulsos_giro += 1;
  }
}

Si Tch1 es != 0 que es la mayor parte del tiempo sino siempre y si Tch1 no esa en el rango 15.97 a 16.10 siempre seva a incrementar error_pulsos_giro
Eso esta bien.
Cuando yo generé con mi simulador un valor duty comprendido en el rango incrementó bien la variable pulsos_giro
que estaba en 0 y subió a 1, y si la mantengo crece y crece.
todo tal cual como lo tienes programado.
Ahora tu dices que estas variables crecen o suben aun cuando las entradas no estan en ese rango, pero te refieres a error_pulsos_giro y a pulsos_giro ? las dos suben?