Simple ranging with Teensy 4. Recurring beeps + FFT trouble

Status
Not open for further replies.

ahinduja

Member
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).


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
 
On further thinking, I think my issue is using the delay() command since that would stop everything and the FFT won't process during the time. I don't know of any other method of timing the beeps though :/
 
Status
Not open for further replies.
Back
Top