Go Down

Topic: I2C Pressure Sensor (Read 4201 times) previous topic - next topic

pasta1234

Thanks for help so much Rob !!

The following was the result of the serial monitor after running the sketch..

Quote

endTransmission: 2
byte 1: 101
byte 2: 188

endTransmission: 0


Much appreicated :)
Pete

robtillaart


pdf page 4

                    Output (dec) - 1,638 
  Pressure (mbar) = ------------------------- +600
                             30.84

Code: [Select]

float toPressure(byte hi, byte lo)
{
  int t = (hi * 256 + lo) & 0x3FFF;  // see pdf, mask 14 bit
 
  float rv = (t - 1638.0) / 30.84 + 600.0;  // (t - 1638.0) * 0.032425422 + 600.0 // faster
  return rv;
}


byte 1: 101 (low?)
byte 2: 188 (high?)
fill in => 1048 seems a reasonable value
Rob Tillaart

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

pasta1234

Again Rob, I really appreciate your time and help !!

I appended and modified the code to the following complete sketch:

Code: [Select]

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


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

void loop()
{
 
   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 your first two registers
   while(Wire.available() < 2 );          // Check for data from slave
   {   
      delay(1000);
      lobyte = Wire.read();       // Read press high byte
      Serial.println(lobyte, DEC);
      hibyte = Wire.read();      // Read press low byte
      Serial.println(hibyte, DEC);
     
      Press = toPressure(hibyte, lobyte);
      Serial.print("Pressure: ");
      Serial.println(Press);
     
      delay(1000);
   }
   
}
   
   
float toPressure(byte hi, byte lo)
{
  int t = (hi * 256 + lo) & 0x3FFF;  // see pdf, mask 14 bit
 
  float rv = (t - 1638.0) / 30.84 + 600.0;  // (t - 1638.0) * 0.032425422 + 600.0 // faster
  return rv;
 



When the sketch Runs as is, i get the following out on the serial monitor:
Quote

endTransmission: 2
103
177
Pressure: 956
endTransmission: 0


I have two questions...
1. Why is it when i remove the following lines of code, the serial monitor shows nothing, it seems to me it should have no affect ?
Code: [Select]

Serial.print("endTransmission: ");
Serial.println(x, DEC);


2. How do i get it to constantly update and report the Pressure instead of only running once ?

Thanks,
Pete

robtillaart

check - http://tronixstuff.wordpress.com/2010/10/20/tutorial-arduino-and-the-i2c-bus/ -


try move the first delay(1000); outside the if and place it instead of the 2 print statements.
Rob Tillaart

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

pasta1234

Thanks a lot for your Help Rob, everything worked well and i am learning a lot :)

At this point i need to incorporate this sensor as well,
http://www.smartec-sensors.com/assets/files/pdf/manuals/SMTH08INv2.2.pdf
http://www.sensorguys.com/pdfs/SMTH08IN.pdf

How do i incorporate both sensors considering they use 3.3V & 5V I2C Systems ?

The datasheet is rather confusing to me, how do i read this sensor, do i need to initiate a "conversion" first ?

Some general help and or skeleton code would be appreciated.

Pete

robtillaart

sparkfun or farnell sell 5V - 3.3V convertors for I2C. That should be the first step.
Then you can see if the I2C scanner on the playground sees it address.
Third step is checking if you can read the config registers.
(I have no time to dive into the datasheet now, sorry)

Rob Tillaart

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

robtillaart

OK a quick look than,
the protocol looks not too difficult, If I am correct you need to request 4 bytes and do some math on them.

It can be done quite similar as the other sensor, something like below.

(partial concept code)
Code: [Select]

Wire.requestFrom(addrs, 4); // contents of your first two registers
   while(Wire.available() < 4 );          // Check for data from slave
   {   
      delay(1000);
      lobyte = Wire.read();       // Read press high byte
      Serial.println(lobyte, DEC);
      hibyte = Wire.read();      // Read press low byte
      Serial.println(hibyte, DEC);
     
      Temp= toTemperature(hibyte, lobyte);
      Serial.print("Temperature: ");
      Serial.println(Temp);

      lobyte = Wire.read();       // Read press high byte
      Serial.println(lobyte, DEC);
      hibyte = Wire.read();      // Read press low byte
      Serial.println(hibyte, DEC);
     
      Hum = toHumidity(hibyte, lobyte);
      Serial.print("Humidity: ");
      Serial.println(Hum);     
      delay(1000);
   }


Now it is your turn ;)
Rob Tillaart

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

robtillaart

check the datasheet for timing (5 seconds), humidity readers need multiple seconds between readings. (DHT series have 2 seconds, but seem not as accurate)
Rob Tillaart

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

pasta1234

Thanks for the advice Robert, I purchased the logic level converter and finally got it connected earlier today. I ran the I2C scanner tool on the sensor and got a hit at 0X10 address.

When i run the below code, i get the values 87,232,103,29 on the serial monitor. What i find strange is blowing gently on the sensor does not cause any data value variation, which leads me to believe its bogus data, is that a correct assumption ?

Is this just a timing issue, advice ?

Thanks,
Pete


Code: [Select]

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


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

void loop()
{
 
   byte lobyte;
   byte hibyte;
 
   

Wire.requestFrom(addrs, 4); // contents of your first four registers
   while(Wire.available() < 4 );          // Check for data from slave
   {   
      delay(5000);
     
      lobyte = Wire.read();       // Read hum high byte
      Serial.println(lobyte, DEC);
      hibyte = Wire.read();      // Read hum low byte
      Serial.println(hibyte, DEC);

//      Hum = toHumidity(hibyte, lobyte);
//      Serial.print("Humidity: ");
//      Serial.println(Hum);
     

      lobyte = Wire.read();       // Read temp high byte
      Serial.println(lobyte, DEC);
      hibyte = Wire.read();      // Read temp low byte
      Serial.println(hibyte, DEC);
     
//     Temp= toTemperature(hibyte, lobyte);
//     Serial.print("Temperature: ");
//     Serial.println(Temp);
   
      delay(1000);
     
   }
}   

robtillaart

can you post some more output?
Rob Tillaart

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

pasta1234

The output was these four values over and over...

87
232
103
29

Hope that helps..

Pete

robtillaart

It rings no bell, especially as they are the same over and over again.

please add:

uint8_t n = Wire.requestFrom(addrs, 4); 
Serial.println(n, DEC);

Rob Tillaart

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

Erdin

This is wrong:
Code: [Select]

while(Wire.available() < 4 );


The line "Wire.requestFrom(addrs, 4);" is a complete I2C session (devices is addressed, data is requested and received and put in a buffer, I2C session is closed).

The "Wire.available()" returns the number of bytes in the buffer. But the I2C session has already ended. So waiting for something is wrong.
The return value of "Wire.requestFrom()" is the same as "Wire.available()" (until you start reading data from the buffer.

I didn't read all the posts, but according to the datasheet, the I2C address is 0x78.
Did you run the i2c_scanner ?
http://playground.arduino.cc/Main/I2cScanner

I think you only have to read 2 bytes.
It is possible to read more bytes during the same I2C session, but that is to increase the data rate.
For now, you only want to try to communicate with the sensor.
I assume that the first byte is the high byte.

Code: [Select]

Wire.requestFrom( addrs, 2);  // contents of the two registers
if( Wire.available() == 2)
{   
  byte hibyte = Wire.read();
  byte lobyte = Wire.read();
  unsigned int pressure = word( hibyte, lobyte);
  Serial.print( pressure);
}
else
{
  Serial.println( "Didn't receive 2 bytes");
}


http://arduino.cc/en/Reference/WordCast

Please remove the humidity and temperature part. It is confusion. You should only use this as a test sketch to try to communicate with the sensor.

pasta1234

I appreciate the help as always !!!

Robert,

I have appended the code with lines you mentioned...

Code: [Select]

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


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

void loop()
{
 
   byte lobyte;
   byte hibyte;
 
   

Wire.requestFrom(addrs, 4); // contents of your first four registers
   while(Wire.available() < 4 );          // Check for data from slave
   {   
      delay(5000);
     
      lobyte = Wire.read();       // Read hum high byte
      Serial.println(lobyte, DEC);
      hibyte = Wire.read();      // Read hum low byte
      Serial.println(hibyte, DEC);

//      Hum = toHumidity(hibyte, lobyte);
//      Serial.print("Humidity: ");
//      Serial.println(Hum);
     

      lobyte = Wire.read();       // Read temp high byte
      Serial.println(lobyte, DEC);
      hibyte = Wire.read();      // Read temp low byte
      Serial.println(hibyte, DEC);
     
//     Temp= toTemperature(hibyte, lobyte);
//     Serial.print("Temperature: ");
//     Serial.println(Temp);
   
      delay(1000);
     
      uint8_t n = Wire.requestFrom(addrs, 4);
      Serial.println(n, DEC);
     
     
   }
}   


When i run the program, the serial monitor outputs the following (repeats):

Quote

100
20
98
117
4
100
20
98
117
4


Erdin,

Wrong sensor, i mentioned another Humidity and Temp later on the thread..take a look :)

Pete

Erdin

This part does not what it should do:
Code: [Select]

while(Wire.available() < 4 );          // Check for data from slave
   {   
...


The ';' after the while closes the while statement.
The '{' is not used. But you don't get an error message.

Could you do this:
Code: [Select]

// while(Wire.available() < 4 );
if( Wire.available() == 4)      // check if actually 4 bytes are received.
...

Go Up