Teensy 4.0 i2c scanner

jesusangel

Active member
Hi, I have to move my project from teensy 3.2 to 4.0, I use an i2c device that sometimes is 0x27 address sometimes 0x3F, to use only one firmware I coded with i2c_t3.h library to scan device 0x27 and checking status I know if there is a device at this address, if not I supose is in the other, but in teensy 4.0 Wire.h lilbrary there is no status cmd to do it so I have to fix code the address and compile 2 different firmwares.

Code:
uint8_t target = 0x27;
  Wire.begin(I2C_MASTER, 0x00, I2C_PINS_18_19, I2C_PULLUP_EXT, I2C_RATE_400);
  //Wire.begin();
  Wire.beginTransmission(target);       // slave addr
  Wire.endTransmission();

 

  switch (Wire.status())
  {
    case I2C_WAITING:
      if (DEBUG) {
        Serial.println("Detectada lcd en 0x27");
      }
      lcd.reinit(0x27);
      break;
    case I2C_ADDR_NAK:
      if (DEBUG) {
        Serial.println("Detectada lcd en 0x3F");
      }
      lcd.reinit(0x3F);
      break;
    default:
      break;
  }

There is a way in Wire.h to scan devices like i2c_t3.h so some way check is something has responded after a transmission?

Thank you in advance
 
I could imaging using something like the i2c scanner example in the setup function that probes a device and sees if it responds within a given period of time.

Lets see, the heart of the i2c scanner looks like:

Code:
void loop() {
  byte error, address;
  for (address = 1; address < 127; address++) {
    // The i2c_scanner uses the return value of
    // the Write.endTransmisstion to see if
    // a device did acknowledge to the address.
    Wire.beginTransmission(address);
    error = Wire.endTransmission();

    if (error == 0) {
      Serial.print("Device found at address 0x");
      if (address < 16) {
        Serial.print("0");
      }
      Serial.println(address,HEX);
    } else if (error==4) {
      Serial.print(F("Unknown error at address 0x"));
      if (address < 16) {
        Serial.print("0");
      }
      Serial.println(address,HEX);
    }
  }

  delay(5000);           // wait 5 seconds for next scan
}
 
Thank you for you answer, you are right, seems like i2c_t3.h have a lot of work done but finally the base is the same
Code:
enum i2c_status   {I2C_WAITING,     // stopped states
                   I2C_TIMEOUT,     //  |
                   I2C_ADDR_NAK,    //  |
                   I2C_DATA_NAK,    //  |
                   I2C_ARB_LOST,    //  |
                   I2C_BUF_OVF,     //  |
                   I2C_NOT_ACQ,     //  |
                   I2C_DMA_ERR,     //  V
                   I2C_SENDING,     // active states
                   I2C_SEND_ADDR,   //  |
                   I2C_RECEIVING,   //  |
                   I2C_SLAVE_TX,    //  |
                   I2C_SLAVE_RX};   //  V

wire.endtransmision
Code:
uint8_t TwoWire::endTransmission(uint8_t sendStop)
{
  // transmit buffer (blocking)
  int8_t ret = twi_writeTo(txAddress, txBuffer, txBufferLength, 1, sendStop);
  // reset tx buffer iterator vars
  txBufferIndex = 0;
  txBufferLength = 0;
  // indicate that we are done transmitting
  transmitting = 0;
  return ret;
}

And twi_writeto returns
Code:
/* 
 * Function twi_writeTo
 * Desc     attempts to become twi bus master and write a
 *          series of bytes to a device on the bus
 * Input    address: 7bit i2c device address
 *          data: pointer to byte array
 *          length: number of bytes in array
 *          wait: boolean indicating to wait for write or not
 *          sendStop: boolean indicating whether or not to send a stop at the end
 * Output   0 .. success
 *          1 .. length to long for buffer
 *          2 .. address send, NACK received
 *          3 .. data send, NACK received
 *          4 .. other twi error (lost bus arbitration, bus error, ..)
 */
The same response as status, so or I adapt Wire.h to have the status command or just check a 0 or a 2 as response to the endtransmission function.

My fault not to deep search the libraries.

Thank you
 
Back
Top