Hi all,
The project I am trying out is to do ranging using a Teensy 4 + speaker + I2S microphone. My plan is to have a recurrent short 8khz tone sent via the speaker (while noting the time sent using elapsed time) and then listening to it via the Microphone + FFT and again noting the time elapsed. Having this, I should be able to determine the range of the speaker from the microphone.
Currently, I have all the individual pieces working. My mic can detect 8khz sounds, and I can generate short beeps of 8khz with the speaker. However when I am trying a simple program to do the recurrent beeps + the FFT together, I can't get both to work simultaneously. If the beep is continuous, the FFT has no problems in detecting the 8khz tone, but either I can make FFT run, or the recurrent beeps. Would really appreciate if anybody can give me some hints on what I am doing wrong, and suggestions on improvements! (To give a more long term goal, I want to extend this to having a speaker on a different teensy, but need to figure out time synchronization without GPS or atomic clocks. This is for the next stage).
To give a brief description of my code, I am using an interrupt timer to call the beep function every 6 seconds (doesn't work the way its written right now), while the FFT is polling in the loop function and every time an 8khz tone is heard it prints out the time and confirmation.(this works when using an external source or making the speaker play a continuous tone). Thanks!
serial monitor: (When interrupt function is used)
Serial monitor when interrupt is commented out and speaker plays continuously:
-Akshay
The project I am trying out is to do ranging using a Teensy 4 + speaker + I2S microphone. My plan is to have a recurrent short 8khz tone sent via the speaker (while noting the time sent using elapsed time) and then listening to it via the Microphone + FFT and again noting the time elapsed. Having this, I should be able to determine the range of the speaker from the microphone.
Currently, I have all the individual pieces working. My mic can detect 8khz sounds, and I can generate short beeps of 8khz with the speaker. However when I am trying a simple program to do the recurrent beeps + the FFT together, I can't get both to work simultaneously. If the beep is continuous, the FFT has no problems in detecting the 8khz tone, but either I can make FFT run, or the recurrent beeps. Would really appreciate if anybody can give me some hints on what I am doing wrong, and suggestions on improvements! (To give a more long term goal, I want to extend this to having a speaker on a different teensy, but need to figure out time synchronization without GPS or atomic clocks. This is for the next stage).
Code:
/*
SD -> pin 8 (in1)/pin 5 (in2)
L/R -> GND/VCC (left/right channel)
WS -> pin 20 (LRCLK1)/pin 3 (LRCLK2)
SCK -> pin21 (BCLK1)/pin 4 (BCLK2)
*/
/*
* Sample rate is 44.1khz
* Therefore max frequency is 22.05khz
* For FFT1024 we have each bin = 22.05/512 = 43.06 hz
* For FFT256 we have each bin = 22.05/128 = 172.26 hz
* for 8khz bin 45-49 for FFT256
* For 8khz 184-189 for FFT1024
*/
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
#include <TimeLib.h>
// GUItool: begin automatically generated code
AudioSynthWaveformSine sine1;
AudioAmplifier amp1;
AudioOutputI2S2 i2s2;
AudioInputI2S i2s1; //xy=500,322
AudioAnalyzeFFT1024 fft1024_1; //xy=701,316
AudioAnalyzeFFT256 fft256_1;
//AudioConnection patchCord1(i2s1, 0, fft1024_1, 0);
AudioConnection patchCord1(i2s1, 0, fft256_1, 0);
AudioConnection patchCord2(sine1, 0, amp1, 0);
AudioConnection patchCord3 (amp1, 0, i2s2, 0);
IntervalTimer pulse;
// GUItool: end automatically generated code
const float freq = 8000.0;
const float amp = 0.8;
const float g = 0.5;
void setup() {
//Serial.begin(9600);
AudioMemory(70);
while (!Serial) ; // wait until Arduino Serial Monitor opens
setSyncProvider(getTeensy3Time);
if(timeStatus()!= timeSet)
Serial.println("Unable to sync with the RTC");
else
Serial.println("RTC has set the system time");
while (!Serial && millis () < 3000);
delay (6000);
AudioNoInterrupts();
//AudioMemory (2);
amp1.gain (0.5);
//sine1.amplitude(0.8); //uncomment for continuous tone.
sine1.frequency(freq);
AudioInterrupts();
Serial.println("setup done");
pulse.begin(beep, 500000); //call beep every 5 secs
}
time_t getTeensy3Time()
{
return Teensy3Clock.get();
}
void beep()
{
delay(100);
sine1.amplitude(0.8);
Serial.println("in beep");
delay(1000);
sine1.amplitude(0.0);
}
void printDigits(int digits){
// utility function for digital clock display: prints preceding colon and leading 0
Serial.print(":");
if(digits < 10)
Serial.print('0');
Serial.print(digits);
}
void digitalClockDisplay() {
// digital clock display of the time
Serial.print(hour());
printDigits(minute());
printDigits(second());
Serial.print(" ");
Serial.print(day());
Serial.print(" ");
Serial.print(month());
Serial.print(" ");
Serial.print(year());
Serial.println();
}
void loop() {
//sine1.amplitude(0.0); // does not work
//delay(10000);
//sine1.amplitude(0.8);
if (fft256_1.available()) {
if (fft256_1.read(45,49)*10>0.01)
{
digitalClockDisplay();
Serial.println("heard ping");
}
}
}
To give a brief description of my code, I am using an interrupt timer to call the beep function every 6 seconds (doesn't work the way its written right now), while the FFT is polling in the loop function and every time an 8khz tone is heard it prints out the time and confirmation.(this works when using an external source or making the speaker play a continuous tone). Thanks!
serial monitor: (When interrupt function is used)
Code:
RTC has set the system time
setup done
in beep
in beep
in beep
in beep
Serial monitor when interrupt is commented out and speaker plays continuously:
Code:
RTC has set the system time
setup done
16:12:45 20 4 2020
heard ping
16:12:45 20 4 2020
heard ping
16:12:45 20 4 2020
heard ping
16:12:45 20 4 2020
-Akshay