This is my first time posting on this forum, so I hope my question is appropriate here. My team is working with the Adafruit TCA9548A 1-to-8 I2C Multiplexer Breakout board to try and read from six HMC5883L Breakout sensors, and I am in the process of trying to look at their code to solve a problem. For some reason, code does not run at all unless you comment out a certain line in the code. Once it is commented out, the code runs as expected.
Now, we have to initialize it in setup(), but the statement tcaselect(0) statement was commented out so it doesn't initialize the 0th sensor in setup(). We can keep the other part, the if(mag0.begin()) statement, and it works as expected. However, if we uncomment out tcaselect(0) in setup, the entire code crashes, and all we see are 'HM' in the display window. A very basic schematic is shown below:
simulate this circuit – Schematic created using CircuitLab
I ran some tests with my team, and when all six HMC5883Ls and the single TCA9548 multiplexer were connected on the same breadboard according to the schematic, they worked when tcaselect(0) in setup() was not commented out. Next, we had an apparatus to hold the six sensors, and we had it connected with long lengths of wire, the same as the schematic. We hooked it up to the same breadboard, and the code would not run unless tcaselect(0) in setup was commented out. This seems strange to me that they would work when connected on the breadboard, but when spread out and connected to the breadboard via long wires, they would not work unless that code was commented out.
https://learn.adafruit.com/adafruit-tca9548a-1-to-8-i2c-multiplexer-breakout?view=all
EDIT: Someone mentioned that wires might have problems with the SDA/SCL bus, so the wires that we're using are 4-pin ribbon cables, 2.54 mm pitch. A very rough schematic of the container that we're using is shown below:
Sorry for the roughness. It's the best I can do to show how the container is assembled. There's an 8x8 in. box where the components are stored, so the sensors go from various locations in the apparatus to the center box where the Pi, Arduino, and breadboard are placed. The nodes in the schematic represent the locations of the sensors. Given the rough dimensions, the longest distance for one of the sensors is around 56.8 inches (or approx. 1.45 meters) accounting for some extra wiring.
Code:
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_HMC5883_U.h>
#define TCAADDR 0x70
/* Assign a unique ID to this sensor at the same time */
Adafruit_HMC5883_Unified mag0 = Adafruit_HMC5883_Unified(0);
Adafruit_HMC5883_Unified mag1 = Adafruit_HMC5883_Unified(1);
Adafruit_HMC5883_Unified mag2 = Adafruit_HMC5883_Unified(2);
Adafruit_HMC5883_Unified mag3 = Adafruit_HMC5883_Unified(3);
Adafruit_HMC5883_Unified mag4 = Adafruit_HMC5883_Unified(4);
Adafruit_HMC5883_Unified mag5 = Adafruit_HMC5883_Unified(5);
//Display details of sensor here
void displaySensorDetails(Adafruit_HMC5883_Unified *mag){
sensor_t sensor;
mag->getSensor(&sensor);
Serial.println("------------------------------------");
Serial.print ("Sensor: "); Serial.println(sensor.name);
Serial.print ("Driver Ver: "); Serial.println(sensor.version);
Serial.print ("Unique ID: "); Serial.println(sensor.sensor_id);
Serial.print ("Max Value: "); Serial.print(sensor.max_value); Serial.println(" uT");
Serial.print ("Min Value: "); Serial.print(sensor.min_value); Serial.println(" uT");
Serial.print ("Resolution: "); Serial.print(sensor.resolution); Serial.println(" uT");
Serial.println("------------------------------------");
Serial.println("");
delay(500);
}
//Given sensor i, select and write to it
void tcaselect(uint8_t i) {
if (i > 7) return;
Wire.beginTransmission(TCAADDR);
Wire.write(1 << i);
Wire.endTransmission();
}
void setup() {
Serial.begin(9600);
/* Initialise the 0st sensor */
//tcaselect(0);
if(!mag0.begin()) {
/* There was a problem detecting the HMC5883 ... check your connections */
Serial.println("Ooops, no HMC5883 detected ... Check your wiring!");
}
/* Initialise Sensors 1-6 */
tcaselect(1); if(!mag1.begin()) { Serial.println("Ooops, no HMC5883 detected ... Check your wiring!"); }
tcaselect(2); if(!mag2.begin()) { Serial.println("Ooops, no HMC5883 detected ... Check your wiring!"); }
tcaselect(3); if(!mag3.begin()) { Serial.println("Ooops, no HMC5883 detected ... Check your wiring!"); }
tcaselect(4); if(!mag4.begin()) { Serial.println("Ooops, no HMC5883 detected ... Check your wiring!"); }
tcaselect(5); if(!mag5.begin()) { Serial.println("Ooops, no HMC5883 detected ... Check your wiring!"); }
}
void loop() {
/* Get a new sensor event */
sensors_event_t event0; sensors_event_t event1;
sensors_event_t event2; sensors_event_t event3;
sensors_event_t event4; sensors_event_t event5;
tcaselect(0); mag0.getEvent(&event0); tcaselect(1); mag1.getEvent(&event1);
tcaselect(2); mag2.getEvent(&event2); tcaselect(3); mag3.getEvent(&event3);
tcaselect(4); mag4.getEvent(&event4); tcaselect(5); mag5.getEvent(&event5);
/* Display the results (magnetic vector values are in micro-Tesla (uT)) */
Serial.print(event1.magnetic.x); Serial.print(" ");
Serial.print(event1.magnetic.y); Serial.print(" ");
Serial.print(event1.magnetic.z); Serial.print(" ");
Serial.print(event2.magnetic.x); Serial.print(" ");
Serial.print(event2.magnetic.y); Serial.print(" ");
Serial.print(event2.magnetic.z + 37); Serial.print(" ");
Serial.print(event3.magnetic.x); Serial.print(" ");
Serial.print(event3.magnetic.y); Serial.print(" ");
Serial.print(event3.magnetic.z); Serial.print(" ");
Serial.print(event4.magnetic.x); Serial.print(" ");
Serial.print(event4.magnetic.y); Serial.print(" ");
Serial.print(event4.magnetic.z + 37); Serial.print(" ");
Serial.print(event5.magnetic.x); Serial.print(" ");
Serial.print(event5.magnetic.y); Serial.print(" ");
Serial.print(event5.magnetic.z); Serial.print(" ");
delay(500);
}
EDIT: Big news, I tried using only two sensors and 1.5m cables and adding 10k pullup resistors from VCC to SDL/SCA on the respective sensors; with these changes, they seem to work even with tcaselect(0) not commented out in setup, though I only used two sensors rather than six. The HMC5883L sensor breakout board contains 10k pullup resistors already, so with another 10k resistor per line, it would make it 5k. Would this value be too much, or is it fine? I looked at the datasheet of the sensor itself, but I can't find anything on what value the input impedance would be for SCL/SDA.
Also, on another related note, one of my sensors had wires crossed deliberately, so SCL and SDA are separated by GND and VCC in the cable. I'm still running tests to see if I need to do this, but is it recommended to do so even if it is not necessary for correct operation? Someone mentioned that having SCL/SDA next to each other would be bad if they cause problems with crosstalk/interference.