Pages: [1]   Go Down
Author Topic: SensorTechnics i2c Pressure Sensor  (Read 1616 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 26
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello All,

I'm trying to interface a SensorTechnics pressure sensor to a Mega. The device is a SSIB001GU9AH5 0-1bar stainless steel housed pressure sensor, seemingly ideal (if a little expensive @£80) for what I need.
It's i2c capable, but also has a analogue voltage out. I'd like to us the i2c function as (if I can get it working) because ultimately I'd like an array of the units.
Attached are the datasheets that I've managed to track down. In one of these there is the code snippet below, which I'm guessing is C ??, but as a Arduio beginner I'm finding it hard to follow/translate this into something I can use on the Arduino.

The datasheet also specifies that the device needs 1.5 K Ohm pullup resistors on from the 5v supply as well as 240 Ohm resistors on the SDA\SCL lines

My question is two fold:
1) Can anyone help me to understand this code and how to get it working?
2) Does the Arduino already have these pullup resistors on the SDA & SCL lines?

I wondered if this might be a device that could be added to the Arduino library....

Many thanks,

Code:
byte byte_msb, byte_lsb; // 8bit values
int16 pressure; // 16bit value
// Set I2C unit to I2C master mode, clock speed 100 kHz and 7 bit addressing
configureI2C (I2C_MASTER | CLK_SPEED_100KHZ | ADDRESSING_7BIT);
// Set the target address of the sensor (0x78 = 120dec)
I2C_set_target(0x78);
// Send start condition for reading from sensor (slave)
I2C_send_start_read();
// Read first (MSB) data byte and answer with ACK (continue communication)
I2C_read (&byte_msb, SEND_ACK);
// Read second (LSB) data byte and answer with NACK (end communication)
I2C_read (&byte_lsb, SEND_NACK);
// Send Stop condition
I2C_send_stop();
// Put both values together
pressure = ((int16)byte_msb << 8) | byte_lsb;


* AN_I2C-Bus-HDI-HCLA-HCA-SSI_E_11155.pdf (53.99 KB - downloaded 25 times.)
* DS_Standard-SSI_E_11671.pdf (116.4 KB - downloaded 21 times.)
Logged

Switzerland
Offline Offline
Faraday Member
**
Karma: 108
Posts: 5152
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
The datasheet also specifies that the device needs 1.5 K Ohm pullup resistors on from the 5v supply as well as 240 Ohm resistors on the SDA\SCL lines

Use 4k7 pull-ups (1k5 @5V is outside the bus specification) and I don't see a reason for the 240 Ω resistors in the lines (maybe prevent short circuit in case of wrong wiring).

Quote
Does the Arduino already have these pullup resistors on the SDA & SCL lines?

It does but they are too weak for most cases.

Quote
Can anyone help me to understand this code and how to get it working?

Translated to Arduino-C:

Code:
byte byte_msb, byte_lsb; // 8bit values
int16_t pressure; // 16bit value
// Set I2C unit to I2C master mode, clock speed 100 kHz and 7 bit addressing
// ### configureI2C (I2C_MASTER | CLK_SPEED_100KHZ | ADDRESSING_7BIT);
Wire.begin();
// Set the target address of the sensor (0x78 = 120dec)
// ### I2C_set_target(0x78);
// Send start condition for reading from sensor (slave)
// ### I2C_send_start_read();
Wire.requestFrom(0x78, 2); // request two bytes from I2C slave address 0x78
// Read first (MSB) data byte and answer with ACK (continue communication)
// ### I2C_read (&byte_msb, SEND_ACK);
byte_msb = Wire.read();
// Read second (LSB) data byte and answer with NACK (end communication)
// ### I2C_read (&byte_lsb, SEND_NACK);
byte_lsb = Wire.read();
// Send Stop condition
// ### I2C_send_stop();
// Put both values together
pressure = ((int16_t)byte_msb << 8) | byte_lsb;
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 26
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks very much for taking the time to reply Pylon,

The code makes sense now, but I cant get the device to be recognised on the i2C bus with the 4k7 pullup resistors installed.

I've tried the following i2c scanner with a HMC5883L connected onto the bus, which is detected, but not so the SSI device so I guess its a wiring\pull up resistor\address issue?

I might have to resort to the analogue pin after all.....  smiley-sad

Code:
#include <Wire.h>
void setup()
{
  Wire.begin();
  Serial.begin(115200);
  Serial.println("\nI2C Scanner");
}
void loop()
{
  byte error, address;
  int nDevices;
  Serial.println("Scanning...");
  nDevices = 0;
  for(address = 1; address < 120; address++ )
  {
    // The i2c_scanner uses the return value of
    // the Write.endTransmisstion to see if
    // a device did acknowledge to the address.
    Wire.beginTransmission(address);
    error = Wire.endTransmission();
    if (error == 0)
    {
      Serial.print("I2C device found at address 0x");
      if (address<16)
        Serial.print("0");
      Serial.print(address,HEX);
      Serial.println("  !");
      nDevices++;
    }
    else if (error==4)
    {
      Serial.print("Unknown error at address 0x");
      if (address<16)
        Serial.print("0");
      Serial.println(address,HEX);
    }   
  }
  if (nDevices == 0)
    Serial.println("No I2C devices found\n");
  else
    Serial.println("done\n");
  delay(5000);           // wait 5 seconds for next scan
}
Logged

Switzerland
Offline Offline
Faraday Member
**
Karma: 108
Posts: 5152
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
  for(address = 1; address < 120; address++ )

This code isn't scanning the sensors address which is 120 (0x78). Might that be a reason for it?
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 26
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Well spotted Pylon, but unfortunately increasing it to 150 as below has made no difference..... smiley-sad

Code:
for(address = 1; address < 150; address++ )
Logged

Switzerland
Offline Offline
Faraday Member
**
Karma: 108
Posts: 5152
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

In the datasheet I cannot find any reference that the sensor supports an I2C write. The I2C scan code does a write and that maybe is the problem. What does the code I wrote for you return? You may also check the return value of Wire.requestFrom(), it should return 2 if the sensor really returned data.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 26
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Pylon,

Thanks for your help, you've helped me solve it! Thank you. I found that it was a voltage dip in the 5v supply from the Arduino board. I measured it at just less than 4.3v and running the Mega off separate power supply rather than the USB power the sensor came to life.

Attached is an image of the results (me blowing air into the sensor), the values are in counts of course.

For reference (in case I lose it!), here's the final code I used:
Code:

//Code to read a SensorTronics SSIB001GU9AH5 Pressure Sensor
//Thanks to 'Pylon' on Arduino Forum.

#include <Wire.h> //For I2C comms
byte byte_msb, byte_lsb; // 8bit values
int16_t pressure; // 16bit value

void setup(void) {
// Set I2C unit to I2C master mode, clock speed 100 kHz and 7 bit addressing
// ### configureI2C (I2C_MASTER | CLK_SPEED_100KHZ | ADDRESSING_7BIT);
Serial.begin(115200); // Initialize the serial port.
Wire.begin();
}

void loop(void) {
// Set the target address of the sensor (0x78 = 120dec)
// ### I2C_set_target(0x78);
// Send start condition for reading from sensor (slave)
// ### I2C_send_start_read();
Wire.requestFrom(0x78, 2); // request two bytes from I2C slave address 0x78
// Read first (MSB) data byte and answer with ACK (continue communication)
// ### I2C_read (&byte_msb, SEND_ACK);
byte_msb = Wire.read();
// Read second (LSB) data byte and answer with NACK (end communication)
// ### I2C_read (&byte_lsb, SEND_NACK);
byte_lsb = Wire.read();
// Send Stop condition
// ### I2C_send_stop();
// Put both values together
pressure = ((int16_t)byte_msb << 8) | byte_lsb;
//Serial.print("P=");
Serial.println (pressure);
delay(50);
}


 


* Pressure.JPG (40.46 KB, 634x374 - viewed 29 times.)
Logged

Offline Offline
Faraday Member
**
Karma: 62
Posts: 3032
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

If you aspire to having "an array" of sensors,   then I2C may be an issue,  because you can usually only have 2 different addresses.
Logged

Offline Offline
Jr. Member
**
Karma: 1
Posts: 61
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi there,

as I am working with Sensortechnics diff. pressure sensors at the moment I thought I share my code which is working as intended. Please note that the HDI-sensors I used, are capable of delivering a non-calibrated temperature signal. This feature however, has to be enabled when programming the adress into each sensor (using a eval-board from Sensortechnics). The Temperature can then be obtained as 3rd and 4th byte using the exact sheme as used in the following code.

By the way I am using the I2c-library created by Wayne Truchsess (http://www.dsscircuits.com/articles/arduino-i2c-master-library.html). However, using the wire library should work just fine.

Using a running average might be a good idea to use on the acquired sensor data. Here is a link to the RunningAverage library from Rob Tillaart:
https://github.com/RobTillaart/Arduino/tree/master/libraries/RunningAverage


Best regards,
Jan

Code:
/*******************************************************
SUBMODULE

This program will initialize communication with I2c
pressure sensors. Additionally it delivers the calculated
value from these sensors.

 The circuit:
 * Digital pin 20 (SDA) is used as the communication I2c-bus line
 * Digital pin 21 (SCL) is used as the common clock for the  I2c-bus
 * PullUp Resistors of 1,5 kOhm need to be attached to SDA and SCL Lines
 * As per Datasheet the SDA and SCL lines are equiped with a 220 Ohm Resistor each
********************************************************/

// Sensor used: HDIM010DUF8P5 [Differential | 10mbar | DIP | 5V]
// Define the I2C-Adresses for the Sensors
#define HDIDiff 0x14      //Adress for the differential pressure sensor | DEC: 20

// Define the calculation parameters
// for each sensor.
// See SensorTechnics-Datasheet: DS_Standard-HDI_E_11650.pdf.
// See SensorTechnics I2C Application Note: AN_I2C-Bus_HMI_HDI_HCLA_HCA_SSI_E_11155.pdf
#define P_min_diff 0       // min. for the differential pressure sensor
#define P_max_diff 10     // max. for the differential pressure sensor
#define T_min -20             // min. temperature for the sensor (same for both sensors)
#define T_max 50              // max. temperature for the sensor (same for both sensors)
/* DIGITAL PERFORMANCE CHARACTERISTIC */
#define Out_min 3277     // min. counts for the sensors (same for both sensors)
#define Out_max 29490 // max. counts for the sensors (same for both sensors)

/* Variables for "getDifferentialPressure" */
  float sensitivity_p_diff = 0; // set the differential pressure sensors sensitivity to zero
  float pressure_diff = 0;      // set the differential pressure to zero
  byte P_counts_diff_msb, P_counts_diff_lsb; // set pressure counts to zero
  int16_t P_counts_diff;        // 16bit value

float getDifferentialPressure()
{
  I2c.read(HDIDiff,2);                // read 2 bytes (we skip temperature [would be byte 3 and 4] for now) from the differential pressure sensor
  P_counts_diff_msb = I2c.receive();  // read the most significant byte from data bytes containing the pressure value
  P_counts_diff_lsb = I2c.receive();  // read the least significant byte from data bytes containing the pressure value
  P_counts_diff = ((int16_t)P_counts_diff_msb << 8) | P_counts_diff_lsb; // combibe msb and lsb
  sensitivity_p_diff = (Out_max - Out_min)/(P_max_diff - P_min_diff); // calculate the differential pressure sensors sensitivity
  pressure_diff = (P_counts_diff - Out_min)/sensitivity_p_diff + P_min_diff;   // calculate the differential pressure in [mbar]
  return pressure_diff;
}
« Last Edit: October 17, 2013, 07:38:00 pm by jabami » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 26
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Jan,

Thanks very much for taking the effort to post your code for this. I'd given up using the SSI sensor in I2C mode because of the address issue as I have 3 sensors in my application and I believe (rightly or wrongly?) you can only have a maximum of two and so have been using them in analogue mode.

I've another application where I'll be using only one sensor so I'll try going back to I2C mode on that one and so I'm very grateful for you being kind enough to share your code,

Steve

Logged

Offline Offline
Jr. Member
**
Karma: 1
Posts: 61
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi Steve,

using more than 2 Sensortechnics I2C Sensors is no problem at all. But it is necessary to programm the adresses before you solder your sensors to your board. Sensortechnics has a evaluation board (which i cannot find a datasheet for on their homepage) which can be used to program the adresses into the sensors. Thus, the full range of 127 adresses can be exploited. Consequently, you could use 127 Sensors on one I2C-bus. However, SDA and SCL line capacitance will prevent you from doing so.
Now I suspect you could ask Sensortechnics to program your sensors with different adresses when you order from them directly. I've never done this, though. I allways programmed the adresses myself with an eval-board I have available. They are quite expensive none the less (~400 Euro).

Hope these information will be helpful at some point. Using the I2c interface on these sensors has still some advantages. You get a build in measuring amplifier, filtering capabilities and a somewhat cripled temperature readout. Additionally you do not have to bother about ADC, as that would significantly largen the footprint of your PCB. Presupposed you need more than the 10 bit provided by the arduino.

Best regards,
Jan
Logged

Pages: [1]   Go Up
Jump to: