100 Hz sampling using Timer 1 interrupt
//
// Arduino Nano interrupt example
// This program uses the Timer 1 interrupt to implement
// 100 Hz sampling on pin A0. The Timer 1 interrupt service
// routine reads a sample from A0, then prints it out over
// the serial connection to the PC.
//
// Written by Ted Burke 4-Apr-2022
//
// Timer 1 interrupt service routine (ISR)
ISR(TIMER1_COMPA_vect)
{
Serial.println(analogRead(0)); // Sample voltage on pin A0
}
void setup()
{
Serial.begin(9600); // Serial connection to print samples
cli(); // disable interrupts during setup
// Configure Timer 1 interrupt
// F_clock = 16e6 Hz, prescaler = 64, Fs = 100 Hz
TCCR1A = 0;
TCCR1B = 1<<WGM12 | 0<<CS12 | 1<<CS11 | 1<<CS10;
TCNT1 = 0; // reset Timer 1 counter
// OCR1A = ((F_clock / prescaler) / Fs) - 1 = 2499
OCR1A = 2499; // Set sampling frequency Fs = 100 Hz
TIMSK1 = 1<<OCIE1A; // Enable Timer 1 interrupt
sei(); // re-enable interrupts
}
void loop()
{
// Let the ISR do all the work
}
100 Hz sampling with moving average
//
// Arduino Nano interrupt example
// Calculates moving average of last N analog samples on pin A0
//
// Written by Ted Burke 6-Apr-2022
//
// Allocate a sample buffer to store N samples
const int N = 4;
int s[N] = {0};
int n = 0; // used as an index variable for the sample buffer
//
// This is the Timer 1 interrupt service routine (ISR).
// This ISR is triggered every 10 ms (i.e. 100 Hz) by Timer 1.
// Each time it is called, it takes a sample from pin A0,
// stores it to the sample buffer (array s[]) and calculates
// the average of all N samples in the buffer.
// For debugging purposes, it prints out the raw samples
// and the moving average, but this would presumably be
// removed in production code, because it's time consuming.
//
ISR(TIMER1_COMPA_vect)
{
int average;
// Increment sample number, but reset to 0 when it reaches N
// Note that "%" is the modulo operator in C
n = (n + 1) % N;
// Sample the voltage on pin A0 and store to the nth element of array s
s[n] = analogRead(0);
// Calculate average of all N samples in array s
average = 0;
for (int m=0 ; m<4 ; ++m) average += s[m];
average = average / N;
// Print out the latest sample and the average of the last N samples
Serial.print(s[n]); // most recent sample
Serial.print(" "); // print space between values
Serial.println(average); // average of last N samples
}
void setup()
{
Serial.begin(9600); // Serial connection to print samples
cli(); // disable interrupts during setup
// Configure Timer 1 interrupt
// F_clock = 16e6 Hz, prescaler = 64, Fs = 100 Hz
TCCR1A = 0;
TCCR1B = 1<<WGM12 | 0<<CS12 | 1<<CS11 | 1<<CS10;
TCNT1 = 0; // reset Timer 1 counter
// OCR1A = ((F_clock / prescaler) / Fs) - 1 = 2499
OCR1A = 2499; // Set sampling frequency Fs = 100 Hz
TIMSK1 = 1<<OCIE1A; // Enable Timer 1 interrupt
sei(); // re-enable interrupts
}
void loop()
{
// Let the ISR do all the work
}