Interfacing Differential Pressure Sensor with Arduino AMS 5915-0100-D
AMS5915 is a highly precise differential pressure sensor with a digital I²C-interface. This high accuracy pressure sensor can be used for various applications and various pressure ranges, differential (relative) devices in the pressure range from 0 to 100 mbar. In this project, we are using AMS5915-0100-D an industrial grade differential pressure sensor. We can also calculate temperature from this single sensor which makes it more compatible, instead of connecting dual sensors for pressure and temperature this device serves all.
What is a differential pressure sensor
The Differential pressure sensors come with 2 nozzles, which are used as pressure intakes, the sensor will measure pressure on both nozzles and will calculate the pressure difference between these two port.
Application of the Differential Pressure sensor
- Flow Monitoring with differential pressure
- Static and dynamic pressure measurement
- Medical devices to determine respiratory flow
- Barometric pressure measurement
- Vacuum monitoring
- Fluid level measurement
- Gas flow moniotoring
AMS5915-0100-D Overview
AMS5915 pressure sensors come in a few formats like as a differential pressure sensors, relative pressure sensors, and differential bidirectional sensor. This sensor has an inbuilt 16 bit analog to digital converter which used to convert pressure values into digital values and this ADC provides a high accuracy pressure readings. These sensors come with stainless steel nozzles which makes them easy to install and durable. If you want to measure the pressure of a chamber you can simply install a tube in the nozzle and monitor the pressure. Temperature is a big factor which affects the pressure readings but in the AMS5915 series pressure sensors there is an inbuilt temperature sensor which is used by the sensors to self-calibrate the pressure readings based on the surrounding temperature, this feature makes this pressure sensors more accurate and ideal pressure sensor for HVAC and industrial pressure monitoring. This sensor communicates through i2c communication, so interfacing this sensor with other microcontrollers or master hardware is really easy.
It is also possible to calculate fluid flow rate through a pipe using this device, These sensors can be also applied in level measurement applications such as total level in separator vessels where other level measurement devices are not feasible owing to the extensive changes in material formation experienced in the upper state.
Hardware
- Arduino of your choice
- Arduino I2C shield
Interfacing I2C with pressure sensor
For pressure and temperature value readout, a total of four data bytes are transmitted from the pressure sensor to the I²C-master using I2C bus. First two bytes are for the pressure and next two bytes are for temperature value, always begin with MSB On each transferred data byte the I²C-master sends an acknowledge bit confirming the correct receipt of data. After the 4th data byte, the receiving master generates a no acknowledge bit after this the pressure sensor is set to inactive. The I²C-master shuts down the data transfer by sending a stop condition.
Pins and pull up resisters:
Pressure sensor board has 2 pull up resister pins on the device which are used by the SDA line. The SDA pin needs a pull-up resistor from the VDD line to the SDA pin. Except for start and stop conditions, the data on the SDA pin must be stable during the high period of the clock. The high or low state of the SDA pin can only change when the clock signal on the SCL pin is low. AMS5915 is a bidirectional pressure sensor with 2 nozzles as its output we can calculate the value of pressure by physically putting one nose on different pressure line and the second one on the other pressure value it calculates the difference in pressure and gives us the output on a serial monitor.
Sensor Configuration
The sensor sends 4 bytes of data 2 bytes for pressure and next 2 bytes for temperature in which pressure takes 14 bits and temperature takes 11 bits of register address.
Byte 1 stores pressure data in register and leaves the last 2 MSB vacant so we do masking of those bits
00101100 these bold bits should be masked during programming.
Byte2 again stores the same data (pressure value) all the bits are consumed in this byte.
Byte3 stores temperature value which is a 11bit data so 8 bits in byte 3 and remaining 3 bits will be stored in the next byte.
Byte4 it uses only 3 bits to store the remaining data rest will be masked.
As you can see in the image starting from the MSB we first store address bits for device address after hat we have 4 bytes to store our pressure and temperature values from the sensor. There is an acknowledge signal after every successful transmission of a single byte by the master or controller.
Arduino library:
Complete library will be found here
https://github.com/ControlEverythingCommunity/CE_ARDUINO_LIB/tree/master/AMS5915
– In this library, we firstly declared device address like this “AMS5915_DEFAULT_ADDRESS (0x28)” 0x28 is the address of the device.
– Then we declare some variables like pressure, temperature and declare functions to get values for these variables.
– We have a function here called Measure_PressureAndTemperature which reads the value from the sensor and convert sensor’s binary values to decimal form after which we assign decimal values to declares variable temperature and pressure.
#define AMS5915_DEFAULT_ADDRESS (0x28) /************************************************************************** CONVERSION DELAY (in mS) **************************************************************************/ #define AMS5915_CONVERSIONDELAY (100) class AMS5915 { protected: // Instance-specific properties uint8_t ams_conversionDelay; float pressure, temperature; public: uint8_t ams_i2cAddress; void getAddr_AMS5915(uint8_t i2cAddress); void begin(void); float getPressure(void); float getTemperature(void); void Measure_PressureAndTemperature(float pMin, float pMax); private: };
Sensor read values
To read values from the AMS5915 differential pressure sensor we define a function by the name Measure_PressureAndTemperature this function reads high and low values from sensor and convert those values into a decimal form which is further put into the formula to get pressure and temperature.
void AMS5915::Measure_PressureAndTemperature(float pMin, float pMax) { uint8_t Pres_Hi, Pres_Low, Temp_Hi, Temp_Low; // pressure and temperature digital output in counts uint16_t pressureCounts, temperatureCounts; uint16_t DigoutPmin = 1638.0; // digital output at minimum specified pressure in counts uint16_t DigoutPmax = 14745.0; // digital output at maximum specified pressure in counts Wire.beginTransmission(ams_i2cAddress); Wire.endTransmission(); Wire.requestFrom(ams_i2cAddress, (uint8_t)4); Pres_Hi = i2cread(); Pres_Low = i2cread(); Temp_Hi = i2cread(); Temp_Low = i2cread(); // Convert the pressure data to 14-bits and then in physical units (mbar) pressureCounts = ((Pres_Hi & 0x3F) << 8) | Pres_Low; pressure = (((float)pressureCounts - DigoutPmin)/((DigoutPmax - DigoutPmin)/(pMax - pMin)) + pMin); // Convert the temperature data to 11-bits and then in physical units (C scale) temperatureCounts = ((Temp_Hi << 8) | (Temp_Low & 0xE0)); temperatureCounts >>= 5; temperature = ((float)temperatureCounts * 200.0) / 2048.0 - 50.0; }
Differential Pressure Sensor Arduino Code
– In Arduino code we first define min. and max. The range of pressure in milibars after that we call device address so that our Arduino will be informed from where to read data
– Then we call Measure_PressureAndTemperature function to convert sensors data and store these data in pressure and temperature using getPressure(), getTemperature functions respectively.
#include <Wire.h> #include <AMS5915.h> AMS5915 ams; const float AMS5915_0005_D_P_MIN = 0.0; // minimum pressure, millibar const float AMS5915_0005_D_P_MAX = 5.0; // maximum pressure, millibar void setup(void) { Serial.begin(9600); // The address can be changed making the option of connecting multiple devices ams.getAddr_AMS5915(AMS5915_DEFAULT_ADDRESS); // 0x28 ams.begin(); delay(500); } void loop(void) { byte error; int8_t address; address = ams.ams_i2cAddress; // 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) { ams.Measure_PressureAndTemperature(AMS5915_0005_D_P_MIN, AMS5915_0005_D_P_MAX); float cTemp, fTemp, pressure, kPa, hg; Serial.println("Getting Readings from AMS5915_0005-D"); Serial.println(" "); // Read and print out the Pressure, convert it to mbar, PSI, kPa, mmHg pressure = ams.getPressure(); PSI = pressure * 0.0145038; kPa = pressure / 10; hg = pressure * 76.0 / 101.325; // Read and print out the temperature, then convert to C and F scales cTemp = ams.getTemperature(); fTemp = cTemp * 1.8 + 32; // Output data to screen Serial.print("Digital Pressure Reading: "); Serial.print(pressure); Serial.println(" mbar"); Serial.print("Digital Pressure Reading: "); Serial.print(PSI); Serial.println(" PSI"); Serial.print("Digital Pressure Reading: "); Serial.print(kPa); Serial.println(" kPa"); Serial.print("Digital Pressure Reading: "); Serial.print(hg); Serial.println(" mmHg"); Serial.print("Temperature Reading in Celsius: "); Serial.print(cTemp); Serial.println(" °C"); Serial.print("Temperature Reading in Fahrenheit: "); Serial.print(fTemp); Serial.println(" °F"); Serial.println(" "); Serial.println(" *************************** "); Serial.println(" "); } else { Serial.println("AMS5915_0005-D Disconnected!"); Serial.println(" "); Serial.println(" ************ "); Serial.println(" "); } delay(1000); }
Testing of sensor
Output of AMS5915 differential pressure sensor (pressure and temperature value)
Reference