problem with millis() funcation

hi
i am trying to sample from to channel of the analog input of the arduino to sensor and i need the time of measuring of the sample.
from some reason that i dont understand the time the i get from the milliys function is 101 for both channel
i will be glad if someone can help me fixing it please?

this is my code:

#include <math.h>
#define Piezo1 A0
#define Piezo2 A1

unsigned long start_time=0;
unsigned long stop_time_CH1=0;
unsigned long stop_time_CH0=0;
float Piezo_arr[2];
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
pinMode(Piezo1,INPUT);
pinMode(Piezo2,INPUT);
analogReference(DEFAULT);
// TIMER 1 for interrupt frequency 520.0039000292502 Hz:
cli(); // stop interrupts
TCCR1A = 0; // set entire TCCR1A register to 0
TCCR1B = 0; // same for TCCR1B
TCNT1  = 0; // initialize counter value to 0
// set compare match register for 520.0039000292502 Hz increments
OCR1A = 30768; // = 16000000 / (1 * 520.0039000292502) - 1 (must be <65536)
// turn on CTC mode
TCCR1B |= (1 << WGM12);
// Set CS12, CS11 and CS10 bits for 1 prescaler
TCCR1B |= (0 << CS12) | (0 << CS11) | (1 << CS10);
// enable timer compare interrupt
TIMSK1 |= (1 << OCIE1A);
sei(); // allow interrupts
start_time=millis();
}

ISR(TIMER1_COMPA_vect){
  Piezo_arr[1]=((3.3/1023.0)*((float)analogRead(Piezo1)))-1.65;
  stop_time_CH0=(millis()-start_time);
  Piezo_arr[2]=((3.3/1023.0)*((float)analogRead(Piezo2)))-1.65;
  stop_time_CH1=(millis()-start_time);
  Serial.print(stop_time_CH0);
  Serial.print(',');
  Serial.print(Piezo_arr[1]);
  Serial.print(',');
  Serial.print(stop_time_CH1);
  Serial.print(',');
  Serial.print(Piezo_arr[2]);
  Serial.println();
}

void loop() {
}

I have no idea. But Piezo_arr does not have an element with index 2.

Also do not attempt to use Serial from within an ISR.

The millis() counter relies on interrupts to increment the count, inside an ISR interrupts are disabled, so it will always return the same value.

You are doing way too much inside an ISR. I suggest you re-think what needs to be done in the ISR, set a flag in the ISR and then read the flag in a function called from loop() and, if the flag is set, clear the flag and do whatever needs to be done.

// TIMER 1 for interrupt frequency 520.0039000292502 Hz:

No chance! The clock on an Arduino is no where near accurate enough to allow you to get a frequency with precision to 13 places after the decimal point. If you want that level of precision you need an atomic clock.

I ran OP’s code on a Mega (fixed the index); he/she did not see all the data.

1,-0.48,1,-0.64
2,-0.52,2,-0.58
4,-0.51,4,-0.54
6,-0.49,6,-0.51
8,-0.50,8,-0.51
10,-0.52,10,-0.53
12,-0.58,12,-0.58
14,-0.64,14,-0.63
15,-0.69,15,-0.69
16,-0.71,16,-0.71
17,-0.71,17,-0.72
18,-0.69,18,-0.70
19,-0.66,19,-0.67
...
...
98,-1.30,98,-1.30
99,-1.27,99,-1.28
100,-1.23,100,-1.24
101,-1.20,101,-1.21
101,-1.18,101,-1.19
101,-1.18,101,-1.19
101,-1.23,101,-1.23
101,-1.28,101,-1.28
101,-1.34,101,-1.33
...
...

Next I ran it on a Leonardo (native USB) and there is no problem. Increasing the baudrate on the Mega (as a workaround) also solved the issue; note that I did not run it for very long on both.

This indicates in my opinion that the serial prints in the ISR start blocking the ISR when the transmit buffer fills up. As a result, millis() has no chance to increment as TIMER0 OVF (used to generate the count that millis() uses) has a lower priority than TIMER1 COMPA.

sterretje:
This indicates in my opinion that the serial prints in the ISR start blocking the ISR when the transmit buffer fills up. As a result, millis() has no chance to increment as TIMER0 OVF (used to generate the count that millis() uses) has a lower priority than TIMER1 COMPA.

Interrupts are disabled inside an ISR, unless you specifically re-enable them. Serial requires interrupts for its operation, so once the send buffer fills up, it will stay full, causing any print() statement to wait forever for enough space to place its data into the buffer.

Millis() has the same problem, it requires interrupts, so cannot increment its counter while in the ISR. This is totally unrelated to any use of Serial or print().

Micros() can be used inside an ISR, but only for short intervals. Micros() reads directly from the hardware timer, and can keep track of whether a counter rollover has occurred, but cannot tell if the counter has rolled over more than once.

If the OP really needs the exact time that each of the analogReads occurs, then the interrupt can be set to occur twice as often, read each analog input on alternate interrupts, and save the data to variables, where the main code can do the calculations and send the serial data.

david_2018:
Interrupts are disabled inside an ISR, unless you specifically re-enable them. Serial requires interrupts for its operation, so once the send buffer fills up, it will stay full, causing any print() statement to wait forever for enough space to place its data into the buffer.

Serial (nowadays?) can work with interrupts disabled; it has a mechanism to do it 'manually' when the buffer is full.

From HardwareSerial.cpp:

  // If the output buffer is full, there's nothing for it other than to 
  // wait for the interrupt handler to empty it a bit
  while (i == _tx_buffer_tail) {
    if (bit_is_clear(SREG, SREG_I)) {
      // Interrupts are disabled, so we'll have to poll the data
      // register empty flag ourselves. If it is set, pretend an
      // interrupt has happened and call the handler to free up
      // space for us.
      if(bit_is_set(*_ucsra, UDRE0))
	_tx_udr_empty_irq();
    } else {
      // nop, the interrupt handler will free up space for us
    }
  }

david_2018:
Millis() has the same problem, it requires interrupts, so cannot increment its counter while in the ISR. This is totally unrelated to any use of Serial or print().

Indeed, but the serial prints make that the ISR takes too long so TIMER1 COMPA will be firing constantly and TIMER0 OVF has no chance.

====
Some calculations:
At 520Hz, TIMER1 COMPA fires every 1.92 ms.
At 115200 baud, "1,-0.48,1,-0.64\r\n" (17 chars, 170 bits) takes 1.476 ms.
At 115200 baud, "10,-0.48,10,-0.64\r\n" (19 chars, 190 bits) takes 1.649 ms.
At 115200 baud, "100,-0.48,100,-0.64\r\n" (21 chars, 210 bits) takes 1.822 ms.

Add approx. 0.1 ms per analogRead and one is over the 1.92 ms when duration reaches 3 digits.