TCA9548 Adafruit multiplexer needing to discard first read from 2 SFM3300 flow sensors

I have just started to use the TCA9548 i2c multiplexer from AdaFruit as I need to read more than 1 SFM3300 flow sensor and it's not possible to change the address of the sensors. I managed to get this sort of "working" pretty quick but almost every other sensor reading was wrong, more specifically the flow variable called "flow4" in my code was often reading to the serial terminal as "433" when every correct reading was much higher, what's interesting is that "4" is the multiplexer register that I set just before reading into "flow4" and "33" is what the sensor often reads as it's 0 reading, so it's almost like the call to the multiplexer channel is interfering with the first new sensor reading... Anyway I solved this problem by discarding the first reading of each flow sensor but I would be grateful if somebody could show me a better way of solving this problem as I don't really understand why this problem exists as various example codes that I have found have not had to discard any readings. My working code is below.

// Code to test the TCA9548 readings 2 SFM3300 flow sensors over i2c

#include <Wire.h>
#define sfm3300i2c 0x40  // #include <Adafruit_Sensor.h>
#define TCAADDR 0x70               // address of i2c multiplexer
#define flowSensorMultiplexPin4 4  // i2c pin of multiplexer
#define flowSensorMultiplexPin6 6  // i2c pin of multiplexer

void setupFlowSensor() {
  Wire.beginTransmission(sfm3300i2c);
  Wire.write(0x10);  // start continuous measurement
  Wire.write(0x00);  // command 0x1000
  Wire.endTransmission();
}

void tcaselect(uint8_t i) {
  if (i > 7) return;

  Wire.beginTransmission(TCAADDR);  // address the multiplexer
  Wire.write(1 << i);               // address the right multiplexer address
  Wire.endTransmission();
}


// ***** Reads air flow sensor. Output in ml/min *****
long getFlow() {
  static unsigned long flowTimer = 0;
  static bool firstFlowRead = true;
  static float flow = 0;  // variabe for flow readings mL/min

  if (millis() - flowTimer >= 1 || firstFlowRead) {  // reads every milisecond apart from first reading
    firstFlowRead = false;
    if (2 == Wire.requestFrom(sfm3300i2c, 2)) {  // read SLM (Standard Liter per Minute)
      uint16_t a = Wire.read();                  // only two bytes need to be read
      uint8_t b = Wire.read();                   // if we don't care about CRC
      a = (a << 8) | b;
      //float flow = ((float)a - 32768) / 120;         // L/min
      //flow = ((float)a - 32768) / 120 * 1000;  // mL/min
      flow = ((float)a - 32768.0) * 8.33333;  // same as line above but without division in ml/min
      flowTimer = millis();
    } else {                  // use large number to flag incorrect readings
      flow = 500000;          // faulty sensor reading
    }
  }
  return long(flow);  // in mL/min
}


void setup(void) {
  Wire.begin();
  Serial.begin(115200);

  tcaselect(flowSensorMultiplexPin4);
  setupFlowSensor();

  tcaselect(flowSensorMultiplexPin6);
  setupFlowSensor();
}

void loop(void) {
  static long flow6 = 0;
  static long flow4 = 0;

  for (int i = 0; i <= 2; i++) {
    tcaselect(flowSensorMultiplexPin6);
    flow6 = getFlow();
  }

  for (int i = 0; i <= 2; i++) {
    tcaselect(flowSensorMultiplexPin4);
    flow4 = getFlow();
  }
  Serial.print(flow4);
  Serial.print(",");
  Serial.print(flow6);
  Serial.print(",");
  Serial.println(2000);
}

Did you use pull up resistors on both sides of the TCA9548.
The Adafruit only has an optional pair with solder bridges on the Arduino side, none on the sensor sides. The sensors don't seem to have them.

I see you don't observe the minimum 0.5ms update time of the sensors in your for loops.
Double-read should not be needed with I2C sensors anyway.
Leo..

Thanks for your message. Yes I am using 4k7 pull ups for both sensors. I'm reading the sensors once every 1ms, this is managed by the if statement copied below to avoid use of delay().
" if (millis() - flowTimer >= 1 || firstFlowRead) { "

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.