Honeywell I2C communication

Hi everyone,

I recently bought a honeywell humidity sensor. This sensor uses I2C communication. I’m trying to write some simple code to receive the measurements. Honeywell has a document that explains how the communication works: http://sensing.honeywell.com/i2c-comms-humidicon-tn-009061-2-en-final-07jun12.pdf

This is the code i wrote:

#include <Wire.h>

#define disk1 0x27

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

}

void loop() {
  int* array = ReceiveTemp(disk1);
  Serial.println(array[0]);
  Serial.println(array[1]);
  Serial.println(array[2]);
  Serial.println(array[3]);
  Serial.println(array[10]);
  delay(1000);
  }

int* ReceiveTemp(int deviceaddress) 
{
  Wire.beginTransmission(deviceaddress); //Requesting data
  Wire.write(deviceaddress);   
  Wire.endTransmission();
  Wire.requestFrom(deviceaddress,4 ); //Receiving data
  int i = 0;
  int* array;
  while (i<4) {
    if (Wire.available()){
      array[i]=Wire.read();
      i+=1;
      delay(5);
    }
  }
  return array;
}

I’ll run you guys through quickly: The sensor always uses the adress 0x27.
To request data you should first send a start message (i just guessed that this was beginTransmission) and then you should send the adress with a writebit followed by a stop message. So these are the first three lines in ReceiveTemp function. Now the data is requested.

This is the point where i get confused. Now the data should be received. The document sais that i have to send a start statement. After that i should send the sensor adress and a read bit (i guess this is the read() function?). Then i must ‘acknowledge’ the receive by a acknowledge bit. But how do i do that? And how do i put the data in variables?

Any help is greatly appreciated!

 int* array;
  while (i<4) {
    if (Wire.available()){
      array[i]=Wire.read();

What are you writing to there?

Hi,
What model Humidity Sensor.

did you google

honeywell humidity sensor arduino I2C

Tom... :slight_smile:

Hi guys,

Thanks for the quick replies!

@AWOL: Its an attempt to store the data, coming from the sensor in an array. I'm quite sure that the problem is at that point of the code. But i don't really know what "requestFrom" bitwise does. What bits does it send? I thought that "requestFrom" perhaps was a bit like an integrated function that sends the startbit and then when "read" is called automatically sends an acknowledge bit. I'm also a bit in the dark about the "available" function :stuck_out_tongue: As you can see i don't really get what the wire-library exactly does.

@Tom: it's the HIH8120-021-001 but i thought this wasn't relevant because all the I2C communication would use the same protocol.

Greetings,

Lolbroek

You're absolutely correct - that is where at least one problem is.
Ask yourself "array is a pointer. What does it point to?"

(OK, it points to an int, but where is that int?)

hmm, i'm not really a programming expert but by googling it i understood that a pointer is just the 'name' of a variable, this name is linked to a memory adress which on its turn indicates where the actual data is stored.

So i guess: Array(i)->computer adress of element i in array->data of element i in array. And this data is stored in the flash memory of the arduino or something?

Hint: I don’t know where the memory array points to is

Sorry i don't get it :stuck_out_tongue: Are you saying that i'm using the variable out of its scope?

No, I'm saying nothing (yet) about the scope of the variable ( the compiler would have told you about the more obvious scope problems).

You pointed out that "array" is a variable.
Does it have a value?

You don't need Wire.write to send the address.

You setup the address in the call to begintransmission and it will be sent when you call endtranission.

You might have to send something else but I can't read the linked documentation at the moment

@AWOL I guess it does, when i run the program it gives for every index a different value but the problem is that the values do not change and they're just not correct. So array is an 'array' of ints?

@sterretje i know that the beginTransmission function already sends the adress but in the honeywell guide they say explicitly "a Measurement Request command consists of the Slave address plus the WRITE bit (0)". So that is why i added that line.

Time to spell it out.
"array" is a pointer.
You didn't give it a value, so it points . . . who knows where?
So you're writing to memory you don't own; could be RAM, might not be. Could be registers, might not be.

Hi,
I found this relating to HIH6130 Hum Sensor.

Also a doc on I2C for it.
I don’t know but the examples may work.

Hope it helps… Tom… :slight_smile:

Honeywell_I2CCommunications.pdf (133 KB)

@AWOL: I don’t really get it (i’m really not a programming expert). Why does it matter where he writes it? Even if i give array an initial value i still wouldn’t have a clue where he actually writes that value. Is this code better then:

int* ReceiveTemp(int deviceaddress) 
{
  Wire.beginTransmission(deviceaddress);
  Wire.write(deviceaddress);   // MSB
  Wire.endTransmission();
  Wire.requestFrom(deviceaddress,4 );
  int i = 0;
  int* array = 0; //this better AWOL?
  while (i<4) {
    if (Wire.available()){
      array[i]=Wire.read();
      i+=1;
      delay(5);
    }
  }
  return array;
}

@Tom thanks i’ll try it this evening, i already tried another library and that didn’t work i hope this will.

Your variable 'array' is not an array. You need to allocate space for an array.

int array[4];

tells the compiler to set aside space for 4 integers. Your code however sets aside space for a pointer.

To make the above work with your code, you need to add the 'static' keyword at the beginning of the line; that will prevent the array variable from going out of scope (and the data being lost) when the function is finished.

PS I'm 99% sure you have misinterpreted the honeywell spec.

Hahaha i'm also sure that i'm quite far from the solution :p, i just lack programming skills. I'll try this library and if that doesn't work i'll come back here crying for help.

@AWOL: I don't really get it (i'm really not a programming expert). Why does it matter where he writes it?

Because you must not write to memory that you don't own.

@Tom i tried your librarie and this one aswell doesnt work. It runs but it just doesn’t output any data. It hangs after the line: hih6130.readSensor().

So i started digging into the library. In this function i noticed something strange. It sais ‘while (Wire.available() == 0);

which is strange i would expect !=0 because you want data to be available when you read it. Below you can see the whole function in the library.

void HIH6130::readSensor(){
  // reads data from the sensor and stores them in temporary variables that
  // are then accessed via public variables
  Wire.beginTransmission(_address);
  Wire.endTransmission();

  Wire.requestFrom( (int) _address, (int) 4);
  while (Wire.available() == 0);

  _humidity_hi = Wire.read();
  _humidity_lo = Wire.read();
  _temp_hi = Wire.read();
  _temp_lo = Wire.read();

  Wire.endTransmission();

  // Get the status (first two bits of _humidity_hi_)
  _status = (_humidity_hi >> 6);

  // Calculate Relative Humidity
  humidity = (float)(((unsigned int) (_humidity_hi & 0x3f) << 8) | _humidity_lo) * 100 / (pow(2,14) - 1);

  // Calculate Temperature
  temperature_C = (float) (((unsigned int) (_temp_hi << 6) + (_temp_lo >> 2)) / (pow(2, 14) - 1) * 165 - 40);
    
    // Calculate Temperate in Fahrenheit. Using the formula F = C * 1.8 + 32
    temperature_F = temperature_C * 1.8 + 32;
}

lolbroek:
So i started digging into the library. In this function i noticed something strange. It sais 'while (Wire.available() == 0);'

which is strange i would expect !=0 because you want data to be available when you read it.

Note the semi-colon at the end of the while statement. It waits till data is available before continuing.

ah got it, the following lines are not in the while loop. is that statement than identical to this one:

while (Wire.available() == 0){
};

Still it remains strange to me, because I2C communication can only read 8 bits at a time, and the sensor should send four times 8 bits. Wouldn't you have to check availability 4 times then?