A variable changes while i modify another one (it isn't even used in the function)

Hi folks, i'm a Little new in the Arduino thopic, Actualy i'm programing a very Basic control system for humidity in a fungículture project, i think that i almost have the programing done, but i'm stuck in a bug that modifies a very important variable, this bug writes a variable whit a value close to 70 in a spot in the code that doesn't even reads the value, it wolud be great if you can helpme, here is the function and the spot where the variable gets modified:

void Leer_sensor(){
  //lee temperatura y humedad en el sensor 1
  T[1]=sensor1.readTemperature();
  Hl[1]=sensor1.readHumidity();
  // lee termperatura y humedad en el sensor 2
  T[2]=sensor2.readTemperature();
  Hl[2]=sensor2.readHumidity();
  //promedia temperatura y humedad de los sensores
  Hl[3]=(Hl[1]+Hl[2])/2; // here is the line where the variable "Modo" gets modified
  Serial.println(Modo);
  T[3]=(T[1]+T[2])/2;
  Serial.println("Sensado Realizado");
}

In this function the arduino reads the humidity and temperature of two DHT 22 sensors and promediates it, the variables are declared as:

// the variables used in the function
byte T[3];
byte Hl[3];
// the variable that gets bugged 
byte Modo=0;

I proceed to add the whole code:


#include <TimerOne.h>
#include <Wire.h>
#include <DHT.h>
#include <DHT_U.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
// Variables del sensor
byte sens1=5;
byte sens2=6;
// variables de manejo temperatura y humedad
byte T[3];
byte Hl[3];
// variables de ejecucion de los botones 
boolean button[3]={7,8,9};
int state_count[3]={0,0,0};
volatile boolean state=0;
volatile boolean btn[3]={0,0,0};
// variables de ejecucion del tiempo
volatile long seg = 0;
long reseteo=3;
//variables de control 
byte Modo=0;
byte Umbral_humedad[2]={70,95};
byte Modificacion=0;
byte Temporizador[3]={8,0,0};
long Tiempo_ventilacion=(Temporizador[0]*3600+Temporizador[1]*60+Temporizador[2]);
// variables de estado
volatile boolean Proceso_ventilacion=0;
volatile boolean Proceso_Humifdificar=0;
//declaracion de lo sensores 
DHT sensor1(sens1,DHT22);
DHT sensor2(sens2,DHT22);

void setup() {
  //inicializacion de comunicacion con lo sensores
  Wire.begin();
  sensor1.begin();
  sensor2.begin();
  // inicializacion de comunicacion con el display
  display.begin(SSD1306_SWITCHCAPVCC,0x3C);
  // inicializa la interrupcion por boton
  attachInterrupt(digitalPinToInterrupt(3),leer_boton,LOW);
  //inicia la comunicacion serial con el 
  Serial.begin(9600);
  // inicializa las interrupciones programada por tiempo  
  Timer1.initialize(1000000);
  Timer1.attachInterrupt(segundero);
  //declara los pines de entrada
  for (int i=0;i<3;i++){
    pinMode(button[i],INPUT);
  }
  //ejecuta la primera lectura y mostrado de la informacion en el display
  Modo=0;
  Leer_sensor();
  Ordenar_display();
  
}


void loop() {
  // Si el sistema se encuentra en modo de ejecucion esta accion se ejecuta cada 3 segundos 
  if (seg==reseteo && Modo==0){
    //se acomoda tiepo de ejecucion
    reseteo=seg+3;
    Serial.println("Orden Sensado");
    //se ejecutan las funciones de lectura del sensor y se muestran los datos en la pantalla
    Leer_sensor();
    Ordenar_display();
    Serial.println("Refrescado");
    //En caso de tener una humedad inferior al minimo de humbral se inicia el proceso de humidificacion 
    if (Hl[3]<=Umbral_humedad[0]){
      Proceso_Humifdificar=1;       
    }
    //en caso de alcanzar la humedad maxima del humbral se detiene el proceso de humidificacion 
    else if(Hl[3]>=Umbral_humedad[1]){
      Proceso_Humifdificar=0;
    }    
  }
  //al presionar un boton se ejecuta el proceso
  if (state==1){
    // realiza la comprobacion de los elementos   
    interfaz_estados();
    Serial.print("state reset: ");
    //resetea el estado
    state=0;
    Serial.println(state);
    //se resetea la lectura de los botones 
    for (int i=0;i<3;i++){
      btn[i]=0;
    }
  }
}

// funcion que se ejecuta con la intrrupcion programada
void segundero(){
  seg=seg+1;
  Serial.println(seg);
}
// funcion que se ejecuta al presionar un boton
void leer_boton(){
  Serial.print("  state input: ");
  Serial.println(state);
  //Si el estado de le ctura es 0 procedera a identificar los botones presionados y a desencadenar sus efectos
  if (state==0){
    Serial.println("entrada: ");
    //realiza la lectura de los botones presionados
    for (int i=0;i<3;i++){
      btn[i]=digitalRead(button[i]);
      Serial.print(i);
      Serial.print("\t");
      Serial.println(btn[i]); 
    }
    //marca el estado de lectura como realizado 
   state=1;
   Serial.print("state Output: ");
   Serial.print(state);
  }
}
//funcion que se ejecuta cuando se desea leer el sensor 
void Leer_sensor(){
  //lee temperatura y humedad en el sensor 1
  T[1]=sensor1.readTemperature();
  Hl[1]=sensor1.readHumidity();
  // lee termperatura y humedad en el sensor 2
  T[2]=sensor2.readTemperature();
  Hl[2]=sensor2.readHumidity();
  //promedia temperatura y humedad de los sensores
  Hl[3]=floor((Hl[1]+Hl[2])/2);
  Serial.println(Modo);
  T[3]=floor((T[1]+T[2])/2);
  Serial.println("Sensado Realizado");
}
//Funcion que realiza la configuracion y visualizacion del display
void Ordenar_display(){
  //se limpia la memoria del display
  display.clearDisplay();
  //se configuran los comandos base del display
  display.setTextColor(WHITE);
  display.setTextSize(1);
  //Ubicacion de la primera linea del display
  display.setCursor(0,0);
  //visualizacion de la informacion sobre la humedad
  display.print("Hm:"); 
  display.print(Hl[3]);
  display.print("%");
  //Ubicacion del titulo de humbral y visualizacion de este
  display.setCursor(40,0);
  display.print("Umbral Humedad");
  //ubicacion de la segunda linea de informacion en el display
  display.setCursor(0,10);
  display.print("T:"); 
  display.print(T[3]);  
  display.print("C");
  // si el dispositvo se encuentra en modificacion de humbral de humedad 1 muestra un indicador
  if (Modo==1){
    display.setCursor(35,10);
    display.print(">");
  }
  //ubicacion y visualizacion del primer valor de humbral de humedad
  display.setCursor(40,10);
  display.print("H1:");
  display.print(Umbral_humedad[0]);
  display.print("%");
  // si el dispositvo se encuentra en modificacion de humbral de humedad 2 muestra un 
  if (Modo==2){
    display.setCursor(78,10);
    display.print(">");
  }
  //ubicacion y visualizacion del segundo valor de humbral de humedad
  display.setCursor(83,10);
  display.print("H2:");
  display.print(Umbral_humedad[1]);
  display.print("%");
  //ubicacion de la tercera linea de informacion
  display.setCursor(0,20);
  // visualizacion de los periodos de ejecucion del temporizador de ventilacion
  display.print("Timer:");
  display.setCursor(40,20);
  // si el Dispositivo se encuentra en 
  if (Modificacion==0 && Modo==1){
    display.print(">");
  }
  if(Temporizador[0]<10){
    display.print("0");
  }
  display.print(Temporizador[0]);
  display.print(":");
  if (Modificacion==0&&Modo==1){
    display.print(">");
  }
  if(Temporizador[1]<10){
    display.print("0");
  }
  display.print(Temporizador[1]);
  display.print(":");
  if (Modificacion==0&&Modo==1){
    display.print(">");
  }
  if(Temporizador[2]<10){
    display.print("0");
  }
  display.print(Temporizador[2]);
  if (Modo==1){
    display.print("<");
  }
  Serial.println("Configuracion display");
  display.display();
}

void interfaz_estados(){
  if (btn[1]==1){
    Modo++;
    if (Modo==4){
      Modo=0;
    }
  }
  switch (Modo){
    case 0:
    state=0;
    break;
    case 1:
    if (btn[1]==1){
      Umbral_humedad[0]++;
      if (Umbral_humedad[0]==Umbral_humedad[1]){
        Umbral_humedad[0]=Umbral_humedad[1]-1;
      }
    }
    if (btn[2]==1){
      Umbral_humedad[0]--;
      if (Umbral_humedad[0]==10){
        Umbral_humedad[1]=11;
      }
    }
    break;
    case 2:
    if (btn[1]==1){
      Umbral_humedad[1]++;
      if (Umbral_humedad[1]==100){
        Umbral_humedad[1]=99;
      }
    }
    if (btn[2]==1){
      Umbral_humedad[1]--;
      if (Umbral_humedad[1]==Umbral_humedad[0]){
        Umbral_humedad[1]=Umbral_humedad[0]+1;
      }
    }
    break;
    case 3:
    if (btn[1]==1){
      Modificacion++;
      if (Modificacion=3){
        Modificacion=0;
      }
    }
    if (btn[2]==1){
      switch(Modificacion){
        case 0:
        Temporizador[0]++;
        if (Temporizador[0]=24){
          Temporizador[0]=0;
        }
        break;
        case 1:
        Temporizador[1]++;
        if (Temporizador[1]=60){
          Temporizador[1]=0;
        }
        break;
        case 2:
        Temporizador[2]++;
        if (Temporizador [0]==0 && Temporizador[1]==0){
          Temporizador[2]=3;
        }
        else if(Temporizador[2]=60){
          Temporizador[2]=0;
        }
        break;
      }
    }
    break;
  }
}

You are out of bounds for your arrays, index starts at 0

byte T[3];
byte Hl[3];

1 Like
`    if (Hl[3]<=Umbral_humedad[0]){`

There is no Hl[3]. You've overrun the end of the array.

void segundero(){
  seg=seg+1;
  Serial.println(seg);
}

...is not appropriate code inside of an interrupt handler.

  Hl[3]=floor((Hl[1]+Hl[2])/2);
...
  T[3]=floor((T[1]+T[2])/2);

The state of your application is now corrupt. You've written past the end of both arrays.

if (Temporizador[1]=60){

...is very likely a bug.

1 Like

Thank you dude, you didn't just solve my problem you also helped me with another bugs, but ¿could you or someone else illustrate me why the counter isn't en appropriate inside the interrupt handler?

1 Like

Getting interrupt handlers correct, even for experienced programmers, is difficult. Blink without delay is a much better choice for what you're doing.

You fail to protect the variable with a critical section.

Serial calls never belong in an interrupt service routine.

1 Like

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