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 | }
|