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

Thread: Audio cuts out when updating I2C OLED display

  1. #1
    Junior Member
    Join Date
    May 2021
    Posts
    2

    Audio cuts out when updating I2C OLED display

    Hello Teensys

    I am working on project that involves the audio and the wire library. I have connected a generic OLED I2C display to my teensy audio project in order to display some information about what the teensy is doing. When I update the display the audio cuts out. If I put the display.display() function in the main loop I get almost no audio. If I make the display update every few hundred milliseconds I can hear the audio cut out every time the display updates. I have done some goggling on this subject and it looks like the teensy can not do anything else while its sending data out to the I2C bus. It looks like the same issue is described in this post

    https://forum.pjrc.com/threads/49187...ng-down-motors

    Bellow is my troubleshooting code. I am using a Teensy 4.1 with a Adafruit I2S Stereo Decoder UDA1334A and a SSD1306 128x64 OLED display.
    I have tied using different I2C bus on the Teensy pins 18, 19 and pins 16, 17 and it did not help. I tried using the wire library and the i2c_t3 library and the end result is the same.
    I have watched the audio library demo video on youtube and the last part they have a display showing the audio level in real time with no audio interruption at all using a SPI display. I understand i2c is a slower protocol but is there not no way to use i2c without pausing all other code?



    Code:
    #include <Audio.h>
    #include <Wire.h>
    #include <SPI.h>
    #include <SD.h>
    #include <SerialFlash.h>
    #include <Adafruit_GFX.h>
    #include <Adafruit_SSD1306.h>
    
    
    #define SCREEN_WIDTH 128 // OLED display width, in pixels
    #define SCREEN_HEIGHT 64 // OLED display height, in pixels
    
    #define OLED_RESET 4
    Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire1, OLED_RESET);
    
    
    // GUItool: begin automatically generated code
    AudioSynthWaveform       waveform1;      //xy=285,305
    AudioEffectEnvelope      envelope1;      //xy=487,307
    AudioEffectEnvelope      envelope2;      //xy=491,371
    AudioFilterStateVariable filter1;        //xy=743,450
    AudioAmplifier           amp1;           //xy=903,444
    AudioOutputI2S           i2s1;           //xy=1094,439
    AudioConnection          patchCord1(waveform1, envelope1);
    AudioConnection          patchCord2(waveform1, envelope2);
    AudioConnection          patchCord3(envelope1, 0, filter1, 0);
    AudioConnection          patchCord4(envelope2, 0, filter1, 1);
    AudioConnection          patchCord5(filter1, 0, amp1, 0);
    AudioConnection          patchCord6(amp1, 0, i2s1, 0);
    AudioConnection          patchCord7(amp1, 0, i2s1, 1);
    // GUItool: end automatically generated code
    
    //Global Variables
    const float noteFreqs[128] = {8.176, 8.662, 9.177, 9.723, 10.301, 10.913, 11.562, 12.25, 12.978, 13.75, 14.568, 15.434, 16.352, 17.324, 18.354, 19.445, 20.602, 21.827, 23.125, 24.5, 25.957, 27.5, 29.135, 30.868, 32.703, 34.648, 36.708, 38.891, 41.203, 43.654, 46.249, 48.999, 51.913, 55, 58.27, 61.735, 65.406, 69.296, 73.416, 77.782, 82.407, 87.307, 92.499, 97.999, 103.826, 110, 116.541, 123.471, 130.813, 138.591, 146.832, 155.563, 164.814, 174.614, 184.997, 195.998, 207.652, 220, 233.082, 246.942, 261.626, 277.183, 293.665, 311.127, 329.628, 349.228, 369.994, 391.995, 415.305, 440, 466.164, 493.883, 523.251, 554.365, 587.33, 622.254, 659.255, 698.456, 739.989, 783.991, 830.609, 880, 932.328, 987.767, 1046.502, 1108.731, 1174.659, 1244.508, 1318.51, 1396.913, 1479.978, 1567.982, 1661.219, 1760, 1864.655, 1975.533, 2093.005, 2217.461, 2349.318, 2489.016, 2637.02, 2793.826, 2959.955, 3135.963, 3322.438, 3520, 3729.31, 3951.066, 4186.009, 4434.922, 4698.636, 4978.032, 5274.041, 5587.652, 5919.911, 6271.927, 6644.875, 7040, 7458.62, 7902.133, 8372.018, 8869.844, 9397.273, 9956.063, 10548.08, 11175.3, 11839.82, 12543.85};
    byte globalNote = 0;
    byte globalVelocity = 0;
    long previousMillis = 0;
    bool envelope_state = true;
    int PlayingNote = 60;
    long DisplayRefresh = 0;
    
    void setup() {
      Wire1.begin();
      display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
      Wire1.setClock(400000);
      display.clearDisplay();
      display.display();
      
      AudioMemory(300);
      waveform1.begin(WAVEFORM_SQUARE);
      waveform1.amplitude(0.75);
      waveform1.frequency(440);
      waveform1.phase(0);
    
      envelope1.attack(50);
      envelope1.decay(5);
      envelope1.sustain(1.0);
      envelope1.release(250);
      envelope2.delay(0);
      envelope2.hold(0);
      filter1.octaveControl(7.0);
      filter1.resonance(2.0);
      envelope1.noteOn();
        envelope2.noteOn();
    }
    
    void loop() {
    waveform1.frequency(noteFreqs[PlayingNote]);
    
    unsigned long currentMillis = millis();
     if (currentMillis - DisplayRefresh > 750) {
      DisplayRefresh = currentMillis;
      UserDisplay();
     }
     
    } // end of main loop
    
    void UserDisplay(){
      display.clearDisplay();
     display.setTextColor(WHITE);
     display.setTextSize(1);
     display.setCursor(0,0);
       display.print("Teensy Bass");
       display.setTextSize(2);
       display.setCursor(0,24);
       display.print("Note ");
       display.print(PlayingNote);
       display.display();
    }

  2. #2
    Senior Member fdaniels's Avatar
    Join Date
    Oct 2020
    Location
    Ostwestfalen, Germany
    Posts
    109
    Try using the U8g2lib which is non-blocking. At least here using teensy 3.2 with a SD1306 OLED on I2C Pins 18+19 and a PT8211. Yeah, i know but I like weird performing D/As, at least for this project....

  3. #3
    Senior Member Blackaddr's Avatar
    Join Date
    Mar 2017
    Location
    Canada
    Posts
    317
    I think the T4 I2C does not yet support DMA which means, when you are sending large blocks of pixel data, you are blocking the entire CPU while those bytes are very slowly pumped out using the standard Wire library. Teensy 3.X had I2C DMA, so you could try a Teensy 3.X and see if you have the same problem.

    There is also this thread which looks at async transfers instead of relying on DMA to avoid blocking the processor.
    https://forum.pjrc.com/threads/61681...c-DMA-possible

  4. #4
    Junior Member
    Join Date
    May 2021
    Posts
    2
    Thank you for the reply.

    I tried the code with the U8g2lib as fdaniels suggested, but the same thing happens. The audio cuts out every time the display updates. The issue seams to be with the Wire library like Blackaddr suggested.

    I downloaded and installed the teensy4_i2c library. I managed to get the code to compile after having replaced all the #include "Wire.h" with #include <i2c_driver_wire.h> in all the files that reference the wire library (this is all the adafruit graphics library files, and the teensy audio library codec control files). Unfortunately the end result is the same. The audio cuts out when the display updates.

    Is there anything else I can do to try and get an I2C display to work on a Teensy 4.1 smoothly? Unfortunately I do not have a teensy 3.x to play with.

Posting Permissions

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