hyt131_i2c_addr_change_release.ino


1
#include <Wire.h>
2
3
/*
4
  HYT131 I2C address change
5
  
6
  Changes the I2C slave address of a HYT-131 temperature/humidity
7
  sensor.
8
  Based on information found in the ZSSC3122 datasheet.
9
  
10
  Connections:
11
  - VCC to the pin defined under POWER_PIN
12
  - SDA to analog pin 4
13
  - SCL to analog pin 5
14
  - GND to ground
15
*/
16
17
#define SENSOR_ADDR 0x29
18
#define SENSOR_NEW_ADDR 0x28
19
20
#define POWER_PIN 12
21
22
/* Don't change anything below here */
23
24
#define CMD_START_CM 0xA0
25
#define CMD_START_NM 0x80
26
#define RESP_ACK_POS 1
27
#define RESP_ACK_NEG 2
28
#define RESP_CMD_MODE 1<<7
29
#define ZMDI_COMM_LOCK 0x300
30
31
/*
32
  enterCmdMode(char dev_addr)
33
  Tries to boot the device at dev_addr into command mode.
34
*/
35
char enterCmdMode(char dev_addr) {
36
  // turn the sensor on
37
  digitalWrite(POWER_PIN, HIGH);
38
  delay(2);
39
  
40
  // send Star_CM command
41
  Wire.beginTransmission(dev_addr);
42
  Wire.write(CMD_START_CM);
43
  Wire.write(0);
44
  Wire.write(0);
45
  return Wire.endTransmission();
46
}
47
48
/*
49
  enterNomMode(char dev_addr)
50
  Tries to change the device at dev_addr to normal mode.
51
*/
52
boolean enterNomMode(char dev_addr) {
53
  // send Start_NM command
54
  Wire.beginTransmission(dev_addr);
55
  Wire.write(CMD_START_NM);
56
  Wire.write(0);
57
  Wire.write(0);
58
  return Wire.endTransmission();
59
}
60
61
/*
62
  readEEPROM(char dev_addr, byte address)
63
  Reads the EEPROM at address from device dev_addr.
64
*/
65
int readEEPROM(char dev_addr, byte address) {
66
  // check address
67
  if (address > 0x1F)
68
    return 0;
69
  
70
  // send EEPROM read command
71
  Wire.beginTransmission(dev_addr);
72
  Wire.write(address);
73
  Wire.write(0);
74
  Wire.write(0);
75
  Wire.endTransmission();
76
  delayMicroseconds(150);
77
  
78
  // retrieve data
79
  Wire.requestFrom(dev_addr, 3);
80
  byte response, hi, lo;
81
  response = Wire.read();
82
  hi = Wire.read();
83
  lo = Wire.read();
84
  
85
  return (hi<<8) | lo;
86
}
87
88
/*
89
  writeEEPROM(char dev_addr, byte address, int data)
90
  Writes data to the EEPROM at address of device dev_addr.
91
*/
92
void writeEEPROM(char dev_addr, byte address, int data) {
93
  // check address
94
  if (address > 0x1F)
95
    return;
96
  
97
  // send data
98
  Wire.beginTransmission(dev_addr);
99
  Wire.write(0x40 + address);
100
  Wire.write((char) (data>>8));
101
  Wire.write((char) data);
102
  Wire.endTransmission();
103
  delay(15);
104
}
105
106
/*
107
  changeAddr(char dev_old_addr, char dev_new_addr)
108
  Changes the device address of dev_addr to dev_new_addr.
109
*/
110
void changeAddr(char dev_addr, byte dev_new_addr) {
111
  int cust_config = readEEPROM(dev_addr, 0x1C);
112
  cust_config = (cust_config & 0xFF80) | dev_new_addr;
113
  writeEEPROM(dev_addr, 0x1C, cust_config);
114
}
115
116
/*
117
  changeCommLock(char dev_addr, byte commlock)
118
  Turns the Comm_lock in register ZMDI_config on or off.
119
*/
120
void changeCommLock(char dev_addr, byte commlock) {
121
  int zmdi_config = readEEPROM(dev_addr, 0x02);
122
  
123
  if (commlock && !(zmdi_config & ZMDI_COMM_LOCK)) {
124
    zmdi_config = (zmdi_config & ~0x700) | ZMDI_COMM_LOCK;
125
    writeEEPROM(dev_addr, 0x02, zmdi_config);
126
  }
127
  
128
  if (!commlock && (zmdi_config & ZMDI_COMM_LOCK)) {
129
    zmdi_config = zmdi_config & ~0x700;
130
    writeEEPROM(dev_addr, 0x02, zmdi_config);
131
  }
132
}
133
134
/*
135
  measHumidity(char dev_addr)
136
  Polls the device dev_addr and returns the measured humidity.
137
*/
138
int measHumidity(char dev_addr) {
139
  int h;
140
  
141
  Wire.beginTransmission(dev_addr);
142
  if (Wire.endTransmission())
143
    return 0xFFFF;
144
  delay(100);
145
  
146
  Wire.requestFrom(dev_addr, 2);
147
  h = (Wire.read() & 0x3F) << 8;
148
  h = h | Wire.read();
149
  return h * 10000L >> 14;
150
}
151
  
152
153
void setup(void) {
154
  int zmdi_config, cust_config;
155
  byte a, b;
156
  
157
  Serial.begin(57600);
158
  
159
  // set POWER_PIN as output
160
  digitalWrite(POWER_PIN, LOW);
161
  pinMode(POWER_PIN, OUTPUT);
162
  
163
  // setup Wire as master
164
  Wire.begin();
165
  
166
  // Wait for user interaction
167
  Serial.println("Press any key to start the procedure...");
168
  while(!Serial.available()) delay(1);
169
  
170
  // Try to enter command mode
171
  Serial.println("Entering command mode...");
172
  if (!enterCmdMode(SENSOR_ADDR)) {
173
    Serial.println("Command sent successfully.");
174
    delayMicroseconds(150);
175
  } else {
176
    Serial.println("Error!");
177
    goto out;
178
  }
179
180
  // Check if command was successful
181
  Wire.requestFrom(SENSOR_ADDR, 2);
182
  a = Wire.read();
183
  b = Wire.read();
184
  if (a & RESP_CMD_MODE) {
185
    Serial.println("Entered command mode.");
186
  } else {
187
    Serial.println("Error!");
188
    goto out;
189
  }
190
  
191
  // Retrieve ZMDI_Config
192
  Serial.println("Retrieve ZMDI_Config...");
193
  zmdi_config = readEEPROM(SENSOR_ADDR, 0x02);
194
  Serial.print("ZMDI_Config: 0x");
195
  Serial.println(zmdi_config, HEX);
196
  if (zmdi_config & ZMDI_COMM_LOCK)
197
    Serial.println("ZMDI_Config: Comm locked");
198
  else
199
    Serial.println("ZMDI_Config: Comm unlocked");
200
  
201
  // Retrieve Cust_Config
202
  Serial.println("Retrieve Cust_Config...");
203
  cust_config = readEEPROM(SENSOR_ADDR, 0x1C);
204
  Serial.print("Cust_Config: 0x");
205
  Serial.println(cust_config, HEX);
206
  Serial.print("I2C-ID: 0x");
207
  Serial.println(cust_config & 0x7F, HEX);
208
  
209
  // Enable Comm_lock
210
  Serial.println("Enable Comm_lock");
211
  changeCommLock(SENSOR_ADDR, 1);
212
  
213
  // Change address
214
  Serial.print("Change address from 0x");
215
  Serial.print(SENSOR_ADDR, HEX);
216
  Serial.print(" to 0x");
217
  Serial.println(SENSOR_NEW_ADDR, HEX); 
218
  changeAddr(SENSOR_ADDR, SENSOR_NEW_ADDR);
219
  
220
  // Enter normal operation
221
  Serial.println("Entering normal operation...");
222
  if (!enterNomMode(SENSOR_ADDR)) {
223
    Serial.println("Command sent successfully.");
224
  } else {
225
    Serial.println("Error!");
226
    goto out;
227
  }
228
  Wire.requestFrom(SENSOR_NEW_ADDR, 2);
229
  a = Wire.read();
230
  b = Wire.read();
231
  if (!(a & RESP_CMD_MODE)) {
232
    Serial.println("Entered normal mode successfully.");
233
  } else {
234
    Serial.println("Error!");
235
  }
236
  
237
  delay(500);
238
239
  out:
240
  Serial.println("Finished.");
241
}
242
243
void loop(void) {
244
  // Display humidity
245
  int humidity = measHumidity(SENSOR_NEW_ADDR);
246
  Serial.print("Humidity: ");
247
  Serial.print((float) humidity / 100, 2);
248
  Serial.println("%relF");
249
  delay(1000);
250
}