Hello all. Is there anyone that can tell me the minimun time between two PCINT:s on Atmega 328p
If a resolution of 0+1 micros is needed between two or more interrupts on that controller, whats best practice?.
Q:S
When can and can i NOT use Delay exept for inside ISR of course:
Does delay and micros occasionally "mess up" with Timer1 values and if so when?
Can i read TCNT1 value inside an ISR just by calling it without setting up the timer and does that increment inside the ISR or not?
//Best NIls
/*Edit Version. 211227-1 (YYMMDD-nr)
Auth: Nils.bruhner@gmail.com
HARDWARE SETUP:
Three sound-sensors of any kind may be attached to an Arduino with X meter CC between mics to test the PCINT "of the shelf" resolution.
Soundwave-front coming in and digitally interrupt (I/0) the three mics in unspecific order will result in X microseconds between the three Interuppts on each vector.
The difference in micros between the interrupts may be used to investigate speed of sound in air and/or the electronics behaviour and resolution etc.
Sketch is compatible and tested only on an Atmega 328p-UNO 16 mhz.
pin A0 PortC pin7 PortD pin8 PortB
(Mic) (Mic) (Mic)
micLeft----------------------------micCenter-----------------------------------micRight
X meter X meter
common Ground -5 volt
common DC +5 volt
*/
// void StartQuickTimer() //Experimental timer for counting chrystal clocksyckles instead of micros. Not used.
// {
// noInterrupts ();
// Reset Timer 1A and Timer 1B
// TCCR1A = 0;
// TCCR1B = 0;
// TCNT1 = 0;
// TIMSK1 = 0;
// TIFR1 = 0;//_BV(TOV1);
// TCCR1B = _BV(CS10);
// TCCR1B |= B0000001;//Set prescaler to 1
// TCCR1B |= B0000010;//Set prescaler to 8
// TCCR1B |= B0000011;//Set prescaler to 64
// TCCR1B |= B0000100;//Set prescaler to 256
// TCCR1B |= B0000101;//Set prescaler to 1024
//TIMSK1 = _BV(TOIE1);
// interrupts ();
// }//END void StartQuickTimer
//____________________________________________________________________________________________________
int micLeft = A0;
int micCenter = 7;
int micRight = 8;
volatile int i0 = 0;//var i(x) for eventually count nr of trigs when debugging . Not used.
volatile int i1 = 0;
volatile int i2 = 0;
volatile char trigged = 0;// var trigged for detection if trigged I/0. Not used.
volatile unsigned long resetcount = 0; // var to increment a fake delay if one mic is accidentally trigged.
volatile unsigned long timeLeft = 0;// Var to store times in micros inside ISR:s. Therefore volatile.
volatile unsigned long timeCenter = 0;
volatile unsigned long timeRight = 0;
volatile int stopLeft = 0; // Flags to handle the trigs. Used in ISR:S Therefore volatile.
volatile int stopCenter = 0;
volatile int stopRight = 0;
void setup() {
// StartQuickTimer(); // Experimental timer for counting chrystal clocksyckles instead of micros. Not used.
pinMode(micLeft, INPUT_PULLUP);
pinMode(micCenter, INPUT_PULLUP);
pinMode(micRight, INPUT_PULLUP);
pinMode(11, OUTPUT);//Eg Buzzer for debugging if trigged when no monitor is used.
Serial.begin(9600);
//PCICR = PCIF2 + PCIF1 + PCIF0; //Also all PCINT-vectors/ports B,C and D.
PCICR |= 0b00000111; // Activate all three PCINT-vectors on atmega 328p
PCIFR = 0; // Zero all INT-Flags.
PCMSK0 = B00000001; // Activate only pin D8 for interrupts (PCINT0) PortB
PCMSK1 = B00000001; // Activate only pin A0 (PCINT8) for interrupts PortC
PCMSK2 = B10000000; // Activate only pin D7 (PCINT23) for interrupts PortD
}
void loop() {
//Listen for accidental trigs on each port. If so ZERO again...
if (stopLeft + stopCenter + stopRight > 0 < 3) {
resetcount ++;
if (resetcount > 10000000) {
stopLeft = 0;
stopCenter = 0;
stopRight = 0;
timeLeft = 0;
timeCenter = 0;
timeRight = 0;
resetcount = 0;
PCICR |= 0b00000111; // Activate all PCINT-vectors
PCIFR = 0; // Zero all INT-Flags.
PCMSK0 = B00000001; // Activate only pin D8 (PCINT0) PortB UNO!
PCMSK1 = B00000001; // Activate only pin A0 (PCINT8) PortC UNO!
PCMSK2 = B10000000; // Activate only pin D7 (PCINT23) PortD UNO!
}//END IF
}//END IF
//If all mics trigged within X Clockcykles, then deactivate PCI Control and send data to serial. After sending data then reactivate PCI Control.
if (stopLeft == 1 && stopCenter == 1 && stopRight == 1 ) {
PCICR = B00000000; //De-Activates PCI_vectors 0, 1, 2 (To Re-activte again set last three bits to 1..("PCICR = B00000111;")
//WRITE TO EXTERNAL EXE APPLICATION. Notice!: Serial.print command may accidentaly activate PCI on Arduino?
//Serial.println(",");
Serial.print("A");
//Serial.print(",");
Serial.write((byte)0x00);
//Serial.print(",");
Serial.print(timeLeft);
//Serial.print(",");
Serial.write((byte)0x00);
//Serial.print(",");
Serial.print("B");
//Serial.print(",");
Serial.write((byte)0x00);
//Serial.print(",");
Serial.print(timeCenter);
//Serial.print(",");
Serial.write((byte)0x00);
//Serial.print(",");
Serial.print("C");
//Serial.print(",");
Serial.write((byte)0x00);
// Serial.print(",");
Serial.print(timeRight);
// Serial.print(",");
Serial.write((byte)0x00);
// Serial.print(",");
Serial.println();
//END WRITE TO EXTERNAL EXE APPLICATION
//WRITE TO ARDUINO IDE-SERIAL-MONITOR FOR DEBUGGING..
Serial.println( timeCenter - timeLeft);
Serial.println( timeRight - timeLeft);
Serial.println();
Serial.println(resetcount);
// Make a buzzer noise for debugging
digitalWrite(11, HIGH);
delay(6000);
digitalWrite(11, LOW);
delay(500); //Debounce before PCICR and PCMSK Re-Activation.
PCIFR = 0; //Zero all INT_Flags..
PCICR = B00000111; //Re-Activates PCI-Possibility on vectors 0, 1, and 2...
PCMSK0 = B00000001; // Re-Activate only pin D8 (PCINT0)
PCMSK1 = B00000001; // Re-Activate only pin A0 (PCINT8)
PCMSK2 = B10000000; // Re-Activate only pin D7 (PCINT23)
//Zero all volatile variables in ISR:s..
timeLeft = 0;
timeCenter = 0;
timeRight = 0;
stopLeft = 0;
stopCenter = 0;
stopRight = 0;
}//END IF
}//END LOOP
//_____________________________Trig 1 Left mic pins-D8-D13-PortB UNO___________________
ISR (PCINT0_vect) {
if (stopLeft == 0) {
stopLeft = 1;
timeLeft = micros();
PCMSK0 = B00000000; //Deactivate all pins in PCINT0-vect..PortB
} //END IF
} //END PCINT0_vect
//____________________________Trig 2 Center mic pins A0-A5-PortC UNO______________________
ISR (PCINT1_vect) {
if (stopCenter == 0) {
stopCenter = 1;
timeCenter = micros();
PCMSK1 = B00000000; //Deactivate all pins in PCINT1-vect..Port C
} //END IF
} //END ISR PCINT1_vect
//____________________________Trig 3 Right mic pins D0-D7-PortD UNO_______________________
ISR (PCINT2_vect) {
if (stopRight == 0) {
stopRight = 1;
timeRight = micros();
PCMSK2 = B00000000; //Deactivate all pins in PCINT2-vect..PortD
} //END IF
} //END ISR PCINT2_Vect