TEENSY41_NE problem with i2c (wire2)

bguthik

Member
Hi,
It seems TEENSY41_NE has problem with i2c (wire2). We tried at least two TEENSY41_NE boards and they both show the i2c problem (no messages received from the slave). Exact same code works fine with TEENSY41.
Teensy is used to talk to an external ADC on wire2. We do have 2.2k pull ups on SCL and SDA. We replaced TEENSY41_NE with TEENSY41 on the board and used the same firmware and it works fine.
It would be great if you could confirm the problem. We purchased bunch of TEENSY41_NE and wondering, to replace them, if we have to purchase TEENSY41 separately.
 
Can you give me a small but complete program to copy into Arduino and run here on a TEENSY41_NE to check?

Here it is. I downloaded this exact program in to two different boards one with TEENSY_41 and other with TEENSY41_NE. TEENSY41 prints some ADC reading and does not print the error message. TEENSY41_NE prints only error message.
FYI, the external ADC and the wire2 library information is in there.

Code:
#include <ADC.h>
#include <ADC_util.h>
#include <SPI.h>
#include <Arduino.h>
#include <i2c_driver.h>
#include <i2c_driver_wire.h>

#define LTC2453_ADDR          0b0010100

//************** GPIO *************
//LED
#define LED_PIN       13

//MUX 
#define EN_MUX_V0     32
#define SEL_MUX_V0_0  33
#define SEL_MUX_V0_1  30
#define SEL_MUX_V0_2  29

//I2C
//teensy4i2c library: https://github.com/Richard-Gemmell/teensy4_i2c

uint8_t ledOut = 0; 
uint64_t tickCount;


void setup() {
  
  //****** LED *********
  pinMode(LED_PIN, OUTPUT);
  
  //MUX  
  pinMode(EN_MUX_V0, OUTPUT);
  digitalWrite(EN_MUX_V0, HIGH); 

  pinMode(SEL_MUX_V0_0, OUTPUT);
  pinMode(SEL_MUX_V0_1, OUTPUT);
  pinMode(SEL_MUX_V0_2, OUTPUT);
  
  digitalWrite(SEL_MUX_V0_0, 0);
  digitalWrite(SEL_MUX_V0_1, 0);
  digitalWrite(SEL_MUX_V0_2, 0);

  //********* I2C **********
  Wire2.begin();  

  Wire2.requestFrom(LTC2453_ADDR, 2);   // request 2 bytes from ADC

  //******* Serial *********
  Serial.begin(9600);
   
  tickCount = millis();
}



void loop() {
    
    uint16_t adcRaw;
    
    if((millis() - tickCount) > 1000) {
      
      tickCount = millis();
      // set the LED on/off
      digitalWrite(LED_PIN, (ledOut&0x01));   
      ledOut++;
      
      //Read
      if (Wire2.available() >= 2) {  

        adcRaw = Wire2.read();      // receive high byte 
        adcRaw = adcRaw << 8;       // shift high byte to be high 8 bits
        adcRaw |= Wire2.read();      // receive low byte as lower 8 bits
        
        Serial.println("ADC read = " + String(adcRaw));
        Wire2.requestFrom(LTC2453_ADDR, 2);   // request 2 bytes from ADC
      }
      else {
          Serial.println("Error! i2c read from ADC not available.");           
      } 
    } 
}
 
That is NOT using the wire library supplied by PJRC in Teensyduino.
Could you try with the Wire.h library rather than the i2c_driver.h and i2c_driver_wire.h drivers.
 
That is NOT using the wire library supplied by PJRC in Teensyduino.
Could you try with the Wire.h library rather than the i2c_driver.h and i2c_driver_wire.h drivers.

I think the wire library supplied by PJRC in Teensyduino does not support wire2. At least thats what my understanding is from the table in Hardware requirements section at https://www.pjrc.com/teensy/td_libs_Wire.html. SCL2 and SDA2 were not mentioned.
Anyway, I followed the recommendation in the same page at the top and used library from Richard Gemmell.
 
I think the wire library supplied by PJRC in Teensyduino does not support wire2.
Yes it does.
I just replaced i2c libraries you were using with Wire.h and the rest compiled just fine.
EDIT:
If you are using that external (to PJRC) library then perhaps it is a question for him.
 
The Wire.h library definitely does support Wire2 on Teensy 4.1 (pins 24 & 25). The old web page needs to be updated.
 
To confirm Wire2 really does work on Teensy 4.1, I connected a SSD1306 OLED display to pins 24 & 25 on Teensy 4.1 and ran the Adafruit_SSD1306 library "ssd1306_128x64_i2c" example. I edited the code to "Wire2" and address "0x3C". The exact code I ran is copied below.

Here it is running on my workbench.

wire2.jpg

This particular Teensy 4.1 (and all the others on my workbench) have the ethernet chip. If you're sure the lack of ethernet chip somehow affects Wire2, I could grab a TEENSY41_NE and repeat this test. Or anyone with one of these really common little displays could do it too.

Code:
/**************************************************************************
 This is an example for our Monochrome OLEDs based on SSD1306 drivers

 Pick one up today in the adafruit shop!
 ------> http://www.adafruit.com/category/63_98

 This example is for a 128x64 pixel display using I2C to communicate
 3 pins are required to interface (two I2C and one reset).

 Adafruit invests time and resources providing this open
 source code, please support Adafruit and open-source
 hardware by purchasing products from Adafruit!

 Written by Limor Fried/Ladyada for Adafruit Industries,
 with contributions from the open source community.
 BSD license, check license.txt for more information
 All text above, and the splash screen below must be
 included in any redistribution.
 **************************************************************************/

#include <SPI.h>
#include <Wire.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

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire2, OLED_RESET);

#define NUMFLAKES     10 // Number of snowflakes in the animation example

#define LOGO_HEIGHT   16
#define LOGO_WIDTH    16
static const unsigned char PROGMEM logo_bmp[] =
{ B00000000, B11000000,
  B00000001, B11000000,
  B00000001, B11000000,
  B00000011, B11100000,
  B11110011, B11100000,
  B11111110, B11111000,
  B01111110, B11111111,
  B00110011, B10011111,
  B00011111, B11111100,
  B00001101, B01110000,
  B00011011, B10100000,
  B00111111, B11100000,
  B00111111, B11110000,
  B01111100, B11110000,
  B01110000, B01110000,
  B00000000, B00110000 };

void setup() {
  Serial.begin(9600);

  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }

  // Show initial display buffer contents on the screen --
  // the library initializes this with an Adafruit splash screen.
  display.display();
  delay(2000); // Pause for 2 seconds

  // Clear the buffer
  display.clearDisplay();

  // Draw a single pixel in white
  display.drawPixel(10, 10, SSD1306_WHITE);

  // Show the display buffer on the screen. You MUST call display() after
  // drawing commands to make them visible on screen!
  display.display();
  delay(2000);
  // display.display() is NOT necessary after every single drawing command,
  // unless that's what you want...rather, you can batch up a bunch of
  // drawing operations and then update the screen all at once by calling
  // display.display(). These examples demonstrate both approaches...

  testdrawline();      // Draw many lines

  testdrawrect();      // Draw rectangles (outlines)

  testfillrect();      // Draw rectangles (filled)

  testdrawcircle();    // Draw circles (outlines)

  testfillcircle();    // Draw circles (filled)

  testdrawroundrect(); // Draw rounded rectangles (outlines)

  testfillroundrect(); // Draw rounded rectangles (filled)

  testdrawtriangle();  // Draw triangles (outlines)

  testfilltriangle();  // Draw triangles (filled)

  testdrawchar();      // Draw characters of the default font

  testdrawstyles();    // Draw 'stylized' characters

  testscrolltext();    // Draw scrolling text

  testdrawbitmap();    // Draw a small bitmap image

  // Invert and restore display, pausing in-between
  display.invertDisplay(true);
  delay(1000);
  display.invertDisplay(false);
  delay(1000);

  testanimate(logo_bmp, LOGO_WIDTH, LOGO_HEIGHT); // Animate bitmaps
}

void loop() {
}

void testdrawline() {
  int16_t i;

  display.clearDisplay(); // Clear display buffer

  for(i=0; i<display.width(); i+=4) {
    display.drawLine(0, 0, i, display.height()-1, SSD1306_WHITE);
    display.display(); // Update screen with each newly-drawn line
    delay(1);
  }
  for(i=0; i<display.height(); i+=4) {
    display.drawLine(0, 0, display.width()-1, i, SSD1306_WHITE);
    display.display();
    delay(1);
  }
  delay(250);

  display.clearDisplay();

  for(i=0; i<display.width(); i+=4) {
    display.drawLine(0, display.height()-1, i, 0, SSD1306_WHITE);
    display.display();
    delay(1);
  }
  for(i=display.height()-1; i>=0; i-=4) {
    display.drawLine(0, display.height()-1, display.width()-1, i, SSD1306_WHITE);
    display.display();
    delay(1);
  }
  delay(250);

  display.clearDisplay();

  for(i=display.width()-1; i>=0; i-=4) {
    display.drawLine(display.width()-1, display.height()-1, i, 0, SSD1306_WHITE);
    display.display();
    delay(1);
  }
  for(i=display.height()-1; i>=0; i-=4) {
    display.drawLine(display.width()-1, display.height()-1, 0, i, SSD1306_WHITE);
    display.display();
    delay(1);
  }
  delay(250);

  display.clearDisplay();

  for(i=0; i<display.height(); i+=4) {
    display.drawLine(display.width()-1, 0, 0, i, SSD1306_WHITE);
    display.display();
    delay(1);
  }
  for(i=0; i<display.width(); i+=4) {
    display.drawLine(display.width()-1, 0, i, display.height()-1, SSD1306_WHITE);
    display.display();
    delay(1);
  }

  delay(2000); // Pause for 2 seconds
}

void testdrawrect(void) {
  display.clearDisplay();

  for(int16_t i=0; i<display.height()/2; i+=2) {
    display.drawRect(i, i, display.width()-2*i, display.height()-2*i, SSD1306_WHITE);
    display.display(); // Update screen with each newly-drawn rectangle
    delay(1);
  }

  delay(2000);
}

void testfillrect(void) {
  display.clearDisplay();

  for(int16_t i=0; i<display.height()/2; i+=3) {
    // The INVERSE color is used so rectangles alternate white/black
    display.fillRect(i, i, display.width()-i*2, display.height()-i*2, SSD1306_INVERSE);
    display.display(); // Update screen with each newly-drawn rectangle
    delay(1);
  }

  delay(2000);
}

void testdrawcircle(void) {
  display.clearDisplay();

  for(int16_t i=0; i<max(display.width(),display.height())/2; i+=2) {
    display.drawCircle(display.width()/2, display.height()/2, i, SSD1306_WHITE);
    display.display();
    delay(1);
  }

  delay(2000);
}

void testfillcircle(void) {
  display.clearDisplay();

  for(int16_t i=max(display.width(),display.height())/2; i>0; i-=3) {
    // The INVERSE color is used so circles alternate white/black
    display.fillCircle(display.width() / 2, display.height() / 2, i, SSD1306_INVERSE);
    display.display(); // Update screen with each newly-drawn circle
    delay(1);
  }

  delay(2000);
}

void testdrawroundrect(void) {
  display.clearDisplay();

  for(int16_t i=0; i<display.height()/2-2; i+=2) {
    display.drawRoundRect(i, i, display.width()-2*i, display.height()-2*i,
      display.height()/4, SSD1306_WHITE);
    display.display();
    delay(1);
  }

  delay(2000);
}

void testfillroundrect(void) {
  display.clearDisplay();

  for(int16_t i=0; i<display.height()/2-2; i+=2) {
    // The INVERSE color is used so round-rects alternate white/black
    display.fillRoundRect(i, i, display.width()-2*i, display.height()-2*i,
      display.height()/4, SSD1306_INVERSE);
    display.display();
    delay(1);
  }

  delay(2000);
}

void testdrawtriangle(void) {
  display.clearDisplay();

  for(int16_t i=0; i<max(display.width(),display.height())/2; i+=5) {
    display.drawTriangle(
      display.width()/2  , display.height()/2-i,
      display.width()/2-i, display.height()/2+i,
      display.width()/2+i, display.height()/2+i, SSD1306_WHITE);
    display.display();
    delay(1);
  }

  delay(2000);
}

void testfilltriangle(void) {
  display.clearDisplay();

  for(int16_t i=max(display.width(),display.height())/2; i>0; i-=5) {
    // The INVERSE color is used so triangles alternate white/black
    display.fillTriangle(
      display.width()/2  , display.height()/2-i,
      display.width()/2-i, display.height()/2+i,
      display.width()/2+i, display.height()/2+i, SSD1306_INVERSE);
    display.display();
    delay(1);
  }

  delay(2000);
}

void testdrawchar(void) {
  display.clearDisplay();

  display.setTextSize(1);      // Normal 1:1 pixel scale
  display.setTextColor(SSD1306_WHITE); // Draw white text
  display.setCursor(0, 0);     // Start at top-left corner
  display.cp437(true);         // Use full 256 char 'Code Page 437' font

  // Not all the characters will fit on the display. This is normal.
  // Library will draw what it can and the rest will be clipped.
  for(int16_t i=0; i<256; i++) {
    if(i == '\n') display.write(' ');
    else          display.write(i);
  }

  display.display();
  delay(2000);
}

void testdrawstyles(void) {
  display.clearDisplay();

  display.setTextSize(1);             // Normal 1:1 pixel scale
  display.setTextColor(SSD1306_WHITE);        // Draw white text
  display.setCursor(0,0);             // Start at top-left corner
  display.println(F("Hello, world!"));

  display.setTextColor(SSD1306_BLACK, SSD1306_WHITE); // Draw 'inverse' text
  display.println(3.141592);

  display.setTextSize(2);             // Draw 2X-scale text
  display.setTextColor(SSD1306_WHITE);
  display.print(F("0x")); display.println(0xDEADBEEF, HEX);

  display.display();
  delay(2000);
}

void testscrolltext(void) {
  display.clearDisplay();

  display.setTextSize(2); // Draw 2X-scale text
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(10, 0);
  display.println(F("scroll"));
  display.display();      // Show initial text
  delay(100);

  // Scroll in various directions, pausing in-between:
  display.startscrollright(0x00, 0x0F);
  delay(2000);
  display.stopscroll();
  delay(1000);
  display.startscrollleft(0x00, 0x0F);
  delay(2000);
  display.stopscroll();
  delay(1000);
  display.startscrolldiagright(0x00, 0x07);
  delay(2000);
  display.startscrolldiagleft(0x00, 0x07);
  delay(2000);
  display.stopscroll();
  delay(1000);
}

void testdrawbitmap(void) {
  display.clearDisplay();

  display.drawBitmap(
    (display.width()  - LOGO_WIDTH ) / 2,
    (display.height() - LOGO_HEIGHT) / 2,
    logo_bmp, LOGO_WIDTH, LOGO_HEIGHT, 1);
  display.display();
  delay(1000);
}

#define XPOS   0 // Indexes into the 'icons' array in function below
#define YPOS   1
#define DELTAY 2

void testanimate(const uint8_t *bitmap, uint8_t w, uint8_t h) {
  int8_t f, icons[NUMFLAKES][3];

  // Initialize 'snowflake' positions
  for(f=0; f< NUMFLAKES; f++) {
    icons[f][XPOS]   = random(1 - LOGO_WIDTH, display.width());
    icons[f][YPOS]   = -LOGO_HEIGHT;
    icons[f][DELTAY] = random(1, 6);
    Serial.print(F("x: "));
    Serial.print(icons[f][XPOS], DEC);
    Serial.print(F(" y: "));
    Serial.print(icons[f][YPOS], DEC);
    Serial.print(F(" dy: "));
    Serial.println(icons[f][DELTAY], DEC);
  }

  for(;;) { // Loop forever...
    display.clearDisplay(); // Clear the display buffer

    // Draw each snowflake:
    for(f=0; f< NUMFLAKES; f++) {
      display.drawBitmap(icons[f][XPOS], icons[f][YPOS], bitmap, w, h, SSD1306_WHITE);
    }

    display.display(); // Show the display buffer on the screen
    delay(200);        // Pause for 1/10 second

    // Then update coordinates of each flake...
    for(f=0; f< NUMFLAKES; f++) {
      icons[f][YPOS] += icons[f][DELTAY];
      // If snowflake is off the bottom of the screen...
      if (icons[f][YPOS] >= display.height()) {
        // Reinitialize to a random position, just off the top
        icons[f][XPOS]   = random(1 - LOGO_WIDTH, display.width());
        icons[f][YPOS]   = -LOGO_HEIGHT;
        icons[f][DELTAY] = random(1, 6);
      }
    }
  }
}
 
Of course the test just carried out is all about writing to the Wire2 i2c.
I have just run a test involving reading from a MCP9808 temperature sensor and that works fine on Teensy41_NE on Wire2.

Of course where @bguthik's code fails is with if (Wire2.available() >= 2) { which I have not been able to test.
Anyone with something that can use that instruction.
Of course @bguthik could come back and tell us if the code works fine with the standard library or not.
Code:
#include <ADC.h>
#include <ADC_util.h>
#include <SPI.h>
#include <Arduino.h>
#include <i2c_driver.h>
#include <i2c_driver_wire.h>

#define LTC2453_ADDR          0b0010100

//************** GPIO *************
//LED
#define LED_PIN       13

//MUX 
#define EN_MUX_V0     32
#define SEL_MUX_V0_0  33
#define SEL_MUX_V0_1  30
#define SEL_MUX_V0_2  29

//I2C
//teensy4i2c library: https://github.com/Richard-Gemmell/teensy4_i2c

uint8_t ledOut = 0; 
uint64_t tickCount;


void setup() {
  
  //****** LED *********
  pinMode(LED_PIN, OUTPUT);
  
  //MUX  
  pinMode(EN_MUX_V0, OUTPUT);
  digitalWrite(EN_MUX_V0, HIGH); 

  pinMode(SEL_MUX_V0_0, OUTPUT);
  pinMode(SEL_MUX_V0_1, OUTPUT);
  pinMode(SEL_MUX_V0_2, OUTPUT);
  
  digitalWrite(SEL_MUX_V0_0, 0);
  digitalWrite(SEL_MUX_V0_1, 0);
  digitalWrite(SEL_MUX_V0_2, 0);

  //********* I2C **********
  Wire2.begin();  

  Wire2.requestFrom(LTC2453_ADDR, 2);   // request 2 bytes from ADC

  //******* Serial *********
  Serial.begin(9600);
   
  tickCount = millis();
}



void loop() {
    
    uint16_t adcRaw;
    
    if((millis() - tickCount) > 1000) {
      
      tickCount = millis();
      // set the LED on/off
      digitalWrite(LED_PIN, (ledOut&0x01));   
      ledOut++;
      
      //Read
 [COLOR="#FF0000"]     if (Wire2.available() >= 2) {  
[/COLOR]
        adcRaw = Wire2.read();      // receive high byte 
        adcRaw = adcRaw << 8;       // shift high byte to be high 8 bits
        adcRaw |= Wire2.read();      // receive low byte as lower 8 bits
        
        Serial.println("ADC read = " + String(adcRaw));
        Wire2.requestFrom(LTC2453_ADDR, 2);   // request 2 bytes from ADC
      [COLOR="#FF0000"]}
      else {
          Serial.println("Error! i2c read from ADC not available.");    
      } [/COLOR]       
    } 
}
 
I just tested with standard i2c library and its the same problem. TEENSY41_NE does not work and TEENSY41 works fine with same code.
Here is the code. I made change to look for any byte available from Wire2 instead of exact two bytes to see if any/some data is coming on Wire2.
Code:
#include <Arduino.h>
#include <Wire.h>

#define LTC2453_ADDR          0b0010100

//************** GPIO *************
//LED
#define LED_PIN       13

//MUX 
#define EN_MUX_V0     32
#define SEL_MUX_V0_0  33
#define SEL_MUX_V0_1  30
#define SEL_MUX_V0_2  29

uint8_t ledOut = 0; 
uint64_t tickCount;


void setup() {
  
  //****** LED *********
  pinMode(LED_PIN, OUTPUT);
  
  //MUX   
  pinMode(EN_MUX_V0, OUTPUT);
  digitalWrite(EN_MUX_V0, HIGH); 

  pinMode(SEL_MUX_V0_0, OUTPUT);
  pinMode(SEL_MUX_V0_1, OUTPUT);
  pinMode(SEL_MUX_V0_2, OUTPUT);
  
  digitalWrite(SEL_MUX_V0_0, 0);
  digitalWrite(SEL_MUX_V0_1, 0);
  digitalWrite(SEL_MUX_V0_2, 0);

  //********* I2C **********
  Wire2.begin();  

  Wire2.requestFrom(LTC2453_ADDR, 2);   // request 2 bytes from ADC

  //******* Serial *********
  Serial.begin(9600);
   
  tickCount = millis();
}



void loop() {
    
    uint16_t adcRaw;
    
    if((millis() - tickCount) > 1000) {
      
      tickCount = millis();
      // set the LED on/off
      digitalWrite(LED_PIN, (ledOut&0x01));   
      ledOut++;
      
      //Read
      if (Wire2.available()) {  

        adcRaw = Wire2.read();      // receive high byte 
        adcRaw = adcRaw << 8;       // shift high byte to be high 8 bits
        adcRaw |= Wire2.read();      // receive low byte as lower 8 bits
        
        Serial.println("ADC read = " + String(adcRaw));
        Wire2.requestFrom(LTC2453_ADDR, 2);   // request 2 bytes from ADC
      }
      else {
          Serial.println("Error! i2c read from ADC not available.");           
      } 
    } 
}


Console output with TEENSY41_NE:
adc_read_nok.jpg

Console output with TEENSY41:
adc_read_ok.jpg
 
Sorry, throwing darts...

How are these Teensy boards being powered? Is it through USB? Or through VIN? If VIN, what is the voltage?

Just wondering if it could be differences in which VR or the like...

Again just a dart
 
Sorry, throwing darts...

How are these Teensy boards being powered? Is it through USB? Or through VIN? If VIN, what is the voltage?

Just wondering if it could be differences in which VR or the like...

Again just a dart

Through USB.
 
TEENSY41_NE does not work and TEENSY41 works fine with same code.

Very mysterious. They exactly the same hardware even made in the same production batches, except the ethernet chip is not placed on the _NE boards.

Can you show us the hardware you're using for testing? Is it 2 separate circuit boards? Could this problem be as simple as 1 build has a flaw in wiring?

If this really is a bug in need of deeper investigation, seeing the way you've built the hardware could really help in trying to recreate the problem.
 
Very mysterious. They exactly the same hardware even made in the same production batches, except the ethernet chip is not placed on the _NE boards.

Can you show us the hardware you're using for testing? Is it 2 separate circuit boards? Could this problem be as simple as 1 build has a flaw in wiring?

If this really is a bug in need of deeper investigation, seeing the way you've built the hardware could really help in trying to recreate the problem.

Our first board, Board #1 has TEENSY41 and it worked fine with no problem. We finished our development and built Board #2 with TEENSY41_NE. We faced this problem with Board #2. We then replaced TEENSY41_NE with TEENSY41 on Board #2 and it worked fine with no problem (and with same program before and after replacing Teensy). We also built Board #3 with TEENSY41_NE and it has the same problem. We haven't replaced Teensy on Board #3 because we don't have TEENSY41 on hand.

SCL and SDA from micro. Please ignore the pinout number shown. Our layout engineer used his own numbering. But, they are SCL2 and SDA2.
Teensy.JPG

ADC pull-ups:
pullups.JPG

ADC:
adc.JPG
 
Code:
int16_t Simple_MCP9808::_i2cRead16(uint8_t reg) {
  Wire2.beginTransmission(_i2cAddr);
  Wire2.write(reg);
  Wire2.endTransmission();

  // conversion time depend on resolution
  int ms[4]={30, 65, 130, 250};
  delay(ms[_resolution]);

  int16_t data = 0;
  Wire2.requestFrom(_i2cAddr, (uint8_t) 0x02);
  if(Wire2.available() == 2) {
    data = (Wire2.read() << 8);
    data |= Wire2.read();
  }

  return data;
}
Just used code that includes Wire2.available() ==2{ (as shown in snippet above) and it works just fine on TEENSY41_NE.
 
You could just stick it down on it's back, like LIDs of old (Leadless Inverted Devices) and solder jump leads down to breakout board.
 
Yeah, could solder wires, but really not excited to work with #36 enameled wire needed to make this work at 0.5mm pitch. I've done that a few time when really necessary and urgent, and every time it's been very unpleasant and taken a lot of time.

But creating a breakout PCB is quick and easy. Sent files in to OSH Park. If this is still unresolved in another week or two when this tiny PCB arrives, maybe I'll get the chip and give this a try.

dfn3x2.jpg

Before then, I'm really hoping @bguthik can do a little more work on this. Maybe solder a socket, so it's easy to plug in either TEENSY41 or TEENSY41_NE to the same PCB.

It's still very difficult to imagine how having versus not having the ethernet chip (sitting unused) on Teensy 4.1 could possibly impact use of Wire2. But if further testing shows we really do have a weird problem, I'll get that chip by mail and run it with the test code... just like I did with the OLED display in msg #10.
 
It's still very difficult to imagine how having versus not having the ethernet chip (sitting unused) on Teensy 4.1 could possibly impact use of Wire2.
Not that I can put any theory on it, but I keep being drawn to a different current draw, without the chip, affecting those capacitors on the I2C lines.
But then again I might be completely wrong.
An interesting (not from your point of view) conundrum!
 
Back
Top