Go Down

Topic: Omron sensor and i2c (Read 9751 times) previous topic - next topic

Esputin

Hello

I have Omron D6F-PH0505AD3 sensor and arduino uno. Im trying to read pressure differential but i dont know how. Sensor I2C bus address is 0x6C and only result i get is "4"

http://www.omron.com/ecb/products/sensor/special/mems/pdf/AN-D6F-PH-01EN_r1.pdf

#include "Wire.h"
#define addrs 0x6C // I2C bus address


void setup()
{
Wire.begin();
Serial.begin(9600);
}

void loop()
{
   delay(500);   
   byte lobyte;
   byte hibyte;
   int Press;
     
  Wire.beginTransmission(addrs);
   Wire.write(1);       
   int x = Wire.endTransmission();

  Serial.print("endTransmission: ");
   Serial.println(x, DEC);
     
  Wire.requestFrom( addrs, 2);  // contents of the two registers
  if( Wire.available() == 2)
  {   
    byte hibyte = Wire.read();
    byte lobyte = Wire.read();
    word pressure = word( hibyte, lobyte);
    Serial.println( pressure);   
    }
}

robtillaart

On page 9 there is an example of a session with the sensor.

In case access to internal registers are needed, the target register's address needs to be set
to the Interface Configuration Register (address:00h and 01h).

think the core code should be something like this (I do not have such sensor disclaimer applies)

// write to the access address the address of the SENS control register 0xD040  see page 6
Wire.beginTransmission(addrs);
Wire.write(0x00); 
Wire.write(0xD0);  // reg 0 - address register high byte
Wire.write(0x40);  // reg 1 - addres register low byte
Wire.write(0x18);  // reg 2  - serial control register - indicate # bytes among others (page 7 bottom)
Wire.write(0x06);  // reg 3 - value to be written to SENS control register
int x = Wire.endTransmission();

// READ THE REGISTER
Wire.beginTransmission(addrs);
Wire.write(0x07);  // set read register
int x = Wire.endTransmission();

Wire.requestFrom(addrs, 2); 
byte hibyte = Wire.read();
byte lobyte = Wire.read();
int value = word( hibyte, lobyte);
Serial.println( value );   // this should be the value that is in register 0xD040

Not really complicated but you need multiple steps to get a value
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

robtillaart


for pressure I think (still all disclaimers apply)

// SET COMPENSATED REGISTER
Wire.beginTransmission(addrs);
Wire.write(0x00); 
Wire.write(0xD0);  // reg 0 - address register high byte
Wire.write(0x51);  // reg 1 - address register low byte
Wire.write(0x18);  // reg 2  - serial control register - indicate # bytes among others (page 7 bottom)
Wire.write(0x06);  // reg 3 - value to be written to SENS control register
int x = Wire.endTransmission();

// READ THE REGISTER
Wire.beginTransmission(addrs);
Wire.write(0x07);  // set read register
int x = Wire.endTransmission();

Wire.requestFrom(addrs, 2); 
byte hibyte = Wire.read();
byte lobyte = Wire.read();
int pressure = word( hibyte, lobyte);
Serial.print("pressure:\t ");
Serial.println( pressure);

give it a try...

Nice one to make a library for ...
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Esputin

Thanks robtillaart. But only reading i get is 0. On page 15 there is 1. Initialization after power up [Must be done], is that possible reason?
This is my first project with i2c and only senson that can measure from -50 pascal to 50 pascal

robtillaart

Quote
On page 15 there is 1. Initialization after power up [Must be done], is that possible reason?
did not see that line so .... yes! could be a cause.

(I do not have such sensor disclaimer applies)
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

robtillaart

did try to translate the code that is in the appendix, should help you a step further ..

Code: [Select]

int initialize(uint8_t address)
{
  Wire.beginTransmission(address);
  Wire.write(0x0B); 
  Wire.write(0x00);
  int x = Wire.endTransmission();
  return x;
}

int flow(uint8_t address)
{
  Wire.beginTransmission(address);
  Wire.write(0x00);   
  Wire.write(0xD0);  // reg 0 - address register high byte
  Wire.write(0x51);  // reg 1 - address register low byte
  Wire.write(0x18);  // reg 2  - serial control register - indicate # bytes among others (page 7 bottom)
  Wire.write(0x06);  // reg 3 - value to be written to SENS control register
  int x = Wire.endTransmission();

  delay(33);

  Wire.beginTransmission(address);
  Wire.write(0x00);   
  Wire.write(0xD0);
  Wire.write(0x51);
  Wire.write(0x2C);
  Wire.write(0x07);
  x = Wire.endTransmission();

  Wire.requestFrom(address, 2); 
  byte hibyte = Wire.read();
  byte lobyte = Wire.read();
  long raw = word( hibyte, lobyte); 
  Serial.print("raw:\t ")
  Serial.println( raw);

  int rangeMode = 250;  /// THIS IS SOME PARAM SOMEWHERE???

  int rd_flow = (raw - 1024) * rangeMode * 10 / 60000L;

  return rd_flow;
}

int temperature(uint8_t address)
{
  Wire.beginTransmission(address);
  Wire.write(0x00);   
  Wire.write(0xD0);  // reg 0 - address register high byte
  Wire.write(0x51);  // reg 1 - address register low byte
  Wire.write(0x18);  // reg 2  - serial control register - indicate # bytes among others (page 7 bottom)
  Wire.write(0x06);  // reg 3 - value to be written to SENS control register
  int x = Wire.endTransmission();

  delay(33);

  Wire.beginTransmission(address);
  Wire.write(0x00);   
  Wire.write(0xD0);
  Wire.write(0x61);
  Wire.write(0x2C);
  Wire.write(0x07);
  x = Wire.endTransmission();

  Wire.requestFrom(address, 2); 
  byte hibyte = Wire.read();
  byte lobyte = Wire.read();
  long raw = word( hibyte, lobyte); 
  Serial.print("raw:\t ")
  Serial.println( raw);

  int temp = (raw - 10214) * 1000L / 3739L;
  return temp;
}


code should be in some wrapping class someday to reduce the footprint....
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

tonazza

Hello,

I'm building a similar prototype with Arduino Duemilanove and Omron differential pressure sensor D6F-PH 5050AD3; I tried the code from robtillaart, but it wasn't working.
After searching a little bit, I found a differente application note for the sensor:
Application note from Mouser
that had one different register address, I tried it and...it worked!  :smiley-mr-green:

In addition to changing the address, I slightly modified the code to better follow what was indicated in the application note, and also to return a temperature with .1°C of resolution.
Furthermore, I added notes to adapt the differential pressure reading for all the 3 "sister" sensors:
D6F-PH0025AD1
D6F-PH0505AD3
D6F-PH5050AD3

Here's the code that worked for me:
Code: [Select]
int initialize(int i2c_addr)
{
  //INITIALIZATION AFTER POWER UP
  Wire.beginTransmission(i2c_addr);
  Wire.write(0x0B); 
  Wire.write(0x00);
  int x = Wire.endTransmission();
  return x;
}

int pressure(int i2c_addr)
{
  //MCU MODE
  Wire.beginTransmission(i2c_addr);
  Wire.write(0x00);   
  Wire.write(0xD0);  // reg 0 - address register high byte
//  Wire.write(0x51);  // reg 1 - address register low byte
  Wire.write(0x40);  // reg 1 - address register low byte
  Wire.write(0x18);  // reg 2  - serial control register - indicate # bytes among others (page 7 bottom)
  Wire.write(0x06);  // reg 3 - value to be written to SENS control register
  int x = Wire.endTransmission();

  delay(33);

  //WRITE
  Wire.beginTransmission(i2c_addr);
  Wire.write(0x00);   
  Wire.write(0xD0);
  Wire.write(0x51);
  Wire.write(0x2C);
  x = Wire.endTransmission();
 
  //READ
  Wire.beginTransmission(i2c_addr);
  Wire.write(0x07);
  x = Wire.endTransmission();

  Wire.requestFrom(i2c_addr, 2);
  byte hibyte = Wire.read();
  byte lobyte = Wire.read();
  long raw = word( hibyte, lobyte); 
  Serial.print("raw pressure:\t ");
  Serial.println(raw);
 
  // D6F-PH5050AD3 ==> rangeMode=500 ==> int rd_pressure =  ((raw - 1024) * rangeMode * 2 / 60000L) - rangeMode
  // D6F-PH0505AD3 ==> rangeMode=50  ==> int rd_pressure =  ((raw - 1024) * rangeMode * 2 / 60000L) - rangeMode
  // D6F-PH0025AD1 ==> rangeMode=250 ==> int rd_pressure=(raw - 1024) * rangeMode / 60000L
  int rangeMode = 500;
  int rd_pressure =  ((raw - 1024) * rangeMode * 2 / 60000L) - rangeMode;
  return rd_pressure;
}

float temperature(int i2c_addr)
{
  //MCU MODE
  Wire.beginTransmission(i2c_addr);
  Wire.write(0x00);   
  Wire.write(0xD0);  // reg 0 - address register high byte
  // Wire.write(0x51);  // reg 1 - address register low byte
  Wire.write(0x40);  // reg 1 - address register low byte 
  Wire.write(0x18);  // reg 2  - serial control register - indicate # bytes among others (page 7 bottom)
  Wire.write(0x06);  // reg 3 - value to be written to SENS control register
  int x = Wire.endTransmission();

  delay(33);
 
  //WRITE
  Wire.beginTransmission(i2c_addr);
  Wire.write(0x00);   
  Wire.write(0xD0);
  Wire.write(0x61);
  Wire.write(0x2C);
  x = Wire.endTransmission();
 
  //READ
  Wire.beginTransmission(i2c_addr);
  Wire.write(0x07);
  x = Wire.endTransmission();

  Wire.requestFrom(i2c_addr, 2); 
  byte hibyte = Wire.read();
  byte lobyte = Wire.read();
  long raw = word( hibyte, lobyte); 
  Serial.print("raw temperature:\t ");
  Serial.println(raw);
  int temp = round((float)(raw - 10214) / 3.739); // this is the temperature multiplied by 10...
  return (temp/10.0); // ...and the function returs the float temperature with 0.1°C resolution
}


Hope this helps!
Thanks to everyone  :D
Andrea

vikneshan

I am a newbie with the arduino platform and I am need of some help figuring out what the overall code would look like  :smiley-red: I'm basically trying to use arduino uno rev3 with D6F-PH0505AD3.

Doesn't seem to be working for me, any help is appreciated. Thank you.

Code: [Select]

#include "Wire.h"
#define addrs 0x6C // I2C bus address
int P;
int I;
float T;

int initialize(int i2c_addr)
{
  //INITIALIZATION AFTER POWER UP
  Wire.beginTransmission(i2c_addr);
  Wire.write(0x0B); 
  Wire.write(0x00);
  int x = Wire.endTransmission();
  return x;
}

int pressure(int i2c_addr)
{
  //MCU MODE
  Wire.beginTransmission(i2c_addr);
  Wire.write(0x00);   
  Wire.write(0xD0);  // reg 0 - address register high byte
//  Wire.write(0x51);  // reg 1 - address register low byte
  Wire.write(0x40);  // reg 1 - address register low byte
  Wire.write(0x18);  // reg 2  - serial control register - indicate # bytes among others (page 7 bottom)
  Wire.write(0x06);  // reg 3 - value to be written to SENS control register
  int x = Wire.endTransmission();

  delay(33);

  //WRITE
  Wire.beginTransmission(i2c_addr);
  Wire.write(0x00);   
  Wire.write(0xD0);
  Wire.write(0x51);
  Wire.write(0x2C);
  x = Wire.endTransmission();
 
  //READ
  Wire.beginTransmission(i2c_addr);
  Wire.write(0x07);
  x = Wire.endTransmission();

  Wire.requestFrom(i2c_addr, 2);
  byte hibyte = Wire.read();
  byte lobyte = Wire.read();
  long raw = word( hibyte, lobyte); 
  //Serial.print("raw pressure:\t ");
  //Serial.println(raw);
 
  // D6F-PH5050AD3 ==> rangeMode=500 ==> int rd_pressure =  ((raw - 1024) * rangeMode * 2 / 60000L) - rangeMode
  // D6F-PH0505AD3 ==> rangeMode=50  ==> int rd_pressure =  ((raw - 1024) * rangeMode * 2 / 60000L) - rangeMode
  // D6F-PH0025AD1 ==> rangeMode=250 ==> int rd_pressure=(raw - 1024) * rangeMode / 60000L
  int rangeMode = 50;
  int rd_pressure =  ((raw - 1024) * rangeMode * 2 / 60000L) - rangeMode;
  return rd_pressure;
}

float temperature(int i2c_addr)
{
  //MCU MODE
  Wire.beginTransmission(i2c_addr);
  Wire.write(0x00);   
  Wire.write(0xD0);  // reg 0 - address register high byte
  // Wire.write(0x51);  // reg 1 - address register low byte
  Wire.write(0x40);  // reg 1 - address register low byte 
  Wire.write(0x18);  // reg 2  - serial control register - indicate # bytes among others (page 7 bottom)
  Wire.write(0x06);  // reg 3 - value to be written to SENS control register
  int x = Wire.endTransmission();

  delay(33);
 
  //WRITE
  Wire.beginTransmission(i2c_addr);
  Wire.write(0x00);   
  Wire.write(0xD0);
  Wire.write(0x61);
  Wire.write(0x2C);
  x = Wire.endTransmission();
 
  //READ
  Wire.beginTransmission(i2c_addr);
  Wire.write(0x07);
  x = Wire.endTransmission();

  Wire.requestFrom(i2c_addr, 2); 
  byte hibyte = Wire.read();
  byte lobyte = Wire.read();
  long raw = word( hibyte, lobyte); 
  //Serial.print("raw temperature:\t ");
  //Serial.println(raw);
  int temp = round((float)(raw - 10214) / 3.739); // this is the temperature multiplied by 10...
  return (temp/10.0); // ...and the function returs the float temperature with 0.1°C resolution
}

void setup()
{  // Open serial communications
  Serial.begin(9600);
 I=initialize (addrs); // start wire connection

}

void loop()
{
    P=pressure(addrs);
    Serial.print("pressure:\t ");
    Serial.println(P);
    T=temperature(addrs);
    Serial.print("temperature:\t ");
    Serial.println(T);
    delay(30000); //delay for 30 seconds

}

robtillaart

Doesn't seem to be working for me, any help is appreciated. Thank you

Doesn't working is a broad problem definition. Can you please describe what is working, what not, what output you see, what you did expect etc.
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

vikneshan

#9
Apr 24, 2015, 06:00 pm Last Edit: Apr 24, 2015, 06:02 pm by vikneshan
Firstly, sorry for being vague.

I did not get any output displayed on the serial monitor.

I printed arbitrary strings to make sure it wasn't my arduino, and it showed up on the serial monitor.

I checked the solder/connections seem to be okay. Attached an image for my setup (not the best picture quality but will work :D).

Sensor side
1: SDA (blue)
2: GND (white)
3: VCC  (red)
4: SCL  (green)
Image Below:
https://plus.google.com/photos/117394791710767889393/albums/6141335354172729489/6141335359919124226?pid=6141335359919124226&oid=117394791710767889393

Arduino side (http://forum.arduino.cc/index.php?topic=84190.0)
white to GND
red to 3.3 V
green to SCL pin
blue to SDA pin
green to SCL

Image Below:
https://plus.google.com/photos/117394791710767889393/albums/6141335354172729489/6141335370457936290?pid=6141335370457936290&oid=117394791710767889393

Thank you in advance, any suggestions would be appreciated.

vikneshan

Silly me :smiley-confuse: , was missing one line of code in the setup "Wire.begin()"

Thanks!

Code: [Select]
#include "Wire.h"
#define addrs 0x6C // I2C bus address
int P;
int I;
float T;

int initialize(int i2c_addr)
{
  //INITIALIZATION AFTER POWER UP
  Wire.beginTransmission(i2c_addr);
  Wire.write(0x0B); 
  Wire.write(0x00);
  int x = Wire.endTransmission();
  return x;
}

int pressure(int i2c_addr)
{
  //MCU MODE
  Wire.beginTransmission(i2c_addr);
  Wire.write(0x00);   
  Wire.write(0xD0);  // reg 0 - address register high byte
//  Wire.write(0x51);  // reg 1 - address register low byte
  Wire.write(0x40);  // reg 1 - address register low byte
  Wire.write(0x18);  // reg 2  - serial control register - indicate # bytes among others (page 7 bottom)
  Wire.write(0x06);  // reg 3 - value to be written to SENS control register
  int x = Wire.endTransmission();

  delay(33);

  //WRITE
  Wire.beginTransmission(i2c_addr);
  Wire.write(0x00);   
  Wire.write(0xD0);
  Wire.write(0x51);
  Wire.write(0x2C);
  x = Wire.endTransmission();
 
  //READ
  Wire.beginTransmission(i2c_addr);
  Wire.write(0x07);
  x = Wire.endTransmission();

  Wire.requestFrom(i2c_addr, 2);
  byte hibyte = Wire.read();
  byte lobyte = Wire.read();
  long raw = word( hibyte, lobyte); 
  //Serial.print("raw pressure:\t ");
  //Serial.println(raw);
 
  // D6F-PH5050AD3 ==> rangeMode=500 ==> int rd_pressure =  ((raw - 1024) * rangeMode * 2 / 60000L) - rangeMode
  // D6F-PH0505AD3 ==> rangeMode=50  ==> int rd_pressure =  ((raw - 1024) * rangeMode * 2 / 60000L) - rangeMode
  // D6F-PH0025AD1 ==> rangeMode=250 ==> int rd_pressure=(raw - 1024) * rangeMode / 60000L
  int rangeMode = 50;
  int rd_pressure =  ((raw - 1024) * rangeMode * 2 / 60000L) - rangeMode;
  return rd_pressure;
}

float temperature(int i2c_addr)
{
  //MCU MODE
  Wire.beginTransmission(i2c_addr);
  Wire.write(0x00);   
  Wire.write(0xD0);  // reg 0 - address register high byte
  // Wire.write(0x51);  // reg 1 - address register low byte
  Wire.write(0x40);  // reg 1 - address register low byte 
  Wire.write(0x18);  // reg 2  - serial control register - indicate # bytes among others (page 7 bottom)
  Wire.write(0x06);  // reg 3 - value to be written to SENS control register
  int x = Wire.endTransmission();

  delay(33);
 
  //WRITE
  Wire.beginTransmission(i2c_addr);
  Wire.write(0x00);   
  Wire.write(0xD0);
  Wire.write(0x61);
  Wire.write(0x2C);
  x = Wire.endTransmission();
 
  //READ
  Wire.beginTransmission(i2c_addr);
  Wire.write(0x07);
  x = Wire.endTransmission();

  Wire.requestFrom(i2c_addr, 2); 
  byte hibyte = Wire.read();
  byte lobyte = Wire.read();
  long raw = word( hibyte, lobyte); 
  //Serial.print("raw temperature:\t ");
  //Serial.println(raw);
  int temp = round((float)(raw - 10214) / 3.739); // this is the temperature multiplied by 10...
  return (temp/10.0); // ...and the function returs the float temperature with 0.1°C resolution
}

void setup()
{  // Open serial communications
 Wire.begin();
  Serial.begin(9600);
 I=initialize (addrs); // start wire connection

}

void loop()
{
    P=pressure(addrs);
    Serial.print("pressure:\t ");
    Serial.println(P);
    T=temperature(addrs);
    Serial.print("temperature:\t ");
    Serial.println(T);
    delay(30000); //delay for 30 seconds

}

koosjr


vaszi1983

#12
Jul 02, 2017, 08:39 pm Last Edit: Jul 02, 2017, 08:49 pm by vaszi1983
Hello. I know is an old topic but I have the same setup Omron D6F PH series differential pressure sensor and arduino genuino uno wired as in your image but I can not figure out where to read the measured value after I uploaded successful the firmware in Arduino IDE. I have a Nokia 5110 LCD hooked to the same arduino but shows nothing now after uploading the code from this topic.

About myself I am new in programing I played before the Genuino Uno with a Mega 2560 and a 3 D printer
modifying the printing size etc after rebuild it to be bigger.

The scope of the project is to measure the human breath pressure in the nose after using sinus heating Mask. The sensor is mesuring from 0 - 250 Pa D6F-PH0025AD1.

Go Up