Honeywell TruStability I2C Pressure Sensor

Hello,

I am trying to program 2 I2C Honeywell Pressure sensors using an Arduino Uno, 2 SEK001 shields, and 2 pressure sensors (HSCDANN150PG2A5). The sensors have the same I2C address so I am using an Adafruit TCA9548A 1-to-8 I2C Multiplexer Breakout. I took inspiration from the example code provided on the Adafruit webpage of the multiplexer, and I obviously manipulated the code to include the Honeywell sensors.

Here is the code:

/*
  The purpose of this program is to take
  the readings of two I2C Honeywell
  pressure sensors and display the data
  on the Serial Monitor.
*/

#include "Wire.h"
#include "Arduino.h"

#define TCA_Addr 0x70   // Address of the multiplexer
#define OUTPUT_MIN 1638.4 // 1638 counts (10% of 2^14 counts or 0x0666)
#define OUTPUT_MAX 14745.6 // 14745 counts (90% of 2^14 counts or 0x3999)
#define PRESSURE_MIN 0  // min is 0 for sensors that give absolute values
#define PRESSURE_MAX 150  // 1.6bar (I want results in bar)

uint8_t sensor1 = 3;
uint8_t sensor2 = 7;

/* Initialize I2C buses using TCA9548A I2C Multiplexer
*/
void tcaselect(uint8_t i) {
  if (i > 7) return;

  Wire.beginTransmission(TCA_Addr);
  Wire.write(1 << i);
  Wire.endTransmission();
}


void setup() {
  Wire.begin();   // start I2C bus
  delay(500);
  Serial.begin(115200); // start Serial connection

  /* Initialize the 1st sensor */
  tcaselect(sensor1);
  if (!sensor1)
  {
    /* Check for errors */
    Serial.println("Sensor not detected...Check your wiring!");
    while (1);
  }

  /* Initialize the 2nd sensor */
    tcaselect(sensor2);
    if (!sensor2)
    {
      /* Check for errors */
      Serial.println("Sensor not detected...Check your wiring!");
      while (1);
    }

}

void loop() {
  float pressure;
  float temperature;
  int bridge_data;
  int temperature_data;
  byte status;

  tcaselect(sensor1);
  delay(20);
  Wire.requestFrom(TCA_Addr, 4);
  while (Wire.available() == 0);
  byte a = Wire.read();
  byte b = Wire.read();
  byte c = Wire.read();
  byte d = Wire.read();

  //    Serial.print("a: ");
  //   Serial.println(a, BIN);
  //    delay(500);
  //  Serial.print("b: ");
  //  Serial.println(b, BIN);
  //  delay(500);
  //   Serial.print("c: ");
  //   Serial.println(c, BIN);
  //    delay(500);
  //   Serial.print("d: ");
  //     Serial.println(d, BIN);
  //    delay(500);


  status = (a & 0xc0) >> 6; // first 2 bits from first byte
  // Serial.println(status, BIN);
  // delay(500);

  bridge_data = ((a & 0x3f) << 8) + b;
  temperature_data = ((c << 8) + (d & 0xe0)) >> 5;

  if (temperature_data == 65535) {
    Serial.println("err HSCDANN150PG2A5 sensor missing");

    /* Command mode is used for programming the sensor.
       This mode should not be seen during normal operation. */
    if (status == 1) {
      Serial.println("Warn command mode ");
      // Serial.println(status, BIN);
    }
    if (status == 2) {
      Serial.println("Warn Stale Data "); // if data has already been feched since the last measurement cycle
      // Serial.println(statues, BIN)l
    }
    if (status == 3) {
      Serial.println("err diagnostic fault "); // When the two status bits are "11", one of the above mentioned diagnostic faults is indicated.
      // Serial.println(status, BIN);
    }

    pressure = 1.0 * (bridge_data - OUTPUT_MIN) * (PRESSURE_MAX - PRESSURE_MIN) / (OUTPUT_MAX - OUTPUT_MIN) + PRESSURE_MIN;
    temperature = (temperature_data * 0.0977) - 50;

    Serial.print("status      ");
    Serial.println(status, BIN);
    Serial.print("bridge_data ");
    Serial.println(bridge_data, DEC);
    Serial.print("temp_data   ");
    Serial.println(temperature_data, DEC);
    Serial.println("");

    Serial.print("pressure    (BAR) ");
    Serial.println(pressure);
    Serial.print("temperature (C) ");
    Serial.println(temperature);
    Serial.println("");

    delay (500);


    tcaselect(sensor2);
    Wire.requestFrom(TCA_Addr, 4);
    while (Wire.available() == 0);
    byte a = Wire.read();
    byte b = Wire.read();
    byte c = Wire.read();
    byte d = Wire.read();

    //    Serial.print("a: ");
    //   Serial.println(a, BIN);
    //    delay(500);
    //  Serial.print("b: ");
    //  Serial.println(b, BIN);
    //  delay(500);
    //   Serial.print("c: ");
    //   Serial.println(c, BIN);
    //    delay(500);
    //   Serial.print("d: ");
    //     Serial.println(d, BIN);
    //    delay(500);


    status = (a & 0xc0) >> 6; // first 2 bits from first byte
    // Serial.println(status, BIN);
    // delay(500);

    bridge_data = ((a & 0x3f) << 8) + b;
    temperature_data = ((c << 8) + (d & 0xe0)) >> 5;

    if (temperature_data == 65535) {
      Serial.println("err HSCDANN150PG2A5 sensor missing");

      /* Command mode is used for programming the sensor.
         This mode should not be seen during normal operation. */
      if (status == 1) {
        Serial.println("Warn command mode ");
        // Serial.println(status, BIN);
      }
      if (status == 2) {
        Serial.println("Warn Stale Data "); // if data has already been feched since the last measurement cycle
        // Serial.println(statues, BIN)l
      }
      if (status == 3) {
        Serial.println("err diagnostic fault "); // When the two status bits are "11", one of the above mentioned diagnostic faults is indicated.
        // Serial.println(status, BIN);
      }

      pressure = 1.0 * (bridge_data - OUTPUT_MIN) * (PRESSURE_MAX - PRESSURE_MIN) / (OUTPUT_MAX - OUTPUT_MIN) + PRESSURE_MIN;
      temperature = (temperature_data * 0.0977) - 50;

      Serial.print("status      ");
      Serial.println(status, BIN);
      Serial.print("bridge_data ");
      Serial.println(bridge_data, DEC);
      Serial.print("temp_data   ");
      Serial.println(temperature_data, DEC);
      Serial.println("");

      Serial.print("pressure    (BAR) ");
      Serial.println(pressure);
      Serial.print("temperature (C) ");
      Serial.println(temperature);
      Serial.println("");

      delay (500);
    }
  }
}

The data will not appear on the Serial Monitor. My wiring is correct. It is a very simple wiring job so I know my wiring is fine.

Any suggestion would be tremendous - Thank you

1 Like

What did the I2C scan show? If it does not show results it is probably not wired correctly.

Your topic has been moved to a more suitable location on the forum. Installation and Troubleshooting is not for problems with (nor for advice on) your project :wink: See About the Installation & Troubleshooting category.

Scan:

I am working on getting Fritzing so I can't provide an ideal wire diagram. However, I do have Paint. Here is a very rough wire diagram.

The way I drew the diagram is how I wired my circuit.

The first step is to get one sensor working, without the multiplexer. Have you done that?

Then add the multiplexer, connected to one sensor, and verify that that works.

You are missing the pull up resistors on SCL and SDA. I believe they are needed on both sides of the multiplexer. I do not think the multiplexer has them as I did not see enough resistors.

Something is definitely wrong. I can't tell if the issue comes from the wiring or the code. When I upload the program, the built-in LED on pin 13 turn off, and the Tx/Rx LEDs are not responding. From my understanding, that means the signal isn't being transmitted (please correct me if I am wrong).

I was able to get a single sensor to work without the multiplexer. I am currently trying to program a single sensor with the multiplexer.

Resistors or not the program still doesn't work.

Here is the code:

#include "Wire.h"
#include "Arduino.h"

#define TCA_Addr 0x70
#define OUTPUT_MIN 1638.4
#define OUTPUT_MAX 14745.6
#define PRESSURE_MIN 0
#define PRESSURE_MAX 150

uint8_t sensor = 7;

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

  Wire.beginTransmission(TCA_Addr);
  Wire.write(1 << i);
  Wire.endTransmission();
}

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

  /* Initialize Sensor */
  tcaselect(sensor);
  if (!sensor) {
    /* Check for errors */
    Serial.println("Sensor not detected...Check Wiring!");
    while(1);
  }
}

void loop() {
  float pressure;
  float temperature;
  float bridge_data;
  float temperature_data;
  byte status;

  tcaselect(sensor);
  delay(20);
  Wire.requestFrom(TCA_Addr, 4);
  byte a = Wire.read();
  byte b = Wire.read();
  byte c = Wire.read();
  byte d = Wire.read();

  status = (a & 0xc0) >> 6;
  // Serial.println(status, BIN);
  // delay(500);

  bridge_data = ((a & 0x3f) << 8) + b;
  temperature_data = ((c << 8) + (d & 0xe0)) >> 5;

  if (temperature_data == 65535) {
    Serial.println("err HSCDANN150PG2A5 sensor missing");

  if (status == 1) {
      Serial.println("Warn command mode ");
      // Serial.println(status, BIN);
    }
    if (status == 2) {
      Serial.println("Warn Stale Data "); // if data has already been feched since the last measurement cycle
      // Serial.println(statues, BIN)l
    }
    if (status == 3) {
      Serial.println("err diagnostic fault "); // When the two status bits are "11", one of the above mentioned diagnostic faults is indicated.
      // Serial.println(status, BIN);
    }

    pressure = 1.0 * (bridge_data - OUTPUT_MIN) * (PRESSURE_MAX - PRESSURE_MIN) / (OUTPUT_MAX - OUTPUT_MIN) + PRESSURE_MIN;
    temperature = (temperature_data * 0.0977) - 50;

    Serial.print("status      ");
      Serial.println(status, BIN);
      Serial.print("bridge_data ");
      Serial.println(bridge_data, DEC);
      Serial.print("temp_data   ");
      Serial.println(temperature_data, DEC);
      Serial.println("");

      Serial.print("pressure    (BAR) ");
      Serial.println(pressure);
      Serial.print("temperature (C) ");
      Serial.println(temperature);
      Serial.println("");

      delay (500);
  }
}

The pullup resistors are connected via solder on the other side of the board.

That was not shown in your link. It also has the schematic in the associated manual and that shows pull up resistors but you must jumper two pads to enable them. Each I2C bus needs seperate pull up resistors. You will need to more sets for the output of the mux. What were the results of the I2C scan you should have run.

I added resistors after posting.

Here is the scan:

The MUX is reading the two sensors. I think my problem is with my code. I am trying to get at least one of the sensors to work with the mux.

After setting the multiplexer to port #2 or port #4, you need to talk to the sensor at I2C address 0x28. All the Wire.beginTransmission() and Wire.requestFrom() for the sensor should use 0x28.

Hello everyone,

Update:

I was able to get the Honeywell sensor to work. However, the data is coming out wrong. There are 2 sets of data. One set contains raw data (bridge_data and temperature_data) and the other contains the refined data (temperature and pressure). My problem is the bridge_data and temperature_data variables are not storing data. When they are printed on the Serial Monitor the return "0". As a result, temperature and pressure return the incorrect value.

Can someone help me understand why my variables are not storing data?

Here is my code:

/* Get data from 1 Honeywell Pressure sensor */

#include "hsc_ssc_i2c.h"
#include "Wire.h"

#define TCA_Addr 0x70
#define HSC_Addr 0x28
#define OUTPUT_MIN 1638.4
#define OUTPUT_MAX 14745.6
#define PRESSURE_MIN 0
#define PRESSURE_MAX 150

unsigned long now = millis();
struct cs_raw ps;
char p_str[10], t_str[10];
uint8_t el;
float p, t;
uint32_t prev = 0;
const uint32_t interval = 5000;

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

  Wire.beginTransmission(TCA_Addr);
  Wire.write(1 << bus);
  Wire.endTransmission();
}

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

  /* Initialize 1st sensor */
  tcaselect(4);
//  if ((now - prev > interval) && (Serial.available() <= 0)) {
//    prev = now;
//    el = ps_get_raw(HSC_Addr, &ps);
//    // for some reason my chip triggers a diagnostic fault
//    // on 50% of powerups without a notable impact
//    // to the output values.
//    if ( el == 4 ) {
//      Serial.println("err sensor missing");
//    } else {
//      if ( el == 3 ) {
//        Serial.print("err diagnostic fault ");
//        Serial.println(ps.status, BIN);
//      }
//      if ( el == 2 ) {
//        // if data has already been feched since the last
//        // measurement cycle
//        Serial.print("warn stale data ");
//        Serial.println(ps.status, BIN);
//      }
//      if ( el == 1 ) {
//        // chip in command mode
//        // no clue how to end up here
//        Serial.print("warn command mode ");
//        Serial.println(ps.status, BIN);
//      }
//    }
//  }
  
}

void loop() {
  tcaselect(2);

//  Wire.beginTransmission(HSC_Addr);
//  Wire.write(1);
//  Wire.endTransmission();

  if ((now - prev > interval) && (Serial.available() <= 0)) {
    prev = now;
    el = ps_get_raw(HSC_Addr, &ps);
    // for some reason my chip triggers a diagnostic fault
    // on 50% of powerups without a notable impact
    // to the output values.
    if ( el == 4 ) {
      Serial.println("err sensor missing");
    } else {
      if ( el == 3 ) {
        Serial.print("err diagnostic fault ");
        Serial.println(ps.status, BIN);
      }
      if ( el == 2 ) {
        // if data has already been feched since the last
        // measurement cycle
        Serial.print("warn stale data ");
        Serial.println(ps.status, BIN);
      }
      if ( el == 1 ) {
        // chip in command mode
        // no clue how to end up here
        Serial.print("warn command mode ");
        Serial.println(ps.status, BIN);
      }
    }
  }
   
  Serial.print("Channel 2 status      ");
  Serial.println(ps.status, BIN);
  Serial.print("Channel 2 bridge_data ");
  Serial.println(ps.bridge_data, DEC);
  Serial.print("Channel 2 temp_data   ");
  Serial.println(ps.temperature_data, DEC);
  Serial.println("");
  delay(500);

    
  ps_convert(ps, &p, &t, OUTPUT_MIN, OUTPUT_MAX, PRESSURE_MIN,
             PRESSURE_MAX);
  // floats cannot be easily printed out
  dtostrf(p, 2, 2, p_str);
  dtostrf(t, 2, 2, t_str);
  Serial.print("Channel 2 pressure    (Pa) ");
  Serial.println(p_str);
  Serial.print("Channel 2 temperature (dC) ");
  Serial.println(t_str);
  Serial.println("");
  delay(500);

  /*tcaselect(4);
  Serial.print("Channel 4 status      ");
  Serial.println(ps.status, BIN);
  Serial.print("Channel 4 bridge_data ");
  Serial.println(ps.bridge_data, DEC);
  Serial.print("Channel 4 temp_data   ");
  Serial.println(ps.temperature_data, DEC);
  Serial.println("");
  delay(500);
  ps_convert(ps, &p, &t, OUTPUT_MIN, OUTPUT_MAX, PRESSURE_MIN,
             PRESSURE_MAX);
  // floats cannot be easily printed out
  dtostrf(p, 2, 2, p_str);
  dtostrf(t, 2, 2, t_str);
  Serial.print("Channel 4 pressure    (Pa) ");
  Serial.println(p_str);
  Serial.print("Channel 4 temperature (dC) ");
  Serial.println(t_str);
  Serial.println("");
  delay(500);*/
}

Thank you!

This might help:

This is the library that you use: https://github.com/rodan/honeywell_hsc_ssc_i2c/blob/master/examples/read_sensor/read_sensor.ino
and you follow this example: honeywell_hsc_ssc_i2c/read_sensor.ino at master · rodan/honeywell_hsc_ssc_i2c · GitHub

You don't have to use millis() or wait for something at the serial port. That is too complex. Keep it simple. Can you remove millis() and Serial ? Use a delay in the loop() to slow it down, and just request the data.

The library does not keep track whether the data was actually received from the sensor.
Only 4 bytes are read from the sensor. Can you print those raw bytes ?
I was thinking about something simple:

void loop()
{
  int n = Wire.requestFrom( 0x28, 4);
  if( n == 4)
  {
    for( int i=0; i<4; i++)
    {
      int data = Wire.read();
      Serial.print( "0x");
      if( data < 0x10)
        Serial.print( "0");
      Serial.print( data, HEX);
      Serial.print( ", ");
    }
    Serial.println();
  }
  else
  {
    Serial.println( "Error, sensor not found on the I2C bus");
  }
  delay(1000);
}

Perhaps you can set the multiplexer in setup() and try that for both sensors.

If I add the second sensor with the multiplexer. Would the 4 bytes of the second sensor be different than the bytes of the first? Can I call those bytes e, f, g, h?

First check what that code does, then you can put it in a function and use it for both sensors.
I don't know if the second sensor has different bytes.

Some sensors have a "identifier" register. That can be read to check if reading is working. The Honeywell sensors do not seem to have such a register.

Hi everyone,

My sensors are working! I am truly grateful for all of your help. I could not have done it without you.

Thank you so much

Hi,

I am dealing with the same problem that you had. Could you please share your code with me? I am trying to connect two sensors I2C but I would be fine starting to make one work. Hope you can help me with this one.

Thanks in advance

Sure, once you understand how to use the multiplexer everything will fall into place.
What kind of sensors do you have? You might be able to find a library on github and find an example to make one sensor work. That's what I used to get mine to work. Once you have one sensor working, you can duplicate the code, apply the multiplexer, and you'll be able to add as many sensors as you want.
The multiplexer also has a library with examples.

Try this first and if you are still having trouble come back

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