Forum Rule: Always post complete source code & details to reproduce any issue!
Page 1 of 2 1 2 LastLast
Results 1 to 25 of 32

Thread: TEENSY41_NE problem with i2c (wire2)

  1. #1
    Junior Member
    Join Date
    Jan 2023
    Posts
    9

    TEENSY41_NE problem with i2c (wire2)

    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.

  2. #2
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    27,647
    Quote Originally Posted by bguthik View Post
    It would be great if you could confirm the problem.
    Can you give me a small but complete program to copy into Arduino and run here on a TEENSY41_NE to check?

  3. #3
    Junior Member
    Join Date
    Jan 2023
    Posts
    9
    Quote Originally Posted by PaulStoffregen View Post
    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.");           
          } 
        } 
    }

  4. #4
    Senior Member BriComp's Avatar
    Join Date
    Apr 2014
    Location
    Cheltenham, UK
    Posts
    1,134
    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.

  5. #5
    Junior Member
    Join Date
    Jan 2023
    Posts
    9
    Quote Originally Posted by BriComp View Post
    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.

  6. #6
    Senior Member BriComp's Avatar
    Join Date
    Apr 2014
    Location
    Cheltenham, UK
    Posts
    1,134
    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.

  7. #7
    Senior Member
    Join Date
    Nov 2012
    Location
    Boston, MA, USA
    Posts
    1,120
    From https://github.com/Richard-Gemmell/teensy4_i2c

    Not Tested

    I haven't been able to test some features because of hardware and time restrictions. These features should work but don't be surprised if they don't. Please contact me if you encounter any problems.

    - Multi-master configurations
    - Cortex i.MX RT1050
    - Teensy 4.1

  8. #8
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    27,647
    The Wire.h library definitely does support Wire2 on Teensy 4.1 (pins 24 & 25). The old web page needs to be updated.

  9. #9
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    27,647
    I've updated the hardware table on the Wire library page.

    https://www.pjrc.com/teensy/td_libs_Wire.html

  10. #10
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    27,647
    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.

    Click image for larger version. 

Name:	wire2.jpg 
Views:	15 
Size:	93.8 KB 
ID:	30276

    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);
          }
        }
      }
    }

  11. #11
    Senior Member BriComp's Avatar
    Join Date
    Apr 2014
    Location
    Cheltenham, UK
    Posts
    1,134
    Yes, works just fine.

  12. #12
    Senior Member BriComp's Avatar
    Join Date
    Apr 2014
    Location
    Cheltenham, UK
    Posts
    1,134
    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
          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.");    
          }        
        } 
    }

  13. #13
    Junior Member
    Join Date
    Jan 2023
    Posts
    9
    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:
    Click image for larger version. 

Name:	adc_read_nok.jpg 
Views:	12 
Size:	112.3 KB 
ID:	30278

    Console output with TEENSY41:
    Click image for larger version. 

Name:	adc_read_ok.jpg 
Views:	12 
Size:	65.9 KB 
ID:	30277

  14. #14
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    11,408
    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

  15. #15
    Junior Member
    Join Date
    Jan 2023
    Posts
    9
    Quote Originally Posted by KurtE View Post
    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.

  16. #16
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    27,647
    Quote Originally Posted by bguthik View Post
    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.

  17. #17
    Junior Member
    Join Date
    Jan 2023
    Posts
    9
    Quote Originally Posted by PaulStoffregen View Post
    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.
    Click image for larger version. 

Name:	Teensy.JPG 
Views:	10 
Size:	45.8 KB 
ID:	30280

    ADC pull-ups:
    Name:  pullups.JPG
Views: 112
Size:  15.8 KB

    ADC:
    Name:  adc.JPG
Views: 111
Size:  14.6 KB

  18. #18
    Senior Member BriComp's Avatar
    Join Date
    Apr 2014
    Location
    Cheltenham, UK
    Posts
    1,134
    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.

  19. #19
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    27,647
    I looked at Digikey. Says they have 5 of this chip.

    https://www.digikey.com/en/products/...TRMPBF/1931289

    But when I try to buy 1 of those 5, says it's backordered.

  20. #20
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    27,647
    @bguthik - If you send me 1 LTC2453 by postal mail, I can test it here when it arrives.

  21. #21
    Junior Member
    Join Date
    Jan 2023
    Posts
    9
    Quote Originally Posted by PaulStoffregen View Post
    @bguthik - If you send me 1 LTC2453 by postal mail, I can test it here when it arrives.
    Yes, I can mail you one. Where should I mail it to?

    FYI, the part you tried to buy has different packaging than the one we use. Ours is https://www.digikey.com/en/products/...TRMPBF/1767937.

  22. #22
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    27,647
    Oh, that's more complicated. I don't have a SMT breakout adaptor to fit that size.

  23. #23
    Senior Member BriComp's Avatar
    Join Date
    Apr 2014
    Location
    Cheltenham, UK
    Posts
    1,134
    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.

  24. #24
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    27,647
    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.

    Name:  dfn3x2.jpg
Views: 101
Size:  3.3 KB

    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.

  25. #25
    Senior Member BriComp's Avatar
    Join Date
    Apr 2014
    Location
    Cheltenham, UK
    Posts
    1,134
    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!

Posting Permissions

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