stickbreaker / arduino-esp32

Arduino core for the ESP32
38 stars 23 forks source link

Bus busy error when using 2nd TwoWire instance #31

Closed chinswain closed 6 years ago

chinswain commented 6 years ago

Hardware:

Board: LOLIN32 Core Installation/update date: Main + latest stickbreaker patched i2c files IDE name: Arduino IDE Flash Frequency: 40Mhz Upload Speed: 115200

Description:

Just testing the second i2c on the ESP32 with the i2c changes, seems there's an issue having both active? I've modified the scanner example to scan both, getting a busy bus error. No issues when scanning only one bus in the loop, even when beginning both.

[I][esp32-hal-i2c.c:971] i2cProcQueue(): Bus busy, reinit

Sketch:


#include <Wire.h>

TwoWire Wire1(1);

void scan() {
  Serial.println("\n Scanning I2C Addresses");
  uint8_t cnt = 0;
  for (uint8_t i = 0; i < 0x7F; i++) {
    Wire.beginTransmission(i);
    uint8_t ec = Wire.endTransmission(true); // if device exists on bus, it will aCK
    if (ec == 0) { // Device ACK'd
      if (i < 16)Serial.print('0');
      Serial.print(i, HEX);
      cnt++;
    }
    else Serial.print(".."); // no one answered
    Serial.print(' ');
    if ((i & 0x0f) == 0x0f)Serial.println();
  }
  Serial.print("Scan Completed, ");
  Serial.print(cnt);
  Serial.println(" I2C Devices found.");
}

void scan2() {
  Serial.println("\n Scanning I2C Addresses");
  uint8_t cnt = 0;
  for (uint8_t i = 0; i < 0x7F; i++) {
    Wire1.beginTransmission(i);
    uint8_t ec = Wire1.endTransmission(true); // if device exists on bus, it will aCK
    if (ec == 0) { // Device ACK'd
      if (i < 16)Serial.print('0');
      Serial.print(i, HEX);
      cnt++;
    }
    else Serial.print(".."); // no one answered
    Serial.print(' ');
    if ((i & 0x0f) == 0x0f)Serial.println();
  }
  Serial.print("Scan Completed, ");
  Serial.print(cnt);
  Serial.println(" I2C Devices found.");
}

void setup() {
  Serial.begin(115200);
  Wire.begin();
  Wire1.begin(19, 23);

}

void loop() {
  scan();
  scan2();
  delay(500);
}

Debug Messages:

 Scanning I2C Addresses
00 .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 
.. .. .. .. .. .. .. .. 48 .. .. .. .. .. .. .. 
.. .. .. .. .. .. .. 57 .. .. .. .. .. .. .. .. 
.. .. .. .. .. .. .. .. 68 .. .. .. .. .. .. .. 
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. Scan Completed, 4 I2C Devices found.

 Scanning I2C Addresses
[I][esp32-hal-i2c.c:971] i2cProcQueue(): Bus busy, reinit
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 
20 .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. Scan Completed, 1 I2C Devices found.
stickbreaker commented 6 years ago

@chinswain What value resistors are you using for your pullups? I have not had any problem using both i2c bus's at the same time.

I use about 2.4k

You are showing one bus busy, does happen more often? Does is happen on both bus's?

This code interleaves both bus's

uint8_t present[16][2]; // array to hold presence status bit.

void check(TwoWire * xWire, uint8_t addr, uint8_t bus){
bool found = false;
xWire->beginTransmission(addr);
found = (xWire->endTransmission(true)==0);
uint8_t byteOffset = addr / 8;
uint8_t bitOffset = addr % 8;
if (found) present[byteOffset][bus] = present[byteOffset][bus] | (1<<bitOffset);
else present[byteOffset][bus] = present[byteOffset][bus] & ~(1<<bitOffset);
}

TwoWire Wire1(1);

void setup(){
Wire.begin(); //use default pins
Wire1.begin(19,23);
for( uint8_t addr=0; addr<128, addr++){
  check(&Wire,addr,0);
  check(&Wire1,addr,1);
  }

Serial.println(" devices on Bus 0");
for(uint8_t addr = 0; addr<128), addr++){
  uint8_t byteOffset = addr /8;
  uint8_t bitOffset = addr % 8;
  If(present[byteOffset][0] & (1<<bitOffset)) { // found it
    Serial.printf("%02x ",addr);
    }
  else {
    Serial.print(".. ");
    }
  if((addr & 0xf)==0xF) Serial.println();
  }

Serial.println(" devices on Bus 1");
for(uint8_t addr = 0; addr<128), addr++){
  uint8_t byteOffset = addr /8;
  uint8_t bitOffset = addr % 8;
  If(present[byteOffset][1] & (1<<bitOffset)) { // found it
    Serial.printf("%02x ",addr);
    }
  else {
    Serial.print(".. ");
    }
  if((addr & 0xf)==0xF) Serial.println();
  }
}

Chuck.

chinswain commented 6 years ago

Hi Chuck, finally got myself a scope, one of the slaves was malfunctioning - replaced with identical part and no more time outs.

stickbreaker commented 6 years ago

Yea!