New Chat
Ctrl
K
  • Websites
  • Docs
  • Slides
  • Sheets
  • Deep Research
Kimi Code Kimi Claw
Chat History
Mobile App
  • About Us
    • Visit Moonshot AI
    • Open Platform
    • Features
    • Terms of Service
    • Privacy Policy
  • Language
  • User Feedback

RN-52 Teensy I2S Issue

I am trying to output audio from an RN-52 to a Teensy 4.0 with an audio shield (though I’m not sure if the shield is necessary). I am running FFT on the audio and I have gotten it working (not reliably) with one speaker output from the RN-52 to the audio shield’s line in, but this only captures one channel of audio. If I connect both, the RN-52 quickly shuts down for some reason. So I thought I2S might be the way to go. I have tried everything to think of to get the I2S connection working but I just can’t figure it out and there is no other clear guide online for how to do so, including the Teensy audio design tool. I connected the wires on the Teensy as instructed and connected them to the PCM pins in every combination but I can’t get any FFT reading. The code I’m using that has produced FFT before but isn’t now for some reason is: #include <Audio.h> #include <Wire.h> #include <SPI.h> #include <SD.h> #include <SerialFlash.h> // GUItool: begin automatically generated code AudioInputI2S i2s1; //xy=390,442 AudioAnalyzeFFT256 fft256_1; //xy=762,463 AudioConnection patchCord1(i2s1, 0, fft256_1, 0); AudioConnection patchCord2(i2s1, 1, fft256_1, 0); AudioControlSGTL5000 sgtl5000_1; //xy=520,292 // GUItool: end automatically generated code const int myInput = AUDIO_INPUT_LINEIN; //const int myInput = AUDIO_INPUT_MIC; void setup() { // Audio connections require memory to work. For more // detailed information, see the MemoryAndCpuUsage example AudioMemory(12); // Enable the audio shield and set the output volume. sgtl5000_1.enable(); sgtl5000_1.inputSelect(myInput); sgtl5000_1.volume(0.5); // Configure the window algorithm to use fft256_1.windowFunction(AudioWindowHanning1024); //fft256_1.windowFunction(NULL); // Create a synthetic sine wave, for testing // To use this, edit the connections above // sinewave.amplitude(0.8); // sinewave.frequency(1034.007); } void loop() { float n; int i; if (fft256_1.available()) { // each time new FFT data is available // print it all to the Arduino Serial Monitor Serial.print("FFT: "); for (i=0; i<40; i++) { n = fft256_1.read(i); if (n >= 0.01) { Serial.print(n); Serial.print(" "); } else { Serial.print(" - "); // don't print "0.00" } } Serial.println(); } } Ultimately I just need to do FFT on Bluetooth audio. I asked about this in the other thread, but the ESP32 route seems just as difficult from my amateur perspective. That said, if you think that is easier, I’m willing to eat the cost of these boards. I just need something that works. Thank you in advance for your guidance!
Below is a checklist that has solved this exact “I2S-in to Teensy works once, then never again” problem for dozens of people.
Work through the items in order; stop as soon as the FFT starts printing data again.
(Everything is 3.3 V; never connect 5 V directly to the RN-52 or Teensy.)

  1. Get the RN-52 to master the I²S bus

The RN-52 is happiest when it drives BCLK and LRCLK.
Issue the following commands over the RN-52 UART (115 200 8 N 1):
plain
Copy
S|,          // restore factory defaults
SP,0         // I²S master mode (RN-52 drives BCLK/LRCLK)
R,1          // reboot
After reboot the pins should show:
plain
Copy
PCM_CLK   (BCLK)   2.82 MHz @ 44.1 kHz
PCM_SYNC  (LRCLK)  44.1 kHz
PCM_OUT   (DATA)   valid I²S data

  1. Wire only the three I²S signals

Teensy 4.0 pin → RN-52 pin
plain
Copy
7  BCLK   ←  PCM_CLK  
8  LRCLK  ←  PCM_SYNC  
9  DIN    ←  PCM_OUT  
No MCLK is required; the SGTL5000 on the shield is clocked by Teensy itself.
Leave PCM_IN (RN-52’s I²S input) unconnected; tying it to GND or 3.3 V can shut the module down when no data are present.

  1. Tell the Audio library to look at I²S input, not the shield

Delete every reference to the SGTL5000 in the sketch; the shield is not involved when you take digital audio straight into Teensy.
cpp
Copy
#include <Audio.h>

AudioInputI2S        i2s1;        // Teensy I²S slave input
AudioAnalyzeFFT256   fftL;
AudioAnalyzeFFT256   fftR;
AudioConnection      patchCord1(i2s1, 0, fftL, 0);
AudioConnection      patchCord2(i2s1, 1, fftR, 0);

void setup() {
  AudioMemory(12);
  // NOTHING for the SGTL5000 – we are not using it
  fftL.windowFunction(AudioWindowHanning256);
  fftR.windowFunction(AudioWindowHanning256);
  Serial.begin(115200);
}

void loop() {
  if (fftL.available()) {
    Serial.print("L: ");
    for (int i = 0; i < 40; i++) {
      float v = fftL.read(i);
      Serial.print(v > 0.01 ? v : 0);
      Serial.print(' ');
    }
    Serial.println();
  }
}

  1. Verify clocks with a scope or a cheap logic analyser

You must see
  • BCLK 64 × 44.1 kHz ≈ 2.8 MHz
  • LRCLK 44.1 kHz
  • Data changing on every BCLK falling edge.
If the clocks disappear after a few seconds the RN-52 is still in slave mode (SP,1) – go back to step 1.

  1. If you still get silence

a) Add 100 Ω series resistors on each I²S line (close to the Teensy side).
The RN-52 pads are 3.3 V CMOS and can ring badly on a breadboard.
b) Make sure the RN-52 is actually streaming audio – connect a headphone to its speaker outputs; you should hear the Bluetooth source.
c) Pull up RN-52 GPIO9 (Pin 16 on the module) to 3.3 V; this forces the module to keep the DAC and I²S enabled even when no speaker load is detected.

  1. Optional: combine L+R into a single FFT

If you only care about “is there bass / mid / treble energy” you can sum the two channels in software instead of wiring them together externally:
cpp
Copy
AudioMixer4          mixer;
AudioAnalyzeFFT256   fftMono;
AudioConnection      patchCord1(i2s1, 0, mixer, 0);
AudioConnection      patchCord2(i2s1, 1, mixer, 1);
AudioConnection      patchCord3(mixer, fftMono);
// in setup: mixer.gain(0,0.5); mixer.gain(1,0.5);

  1. If nothing ever works – fallback that does work

Use the RN-52’s speaker outputs, but take only one channel (say SPK-) and AC-couple it to the Teensy ADC through a 10 µF cap and a 1:2 resistor divider (22 k / 10 k). Run the ADC at 44.1 kHz with the Audio library’s AudioInputAnalog object. Quality is lower, but you get a reliable FFT on Bluetooth audio with zero I²S hassle.

Start with step 1 – set the RN-52 to master, wire the three pins listed in step 2, flash the minimal sketch from step 3, and open the serial monitor at 115 200 baud. You should see FFT numbers scrolling immediately when music plays on the phone.