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

Thread: Teensy 4.1 I2C to Arduino Portenta

  1. #1
    Junior Member
    Join Date
    Apr 2022
    Posts
    18

    Teensy 4.1 I2C to Arduino Portenta

    Hi, long time reader, first time poster.

    I purchased a Teensy 4.1 with Audio Shield a while ago and it has been perfect. I recently set it up to accept I2C commands from an Arduino Portenta instead of Serial commands however I cannot get it to function as a slave.

    Both the Arduino and the Teensy I2C are 3.3v and I use 4.7K pull ups between the connection.

    I loaded the Master script on the Portenta, and the slave script on the teensy to no effect, the teensy reports via serial console that it is just "Waiting..." (see script) but reversing that, it works with the Teensy as the master and the Portenta as the slave. I am at a bit of a loss, any ideas on what I am doing wrong?

    Master Script
    Code:
    #include <Wire.h>
    
    int led = LED_BUILTIN;
    
    void setup()
    {
      pinMode(led, OUTPUT);
      Wire.begin();
    }
    
    byte x = 0;
    
    void loop()
    {
      digitalWrite(led, HIGH);
      Wire.beginTransmission(0x10);
      Wire.write("x is ");
      Wire.write(x);
      Wire.endTransmission();
      digitalWrite(led, LOW);
    
      Serial.print("x is ");
      Serial.println(x);
    
      x++;
      delay(500);
    }
    Slave Script
    Code:
    #include <Wire.h>
    
    int led = LED_BUILTIN;
    
    void setup()
    {
      pinMode(led, OUTPUT);
      Wire.begin(0x10);
      Wire.onReceive(receiveEvent);
      Serial.begin(9600);
    }
    
    void loop()
    {
      Serial.println("Waiting...");
      delay(1500);
    }
    
    void receiveEvent(int howMany)
    {
      digitalWrite(led, HIGH);
      while(Wire.available() > 1) {
        char c = Wire.read();
        Serial.print(c);
      }
      int x = Wire.read();
      Serial.println(x);
      digitalWrite(led, LOW);
    }
    Any help or thoughts are greatly appreciated

  2. #2
    Junior Member
    Join Date
    Apr 2022
    Posts
    18
    I realised that Teensy 4.1 with Wire library does not work as expected.

    Switched to using the following worked in replacement of the wire library on the slave teensy.

    https://github.com/Richard-Gemmell/teensy4_i2c
    Code:
    #include <i2c_driver.h>
    #include <i2c_driver_wire.h>
    Sourced from the forum:
    https://forum.pjrc.com/threads/57861...ve-on-Teensy-4
    https://forum.pjrc.com/threads/69607...ight=I2C+Slave
    Last edited by Roy86; 04-26-2022 at 01:34 AM.

  3. #3
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    26,387
    Indeed Wire in Teensyduino 1.56 only supports master mode.

    Slave mode support has been added on github. If you install it, know that it also requires a core library update. Soon we'll be starting beta testing for 1.57, but until then no simple installer exists to give all the updated files easily.

  4. #4
    Junior Member
    Join Date
    Apr 2022
    Posts
    18
    Awesome, thanks for the heads up. I'll definitely update to 1.57 when it's ready.

  5. #5
    Junior Member
    Join Date
    Apr 2022
    Posts
    18
    Quote Originally Posted by PaulStoffregen View Post
    Indeed Wire in Teensyduino 1.56 only supports master mode.

    Slave mode support has been added on github. If you install it, know that it also requires a core library update. Soon we'll be starting beta testing for 1.57, but until then no simple installer exists to give all the updated files easily.
    I've added the updated Wire library with the core update. It looks to be working as planned and I have not required the work around library at all This has made using the Audio Library now conflict free without extensive edits.

  6. #6
    Junior Member
    Join Date
    Apr 2022
    Posts
    18
    @PaulSoffregen I2C is running ok however I'm getting a lot of bad character read and transmission. I've isolated and tested with Teensy 4.1 and other boards in identical configuration however while all other boards get good clean read-send messages, the teensy 4.1 has a character error rate over 80% of the time.

    I2C bridge is 3.3V with 50mm cable to breakout board or direct to pin. Tested with Teensy 4.1 (S), Arduino Nano (S), Uno(S), Jetson Nano (S) with the Portenta as the Master. Tests were in isolation, common bridge and chained via Sparkfun Breakout Boards in various combinations.

    Code:
    #include <Wire.h>
    
    String sendCache = "QE14,0,0,1";
    
    void setup() {
        Wire.onReceive(onI2Creceieve);
        Wire.onRequest(onI2Crequest);
        Wire.setClock(1000000);
        Wire.begin(0x18);
    }
    
    void loop() {
      // put your main code here, to run repeatedly:
    
    }
     
    void onI2Creceieve(int howmany){
      Serial.print("Receiving: ");
      while (Wire.available() > 0) 
      {
        char rc = Wire.read();
        Serial.print(rc);
      }
      Serial.println("End");
    }
    
    static void onI2Crequest(){
      Serial.println(("Sending: <" + sendCache + ">").c_str());
      byte sendlen = sendCache.length();
      Wire.write(sendlen);
      Wire.write(("<" + sendCache + ">").c_str());
      sendCache = "";
    }
    Last edited by Roy86; 05-15-2022 at 02:56 AM. Reason: add test script

  7. #7
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    26,387
    Could I talk you into trying with 1.57-beta1?

    https://forum.pjrc.com/threads/70196...no-1-57-Beta-1

    If that doesn't solve the problem (odds are it will be exactly the same) then I'm hoping you can give me more specific info about how to set up a test here with Teensy 4.1 and Arduino Portenta?

    Which program do I run on each? I see 2 programs on msg #1 and 1 on msg #6. Which do I run on Teensy and which runs on Portenta?

    Could you also show me a photo of the wiring, so I connect it the same way you have? If the pullup resistors aren't clearly visible or colors aren't clear in the picture, which resistor values are used? If I dig out that Portenta board and go to the trouble of wiring it up on my workbench, please leave nothing to chance. Let me see exactly how you did it, so I don't waste a lot of time trying the different ways.

    Right now this USB host test is on my workbench. If you check out that thread, you can see how sometimes just getting the test setup correct to reproduce a specific problem takes a lot of time. It wasn't until msg #36 on that thread until I was finally able to reproduce the problem. I know a photo and specif detail takes some effort to write here on this forum, but it really does save a lot of time when it comes to reproducing a problem. Just like that communication between Teensy 4.1 and Raspberry Pi Pico, I do want to look into this I2C issue. Please help me with clear & specific info so I can set it up next on my workbench... after I figure out what's going wrong with the USB enumeration on Pico while slowed down with those Adafruit Python libraries.

  8. #8
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    4,050
    try 2.2k resistors instead of 4.7k for 3.3v i2c

  9. #9
    Junior Member
    Join Date
    Apr 2022
    Posts
    18
    Hi Paul,

    Updated to 1.57 and still no luck.

    Test setup is msg#1 with the Portenta as the "Master" Script above and the teensy with "Slave" Script. i've attached an image of the teensy on the breakout board connecting to the I2C ports on the Portenta with its breakout board.
    What is interesting is if you reverse it and make the Teensy the master and the portenta the slave, the success rate of transmission is much higher.

    Teensy as slave: 1%-5% successful read
    Portenta as slave: >99% successful read

    I do notice that the I2C wires between the teensy 19/18 and the breadboard are very sensitive to possible interference where as using the same wires but on the nano setup I get no issues.
    The Nano setup uses the SparkFun Qwiic shield for 3.3v compatibility which have a 4.7kohm pullup. When chaining them all together, only the teensy observes any issues.

    Below is the shots of the setup, I've tried various pull ups from 4.7k, 2.2K and (in shot) 470

    Click image for larger version. 

Name:	teensyi2c.jpg 
Views:	7 
Size:	148.5 KB 
ID:	28382 Click image for larger version. 

Name:	portentai2c.jpg 
Views:	6 
Size:	181.8 KB 
ID:	28383

  10. #10
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    4,050
    if thats the 4.1, could you try the GND on the other side of the board, not the one next to pin 0

  11. #11
    Junior Member
    Join Date
    Apr 2022
    Posts
    18
    @tonton81 Switched it over and repeated the test but got the same results

    Also I tested directly with Sparkfun I2C shield and same results. Works great as the master, horrible as the slave.

    Click image for larger version. 

Name:	teensyi2cshield.jpg 
Views:	6 
Size:	165.9 KB 
ID:	28384

  12. #12
    Junior Member
    Join Date
    Apr 2022
    Posts
    18
    Update: I think it is safe to say this is a user/hardware issue not a software/firmware issue.

    I replaced the I2C cables and rewired with untwisted cables between the I2C shields and it is communicating strongly now even as part of a longer chain.

    Apologies if I wasted anyones time trying to replicate this. It is all working now.
    Thanks for eveyone's support, especially paul. I'm liking 1.57 alot. Keep up the great work.

  13. #13
    Junior Member
    Join Date
    Apr 2022
    Posts
    18
    @PaulSoffregen it's worth noting that I still get more errors than other boards but it is massively reduced when shielding the wires and removing nearby potential interference.

  14. #14
    Junior Member
    Join Date
    Apr 2022
    Posts
    18
    @PaulSoffregen, I'm stumped as to why this is happening. Board responds to I2C commands when the AudioOutput is PWM or others but not I2S.

    On Teensy 4.1 with Audio Shield
    Code:
    #include <Audio.h>
    #include <Wire.h>
    #include <SPI.h>
    #include <SD.h>
    #include <SerialFlash.h>
    
    // GUItool: begin automatically generated code
    AudioPlaySdWav           playSdWav1;
    //AudioOutputI2S           i2s2;
    AudioOutputPWM           i2s2;           
    AudioConnection          patchCord1(playSdWav1, 0, i2s2, 0);
    AudioControlSGTL5000     sgtl5000_1; 
    // GUItool: end automatically generated code
    
    int delayTimer = 0;
    
    int led = LED_BUILTIN;
    
    void setup()
    {
      Serial.begin(9600);
    
      AudioMemory(24);
      sgtl5000_1.enable();
      sgtl5000_1.volume(0.6);
      
      Wire.begin(0x30);
      Wire.setClock(400000);
      Wire.onReceive(receiveEvent);
      
      pinMode(led, OUTPUT);
    }
    
    void loop()
    {
      if(delayTimer<1)
        Serial.print(".");
        
      delayTimer--;
      
      delay(2000);
    }
    
    void receiveEvent(int howMany)
    {
      if (!Wire.available()) return;
      
      digitalWrite(led, HIGH);
      Serial.print("I2C: ");
    
      int rcIndex = 0;
      char rcArray[31];
      while (Wire.available() > 0)
      {
        rcArray[rcIndex] = (byte) Wire.read();
        rcIndex++;
      };
    
      delayTimer = 10;
    
      Serial.print(rcArray);
      Serial.println(";");
      delay(50);
      digitalWrite(led, LOW);
    }
    Output when using programed with the PWM output, you can see via serial it is receiving the commands however when I switch to I2Soutput, it does not show the I2C but does run the loop. Board is plugged as in the picture above with the addition of the AudioShield.
    Last edited by Roy86; 05-23-2022 at 05:25 AM.

  15. #15
    Junior Member
    Join Date
    Apr 2022
    Posts
    18
    @PaulSoffregen I switched to the Richard-Gemmell I2C and repointed the Audio.h libraries to that instead of Wire and this has restored I2C connectivitiy while using I2S Output

    https://github.com/Richard-Gemmell/teensy4_i2c

  16. #16
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    26,387
    I replied to your message on the 1.57-beta1 thread, and also posting a followup here.

    I added a fix to the Wire library, which turns on the pin's input hysteresis.

    https://github.com/PaulStoffregen/Wi...6e53a27c9c66a8

    I've also been doing more testing, with both libraries. Turns out the SCL pin is sensitive to picking up high frequency noise. With hysteresis and a normal I2C pullup resistor (even as high as 10K) I can't get the problem to happen. But if I use analogWriteFrequency for 12 MHz on pin 23, and then I try communication with a Teensy LC using no external pullup resistors at all, the problem returns. And they are able to communicate using only the internal pullup if I turn off the 12 MHz waveform on pin 23.

    I also found adding a 22pF capacitor from SCL (pin 19) to GND also allows the 2 boards to communicate without any external pullup resistors, with pin 23 pulsing at 12 MHz. While it's probably overkill if you have a normal resistor in the 1K to 4.7K range, adding a 22pF capacitor might also be a good idea if you want highly robust communication.

Posting Permissions

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