Timer0 slow down Timer1 interrupt

Hello,
I am trying with an Arduino UNO to read data from the ADC at a specific frequency triggering the conversion with the Timer1 COMPB, and then at a slower rate to print a big message using Timer0 interrupts.
Putting pin toggle on each interrupt, I see that the biggest the message on timer0 interruption, the slower work the Timer1 interruption. (according to my oscilloscope)
But according to the datasheet the Timer1 interrupt should have a higher priority level than Timer0 Interruption.

There is a fault in the documentation?

Here my code:

#include <avr/sleep.h>
#define ALLMUX 0x0f

int ledbl = 13;
int ledbl2 = 12;
int ledbl3 = 11;
int ledbl4 = 10;

int c = 1;
int analogPin = 3;
int analogVal[4] = {0,0,0,0};
float voltageVal[4]={0,0,0,0};
float VrefInt = 1.1;
float analogStepInt = VrefInt / 1024;

boolean toogle0=0;
boolean toogle1=0;
boolean toogle2=0;
boolean toogle3=0;

int channelADC =0;


void setup() {
  
  pinMode(ledbl, OUTPUT);
  pinMode(ledbl2, OUTPUT);
  pinMode(ledbl3, OUTPUT);
  pinMode(ledbl4, OUTPUT);
  digitalWrite(ledbl, LOW);
  digitalWrite(ledbl2, LOW);
  digitalWrite(ledbl3, LOW);
  digitalWrite(ledbl4, LOW);

  Serial.begin(9600);
  Serial.print("\033[1;1H\033[JStarting measure with 1.1V on 4 channel\n\rA0 =      that mean\n\rA1 =      that mean\n\rA2 =      that mean\n\rA3 =      that mean\n\r");
  //while(!(UCSR0A==UCSR0A&(1<<TXC0)));
  
//ADC init trigger mode on timer0, and end measure interrups

  ADMUX=0;                          //reset to init
  ADMUX|=((1<<REFS1)|(1<<REFS0));   //set measure reference to internal voltage 1.1V

  ADMUX=ADMUX&~ALLMUX;              //reset to init
  ADMUX|=channelADC;                //select ADC channel ADC0 

  ADCSRA=0;                         //reset to init
  //ADC enable, autotrigger enable, ADC interrupt enable, ADC clk rescaler to /128 -> 16MHz/128= 125kHz
  ADCSRA|=(1<<ADEN)|(1<<ADATE)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);   
  //trigger mode 14 clk (13.5) for convertion (1/125kHz)*14=112us 
  
  ADCSRB=0;                         //reset to init
  ADCSRB|=(1<<ADTS0)|(1<<ADTS2);    //set timer1 compB as ADC trigger 

  DIDR0=0;                          //reset to init
  DIDR0|=ALLMUX;                    //disable digital input on ADC0-4 

  set_sleep_mode( SLEEP_MODE_ADC );
  sleep_enable();
  
  cli();//disable interrupt

//set timer0 interrupt information print
  TCCR0A=0;   //reset to init
  TCCR0B=0;   //reset to init
  TCNT0=0;    //reset to init
  OCR0A=156;  // 15.625kHz/100Hz=156kHz => 15.625kHz/156=100.16025
  TCCR0A|=(1 << WGM01); //set timer2 mode to CTC
  TCCR0B|=(1 << CS02)|(1 << CS00);   //set prescaler at /1024 so timer0clk at 15.625kHz
  TIMSK0|=(1 << OCIE0A); //enable compA interrupts
  
  //set timer1 interrupt 7.1kHz ADC trigger and control
  TCCR1A=0;   //reset to init
  TCCR1B=0;   //reset to init
  TCNT1=0;    //reset to init
  OCR1A=2254;  // 16MHz/7.1kHz ~= 2254 => 7.09849kHz = 140.8us
  OCR1B=320;  // (1/16MHz)*320=20us => 140.8us-20us=120.8us for the convertion
  TCCR1B|=(1 << WGM12);    //set timer1 mode to CTC 
  TCCR1B|=(1 << CS10);    //set prescaler at /1 so timer1clk at 16MHz
  TIMSK1|=(1 << OCIE1A)|(1 << OCIE1B);    //enable compA and CompB interrupts
 
  sei();//enable interrupt;
}

ISR(TIMER1_COMPA_vect){//timer1 compA interrupts
  if(toogle2==0)digitalWrite(ledbl3, HIGH);
  else digitalWrite(ledbl3, LOW);
  toogle2^=0x01;
  analogVal[channelADC]=ADCL|((ADCH&0x03)<<8); //read before low and then high or the value are not updated
  channelADC++;
  if(channelADC>=4)channelADC=0;
  ADMUX=ADMUX&~ALLMUX;
  ADMUX|=channelADC;

  //space for digital filter
  //  
  //
  }
  
ISR(TIMER1_COMPB_vect){//timer1 compB interrupts
   if(toogle3==0)digitalWrite(ledbl4, HIGH);
  else digitalWrite(ledbl4, LOW);
  toogle3^=0x01;
  }
    

  
ISR(TIMER0_COMPA_vect){//timer1 interrupt
  digitalWrite(ledbl2, HIGH);
  for(int i=0;i<4;i++){
    voltageVal[i] = analogVal[i] * analogStepInt;
  }
  String initCursor = "\033[2;6H    \033[2;6H";
  String fullMsg=initCursor +analogVal[0] + "\033[2;21H" + voltageVal[0] + "V\033[3;6H    \033[3;6H"+analogVal[1] + "\033[3;21H" + voltageVal[1] + "V\033[4;6H    \033[4;6H"+analogVal[2] + "\033[4;21H" + voltageVal[2] + "V\033[5;6H    \033[5;6H"+analogVal[3] + "\033[5;21H" + voltageVal[3] + "V";
  Serial.println(fullMsg);
  digitalWrite(ledbl2, LOW);
}

ISR(ADC_vect) 
{
  if(toogle0==0)digitalWrite(ledbl, HIGH);
  else digitalWrite(ledbl, LOW);
  toogle0^=0x01;
}

void loop() {
  //if nothing to transmit, then go sleep
  if(UCSR0A==UCSR0A&(1<<TXC0))
    sleep_cpu();
}

P.S. I know that sending a message in Timer0 interruption isn’t a good idea, but even if I remove the message, the fact that the priority didn’t match still a problem.

P.S.S The strange stuff I write are in ANSI escape code, I use it to move the cursor in the terminal

Why are you trying to use an interrupt to manage the printing?

What is the interval between analogRead()s (in millisecs)?

What is the desired interval between printing messages?

It is not a good idea to use the String (capital S) class on an Arduino as it can cause memory corruption in the small memory on an Arduino. Just use cstrings - char arrays terminated with 0.

...R

If an interrupt is in progress, all interrupts are disabled (unless you enable them again in code). So if an isr takes long, you will have to wait that period of time before another interrupt will be honoured (independent of priority).

What streretje said. The "priority" of AVR interrupts only comes into play when you have two hardware events that happen at exactly the same time - the higher priority interrupt will happen first. Unlike other chips (say, an ARM) with NESTED interrupt capabilities, a higher-priority interrupt on a AVR will NOT interrupt a running lower-priority interrupt.

westfw:
The "priority" of AVR interrupts only comes into play when you have two hardware events that happen at exactly the same time

Or when you enable interrupts after they where disabled and more than one interrupt happened in that time.

The "priority" of AVR interrupts only comes into play when you have two hardware events that happen at exactly the same time - the higher priority interrupt will happen first.

Err no. It happens when two are WAITING to be dealt with eg because they occurred while another interrupt was being dealt with. No "exactly" required.

Unlike other chips (say, an ARM) with NESTED interrupt capabilities, a higher-priority interrupt on a AVR will NOT interrupt a running lower-priority interrupt.

This is just the way things are done here. You can re arm interrupts with in an ISR allowing interrupts to interrupt each other See avr/interrupts.

Mark

Or when you enable interrupts after they where disabled and more than one interrupt happened in that time.

Ah. Good point.