Teensy4.X I2C issues if using Audio.h

Rolfdegen

Well-known member
I'm building an effects device with Teensy4.0. I want to control Teensy4 FX parameters via I2C. A Teensy4.1 controls the FX parameters via I2C and supplies the audio signal to the Teensy4.0 via I2S. I have Teensy4.1 as the I2C master and Teensy4.0 as the I2C slave. Errors occur again during I2C transmission. If I disable the audio functions, I2C works flawlessly.

For testing, I plugged the Teensy4.0 and Teensy4.1 onto a breadboard and connected them via I2C. I'm not using audio, only I2C. I2C transmission is OK. Now I'm using a simple audio example on the Teensy4.1 (see code), and the I2C transmission is faulty. The I2C cables are very short, and I have 4.7K pull-up resistors on the I2C lines.

I use Arduino IDE Version 2.3.5 and Teensy Loader 1.59

Code Teensy4.1 I2C master
C:
// Wire Master Sender
#include <Audio.h>
#include <Wire.h>


int led = 13;

AudioSynthWaveformSine sine1;  //xy=285,416
AudioOutputI2S i2s1;           //xy=501,413
AudioConnection patchCord1(sine1, 0, i2s1, 0);
AudioConnection patchCord2(sine1, 0, i2s1, 1);


void setup() {
  AudioMemory(64);
  pinMode(led, OUTPUT);
  Wire1.begin();
  Wire1.setClock(100000UL);  // I2C speed 100KHz
  sine1.amplitude(0.5);
  sine1.frequency(500);
}


void loop() {
  digitalWrite(led, HIGH);      // briefly flash the LED
  Wire1.beginTransmission(40);  // transmit to device #40
  Wire1.write(20);              // sends five bytes
  Wire1.write(55);              // sends one byte
  Wire1.endTransmission();      // stop transmitting
  digitalWrite(led, LOW);
  delay(250);
}

Code Teensy4.0 I2C slave
C:
// Wire Slave Receiver

#include <Audio.h>
#include <Wire.h>

int led = 13;

AudioInputI2S2slave i2s1;  //xy=284,366
AudioOutputI2S i2s2;       //xy=531,368
AudioConnection patchCord1(i2s1, 0, i2s2, 0);  // is connected to DAC (PCM5102)
AudioConnection patchCord2(i2s1, 1, i2s2, 1);

// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany) {

  while (Wire1.available() > 1) {  // loop through all but the last
    uint8_t c = Wire1.read();      // receive byte as a character
    Serial.println(c);             // print the character
    digitalWrite(led, HIGH);       // briefly flash the LED
  }
  int x = Wire1.read();  // receive byte as an integer
  Serial.println(x);     // print the integer
  digitalWrite(led, LOW);
}

void setup() {
  Serial.begin(9600);             // start serial for output
  Wire1.begin(40);                // join i2c bus with address #40
  Wire1.onReceive(receiveEvent);  // register event
  AudioMemory(64);
  pinMode(led, OUTPUT);
}

void loop() {
  delay(10);
}

Rigol MSO5104 I2C analysis
 
Last edited:
In my TeensyMIDIPolySynth (TMPS) project, I have a T4.1 that controls/manages the traditional 5-pin DIN serial MIDI IN/OUT interfaces, the USBmidi IN/OUT interfaces, & the USBhostMIDI IN/OUT interfaces for up to 7 USB devices, as well as fully controlling/managing an RA8875 touchscreen display. The T4.1 communicates over a shared hardware serial port at 500kbaud to a T4.0, which is controlling/managing a Teensy Audio Adapter to generate synthesized/modulated/filtered/reverb sound, potentially sent thru software reverb as well. A very simple protocol is employed to allow bi-directional data/control/debug communications over the shared hardware serial port. Real-time changes on the display and/or incoming MIDI notes/commands from any & all sources can be received and sent to the Audio T4.0, and the audio responds appropriately, with no dropouts nor delays.

Unless you have an unstated need for specifically using I2C, you might consider using a shared hardware port between your Teensy processors instead of I2C.

Mark J Culross
KD5RXT
 
Hi Mark
Thanks for the info. That would be a solution. I was thinking about using a serial port on the Teensy. I hope that doesn't cause any problems.
But the question remains.. Why doesn't I2C work on a Teensy if using Audio.h :unsure:
 
I2S + I2C master has been tested and works, since even the SGTL5000 codec needs the I2C for configuration or parameter change on the fly.
Based on that i think we can assume the issue is with the T4.0 running the I2S + I2C slave?
Have you checked what happens if you disable the Audio on the I2C-Slave T4.0 only? Let the T4.1 send the data, while not enabling the audio on the T4.0.
I did use a combo of I2S + I2C slave in my TGX4 project, not exactly the same case, since one board is an ESP32S23 based display which controls the main Teensy4.1 DSP via I2C, ESP being the master and the Teensy (running audio) being the slave. It works fine.
The part handling the I2C slave is here:
LINK

One thing i would try is to minimize the I2C slave receive interrupt handler, ie. grab the data into a buffer and process it later, avoid any printing from the interrupt handler.

Does the problem still exists if the T4.1 sends a single byte only? It's sending two bytes (20, 55) in the example above.
 
I²C certainly does work on a Teensy with the audio library. I'm using M5stack encoder and potentiometer units (8-Encoder and 8-Angle) with an audio application, and they work just fine.

I'm not 100% sure your scope is decoding the bus correctly; for examples, at ~7s into your video two bytes are transmitted, but the decoder insists there's only one, and that it's not ACKed when it clearly is. That being said, the traces don't look quite right - there seems to be a STOP condition after only two bytes.
 
Thanks for the help. I tested the following:

1. Teensy4.1 as an I²C master and ATtiny412 as an I²C slave. The Teensy4.1 sends I²C data and simultaneously audio data via I²S to a DAC (PCM5102a). Good results. Data transmission on the I²C bus is stable and error-free :)

2. Teensy4.1 as an I²C master and ATtiny412 and Teensy4.0 as I²C slaves. The Teensy4.1 sends I²C data to the ATtiny412 and simultaneously audio data via I²S to the Teensy4.0. The Teensy4.0 sends I²S audio data to the DAC. Good results. Data transfer on the I²C bus is stable and error-free :)

3. Same as 2. The difference is that I'm now accessing Teensy4.0 (address 49). Result: When I access Teensy4.0 (address 49), the I²C data is corrupted. When I access ATtiny412 (address 48), everything works fine :unsure:

It could be that the Teensy is defective. I'll buy a new one.

I2C-Adresse Nr. 48 ATtiny412
I2C_ATtiny412.png


I2C-Adresse Nr. 49 Teensy4.0
I2C_Teensy4.0.png
 
Last edited:
Do you really need two I2S busses for the T4.0? The master (T4.1) provides all I2S clocks, both T4.0 and the DAC could be I2S Slaves with T4.0 put in series in the data line, something like this:
t4_i2s.png
I have just run a test using
  • ESP32 as I2C master, repeatedly sending 20 and 55 to addr. 40
  • T4.0, as I2C slave @ addr. 40, also running I2S (master in/out, slave i2s2 in+master i2s out as in your example, slave in/out)
In all cases i'm getting correct data printed out from the T4.0, even at 400kHz SCL.
 
Thanks for the tip. I'll test it. But.. Which pin on the PCM5102 is MCLK :unsure:

The Teensy 4.0 is an FX sound module controlled by the Teensy 4.1. The Teensy 4.1 is an 8-voice synthesizer and sampler with 3 oscillators per voice, digital filters, and a touchscreen. To offload the Teensy 4.1 MCU, the Teensy 4.0 provides reverb, chorus, delay, and other sound effects (see Link).

My new DIY project: https://forum.pjrc.com/index.php?threads/new-polyhonic-teensy-diy-sampler.76219/page-2

I2S audio connection: Teensy4.1 (Synth) >>> Teensy4.0 (Fx) >>> DAC (PCM5102)
 
Last edited:
Do you really need two I2S busses for the T4.0? The master (T4.1) provides all I2S clocks, both T4.0 and the DAC could be I2S Slaves with T4.0 put in series in the data line, something like this:
View attachment 37583
I have just run a test using
  • ESP32 as I2C master, repeatedly sending 20 and 55 to addr. 40
  • T4.0, as I2C slave @ addr. 40, also running I2S (master in/out, slave i2s2 in+master i2s out as in your example, slave in/out)
In all cases i'm getting correct data printed out from the T4.0, even at 400kHz SCL.

The Teensy4.0 slave doesn't have an MCLK input :unsure:

Screenshot 2025-05-22 010532.png


I wired it without MCLK and it works. But there are still I2C transmission errors. I've ordered a new Teensy4.0. It'll arrive tomorrow, and I'll test it again then.

34119-9c5a40a217ebad23006268437ea213ba.png

C:
// Wire Slave Receiver

#include <Audio.h>
#include <Wire.h>

int led = 13;

AudioInputI2S2slave i2s1;  //xy=284,366
AudioOutputI2S2 i2s2;       //xy=531,368
AudioConnection patchCord1(i2s1, 0, i2s2, 0);  // is connected to DAC (PCM5102)
AudioConnection patchCord2(i2s1, 1, i2s2, 1);

// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany) {

  while (Wire1.available() > 1) {  // loop through all but the last
    uint8_t c = Wire1.read();      // receive byte as a character
    //Serial.println(c);             // print the character
    digitalWrite(led, HIGH);       // briefly flash the LED
  }
  int x = Wire1.read();  // receive byte as an integer
  //Serial.println(x);     // print the integer
  digitalWrite(led, LOW);
}

void setup() {
  Serial.begin(9600);             // start serial for output
  Wire1.begin(49);                // join i2c bus with address #40
  Wire1.onReceive(receiveEvent);  // register event
  AudioMemory(20);
  pinMode(led, OUTPUT);
}

void loop() {
  delay(100);
}
 
Last edited:
I'm trying to investigate. So far I have only the I2C wires connected between a Teensy 4.0 and Teensy 4.1 running the 2 programs from msg #1.

1747916528785.png


I'm seeing all the bytes printed in the Arduino Serial Monitor.

1747916618059.png


My scope sees both bytes too.

1747916649323.png


Maybe this will change once I connect the I2S signals? I just started looking into this. Will post another update as I connect more wires...
 
I added wires for BCLK and LRCLK, and indeed strange problems appear.

So far I have no idea why... just sharing the info and confirming I can see a problem as I start to investigate.

1747917982595.png


1747918013915.png


1747918078593.png
 
I tried adding 1K resistors in series with BCLK and LRCLK... on a (admittedly pretty weak) hunch this may be a signal quality problem. It doesn't solve the problem, but does seem to make it behave differently.

I'm out of time for right now, but will dive deeper into this later tonight and over the next few days as needed. There definitely is some strange problem with I2S slave mode messing up I2C slave reception.

For now, could you have series resistors on BCLK and LRCLK to check if they make any difference on your setup (or maybe I'm just imagining things.... maybe I'm just seeing things because tired?)

1747920278398.png
 
Hello Paul. Thank you for taking the time to investigate the problem :) I'll test it with the 1K resistors right away. See you then...
 
With 1K on BCLK and LRCLK, audio noise from the DAC (PCM5102) occurs. I2C data is still corrupted.
I also tested it with 22R resistors, but that didn't work. The I2C data was corrupted.

I2s_bus_1k.png
 
Last edited:
Since I don't have a second Teensy4.0 at the moment (order will arrive tomorrow), I will test a Teensy4.1 as an I2C slave.
Teensy4.1 has the same issues as Teensy4.0. I2C data is corrupted :unsure:
I discovered another bug. If the master and slave address is 127, then random data is on the bus (see video).

Fist Master/Slave adress 49 than adress 127. The I2C address range is 0-127
 
Last edited:
The I2C hardware has a glitch filter. Maybe we're configuring it wrong in slave mode?

Will investigate soon. Realistically, at the rate things are going I probably can't do much until late tonight or tomorrow. But it's clear we do have a confirmed problem here and something needs to be done about it (even if that thing is only documentation about hardware limitations).
 
Thank you for your tremendous support. These types of errors only become apparent in certain hardware and software situations. You can't test everything :)
 
I experimented a bit and found that a 4.7K pull-up resistor on the master and a 1K resistor on the CLK line to the slave produced the best results. I also soldered a 22pF capacitor to CLK and GND on the slave. The capacitor should have very short leads.
 
I tested data transfer via a serial port on the Teensy with Audio (without resistors or capacitors). Teensy4 (slave) receives data from Teensy4.1 (master) via the serial interface. This works with audio and without any transmission errors :)
 
I tested data transfer via a serial port on the Teensy with Audio (without resistors or capacitors). Teensy4 (slave) receives data from Teensy4.1 (master) via the serial interface. This works with audio and without any transmission errors :)
Yes, it appears that you have had a positive experience identical to mine, which has been that, when I2C audio control is being utilized, everything plays nicely together with the T4.x processors communicating over a shared hardware serial interface (much simpler, very efficient, & very effective) !! Depending upon the speed at which you choose for this shared hardware serial interface to operate (I use 500Kbaud in my TMPS), you may need to add additional interface buffering as follows (with Serial4 shown in this example):

Code:
#define SERIAL4_RX_BUFFER_SIZE 32768
DMAMEM byte serial4RXbuffer[SERIAL4_RX_BUFFER_SIZE];

#define SERIAL4_TX_BUFFER_SIZE 32768
DMAMEM byte serial4TXbuffer[SERIAL4_TX_BUFFER_SIZE];

Serial4.begin(500000);
Serial4.addMemoryForRead(serial4RXbuffer, SERIAL4_RX_BUFFER_SIZE));
Serial4.addMemoryForWrite(serial4TXbuffer, SERIAL4_TX_BUFFER_SIZE);

Mark J Culross
KD5RXT
 
Thanks for your advice
I'll include a small receive buffer in Teensy4.0 (slave). I'll use 4 bytes to transmit the effect parameters. There is no feedback data from the slave.

1. byte = Status 0x55
2. byte = ID for the parameter
3. byte = MSB value
4. byte = LSB value

Polyphonic DIY Synthesizer/Sampler
with 8 Voices, 3 oscilator per voice, wavetable, va synthesis, digital Filter, FX (Teensy4.0), Sequencer, Touchscreen and more
See my Audio project: https://forum.pjrc.com/index.php?threads/new-polyhonic-teensy-diy-sampler.76219/

Degenerator2.jpg


20250524_094837.jpg
 
Back
Top