Unable to change pin logic inside timer interrupt

Hello,

Using the Arduino Mega.

→ Problem:
The timers were set but I have found a problem related to the timer 3, there is a LED that I want to make blink so I have digitalWrite and digitalRead functions in there to do the job, but the problem is that the microcontroller appears to be ignoring them (I had it done with registers first but wasn’t working so I changed to Arduino functions).

If I place the code for alternating the LED logic in the loop function the microcontroller will execute it.

Had already placed a “Serial.println(” message “);” inside the timer to know if it was being done and it was, I received the message in the serial monitor.

I have been looking around but I can’t manage to find the problem, could you please help me out?

#define pinCap 0b00000001 //PL0
#define pinLED  0b00000100  //PA2 -> 24
#define pinTrig 0b00000010  //PC1 -> 36
#define pinEcho 0b00000000  //PC3 -> 34

bool offsetDist = 0;
int dist = 0;
unsigned long int pulse = 0;
int lvlDist = 0;
int contH[4]  = {0xC2, 0x85, 0x0B, 0};  //primeiros 2 num em hex de cada freq (4Hz, 2Hz, 1Hz)
int contL[4]  = {0xF7, 0xEE, 0xDC, 0};  //ultimos 2 num em hex de cada freq (4Hz, 2Hz, 1Hz)

volatile int timer_overflow = 0;
volatile char captura = 0;

void setup()
{
  //config Timer1 ---------------
  TCCR1A = 0; //Bit 7:6 CompOutMode ChanA, 5:4 CompOutMode Chan B, 3:2 CompOutMode Chan C, WGMn1:0: Waveform Generation Mode
  TCCR1B = 0b0000010; // prescaler = 8
  // Habilita a interrupção quando for atingido o overflow
  TIMSK1 = 0b00000001;
  TIFR1 = 0b00000000;
  //contagem para 100 ms = 40536 = 0x9E58
  TCNT1H = 0x9E;
  TCNT1L = 0x58;
  // inicializar timer
  TCNT1 = 0;

  //config Timer3 ---------------
  TCCR3A  = 0;  //nao alterar estado do pino
  TCCR3B  = 0b00000100;  // ...100 = 256 prescaler
  TIMSK3  = 0b00000001;
  TCNT3H  = 0xC2; //primeira config e 250ms (4Hz)
  TCNT3L  = 0xF7; //primeira config e 250ms (4Hz)
  TCNT3   = 0;


  //pinos
  DDRA = 0b11111111;  //PA2 pinLED
  DDRC = 0b11110111;  //PC3 pinEcho, PC1 pinTrig
  
  DDRL = 0b11111110;  //PL0 pinCap
  //PORTL = 0b00000001; //Pullup no PL0                   ### nao ativar pullup no pino 49
  
  Serial.begin(9600);
  while( !Serial ) 
  {
    continue;  // Aguardar ligação da porta série
  }
}


ISR(TIMER3_OVF_vect)  // Interrupcao do timer3
{
//  if (offsetDist == 1)
//  {
//    ; //offsetDist "diz" se a distancia e <5 e/ou >20
//  }
//  else if (PINA != (PORTA | pinLED) ) //alterar o estado do LED
//  {
//    PORTA = PORTA | pinLED; // Colocar pino (n2) a estado logico 1
//  }
//  else  //#define pinLED  0b00000100  //PA2
//  {
//    PORTA = PORTA & ~pinLED; // Colocar pino (n2) a estado logico 0
//  }

  if (digitalRead(24) == 0) //alterar o estado do LED
  {
    digitalWrite(24,1); // Colocar pino (n2) a estado logico 1
  }
  else  //#define pinLED  0b00000100  //PA2
  {
    digitalWrite(24,0); // Colocar pino (n2) a estado logico 0
  }

  // reiniciar a contagem
  TCNT3H = contH[lvlDist];
  TCNT3L = contL[lvlDist];

}

ISR(TIMER1_OVF_vect)  // Interrupcao do timer1 100ms
{
  sensor();

  // reiniciar a contagem
  TCNT1H = 0x9E;
  TCNT1L = 0x58;
}

void sensor() //    <------------------------------
{
  
  PORTC = PORTC & ~pinTrig; // Colocar pino a estado logico 0
  delayMicroseconds(2);
  PORTC = PORTC | pinTrig; // Colocar pino a estado logico 1
  delayMicroseconds(10);
  PORTC = PORTC & ~pinTrig; // Colocar pino a estado logico 0

  
  //calcular distancia
  pulse = pulseIn(49, 1); // (pin, HIGH/LOW)
  Serial.println(pulse);
  dist = ((pulse) / 2) * 0.034; //calculo da distancia
  Serial.print("Distancia: ");
  Serial.println(dist);
}


void loop()
{

  //alterar o piscar do LED

  if ( dist < 5)  
  {
    offsetDist = 1;
    PORTA = PORTA | pinLED;   // Colocar pino a estado logico 1
  }
  //alterar contH e contL (cada var tem 4 valores)
  else if ( (dist >= 5) && (dist < 10) )  
  {
    offsetDist = 0;
    lvlDist = 0;
  }
  else if ( (dist >= 10) && (dist < 15) )  
  {
    offsetDist = 0;
    lvlDist = 1;
  }
  else if ( (dist >= 15) && (dist < 20) )  
  {
    offsetDist = 0;
    lvlDist = 2;
  }

  else if ( dist >= 20)  
  {
    offsetDist = 1; // offsetDist garante que o estado do LED nao vai alterar
    PORTA = PORTA & ~pinLED;    // Colocar pino a estado logico 0 
  }

}

This is supposed to read a distance using the ultrasonic module and make the LED blinking faster when the distance gets shorter.

Thanks in advance for your time and attention.

Don't put serial I/O in interrupt context.

Understood, did the change and now everything works as indeed.
If you wouldn't mind, could you please tell the reason why serial context cause the problem?
Was it related to interrupts being activated during serial communication?

F1_:
Was it related to interrupts being activated during serial communication?

Serial output is buffered, so requires interrupts. When the buffer is full, if interrupts are disabled (as they are in interrupt context), the code will lock up waiting for buffer space that can never appear.

Understood, thank you very much.
I will have this in mind in future programs.