timerarduinoadc

Arduino Code is acting weird(Timer keeps working, Printed ADC values always zero)


I am using Arduino Mega Pro, in the code I am reading 2 LM35 sensors using ADC and printing the value every 1 sec, and I am counting that 1 sec using a timer.

But, the two sensors are giving me zero value on the monitor, tried to debug around to see where is the problem I found that the analogRead isn't getting any values at all when I tried to print the sensor1Valuevalue.

I thought that the timer might interfering with something that I don't yet know about, because the ADC was working fine before i stated implementing the timer, so I commented the line that initializes the timer init(); but I found that the timer keeps working even after commenting this line, and the ISR keeps coming and printing the DEBUGING line.

I used this code in another sketch to test the sensors, because I thought the problem might be in my connection but it worked fine.

#define INPUT_5_VOLT 5.0
#define TEMP_SENSOR_1_PIN A0  //Define ADC pin for Temp Sensor 1
#define TEMP_SENSOR_2_PIN A1  //Define ADC pin for Temp Sensor 2
#define ADC_RESOLUTION 1024.0

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

void loop() {
  int sensor1Value = analogRead(TEMP_SENSOR_1_PIN);
  int sensor2Value = analogRead(TEMP_SENSOR_2_PIN);

  float voltage1 = sensor1Value * (INPUT_5_VOLT / ADC_RESOLUTION);

  // Convert the voltage into the temperature in Celsius
  float temp_sensore_1_read = voltage1 * 100;

  float voltage2 = sensor2Value * (INPUT_5_VOLT / ADC_RESOLUTION);

  // Convert the voltage into the temperature in Celsius
  float temp_sensore_2_read = voltage2 * 100;

  Serial.print("Sensor 1 Value: ");
  Serial.println(temp_sensore_1_read);

  Serial.print("Sensor 2 Value: ");
  Serial.println(temp_sensore_2_read);

  delay(1000);
}

And this is the code I am trying to debug.

//Hardware Configuratio
//Use input 5V for Temp Sensors
#define INPUT_5_VOLT 5.0
#define TEMP_SENSOR_1_PIN A0  //Define ADC pin for Temp Sensor 1
#define TEMP_SENSOR_2_PIN A1  //Define ADC pin for Temp Sensor 2
#define ADC_RESOLUTION 1024.0


//Enable Debugging
#define DEBUGGING 0

//MACROS
#define ENABLE_GLOBAL_INTERRUPT()  (SREG = SREG | (1<<7))
#define DISABLE_GLOBAL_INTERRUPT() (SREG = SREG & (~(1<<7)))

//Global Variable
char start_app_first_time_flag = false;
volatile bool print_data_flag = false;
volatile float temp_sensore_1_read = 0;
volatile float temp_sensore_2_read = 0;

//Function Declaration
void temp_sensors(void);  //Print the Sensors Data if the flag is set by the timer
void read_temp_sensor_1(void);
void read_temp_sensor_2(void);
void print_temp_sensors_readings(void);
void init(void);
void bit16_timer_1_init(void);


//ISR
ISR(TIMER1_COMPA_vect)
{
  #if DEBUGGING == 1
  Serial.print("Enter Tiemr TIMER1_COMPA ISR\n");
  #endif

  print_data_flag = true;
}

//Init Fucntion
void setup() {
  Serial.begin(9600);
  init();
}

//App Function
void loop() {
  //Print the Sensors Data if the flag is set by the timer.
  temp_sensors();
  //delay(1000);
}

//Fucntion Definition
void temp_sensors(void) {
  #if DEBUGGING == 1
  Serial.print("Enter temp_sensors Function\n");
  #endif

  read_temp_sensor_1();
  read_temp_sensor_2();

  if (true == print_data_flag) {
    print_temp_sensors_readings();

    print_data_flag = false;
  }
}

void read_temp_sensor_1(void) {
  #if DEBUGGING == 1
  Serial.print("Enter read_temp_sensor_1 Function\n");
  #endif

  // Get the voltage reading from the LM35
  int sensor1Value = analogRead(TEMP_SENSOR_1_PIN);
  //Serial.println(sensor1Value);

  // Convert that reading into voltage
  float voltage1 = sensor1Value * (INPUT_5_VOLT / ADC_RESOLUTION);
  //Serial.println(voltage1);

  // Convert the voltage into the temperature in Celsius
  temp_sensore_1_read = voltage1 * 100;
  //Serial.println(temp_sensore_1_read);


}

void read_temp_sensor_2(void) {
  #if DEBUGGING == 1
  Serial.print("Enter read_temp_sensor_2 Function\n");
  #endif

  // Get the voltage reading from the LM35
  int sensor2Value = analogRead(TEMP_SENSOR_2_PIN);

  // Convert that reading into voltage
  float voltage2 = sensor2Value * (INPUT_5_VOLT / ADC_RESOLUTION);

  // Convert the voltage into the temperature in Celsius
  temp_sensore_2_read = voltage2 * 100;
}

void print_temp_sensors_readings(void) {
  #if DEBUGGING == 1
  Serial.print("Enter print_temp_sensors_readings Function\n");
  #endif

  // Print the temperature 1 in Celsius
  Serial.print("Temperature1: ");
  Serial.print(temp_sensore_1_read);
  Serial.print("\xC2\xB0");  // shows degree symbol
  Serial.print("C\n");

  // Print the temperature 2 in Celsius
  Serial.print("Temperature2: ");
  Serial.print(temp_sensore_2_read);
  Serial.print("\xC2\xB0");  // shows degree symbol
  Serial.print("C\n\n");
}

void init(void) {
  #if DEBUGGING == 1
  Serial.print("Enter init Function\n");
  #endif

  bit16_timer_1_init();
}

void bit16_timer_1_init(void)
{
  #if DEBUGGING == 1
  Serial.print("Enter bit16_timer_1_init Function\n");
  #endif
  
  /*
    To make 1 sec timer, we will use this equation 
    Time = (1/(Frequency/Prescaler))*ticks = (1/(16,000,000/1024))*15625 = 1 sec
  */
 DISABLE_GLOBAL_INTERRUPT();
  TCCR1A = 0;
  TCCR1B = 0;  //No Prescaler - Stop Timer
  TCNT1 = 0;
  OCR1A = 15625;
  TIMSK1 = 0b00000010; //Enable interrupt for timer 1 A
  ENABLE_GLOBAL_INTERRUPT();
  TCCR1B |= (1 << WGM12) | (1 << CS12) | (1 << CS10); //1024 Prescaler - Start Timer - Enable CTC

}

The last step i did, is to comment this line bit16_timer_1_init(); and I managed to stop the timer. But after setting this flag print_data_flag always with true and commenting the line the clears it, the values of the sensors keeps printing zeros.

If someone knows what might be the problem, please help me fix it. Thank you in advance.


Solution

  • You're using timer mode 4 which is CTC with OCR1A defining the TOP value. Since OCR1A is being used for TOP, it can't also be used as a compare match. The datasheet even mentions that if OCR1A is set to TOP then the match will be ignored.

    Instead of a compare match, use the overflow interrupt instead. Change your interrupt handler to TIMER1_OVF_vect. That will fire when the timer reaches the TOP value which is defined in OCR1A.