HIH6130 address change - syntax errors in example code

There are many HIH6130 libraries out there.
I installed and tried all of them.

One example that worked for me was
HIH6130tester.ino from HIH6130-master.zip

I bought 3 sensors, spending $120

I need 3 different addresses for 3 sensors. Right now there is an LCD screen that is already usingx27
So far I tried 6 different libraries with attached examples.

HIH6130-master.zip - HIH6130-master (by David Hagan Dec 2, 2014) - only one that works!
HIH6130_Breakout-master.zip
20130224-HIH6130_Arduino.zip
HIH-0.2.tar.gz - had to extract and ZIP 2 included folders to get them to install.
cactus_io_HIH6130.zip
HIH61xx by Steve Marlpe - comes up in the library search in Arduino IDE, Arduino IDE offers to install it. Example compiles if I install all the libraries it uses - did not test.

I deleted libraries from C:\Users\VTolskiy\Documents\Arduino\libraries
to prevent interference. There is no option to uninstall or disable a library.

ALL PROGRAMS FOR CHANGING THE I2C ADDRESS of the sensor give syntax errors and refuse to compile (for any board)
WHY?

I am using:
Newly installed Arduino IDE 1.8.1
Windows 8.1
Arduino Micro Pro - never got to uploading stage

MAYBE THE PROBLEM IS IN Wire.h that I am using. I am using the one that came with the new version of Arduino.

I get all kinds of errors. I can make a table that would list libraries, example code and errors that I receive.

How do I get it to work?
Thank you.

Declaring a library itself generates an error.
Commented code shown on purpose. Research suggests that it has to do with how libraries are installed:

http://www.muratarslan.me/humidity-temperature-sensors-hih6130-6131-and-hih6120-6121-series/

//  Arduino pin connection;
//  SDA -> A4
//  SCL -> A5
//  GND -> GND
//  VDD -> 3.3v (If you want to use Command Mode you must connect it to D3)

#include <Wire.h>
//#include <HIH61xx.h>
#include <HIH61XXCommander.h>

////  Create an HIH61XXCommander with I2C address 0x**
//HIH61XXCommander hih(0x27, 3);
//
//
void setup()  
{
//  Serial.begin(9600);
//  Wire.begin();
}
//
//
void loop()  
{
//  //  Starts the sensor
//  hih.start();
//
//  //  Set I2C address to 0x**:
//  hih.setAddress(0x29);
//  hih.restart();      
//
//  //  Close Command Mode
//  hih.leaveCommandMode();
//
//  //  Update the datas in eprom 
////  hih.update();
//
}

You forgot the link to the libraries you're listing!

I got this example to work: HIH_Commander_Mode.ino
No special libraries are used, only Wire.h

I decided to combine the commender with an I2C tester: Test_I2C.ino

End result should be that the I2C scanner gives me some feedback about the successful address change.
I use page 5 of a PDF named honeywell-tn-entering-command-mode.pdf
for reference.

So far I had not successfully changed the I2C address. Why?
I am really not sure about what I am doing. To me this is all trial and error based.

I can proudly announce that I get this:
Unknow error at address 0x01
Unknow error at address 0x02
Unknow error at address 0x03
Unknow error at address 0x04
Unknow error at address 0x05
Unknow error at address 0x06
instead of this:
I2C device found at address 0x27

New Arduino IDE gets stuck a lot in the Serial Monitor mode,
so I may add some updates to this message.
Thank you.

HIH_Commander_Mode.ino (4.16 KB)

Test_I2C.ino (2.07 KB)

HIH_Commander_Mode_2.ino (6.93 KB)

honeywell-tn-entering-command-mode.pdf (160 KB)

pylon: You forgot the link to the libraries you're listing!

I may upload links later. For now I want to focus on things that work, not things that dont work.

Cross examination of all those libraries that fail to work with HIH6130 is not at the top of my agenda

I may upload links later. For now I want to focus on things that work, not things that dont work.

Then focus yourself. I won't help you if you don't provide the information needed!

There is a bug in HIH_Commander_Mode.ino which will prevent it ever changing the I2C address. This:

    write_word(0x5b, 40.0);  // change I2C

should be

    write_word(0x5c, 40.0);  // change I2C

I have no idea why it is specifying the address as a floating point number!

Pete

It is a mystery why they use floating point. I want to represent every number as a binary in my program to make it easier to read.

Is my byte loading sequence correct, based on the datasheet that I provided. The datasheet is a legitimate Honeywell reference. Everything else has bugs in it.

el_supremo: There is a bug in HIH_Commander_Mode.ino which will prevent it ever changing the I2C address. This:

    write_word(0x5b, 40.0);  // change I2C

should be

    write_word(0x5c, 40.0);  // change I2C

I have no idea why it is specifying the address as a floating point number!

Pete

There is write_word(0x5e, 0xA5D3); write_word(0X5f, 0x5A53); There is also this: write_alarm(0x5b, 40.0); // low alarm off

I don't see any write_word(0x5c, 40.0); // change I2C

I want someone with more experience to help me formulate that binary number that gets fed into the HIH6130. I want to know what each individual bit does. I have no experience reading the datasheet and turning those bit register charts into the code that works.

Thank you.

// HIH_6130_2  - Arduino
// 
// Arduino                HIH-6130
//
// Digital 4 ------------ Vdd (term 8) // Note that the Arduino provides power to the device.
//
// SCL (Analog 5) ------- SCL (term 3)
// SDA (Analog 4) ------- SDA (term 4)
//
// Note 2.2K pullups to _5 VDC on both SDA and SCL
//
// copyright, Peter H Anderson, Baltimore, MD, Oct 14, '11
// You may use it, but please give credit.
    
#include <Wire.h> //I2C library

//#include <HIH61XX.h>
//#include <HIH61XXCommander.h>


void write_word(byte command, unsigned int dat);
unsigned int read_word(byte command); 
void write_alarm(byte command, float huma_alm);
float read_alarm(byte command);


#define TRUE 1
#define FALSE 0

void setup(void)
{
    Serial.begin(9600);
    Wire.begin();
    pinMode(4, OUTPUT);
    digitalWrite(4, LOW);
    delay(5000);

  
    Serial.println("\nI2C Scanner");
    Serial.println(">>>>>>>>>>>>>>>>>>>>>>>>");  // just to be sure things are working
}
    
void loop(void)
{

    byte error, address; // 2/22
    int nDevices;        // 2/22
    
    byte n;
    unsigned int w;
    float v;
    
    digitalWrite(4, HIGH);  // turn on power
    write_word(0xa0, 0x0000);  // and enter command mode within 10 ms
  
    for (n=0; n<0x20; n++)
    {
        w = read_word(n);
        Serial.print(n, HEX);
        Serial.print("  ");
        print_hex(w, 16);
        Serial.println();
    }
    
    write_alarm(0x58, 80.0);  // high alarm on          //80.0 = 0x50 = 0b1010000
    write_alarm(0x59, 75.0);  // high alarm off         //75.0 = 0x4B = 0b1001011
 
    write_alarm(0x5a, 33.0);  // low alarm on           //33.0 = 0x21 =  0b100001
    write_alarm(0x5b, 40.0);  // low alarm off          //40.0 = 0x28 =  0b101000


    //ORIGINAL CODE
    /*
    write_word(0x5e, 0xa5a5); // write data to customer ID locations
    write_word(0X5f, 0x5a5a);
    */

    //0x5a5a =  0b101101001011010
    //0xa5a5 = 0b1010010110100101
    
    // change I2C
    
    //0xF800 = 0b1111100000000000
    // (1) try stick it in here to change address
    //From the Datasheet: 
    //Set I2C Address = 0x53 (Write Bits 6:0 of Customer Configuration Register = 0b1010011)
    //
    //                                                                           bbbbbbb bbbbb b bbbb                                                                                             
    //                                                                           bits 6:0   65 4 3210
    //Set I2C Address = 0x53 (Write Bits 6:0 of Customer Configuration Register = 0b        10 1 0011)
    //
    //                                                                 0xa5a5 = 0b1010010 1101 0 0101
    //                                                                          0b1010010 1110 1 0011 = 0xA5D3
                                                          write_word(0x5e, 0xA5D3); // write data to customer ID locations
                //53 =  0b110101
                //83 = 0b1010011
                
    //From the Datasheet:
    /*
    Make Alarm_Low = Active High (Write Bit 7 of Customer Configuration Register = 0)
    Make Alarm_Low = Push-Pull (Write Bit 8 of Customer Configuration Register = 0)
    Make Alarm_High = Active High (Write Bit 9 of Customer Configuration Register = 0)
    Make Alarm_High = Push-Pull (Write Bit 10 of Customer Configuration Register = 0)
    Make Command Window = 3 ms (Write Bit 13 of Customer Configuration Register = 1)
    */

    // (2) try stick it in here to change the address instead

    //                                                                            0b1010010110100101
    //                                                                                       1010011
    //                                                                            0b1010010111010011 = 0xA5D3
                                             write_word(0X5f, 0xA5D3);
    //Set I2C Address = 0x53 (Write Bits 6:0 of Customer Configuration Register = 0b         1010011


       
    Serial.println(".......");
    
    for (n=0x18; n<0x20; n++)
    {
        w = read_word(n);
        Serial.print(n, HEX);
        Serial.print("  ");
        print_hex(w, 16);
        Serial.println();
    }  
    
    Serial.println("...........................");
    
    for (n=0x18; n<=0x1b; n++)
    {
        v = read_alarm(n);
        Serial.print(n, HEX);
        Serial.print("  ");
        print_float(v, 2);
        Serial.println();
    }
  
    write_word(0x80, 0x0000);  // go to normal operation
   
  Serial.println("Done Programming");

  Serial.println("Scanning for I2C Changes");

  nDevices = 0;
  for(address = 1; address < 127; 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("Unknow 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(1500);           // wait 15 seconds for next scan
}

void write_word(byte command, unsigned int dat)
{
      byte H, L;
      H = dat >> 8;
      L = dat & 0xff;
      
      Wire.beginTransmission(0x27);
      Wire.write(command);
      Wire.write(H);
      Wire.write(L);
      Wire.endTransmission();
      delay(15);
}

unsigned int read_word(byte command)
{
     byte high, low, response_byte;
     unsigned int w;
     
     write_word(command, 0x0000);      
     Wire.requestFrom((int) 0x27, (int) 3);
     response_byte =Wire.read();
     high =Wire.read();
     low =Wire.read();
     Wire.endTransmission();
     w = high;
     w = w *256 + low;
     return(w);
}    

void write_alarm(byte command, float huma_alm)
{
    unsigned int w;
    w = (unsigned int)(huma_alm * 163.83);
    write_word(command, w);
}

float read_alarm(byte command)
{
    unsigned int w;
    float v;
    
    w = read_word(command);
    v = ((float) w) * 6.103e-3;
    return(v);
}
      
void print_hex(int v, int num_places)
{
    int mask=0, n, num_nibbles, digit;

    for (n=1; n<=num_places; n++)
    {
        mask = (mask << 1) | 0x0001;
    }
    v = v & mask; // truncate v to specified number of places

    num_nibbles = num_places / 4;
    if ((num_places % 4) != 0)
    {
        ++num_nibbles;
    }

    do
    {
        digit = ((v >> (num_nibbles-1) * 4)) & 0x0f;
        Serial.print(digit, HEX);
    } while(--num_nibbles);

}
  
void print_float(float f, int num_digits)
{
    int f_int;
    int pows_of_ten[4] = {1, 10, 100, 1000};
    int multiplier, whole, fract, d, n;

    multiplier = pows_of_ten[num_digits];
    if (f < 0.0)
    {
        f = -f;
        Serial.print("-");
    }
    whole = (int) f;
    fract = (int) (multiplier * (f - (float)whole));

    Serial.print(whole);
    Serial.print(".");

    for (n=num_digits-1; n>=0; n--) // print each digit with no leading zero suppression
    {
         d = fract / pows_of_ten[n];
         Serial.print(d);
         fract = fract % pows_of_ten[n];
    }
}

Made some changes to the code - the address haven’t changed still.

I need help writing a program that would scan the memory, convert it to what it means, according to the datasheet.
Then put new data into the sensor memory and tell me how it interprets what it recorded, bit by bit.
Otherwise it is very confusing.

This was a test code that proved that the code changes nothing.
write_word(0x5e, 0b10000000);
write_word(0X5f, 0b10000000);

(Powering through pin 4 works. I did a simple test. My sensor can be either powered by pin 4 or by an external power supply. When I disconnect the supply, the program stops reporting.)

I just wasted some money on the sensors because the code for them does not work. :frowning: :frowning: :frowning:

// HIH_6130_2  - Arduino
// 
// Arduino                HIH-6130
//
// Digital 4 ------------ Vdd (term 8) // Note that the Arduino provides power to the device.
//
// SCL (Analog 5) ------- SCL (term 3)
// SDA (Analog 4) ------- SDA (term 4)
//
// Note 2.2K pullups to _5 VDC on both SDA and SCL
//
// copyright, Peter H Anderson, Baltimore, MD, Oct 14, '11
// You may use it, but please give credit.
    
#include <Wire.h> //I2C library

//#include <HIH61XX.h>
//#include <HIH61XXCommander.h>


void write_word(byte command, unsigned int dat);
unsigned int read_word(byte command); 
void write_alarm(byte command, float huma_alm);
float read_alarm(byte command);


#define TRUE 1
#define FALSE 0

void setup(void)
{
    Serial.begin(9600);
    Wire.begin();
    pinMode(4, OUTPUT);
    digitalWrite(4, LOW);
    delay(5000);

  
    Serial.println("\nI2C Scanner");
    Serial.println(">>>>>>>>>>>>>>>>>>>>>>>>");  // just to be sure things are working
}
    
void loop(void)
{

    byte error, address; // 2/22
    int nDevices;        // 2/22
    
    byte n;
    unsigned int w;
    float v;
    
    digitalWrite(4, HIGH);  // turn on power
    write_word(0xa0, 0x0000);  // and enter command mode within 10 ms
  
    for (n=0; n<0x20; n++)
    {
        w = read_word(n);
        Serial.print(n, HEX);
        Serial.print("  ");
        print_hex(w, 16);
        Serial.println();
    }
    
    write_alarm(0x58, 80.0);  // high alarm on          //80.0 = 0x50 = 0b1010000
    write_alarm(0x59, 75.0);  // high alarm off         //75.0 = 0x4B = 0b1001011
 
    write_alarm(0x5a, 33.0);  // low alarm on           //33.0 = 0x21 =  0b100001
    write_alarm(0x5b, 40.0);  // low alarm off          //40.0 = 0x28 =  0b101000


    //ORIGINAL CODE
    /*
    write_word(0x5e, 0xa5a5); // write data to customer ID locations
    write_word(0X5f, 0x5a5a);
    */

    //0x5a5a =  0b101101001011010
    //0xa5a5 = 0b1010010110100101
    
    // change I2C
    
    //0xF800 = 0b1111100000000000
    // (1) try stick it in here to change address
    //From the Datasheet: 
    //Set I2C Address = 0x53 (Write Bits 6:0 of Customer Configuration Register = 0b1010011)
    //
    //                                                                           bbbbbbb bbbbb b bbbb                                                                                             
    //                                                                           bits 6:0   65 4 3210
    //Set I2C Address = 0x53 (Write Bits 6:0 of Customer Configuration Register = 0b        10 1 0011)
    //
    //                                                                 0xa5a5 = 0b1010010 1101 0 0101
    //                                                                          0b1010010 1110 1 0011 = 0xA5D3
                                                     //   write_word(0x5e, 0xA5D3); // write data to customer ID locations
                                                          write_word(0x5e, 0b10000000);
                //53 =  0b110101
                //83 = 0b1010011
                
    //From the Datasheet:
    /*
    Make Alarm_Low = Active High (Write Bit 7 of Customer Configuration Register = 0)
    Make Alarm_Low = Push-Pull (Write Bit 8 of Customer Configuration Register = 0)
    Make Alarm_High = Active High (Write Bit 9 of Customer Configuration Register = 0)
    Make Alarm_High = Push-Pull (Write Bit 10 of Customer Configuration Register = 0)
    Make Command Window = 3 ms (Write Bit 13 of Customer Configuration Register = 1)
    */

    // (2) try stick it in here to change the address instead

    //                                                                            0b1010010110100101
    //                                                                                       1010011
    //                                                                            0b1010010111010011 = 0xA5D3
                                         //  write_word(0X5f, 0xA5D3);
                                             write_word(0X5f, 0b100000000);
    //Set I2C Address = 0x53 (Write Bits 6:0 of Customer Configuration Register = 0b         1010011


       
    Serial.println(".......");
    
    for (n=0x18; n<0x20; n++)
    {
        w = read_word(n);
        Serial.print(n, HEX);
        Serial.print("  ");
        print_hex(w, 16);
        Serial.println();
    }  
    
    Serial.println("...........................");
    
    for (n=0x18; n<=0x1b; n++)
    {
        v = read_alarm(n);
        Serial.print(n, HEX);
        Serial.print("  ");
        print_float(v, 2);
        Serial.println();
    }
  
    write_word(0x80, 0x0000);  // go to normal operation
   
  Serial.println("Done Programming");

  Serial.println("Scanning for I2C Changes");

  nDevices = 0;
  for(address = 1; address < 127; 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("Unknow 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(1500);           // wait 15 seconds for next scan
}

void write_word(byte command, unsigned int dat)
{
      byte H, L;
      H = dat >> 8;
      L = dat & 0xff;
      
      Wire.beginTransmission(0x27);
      Wire.write(command);
      Wire.write(H);
      Wire.write(L);
      Wire.endTransmission();
      delay(15);
}

unsigned int read_word(byte command)
{
     byte high, low, response_byte;
     unsigned int w;
     
     write_word(command, 0x0000);      
     Wire.requestFrom((int) 0x27, (int) 3);
     response_byte =Wire.read();
     high =Wire.read();
     low =Wire.read();
     Wire.endTransmission();
     w = high;
     w = w *256 + low;
     return(w);
}    

void write_alarm(byte command, float huma_alm)
{
    unsigned int w;
    w = (unsigned int)(huma_alm * 163.83);
    write_word(command, w);
}

float read_alarm(byte command)
{
    unsigned int w;
    float v;
    
    w = read_word(command);
    v = ((float) w) * 6.103e-3;
    return(v);
}
      
void print_hex(int v, int num_places)
{
    int mask=0, n, num_nibbles, digit;

    for (n=1; n<=num_places; n++)
    {
        mask = (mask << 1) | 0x0001;
    }
    v = v & mask; // truncate v to specified number of places

    num_nibbles = num_places / 4;
    if ((num_places % 4) != 0)
    {
        ++num_nibbles;
    }

    do
    {
        digit = ((v >> (num_nibbles-1) * 4)) & 0x0f;
        Serial.print(digit, HEX);
    } while(--num_nibbles);

}
  
void print_float(float f, int num_digits)
{
    int f_int;
    int pows_of_ten[4] = {1, 10, 100, 1000};
    int multiplier, whole, fract, d, n;

    multiplier = pows_of_ten[num_digits];
    if (f < 0.0)
    {
        f = -f;
        Serial.print("-");
    }
    whole = (int) f;
    fract = (int) (multiplier * (f - (float)whole));

    Serial.print(whole);
    Serial.print(".");

    for (n=num_digits-1; n>=0; n--) // print each digit with no leading zero suppression
    {
         d = fract / pows_of_ten[n];
         Serial.print(d);
         fract = fract % pows_of_ten[n];
    }
}

This is how output looks like:

0  E765
1  DB65
2  DB65
3  DB65
4  DF65
5  DF65
6  DF65
7  DF65
8  DF65
9  DF65
A  DF65
B  DF65
C  DF65
D  DF65
E  DF65
F  DF65
10  DB65
11  DB65
12  DB65
13  DF65
14  DF65
15  DF65
16  DF65
17  DF65
18  DF65
19  DF65
1A  DF65
1B  DF65
1C  DF65
1D  DF65
1E  DF65
1F  E365
.......
18  E365
19  E365
1A  E365
1B  E365
1C  E365
1D  E365
1E  E365
1F  E365
...........................
18  349.02
19  349.02
1A  349.02
1B  355.27
Done Programming
Scanning for I2C Changes
I2C device found at address 0x27  !
done

Find this statement in the original HIH_Commander_Mode.ino file as you posted in your original message:

   write_word(0x5b, 40.0);  // change I2C

and change it to:

   write_word(0x5c, 40.0);  // change I2C

Pete

pylon: Then focus yourself. I won't help you if you don't provide the information needed!

Pylon, thank you for helping me!

My current example only uses Wire.h (Or rather pretends to use it because nothing works anyways.)

I may look into other libraries when I get too tired of playing with this malfunctioning piece of code

I may also look into other libraries if I get a forum post reply telling me that it is impossible to change the address of HIH6130 only with Wire.h library.

el_supremo:
Find this statement in the original HIH_Commander_Mode.ino file as you posted in your original message:

   write_word(0x5b, 40.0);  // change I2C

and change it to:

   write_word(0x5c, 40.0);  // change I2C

Pete

I think that I accidentally entered a line into the original code that was not there.
Second program on this web page: http://www.phanderson.com/arduino/hih6130.html

** write_word(0x5e, 0xa5a5); // write data to customer ID locations**
** write_word(0X5f, 0x5a5a);**

“Customer ID locations” is where the address is stored, according to the datasheet.

Or I put something there to allow for the change of the I2C address in the next programming cycle.
That I don’t understand, more inclined towards the former then the latter.

// HIH_6130_2  - Arduino
// 
// Arduino                HIH-6130
//
// Digital 4 ------------ Vdd (term 8) // Note that the Arduino provides power to the device.
//
// SCL (Analog 5) ------- SCL (term 3)
// SDA (Analog 4) ------- SDA (term 4)
//
// Note 2.2K pullups to _5 VDC on both SDA and SCL
//
// copyright, Peter H Anderson, Baltimore, MD, Oct 14, '11
// You may use it, but please give credit.
//  
    
#include <Wire.h> //I2C library

void write_word(byte command, unsigned int dat);
unsigned int read_word(byte command); 
void write_alarm(byte command, float huma_alm);
float read_alarm(byte command);


#define TRUE 1
#define FALSE 0

void setup(void)
{
    Serial.begin(9600);
    Wire.begin();
    pinMode(4, OUTPUT);
    digitalWrite(4, LOW);
    delay(5000);
    Serial.println(">>>>>>>>>>>>>>>>>>>>>>>>");  // just to be sure things are working
}
    
void loop(void)
{
    byte n;
    unsigned int w;
    float v;
    
    digitalWrite(4, HIGH);  // turn on power
    write_word(0xa0, 0x0000);  // and enter command mode within 10 ms
  
    for (n=0; n<0x20; n++)
    {
        w = read_word(n);
        Serial.print(n, HEX);
        Serial.print("  ");
        print_hex(w, 16);
        Serial.println();
    }
    
    write_alarm(0x58, 80.0);  // high alarm on
    write_alarm(0x59, 75.0);  // high alarm off
 
    write_alarm(0x5a, 33.0);  // low alarm on
    write_alarm(0x5b, 40.0);  // low alarm off
    
    write_word(0x5e, 0xa5a5); // write data to customer ID locations
    write_word(0X5f, 0x5a5a);
    
    Serial.println(".......");
    
    for (n=0x18; n<0x20; n++)
    {
        w = read_word(n);
        Serial.print(n, HEX);
        Serial.print("  ");
        print_hex(w, 16);
        Serial.println();
    }  
    
    Serial.println("...........................");
    
    for (n=0x18; n<=0x1b; n++)
    {
        v = read_alarm(n);
        Serial.print(n, HEX);
        Serial.print("  ");
        print_float(v, 2);
        Serial.println();
    }
  
    write_word(0x80, 0x0000);  // go to normal operation
   
    Serial.println("Done");
    
    while(1)
    {
    }    
}

void write_word(byte command, unsigned int dat)
{
      byte H, L;
      H = dat >> 8;
      L = dat & 0xff;
      
      Wire.beginTransmission(0x27);
      Wire.send(command);
      Wire.send(H);
      Wire.send(L);
      Wire.endTransmission();
      delay(15);
}

unsigned int read_word(byte command)
{
     byte high, low, response_byte;
     unsigned int w;
     
     write_word(command, 0x0000);      
     Wire.requestFrom((int) 0x27, (int) 3);
     response_byte = Wire.receive();
     high = Wire.receive();
     low = Wire.receive();
     Wire.endTransmission();
     w = high;
     w = w *256 + low;
     return(w);
}    

void write_alarm(byte command, float huma_alm)
{
    unsigned int w;
    w = (unsigned int)(huma_alm * 163.83);
    write_word(command, w);
}

float read_alarm(byte command)
{
    unsigned int w;
    float v;
    
    w = read_word(command);
    v = ((float) w) * 6.103e-3;
    return(v);
}
      
void print_hex(int v, int num_places)
{
    int mask=0, n, num_nibbles, digit;

    for (n=1; n<=num_places; n++)
    {
        mask = (mask << 1) | 0x0001;
    }
    v = v & mask; // truncate v to specified number of places

    num_nibbles = num_places / 4;
    if ((num_places % 4) != 0)
    {
        ++num_nibbles;
    }

    do
    {
        digit = ((v >> (num_nibbles-1) * 4)) & 0x0f;
        Serial.print(digit, HEX);
    } while(--num_nibbles);

}
  
void print_float(float f, int num_digits)
{
    int f_int;
    int pows_of_ten[4] = {1, 10, 100, 1000};
    int multiplier, whole, fract, d, n;

    multiplier = pows_of_ten[num_digits];
    if (f < 0.0)
    {
        f = -f;
        Serial.print("-");
    }
    whole = (int) f;
    fract = (int) (multiplier * (f - (float)whole));

    Serial.print(whole);
    Serial.print(".");

    for (n=num_digits-1; n>=0; n--) // print each digit with no leading zero suppression
    {
         d = fract / pows_of_ten[n];
         Serial.print(d);
         fract = fract % pows_of_ten[n];
    }
}

Sorry, I should have said HIH_Commander_Mode.ino in your message #2 (not the first one).

Pete

In write_word(0x5c, 40.0);

the 0x5c is the address and 40.0 is the data that is being entered?

write_alarm(address, data);
or
write_alarm(data, address);

Where do I find the official description of the library Wire.h ?

I added the linewrite_word(0x5c, 40.0); into the code.
This version of the code have not changed anything either:
I am lost.

// HIH_6130_2  - Arduino
// 
// Arduino                HIH-6130
//
// Digital 4 ------------ Vdd (term 8) // Note that the Arduino provides power to the device.
//
// SCL (Analog 5) ------- SCL (term 3)
// SDA (Analog 4) ------- SDA (term 4)
//
// Note 2.2K pullups to _5 VDC on both SDA and SCL
//
// copyright, Peter H Anderson, Baltimore, MD, Oct 14, '11
// You may use it, but please give credit.
    
#include <Wire.h> //I2C library

//#include <HIH61XX.h>
//#include <HIH61XXCommander.h>


void write_word(byte command, unsigned int dat);
unsigned int read_word(byte command); 
void write_alarm(byte command, float huma_alm);
float read_alarm(byte command);


#define TRUE 1
#define FALSE 0

void setup(void)
{
    Serial.begin(9600);
    Wire.begin();
    pinMode(4, OUTPUT);
    digitalWrite(4, LOW);
    delay(5000);

  
    Serial.println("\nI2C Scanner");
    Serial.println(">>>>>>>>>>>>>>>>>>>>>>>>");  // just to be sure things are working
}
    
void loop(void)
{

    byte error, address; // 2/22
    int nDevices;        // 2/22
    
    byte n;
    unsigned int w;
    float v;
    
    digitalWrite(4, HIGH);  // turn on power
    write_word(0xa0, 0x0000);  // and enter command mode within 10 ms
  
    for (n=0; n<0x20; n++)
    {
        w = read_word(n);
        Serial.print(n, HEX);
        Serial.print("  ");
        print_hex(w, 16);
        Serial.println();
    }
    
    write_alarm(0x58, 80.0);  // high alarm on          //80.0 = 0x50 = 0b1010000
    write_alarm(0x59, 75.0);  // high alarm off         //75.0 = 0x4B = 0b1001011
 
    write_alarm(0x5a, 33.0);  // low alarm on           //33.0 = 0x21 =  0b100001
    write_alarm(0x5b, 40.0);  // low alarm off          //40.0 = 0x28 =  0b101000


    //ORIGINAL CODE
    /*
    write_word(0x5e, 0xa5a5); // write data to customer ID locations
    write_word(0X5f, 0x5a5a);
    */

    //0x5a5a =  0b101101001011010
    //0xa5a5 = 0b1010010110100101
    
    // change I2C
    
    //0xF800 = 0b1111100000000000
    // (1) try stick it in here to change address
    //From the Datasheet: 
    //Set I2C Address = 0x53 (Write Bits 6:0 of Customer Configuration Register = 0b1010011)
    //
    //                                                                           bbbbbbb bbbbb b bbbb                                                                                             
    //                                                                           bits 6:0   65 4 3210
    //Set I2C Address = 0x53 (Write Bits 6:0 of Customer Configuration Register = 0b        10 1 0011)
    //
    //                                                                 0xa5a5 = 0b1010010 1101 0 0101
    //                                                                          0b1010010 1110 1 0011 = 0xA5D3
                                                     //   write_word(0x5e, 0xA5D3); // write data to customer ID locations
                                                     //   write_word(0x5e, 0b10000000);
                //53 =  0b110101
                //83 = 0b1010011
                
    //From the Datasheet:
    /*
    Make Alarm_Low = Active High (Write Bit 7 of Customer Configuration Register = 0)
    Make Alarm_Low = Push-Pull (Write Bit 8 of Customer Configuration Register = 0)
    Make Alarm_High = Active High (Write Bit 9 of Customer Configuration Register = 0)
    Make Alarm_High = Push-Pull (Write Bit 10 of Customer Configuration Register = 0)
    Make Command Window = 3 ms (Write Bit 13 of Customer Configuration Register = 1)
    */

    // (2) try stick it in here to change the address instead

    //                                                                            0b1010010110100101
    //                                                                                       1010011
    //                                                                            0b1010010111010011 = 0xA5D3
                                         //  write_word(0X5f, 0xA5D3);
                                         //  write_word(0X5f, 0b10000000);
    //Set I2C Address = 0x53 (Write Bits 6:0 of Customer Configuration Register = 0b         1010011

    //               40.0 = 0b101000
    write_word(0x5c, 40.0);  // change I2C
       
    Serial.println(".......");
    
    for (n=0x18; n<0x20; n++)
    {
        w = read_word(n);
        Serial.print(n, HEX);
        Serial.print("  ");
        print_hex(w, 16);
        Serial.println();
    }  
    
    Serial.println("...........................");
    
    for (n=0x18; n<=0x1b; n++)
    {
        v = read_alarm(n);
        Serial.print(n, HEX);
        Serial.print("  ");
        print_float(v, 2);
        Serial.println();
    }
  
    write_word(0x80, 0x0000);  // go to normal operation
   
  Serial.println("Done Programming");

  Serial.println("Scanning for I2C Changes");

  nDevices = 0;
  for(address = 1; address < 127; 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("Unknow 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(1500);           // wait 15 seconds for next scan
}

void write_word(byte command, unsigned int dat)
{
      byte H, L;
      H = dat >> 8;
      L = dat & 0xff;
      
      Wire.beginTransmission(0x27);
      Wire.write(command);
      Wire.write(H);
      Wire.write(L);
      Wire.endTransmission();
      delay(15);
}

unsigned int read_word(byte command)
{
     byte high, low, response_byte;
     unsigned int w;
     
     write_word(command, 0x0000);      
     Wire.requestFrom((int) 0x27, (int) 3);
     response_byte =Wire.read();
     high =Wire.read();
     low =Wire.read();
     Wire.endTransmission();
     w = high;
     w = w *256 + low;
     return(w);
}    

void write_alarm(byte command, float huma_alm)
{
    unsigned int w;
    w = (unsigned int)(huma_alm * 163.83);
    write_word(command, w);
}

float read_alarm(byte command)
{
    unsigned int w;
    float v;
    
    w = read_word(command);
    v = ((float) w) * 6.103e-3;
    return(v);
}
      
void print_hex(int v, int num_places)
{
    int mask=0, n, num_nibbles, digit;

    for (n=1; n<=num_places; n++)
    {
        mask = (mask << 1) | 0x0001;
    }
    v = v & mask; // truncate v to specified number of places

    num_nibbles = num_places / 4;
    if ((num_places % 4) != 0)
    {
        ++num_nibbles;
    }

    do
    {
        digit = ((v >> (num_nibbles-1) * 4)) & 0x0f;
        Serial.print(digit, HEX);
    } while(--num_nibbles);

}
  
void print_float(float f, int num_digits)
{
    int f_int;
    int pows_of_ten[4] = {1, 10, 100, 1000};
    int multiplier, whole, fract, d, n;

    multiplier = pows_of_ten[num_digits];
    if (f < 0.0)
    {
        f = -f;
        Serial.print("-");
    }
    whole = (int) f;
    fract = (int) (multiplier * (f - (float)whole));

    Serial.print(whole);
    Serial.print(".");

    for (n=num_digits-1; n>=0; n--) // print each digit with no leading zero suppression
    {
         d = fract / pows_of_ten[n];
         Serial.print(d);
         fract = fract % pows_of_ten[n];
    }
}

What output is printed in the serial monitor from your code in message #13?

the 0x5c is the address and 40.0 is the data that is being entered?

Not quite. 0x5c is the command to write a new I2C address into the EEPROM and 40.0 is the new address (0x28)

Pete

The code works! Thank you Peter!
Now I would like to figure out how to set other bits, following the analogy.
I don’t really need alarms for my purposes, yet I want this to be a complete example.

OUTPUT

0  FFFF
1  FFFF
2  FFFF
3  FFFF
4  FFFF
5  FFFF
6  FFFF
7  FFFF
8  FFFF
9  FFFF
A  FFFF
B  FFFF
C  FFFF
D  FFFF
E  FFFF
F  FFFF
10  FFFF
11  FFFF
12  FFFF
13  FFFF
14  FFFF
15  FFFF
16  FFFF
17  FFFF
18  FFFF
19  FFFF
1A  FFFF
1B  FFFF
1C  FFFF
1D  FFFF
1E  FFFF
1F  FFFF
.......
18  FFFF
19  FFFF
1A  FFFF
1B  FFFF
1C  FFFF
1D  FFFF
1E  FFFF
1F  FFFF
...........................
18  399.96
19  399.96
1A  399.96
1B  399.96
Done Programming
Scanning for I2C Changes
I2C device found at address 0x28  !

CODE ITSELF:

// HIH_6130_2  - Arduino
// 
// Arduino                HIH-6130
//
// Digital 4 ------------ Vdd (term 8) // Note that the Arduino provides power to the device.
//
// SCL (Analog 5) ------- SCL (term 3)
// SDA (Analog 4) ------- SDA (term 4)
//
// Note 2.2K pullups to _5 VDC on both SDA and SCL
//
// copyright, Peter H Anderson, Baltimore, MD, Oct 14, '11
// You may use it, but please give credit.
    
#include <Wire.h> //I2C library

//#include <HIH61XX.h>
//#include <HIH61XXCommander.h>


void write_word(byte command, unsigned int dat);
unsigned int read_word(byte command); 
void write_alarm(byte command, float huma_alm);
float read_alarm(byte command);


#define TRUE 1
#define FALSE 0

void setup(void)
{
    Serial.begin(9600);
    Wire.begin();
    pinMode(4, OUTPUT);
    digitalWrite(4, LOW);
    delay(5000);

  
    Serial.println("\nI2C Scanner");
    Serial.println(">>>>>>>>>>>>>>>>>>>>>>>>");  // just to be sure things are working
}
    
void loop(void)
{

    byte error, address; // 2/22
    int nDevices;        // 2/22
    
    byte n;
    unsigned int w;
    float v;
    
    digitalWrite(4, HIGH);  // turn on power
    write_word(0xa0, 0x0000);  // and enter command mode within 10 ms
  
    for (n=0; n<0x20; n++)
    {
        w = read_word(n);
        Serial.print(n, HEX);
        Serial.print("  ");
        print_hex(w, 16);
        Serial.println();
    }
    
    write_alarm(0x58, 80.0);  // high alarm on          //80.0 = 0x50 = 0b1010000
    write_alarm(0x59, 75.0);  // high alarm off         //75.0 = 0x4B = 0b1001011
 
    write_alarm(0x5a, 33.0);  // low alarm on           //33.0 = 0x21 =  0b100001
    write_alarm(0x5b, 40.0);  // low alarm off          //40.0 = 0x28 =  0b101000


    //ORIGINAL CODE
    /*
    write_word(0x5e, 0xa5a5); // write data to customer ID locations
    write_word(0X5f, 0x5a5a);
    */
    
 
    /*From the Datasheet: 
    Set I2C Address = 0x53 (Write Bits 6:0 of Customer Configuration Register = 0b1010011)
    
    Make Alarm_Low = Active High (Write Bit 7 of Customer Configuration Register = 0)
    Make Alarm_Low = Push-Pull (Write Bit 8 of Customer Configuration Register = 0)
    Make Alarm_High = Active High (Write Bit 9 of Customer Configuration Register = 0)
    Make Alarm_High = Push-Pull (Write Bit 10 of Customer Configuration Register = 0)
    Make Command Window = 3 ms (Write Bit 13 of Customer Configuration Register = 1)
    */

    //Set I2C Address = 0x53 (Write Bits 6:0 of Customer Configuration Register = 0b1010011

    // 0b1011100 = 92
    write_word(0b1011100, 0x28);  // change I2C to 0x28
    

       
    Serial.println(".......");
    
    for (n=0x18; n<0x20; n++)
    {
        w = read_word(n);
        Serial.print(n, HEX);
        Serial.print("  ");
        print_hex(w, 16);
        Serial.println();
    }  
    
    Serial.println("...........................");
    
    for (n=0x18; n<=0x1b; n++)
    {
        v = read_alarm(n);
        Serial.print(n, HEX);
        Serial.print("  ");
        print_float(v, 2);
        Serial.println();
    }
  
    write_word(0x80, 0x0000);  // go to normal operation
   
  Serial.println("Done Programming");

  Serial.println("Scanning for I2C Changes");

  nDevices = 0;
  for(address = 1; address < 127; 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("Unknow 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(1500);           // wait 15 seconds for next scan
}

void write_word(byte command, unsigned int dat)
{
      byte H, L;
      H = dat >> 8;
      L = dat & 0xff;
      
      Wire.beginTransmission(0x27);
      Wire.write(command);
      Wire.write(H);
      Wire.write(L);
      Wire.endTransmission();
      delay(15);
}

unsigned int read_word(byte command)
{
     byte high, low, response_byte;
     unsigned int w;
     
     write_word(command, 0x0000);      
     Wire.requestFrom((int) 0x27, (int) 3);
     response_byte =Wire.read();
     high =Wire.read();
     low =Wire.read();
     Wire.endTransmission();
     w = high;
     w = w *256 + low;
     return(w);
}    

void write_alarm(byte command, float huma_alm)
{
    unsigned int w;
    w = (unsigned int)(huma_alm * 163.83);
    write_word(command, w);
}

float read_alarm(byte command)
{
    unsigned int w;
    float v;
    
    w = read_word(command);
    v = ((float) w) * 6.103e-3;
    return(v);
}
      
void print_hex(int v, int num_places)
{
    int mask=0, n, num_nibbles, digit;

    for (n=1; n<=num_places; n++)
    {
        mask = (mask << 1) | 0x0001;
    }
    v = v & mask; // truncate v to specified number of places

    num_nibbles = num_places / 4;
    if ((num_places % 4) != 0)
    {
        ++num_nibbles;
    }

    do
    {
        digit = ((v >> (num_nibbles-1) * 4)) & 0x0f;
        Serial.print(digit, HEX);
    } while(--num_nibbles);

}
  
void print_float(float f, int num_digits)
{
    int f_int;
    int pows_of_ten[4] = {1, 10, 100, 1000};
    int multiplier, whole, fract, d, n;

    multiplier = pows_of_ten[num_digits];
    if (f < 0.0)
    {
        f = -f;
        Serial.print("-");
    }
    whole = (int) f;
    fract = (int) (multiplier * (f - (float)whole));

    Serial.print(whole);
    Serial.print(".");

    for (n=num_digits-1; n>=0; n--) // print each digit with no leading zero suppression
    {
         d = fract / pows_of_ten[n];
         Serial.print(d);
         fract = fract % pows_of_ten[n];
    }
}

I tried to understand the code better and compared it to the datasheet.

  1. How do I take care of this part of the datasheet?
/*From the Datasheet: 
    Step 10. Set I2C Address = 0x53 (Write Bits 6:0 of Customer Configuration Register = 0b1010011)
    Make Alarm_Low = Active High (Write Bit 7 of Customer Configuration Register = 0)
    Make Alarm_Low = Push-Pull (Write Bit 8 of Customer Configuration Register = 0)
    Make Alarm_High = Active High (Write Bit 9 of Customer Configuration Register = 0)
    Make Alarm_High = Push-Pull (Write Bit 10 of Customer Configuration Register = 0)
    Make Command Window = 3 ms (Write Bit 13 of Customer Configuration Register = 1)
    */

I guess that the original code did that. What bits correspond to what? (This is why I converted those HEX numbers to binary.)

   /*  ORIGINAL CODE:
        write_word(0x5e, 0xa5a5); // write data to customer ID locations               0x5e = 94
    //                   0xa5a5 = 0b1010010110100101
        
        write_word(0X5f, 0x5a5a); //                                                   0x5f = 95
    //                   0x5a5a = 0b101101001011010   
    */

Program outputs FFFF for all data stored in the memory.

My attempt to get it to print meaningful binary, hexadecimal and decimal numbers failed. I got n to print like that instead of the date. I want it to be easy for a programmer to see the what bit they need to change to accomplish a specific result.

I am mostly talking about Step 10 from the datasheet where all of this is piled together. I can’t apply the information.

print_hex(w, 16); - what does this operator do? Where can I find a description of this operator?
Is there a print_bin(); and print_dec(); following the analogy?

 //Step 6. Set Alarm_High_On = 80% Humidity. (Write 0x3333 to EEPROM Location 0x18).  0x18 = 24 // all off by 64
    write_alarm(0x58, 80.0);  // high alarm on          //80.0 = 0x50 = 0b1010000      0x58 = 88

All memory locations in the datasheet are off by 64 units. Why?

I attached the new code that I am working with right now:
References to the datasheet in comments would help many other people connect the two together and learn.

HIH_Commander_Mode_2.ino (6.95 KB)

What bits correspond to what?

Those bits are all described in Table 6 of the datasheet.

Program outputs FFFF for all data stored in the memory

The basic communication between Arduino and the sensor must be working because you've been able to change the I2C address. There's something else wrong in the code. I'm going to be busy most of today but will try to have a look.

Pete

I am taking a break from this subject: doing some exercise, doing some more work assignments.

I am looking at table 6 now. I am still not sure how I address individual bits. There is an address mismatch between the datasheet and the program as I see. It is weird. Could I have overwritten some precious factory settings that are specific to calibrating the sensor?

It is not like I can take my HIH6130 to Walmart and say that it doesn't work for some unknown reasons, get a full refund.

Pete, are you Peter H Anderson?

Pete, are you Peter H Anderson?

No. But I am going to bed :) I'll look at this tomorrow.

Pete