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.



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:


simulate this circuit

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.


#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_HMC5883_U.h>

#define TCAADDR 0x70

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;
  Serial.print  ("Sensor:       "); Serial.println(sensor.name);
  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");  

//Given sensor i, select and write to it
void tcaselect(uint8_t i) {
  if (i > 7) return; 
  Wire.write(1 << i);

    void setup() {
  /* Initialise the 0st sensor */
   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("  ");


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.

  • You could follow that tutorial from start to finish. There is a I2C scanner for each of the 8 channels. You could run that to see what it finds. How many pullup resistors did you add. I think that you need 2 pullup resistors that are on the multiplexer module, and 16 more pullup resistors. Did you read the note about the pullups in the "I2C Multiplexed-Side pins" paragraph ? Don't select a channel without pullups, when SDA or SCL is low, the Arduino I2C scanner stops working. – Jot Jun 15 '17 at 17:26
  • It stops at your dummy sensor ? What is a hardware dummy I2C sensor ? I have never heard of it before. Did you ask patent for it ? You might be the only one in the world that has one. – Jot Jun 15 '17 at 17:53
  • Thanks for your replies. Sorry, I use the term dummy sensor to denote a sensor that is attached to the setup, but we don't use it. It's just another HMC5883L, but we don't use it. – user101402 Jun 15 '17 at 17:55
  • The HMC5883L breakout board has 10k pullup resistors from the SCL/SDA pins to VCC, so there's no problems there. For the multiplexer itself, we didn't add any pull up resistors. I saw the paragraph, but with the pull ups on the sensor, it should be fine, right? – user101402 Jun 15 '17 at 17:59
  • 1
    I apologize, but this doesn't exactly help with my problem. All of the sensors that we are using contain pullup resistors. It's just that something seems to happen when we don't have a sensor connected to SD/SC0 on the multiplexer, so we can't read from the other sensors as well. Looking at tcaselect, it seems to write an 8-bit signal to TCAADDR, but with a '1' bit depending on the device. If that's the case, then TCAADDR should be no problem. – user101402 Jun 15 '17 at 18:16

I'm sure you have, but have you connected the grounds together?

Have you tried 1 sensor on SD/C0 and then moving it to SD/C1 it should stop working, so the fault has to be with SD/C0.

Looking at your code, is there a reason you haven't initialised sensor 0?

 /* Initialise Sensors 1-6 */

So it looks to me as the fault is caused by you not calling begin() on mag0

  • We connected the grounds together; they all lead to a node on the breadboard which feeds back to the Arduino. We tried your suggestion with SD/C0 and SD/C1, but the results were the same. I'll ask the team to try again since I can't exactly test it because I'm not on site with the device. The reason why we haven't initialized sensor 0 with tcaselect(0) was that it was causing our code to hang. Once we commented it out, the code continued, and we could read from all sensors. The guy in charge tested it, commented out stuff, and found that this was the issue, though we still don't know why. – user101402 Jun 20 '17 at 12:37

Try bumping the empty to the last slot and changing your for loop to only iterate the first 7.

Serial prints along the way help debugging

Your Answer

