Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 4 of 4

Thread: Simple ranging with Teensy 4. Recurring beeps + FFT trouble

  1. #1

    Simple ranging with Teensy 4. Recurring beeps + FFT trouble

    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

  2. #2
    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 :/

  3. #3
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    22,539
    Try using elapsedMillis. Details and examples here:

    https://www.pjrc.com/teensy/td_timin...pedMillis.html

  4. #4
    Thanks Paul! That did the trick!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •