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

Thread: Teensy 4.0 I2C Slave issue.

  1. #1
    Junior Member
    Join Date
    May 2020
    Posts
    5

    Teensy 4.0 I2C Slave issue.

    Hello there,

    I'm currently working on a project in which i am trying to include a visualizer, for which i am using the Teensy 4.0 to run FFT on my audio signal,
    which gets read through the Audio Adapter Shield (Rev D), and should then transfer the FFT values over to my main controller / display.

    However i've run into a bit of an issue, as it seems the Teensy is refusing to communicate with the main controller over I2C,
    and I'm unsure if the problem is a hardware or software issue, the I2C lines are pulled up to 3.3V with 4.7Kohm, and the grounds are connected,
    but the Teensy doesn't get found by the I2C scanner application loaded onto the main controller.

    I found a thread from back in june (2019) about the Wire.h library not supporting slave functionality for the Teensy, is this still the case?
    Or do i have some other problem i just haven't discovered yet?

    Any and all help is very appreciated.
    Thanks.


    Source Code:
    Code:
    #include <Audio.h>
    #include <Wire.h>
    #include <SPI.h>
    #include <SD.h>
    #include <SerialFlash.h>
    
    // GUItool: begin automatically generated code
    AudioInputI2S            i2s;           //xy=347,467
    AudioMixer4              mixer;         //xy=491,480
    AudioAnalyzeFFT1024      fft1024;      //xy=669,479
    AudioConnection          patchCord1(i2s, 0, mixer, 0);
    AudioConnection          patchCord2(i2s, 1, mixer, 1);
    AudioConnection          patchCord3(mixer, fft1024);
    AudioControlSGTL5000     audioShield;    //xy=366,225
    // GUItool: end automatically generated code
    
    
    //Needed FFT Bands are 1, 2, 3, 6, 12, 24, 47, 94, 187, 373.
    //These represent the 10 bands i am attempting to read, which are
    //32Hz, 64Hz, 125Hz, 250Hz, 500Hz, 1KHz, 2KHz, 4KHz, 8KHz & 16KHz.
    //although they're slightly off because the FFT has a resolution of 43Hz, however it should be close enough to give
    //usable data, if not i will have to modify the components the equalizer is comprised of.
    
    const int addr = 16; //I2C communication address, device will work as slave.
    
    const int myInput = AUDIO_INPUT_LINEIN; //Defines Audio Input pins for FFT function.
    
    float levelF[10]; //array to hold the frequency band levels
    int   levelI[10];
    
    
    void setup() {
      AudioMemory(12); //Audio library requires memory to function properly.
    
      //Enable the Audio Shield (SGTL5000) and select input
      audioShield.enable();
      audioShield.inputSelect(myInput);
      //Mute Outputs, as we aren't using those.
      audioShield.muteHeadphone();
      audioShield.muteLineout();
    
      //configure mixer to equally add left & right channels.
      mixer.gain(0, 0.5);
      mixer.gain(1, 0.5);
    
      while(!Serial && millis() < 1000){} //wait for a Serial connection to start, timeout after 1000ms
      Serial.println("Serial Start");
      
      //Begin I2C
      Wire1.begin(addr);
      Wire1.onRequest(SendFFT);
    
    }
    
    void loop() {
      if(fft1024.available()){
        //The FFT library works linearly, but music works in octaves
        //because of that, we read multiple bins for the higher frequencies, 
        //so we don't throw away useful data.
    
        //NOTE TO SELF: Bins should be in order now. 24/03 kl.4:10 ... du skal virkelig have fikset hvornår du sover...
        levelF[0] =  fft1024.read(0);
        levelF[1] =  fft1024.read(1);
        levelF[2] =  fft1024.read(2, 4);
        levelF[3] =  fft1024.read(5, 8);
        levelF[4] =  fft1024.read(9, 17);
        levelF[5] =  fft1024.read(18, 35);
        levelF[6] =  fft1024.read(36, 72);
        levelF[7] =  fft1024.read(73, 140);
        levelF[8] =  fft1024.read(141, 280);
        levelF[9] =  fft1024.read(281, 511);
    
        for(int i = 0; i > 9; i++){
          levelF[i] = levelF[i] + 0.5;
          levelI[i] = (int) levelF[i];    
        }
      }
      //Serielt Output for at tjekke FFT værdier
      for(int j = 0; j > 9; j++){
        Serial.print("Band ");
        Serial.print(j);
        Serial.print(": ");
        Serial.println(levelF[j]);
      }
    }
    
    //When the I2C Master (the Touch Display) requests updated values, send them over.
    void SendFFT() {
      Serial.println("I2C Requested");
      for(int i = 0; i > 9; i++){
          Wire1.write(levelI[i]);
      } 
      Serial.println("I2C Sent"); 
    }

  2. #2
    Junior Member
    Join Date
    Sep 2019
    Posts
    13
    Hi weirdwolf,

    Wire.h lib for Teensy 4.0 does not support slave mode up to now. Instead of Wire.h you can use Richard Gemmells teensy4_i2c lib (github: https://github.com/Richard-Gemmell/teensy4_i2c).
    I had a small problem with that as well but for me it could be fixed. Have a look at post # 32 at this thread https://forum.pjrc.com/threads/57861...I2C+slave+mode

    Regards,
    Helmut

  3. #3
    Junior Member
    Join Date
    May 2020
    Posts
    5
    Thank you for the response, I'll look into that and see if i can make it work.

    Edit: I got a little further, but hit another snag.

    So I've changed the dependencies in the main sketch and the audio library dependencies over to "I2C_driver_wire.h" from the standard wire library, and I'm getting a weird error, which seems to say Wire.write() has been defined in two places and doesn't know which one to use, at least as far as i can tell.

    Do you have any ideas on how to get around / fix this, or should i head over to github and post an issue about it there instead?

    I'll continue looking through it and see if i can't figure it out myself, but I'm not the most experienced in troubleshooting libraries, so I'm in deep waters here.

    Error Message looks like so:
    Code:
    Arduino: 1.8.11 (Windows 10), TD: 1.50, Board: "Teensy 4.0, Serial, 600 MHz, Faster, US English"
    
    C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio\control_tlv320aic3206.cpp: In member function 'bool AudioControlTLV320AIC3206::aic_goToPage(byte)':
    
    C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio\control_tlv320aic3206.cpp:561:18: error: call of overloaded 'write(int)' is ambiguous
    
       Wire.write(0x00); delay(10);// page register  //was delay(10) from BPF
    
                      ^
    
    In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio\control_tlv320aic3206.cpp:11:0:
    
    C:\Users\Weirdwolf\Documents\Arduino\libraries\teensy4_i2c\src/i2c_driver_wire.h:52:12: note: candidate: virtual size_t I2CDriverWire::write(uint8_t)
    
         size_t write(uint8_t data) override;
    
                ^
    
    In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/Stream.h:24:0,
    
                     from C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/HardwareSerial.h:106,
    
                     from C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/WProgram.h:46,
    
                     from C:\Users\WEIRDW~1\AppData\Local\Temp\arduino_build_875490/pch/Arduino.h:6,
    
                     from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio\control_tlv320aic3206.h:58,
    
                     from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio\control_tlv320aic3206.cpp:10:
    
    C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/Print.h:59:9: note: candidate: size_t Print::write(const char*)
    
      size_t write(const char *str)   { return write((const uint8_t *)str, strlen(str)); }
    
             ^
    Last edited by weirdwolf; 05-14-2020 at 04:19 PM. Reason: To avoid double-posting too soon.

  4. #4
    Junior Member
    Join Date
    Sep 2019
    Posts
    13
    Hi weirdwolf,

    sorry I should have had a closer look to your code. You are using the audio lib and right you have to change all the includes of Wire.h to I2C_driver_wire.h. But nevertheless I had nearly the same problem with control_tlv320aic3206.cpp. The easiest for me was to skip control_tlv320aic3206.cpp because I don' t need it (rename it, so that it is not compiled).

    Regards,
    Helmut

  5. #5
    Junior Member
    Join Date
    May 2020
    Posts
    5
    Thanks a ton for that fix!
    code is now compiling and running, although i can't seem to properly read the data sent, but that could be an issue on my master, so i'll have to test that out next.

    Many thanks,
    Weirdwolf

  6. #6
    Junior Member
    Join Date
    May 2020
    Posts
    5
    Thought i'd add a quick update just to close this out.

    The error i got while compiling, after having switched to Richard Gemmels I2C Library has been fixed, and there should be no need to remove/rename 'control_tlv320aic3206.cpp' from the audio library folder anymore.

    And i couldn't read the data i was sending because i wasn't sending any data, had reversed a '<' symbol in a for loop, so the loop was never running, Hah.

    But none the less, Thanks for the help, hbit!

    Cheers,
    Weirdwolf.

  7. #7
    Ok as of now: No wire.h support for T4. Is that on anyone's roadmap to complete?

Tags for this Thread

Posting Permissions

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