I have single device permanently connected on I2C1 and external board with 4 I2C devices which I can easily connect to any I2C bus for testing.
When I modify code below to only run on one of the I2C buses then it scans fine and everything works as expected, but when I enable all 4 instances of TwoWire and start plugging my external board to different I2C buses this happens: I2C1 internal device doesn't work when external board is connected to I2C2 or I2C3, but works when connected to I2C4, but I2C4 only detects one of the 4 devices (which has same address as the one permanently on I2C1). I2C2 and I2C3 work fine either way. With external board disconnected completely I2C1 also shows nothing.
Since I've verified that single instance of TwoWire works fine I'm suspecting it is purely software issue, I've also tried various I2C_VALID_TIMING_NBR and I2C_TIMEOUT_TICK values to no avail.
Here's my code for testing:
Code: Select all
#include <Wire.h>
HardwareSerial S4(PA11, PA12);
TwoWire Wire2(PB11, PB10);
TwoWire Wire3(PC9, PA8);
TwoWire Wire4(PB9, PB8);
void setup() {
S4.begin(9600);
//not needed, but doesn't make difference when used
Wire.setSDA(PB7);
Wire.setSCL(PB6);
Wire.begin();
Wire2.begin();
Wire3.begin();
Wire4.begin();
}
void i2scan(TwoWire *tw, HardwareSerial *sw, int x)
{
byte error, address;
int nDevices;
(*sw).print("Scanning I2C ");
(*sw).print(x);
(*sw).println("...");
nDevices = 0;
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.
(*tw).beginTransmission(address);
error = (*tw).endTransmission();
if (error == 0)
{
(*sw).print("I2C device found at address 0x");
if (address<16)
(*sw).print("0");
(*sw).print(address,HEX);
(*sw).println(" !");
nDevices++;
}
else if (error==4)
{
(*sw).print("Unknown error at address 0x");
if (address<16)
(*sw).print("0");
(*sw).println(address,HEX);
}
}
if (nDevices == 0)
(*sw).println("No I2C devices found\n");
else
(*sw).println("done\n");
delay(1000);
}
void loop() {
i2scan(&Wire, &S4, 1);
i2scan(&Wire2, &S4, 2);
i2scan(&Wire3, &S4, 3);
i2scan(&Wire4, &S4, 4);
}
edit: Here's how it behaves with external board connected on I2C4:
Code: Select all
Scanning I2C 1...
I2C device found at address 0x4A !
done
Scanning I2C 2...
No I2C devices found
Scanning I2C 3...
No I2C devices found
Scanning I2C 4...
I2C device found at address 0x4A !
done
Code: Select all
Scanning I2C 1...
No I2C devices found
Scanning I2C 2...
No I2C devices found
Scanning I2C 3...
I2C device found at address 0x48 !
I2C device found at address 0x49 !
I2C device found at address 0x4A !
I2C device found at address 0x4B !
done
Scanning I2C 4...
No I2C devices found