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

Thread: Arduino <Wire.h> Now supports Wire1, Wire2 & Wire3?

  1. #1

    Arduino <Wire.h> Now supports Wire1, Wire2 & Wire3?

    In another post I described my idea for managing an array of VL53L0X ToF sensors using one of the secondary I2C buses available on T3.x devices.

    However, that meant I had to once again run the gauntlet of the Wire library's lack of Wire1/Wire2/Wire3 support. After struggling unsuccessfully to modify the Adafruit VL53L0X library (Adafruit_VL53L0X.h), and unsuccessfully trying to implement nox771's 'global' solution, I ran across a curious section in the current Wire.h file at (on my Win10 laptop) C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Wire\W ire.h


    Code:
    #elif defined(__arm__) && defined(TEENSYDUINO)
    #include "WireKinetis.h"
    I had never seen any reference to the Teensy world before in this file, so I was curious and opened "WireKinetis.h" to find

    Code:
    // Teensy LC
    #if defined(__MKL26Z64__)
    #define WIRE_IMPLEMENT_WIRE
    //Wire1 consumes precious memory on Teensy LC
    //#define WIRE_IMPLEMENT_WIRE1
    #define WIRE_HAS_STOP_INTERRUPT
    
    // Teensy 3.0
    #elif defined(__MK20DX128__)
    #define WIRE_IMPLEMENT_WIRE
    
    // Teensy 3.1 & 3.2
    #elif defined(__MK20DX256__)
    #define WIRE_IMPLEMENT_WIRE
    #define WIRE_IMPLEMENT_WIRE1
    
    // Teensy 3.5
    #elif defined(__MK64FX512__)
    #define WIRE_IMPLEMENT_WIRE
    #define WIRE_IMPLEMENT_WIRE1
    #define WIRE_IMPLEMENT_WIRE2
    #define WIRE_HAS_START_INTERRUPT
    #define WIRE_HAS_STOP_INTERRUPT
    
    // Teensy 3.6
    #elif defined(__MK66FX1M0__)
    #define WIRE_IMPLEMENT_WIRE
    #define WIRE_IMPLEMENT_WIRE1
    #define WIRE_IMPLEMENT_WIRE2
    //Wire3 is seldom used on Teensy 3.6
    //#define WIRE_IMPLEMENT_WIRE3
    #define WIRE_HAS_START_INTERRUPT
    #define WIRE_HAS_STOP_INTERRUPT
    
    #endif
    And a bit further down...


    Code:
    #ifdef WIRE_IMPLEMENT_WIRE
    extern TwoWire Wire;
    #endif
    #ifdef WIRE_IMPLEMENT_WIRE1
    extern TwoWire Wire1;
    #endif
    #ifdef WIRE_IMPLEMENT_WIRE2
    extern TwoWire Wire2;
    #endif
    #ifdef WIRE_IMPLEMENT_WIRE3
    extern TwoWire Wire3;
    #endif

    Whoa! does this mean I could simply change


    Code:
    class Adafruit_VL53L0X {
    public:
      boolean begin(uint8_t i2c_addr = VL53L0X_I2C_ADDR, boolean debug = false,
                    TwoWire *i2c = &Wire);
    To

    Code:
    class Adafruit_VL53L0X {
    public:
      boolean begin(uint8_t i2c_addr = VL53L0X_I2C_ADDR, boolean debug = false,
                    TwoWire *i2c = &Wire1);
    or

    Code:
    class Adafruit_VL53L0X {
    public:
      boolean begin(uint8_t i2c_addr = VL53L0X_I2C_ADDR, boolean debug = false,
                    TwoWire *i2c = &Wire2);
    And communicate with my VL53L0X using one of the alternate I2C ports?

    Well, I tried this trick, and it seems to work! Here's my VL53L0X demo code:

    Code:
    /*
        Name:       Teensy_Adafruit_Single_VL53L0X_Demo.ino
        Created:	5/21/2020 7:07:44 PM
        Author:     FRANKNEWXPS15\Frank
    */
    
    //#include <i2c_t3.h>
    //#include <T3_I2C_Anything.h>
    
    #include <Wire.h>
    #include "Adafruit_VL53L0X.h"
    
    Adafruit_VL53L0X lox = Adafruit_VL53L0X();
    
    void setup() {
        Serial.begin(115200);
    
        // wait until serial port opens for native USB devices
        while (!Serial) {
            delay(1);
        }
    
        Serial.println("Adafruit VL53L0X test");
        if (!lox.begin()) {
            Serial.println(F("Failed to boot VL53L0X"));
            while (1);
        }
        // power 
        Serial.println(F("VL53L0X API Simple Ranging example\n\n"));
    }
    
    
    void loop() {
        VL53L0X_RangingMeasurementData_t measure;
    
        Serial.print("Reading a measurement... ");
        lox.rangingTest(&measure, false); // pass in 'true' to get debug data printout!
    
        if (measure.RangeStatus != 4) {  // phase failures have incorrect data
            Serial.print("Distance (mm): "); Serial.println(measure.RangeMilliMeter);
        }
        else {
            Serial.println(" out of range ");
        }
    
        delay(100);
    }
    And my modified Adafruit_VL53L0X.h file

    Code:
    /*!
     * @file Adafruit_VL53L0X.h
    
      This is a library for the Adafruit VL53L0X Sensor Breakout
    
      Designed specifically to work with the VL53L0X sensor from Adafruit
      ----> https://www.adafruit.com/products/3317
    
      These sensors use I2C to communicate, 2 pins are required to
      interface
      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.
      BSD license, all text above must be included in any redistribution
     ****************************************************/
    
    #ifndef ADAFRUIT_VL53L0X_H
    #define ADAFRUIT_VL53L0X_H
    
    #if (ARDUINO >= 100)
    #include "Arduino.h"
    #else
    #include "WProgram.h"
    #endif
    
    #include "Wire.h"
    #include "vl53l0x_api.h"
    
    #define VL53L0X_I2C_ADDR 0x29 ///< Default sensor I2C address
    
    /**************************************************************************/
    /*!
        @brief  Class that stores state and functions for interacting with VL53L0X
       time-of-flight sensor chips
    */
    /**************************************************************************/
    class Adafruit_VL53L0X {
    public:
      boolean begin(uint8_t i2c_addr = VL53L0X_I2C_ADDR, boolean debug = false,
                    TwoWire *i2c = &Wire1);
      boolean setAddress(uint8_t newAddr);
    
      /**************************************************************************/
      /*!
          @brief  get a ranging measurement from the device
          @param  pRangingMeasurementData the pointer to the struct the data will be
         stored in
          @param debug Optional debug flag. If true debug information will print via
         Serial.print during execution. Defaults to false.
          @returns True if address was set successfully, False otherwise
      */
      /**************************************************************************/
      VL53L0X_Error
      rangingTest(VL53L0X_RangingMeasurementData_t *pRangingMeasurementData,
                  boolean debug = false) {
        return getSingleRangingMeasurement(pRangingMeasurementData, debug);
      };
    
      VL53L0X_Error getSingleRangingMeasurement(
          VL53L0X_RangingMeasurementData_t *pRangingMeasurementData,
          boolean debug = false);
      void
      printRangeStatus(VL53L0X_RangingMeasurementData_t *pRangingMeasurementData);
    
      VL53L0X_Error Status =
          VL53L0X_ERROR_NONE; ///< indicates whether or not the sensor has
                              ///< encountered an error
    
    private:
      VL53L0X_Dev_t MyDevice;
      VL53L0X_Dev_t *pMyDevice = &MyDevice;
      VL53L0X_DeviceInfo_t DeviceInfo;
    };
    
    #endif

    And some of the output, with the V53L0X physically connected to a Teensy 3.5 on pins 37 & 38 (SCL1,SDA1)

    Code:
    Opening port
    Port open
    Reading a measurement... Distance (mm): 66
    Reading a measurement... Distance (mm): 66
    And it also appears that I can set the 'normal' I2C bus (SCL0, SDA0) to SLAVE mode with the following lines in my main sketch:

    Code:
        Wire.begin(0x66); //init as SLAVE
        Wire.setClock(100000);
        Wire.setSCL(19);
        Wire.setSDA(18);
    Am I missing anything here?

    TIA,

    Frank

  2. #2
    Senior Member vjmuzik's Avatar
    Join Date
    Apr 2017
    Posts
    510
    The only thing you are missing is that you don't have to edit the library to change which Wire object you want to call, just add the additional statements to your sketch begin call.

    Code:
    if (!lox.begin(VL53L0X_I2C_ADDR, false, &Wire1)) {
            Serial.println(F("Failed to boot VL53L0X"));
            while (1);
        }

  3. #3
    vjmuzik,

    Thanks - I tried this and it worked!

Posting Permissions

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