Hello,
now I did some tests with the TimerOne-Library:
Firstly I set the sampling rate at my “filtered data triggers a LED” sketch:
// Arduino Signal Filtering Test
// Turn a LED on if filter amplitude reaches an arbitrary threshold and whit a defined sampling rate
// June 2014
// Arduino Signal Filtering Library
// Copyright 2012-2013 Jeroen Doggen (jeroendoggen@gmail.com)
// http://jeroendoggen.github.io/Arduino-signal-filtering-library/
// http://www.schwietering.com/jayduino/filtuino/
// Timer 1 Library for a defined sampling rate
// http://playground.arduino.cc/Code/Timer1
#include <TimerOne.h>
#include <SignalFilter.h> // Filter Library
SignalFilter Filter;
int Pin8 = 8; // for sampling measurement
const int ledPin = 13; // pin that the LED is attached to
const int threshold = 400; // an arbitrary threshold level that's in the range of the analog input
int data1; // variable for Analog In
int data2; // variable for filter
void setup()
{
pinMode(Pin8, OUTPUT); // for sampling rate measurement
pinMode(ledPin, OUTPUT); // initialize the LED pin as an output:
Filter.begin();
Filter.setFilter('c'); // filter settings: c=Cebycheff b= Bessel
Filter.setOrder(2); // filter settings: order 1 or 2
Timer1.initialize(200); // set a timer of length 200 microseconds (1.000.000/200 = 5000Hz)
Timer1.attachInterrupt( timerIsr ); // attach the service routine here
}
/*
Filter characteristics are stored in: “SignalFilter.cpp”.
Current filter settings and code: for “c” “2”
/// runChebyshev: Band Pass 220Hz; 1. Order; lower corner =215Hz; upper corner 225Hz; sampling=5000Hz; long type 8bit; enabled "-1 bit saturation";
_v[0] = _v[1];
_v[1] = _v[2];
long tmp = ((((data * 3360365L) >> 8) //= ( 6.2591678898e-3 * x)
+ ((_v[0] * -4141801L) >> 1) //+( -0.9874824279*v[0])
+ (_v[1] * 4009861L) //+( 1.9120508347*v[1])
)+1048576) >> 21; // round and downshift fixed point /2097152
_v[2]= (short)tmp;
return (short)((
(_v[2] - _v[0]))); // 2^
*/
void loop()
{
// Main code loop
// TODO: Put your regular (non-ISR) logic here
}
void timerIsr()
{
// Read Analog Input... you can connect accelerometer, gyro, temperature sensor, microphone etc to the channel
data1 = analogRead(0)-512; //Read Analog channel (value of microphone) and substract DC-Offset from Microphone "BOB-09964"
data2 = Filter.run(data1); //Read the filtered signal
/*
http://arduino.cc/en/Tutorial/IfStatement
the variable called data1 is used to store the data collected from a Analog Pin A0.
This data is then compared to a threshold value.
If the value is found to be above the set threshold the LED connected to digital pin 13 is turned on.
If analogValue is found to be < threshold, the LED remains off. */
// if the filter value is high enough, turn on the LED:
if (data2 > threshold) {
digitalWrite(ledPin, HIGH);
}
else {
digitalWrite(ledPin,LOW);
}
digitalWrite(Pin8, HIGH); // PIN Output High for sampling rate measurement
digitalWrite(Pin8, LOW); // PIN Output Low for sampling rate measurement
}
It works fine!
At PIN8 I measured a sampling rate of 5000Hz. This was the sampling rate I programmed. And also the filter works now. The in the filter code generator appointed frequency of 220Hz passes now.
But then I tried the same whit my other sketch, were simultaneously I want produce a tone and it didn't work. I measured a sampling rate of 6250Hz:
// Arduino:
// Generating sine waves
// Filter
// Turn a LED on if filter amplitude reaches an arbitrary threshold
// try to set the sampling rate with TimerOne-Library
// 2014
// and generate a Sinewave
/******** Load AVR timer interrupt macros ********/
// http://makezine.com/projects/make-35/advanced-arduino-sound-synthesis/
// Arduino Signal Filtering Library
// Copyright 2012-2013 Jeroen Doggen (jeroendoggen@gmail.com)
// http://jeroendoggen.github.io/Arduino-signal-filtering-library/
// http://www.schwietering.com/jayduino/filtuino/
// IF Statement LED ON
// http://arduino.cc/en/Tutorial/IfStatement
// Timer 1 Library for a defined sampling rate
// http://playground.arduino.cc/Code/Timer1
int Pin8 = 8; // for sampling rate measurement
#include <TimerOne.h> //include library for set timer1 and sampling rate
#include <avr/interrupt.h> // library for Sinewave
//Sine wave parameters
#define PI2 6.283185 // 2 * PI - saves calculating it later
#define AMP 127 // Multiplication factor for the sine wave
#define OFFSET 128 // Offset shifts wave to just positive values
// Lookup table
#define LENGTH 256 // The length of the waveform lookup table
byte wave[LENGTH]; // Storage for the waveform
#include <SignalFilter.h> // Filter Library
SignalFilter Filter;
const int ledPin = 13; // pin that the LED is attached to
const int threshold = 480; // an arbitrary threshold level that's in the range of the analog input
int data1; // variable for Analog In
int data2; // variable for filter
void setup()
{
pinMode(Pin8, OUTPUT); // for sampling measurement
// Filter Parameters
pinMode(ledPin, OUTPUT); // initialize the LED pin as an output:
// digitalWrite(ledPin, ledState);
Timer1.initialize(200); // set a timer of length 200 microseconds (1.000.000/200 = 5000Hz) this will be your samplerate
Timer1.attachInterrupt( timerIsr ); // attach the service routine here
Filter.begin();
Filter.setFilter('c'); // filter settings: c=Cebycheff b= Bessel
Filter.setOrder(2); // filter settings: order 1 or 2
// Sinewave Parameters
// Populate the waveform lookup table with a sine wave
for (int i=0; i<LENGTH; i++) { // Step across wave table
float v = (AMP*sin((PI2/LENGTH)*i)); // Calculate current entry
wave[i] = int(v+OFFSET); // Store value as integer
}
// Set timer1 for 8-bit fast PWM output
pinMode(9, OUTPUT); // Make timer's PWM pin an output
TCCR1B = (1 << CS10); // Set prescaler to full 16MHz
TCCR1A |= (1 << COM1A1); // PWM pin to go low when TCNT1=OCR1A
TCCR1A |= (1 << WGM10); // Put timer into 8-bit fast PWM mode
TCCR1B |= (1 << WGM12);
// Set up timer 2 to call ISR
TCCR2A = 0; // We need no options in control register A
TCCR2B = (1 << CS21); // Set prescaller to divide by 8
TIMSK2 = (1 << OCIE2A); // Set timer to call ISR when TCNT2 = OCRA2
OCR2A = 32; // sets the frequency of the generated wave (32=246.94Hz)
sei(); // Enable interrupts to generate waveform!
}
/*
Filter characteristics are stored in: “SignalFilter.cpp”.
Current filter settings and code: for “c” “2”
/// runChebyshev: Band Pass 220Hz; 1. Order; lower corner =215Hz; upper corner 225Hz; sampling=5000Hz; long type 8bit; enabled "-1 bit saturation";
_v[0] = _v[1];
_v[1] = _v[2];
long tmp = ((((data * 3360365L) >> 8) //= ( 6.2591678898e-3 * x)
+ ((_v[0] * -4141801L) >> 1) //+( -0.9874824279*v[0])
+ (_v[1] * 4009861L) //+( 1.9120508347*v[1])
)+1048576) >> 21; // round and downshift fixed point /2097152
_v[2]= (short)tmp;
return (short)((
(_v[2] - _v[0]))); // 2^
*/
void loop()
{
// Main code loop
// TODO: Put your regular (non-ISR) logic here
}
void timerIsr()
{
// Read Analog Input... you can connect accelerometer, gyro, temperature sensor, microphone etc to the channel
data1 = analogRead(0)-512; //Read Analog channel (value of microphone) and substract DC-Offset from microphone "BOB-09964"
data2 = Filter.run(data1); //Read the filtered signal
// if the filter value is high enough, turn on the LED:
if (data2 > threshold) {
digitalWrite(ledPin, HIGH);
}
else {
digitalWrite(ledPin, LOW);
}
digitalWrite(Pin8, HIGH); // PIN Output High Sample Measurement
digitalWrite(Pin8, LOW); // PIN Output Low Sample Measurement
}
//Called every time TCNT2 = OCR2A
ISR(TIMER2_COMPA_vect) { // Called each time TCNT2 == OCR2A
static byte index=0; // Points to successive entries in the wavetable
OCR1AL = wave[index++]; // Update the PWM output
asm("NOP;NOP"); // Fine tuning
TCNT2 = 6; // Timing to compensate for time spent in ISR
}
Maybe the problem is that Timer1 is also used by the tone generator.
If that's really the problem how can I regulate the sampling rate?
Any suggestions?