-
Notifications
You must be signed in to change notification settings - Fork 319
/
_P162_MPL3115A2.ino
362 lines (315 loc) · 13.2 KB
/
_P162_MPL3115A2.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
//#######################################################################################################
//################## Plugin 162 : MPL3115A2 I2C Altitude Barometric Pressure Temperature Sensor ########
//#######################################################################################################
// This plugin works with ESPEasy V2
#define PLUGIN_162
#define PLUGIN_ID_162 162
#define PLUGIN_NAME_162 "Temperature & Pressure & Altitude - MPL3115A2"
#define PLUGIN_VALUENAME1_162 "Temperature"
#define PLUGIN_VALUENAME2_162 "Pressure"
#define PLUGIN_VALUENAME3_162 "Altitude"
boolean Plugin_162_init = false;
uint8_t i2cAddress162;
uint8_t osr162;
uint8_t mode162;
uint8_t configRegister162;
boolean Plugin_162(byte function, struct EventStruct *event, String& string)
{
boolean success = false;
static byte portValue = 0;
switch (function)
{
case PLUGIN_DEVICE_ADD:
{
Device[++deviceCount].Number = PLUGIN_ID_162;
Device[deviceCount].Type = DEVICE_TYPE_I2C;
Device[deviceCount].VType = SENSOR_TYPE_TEMP_BARO;
Device[deviceCount].Ports = 0;
Device[deviceCount].PullUpOption = false;
Device[deviceCount].InverseLogicOption = false;
Device[deviceCount].FormulaOption = true;
Device[deviceCount].ValueCount = 3;
Device[deviceCount].SendDataOption = true;
Device[deviceCount].TimerOption = true;
Device[deviceCount].GlobalSyncOption = true;
break;
}
case PLUGIN_GET_DEVICENAME:
{
string = F(PLUGIN_NAME_162);
break;
}
case PLUGIN_GET_DEVICEVALUENAMES:
{
strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME1_162));
strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[1], PSTR(PLUGIN_VALUENAME2_162));
strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[2], PSTR(PLUGIN_VALUENAME3_162));
break;
}
case PLUGIN_WEBFORM_LOAD:
{
byte choice0 = Settings.TaskDevicePluginConfig[event->TaskIndex][0];
String options0[2];
options0[0] = F("Pressure");
options0[1] = F("Altitude");
int optionValues0[2] = { 0, 1 };
addFormSelector(string, F("Mode"), F("plugin_162_mode"), 2 , options0, optionValues0, choice0);
byte choice1 = Settings.TaskDevicePluginConfig[event->TaskIndex][1];
String options1[8];
options1[0] = F("1");
options1[1] = F("2");
options1[2] = F("4");
options1[3] = F("8");
options1[4] = F("16");
options1[5] = F("32");
options1[6] = F("64");
options1[7] = F("128");
int optionValues1[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
addFormSelector(string, F("Oversample Ratio"), F("plugin_162_osr"), 8 , options1, optionValues1, choice1);
success = true;
break;
}
case PLUGIN_WEBFORM_SAVE:
{
Settings.TaskDevicePluginConfig[event->TaskIndex][0] = getFormItemInt(F("plugin_162_mode"));
Settings.TaskDevicePluginConfig[event->TaskIndex][1] = getFormItemInt(F("plugin_162_osr"));
success = true;
Plugin_162_init = false;
success = true;
break;
}
case PLUGIN_INIT:
{
Plugin_162_init = true;
mode162 = (uint8_t)Settings.TaskDevicePluginConfig[event->TaskIndex][0];
osr162 = (uint8_t)Settings.TaskDevicePluginConfig[event->TaskIndex][1];
if (checkDeviceID162()) addLog(LOG_LEVEL_INFO, F("MPL3115A2 : Found"));
else addLog(LOG_LEVEL_INFO, F("MPL3115A2 : Not Found"));
configRegister162 = (mode162 * 128) + (osr162 * 8);
setup162(configRegister162);
success = true;
break;
}
case PLUGIN_READ:
{
float temperature = -99.99;
float pressure = 0.0;
float altitude = -9999.99;
mode162 = (uint8_t)Settings.TaskDevicePluginConfig[event->TaskIndex][0];
osr162 = (uint8_t)Settings.TaskDevicePluginConfig[event->TaskIndex][1];
configRegister162 = (mode162 * 128) + (osr162 * 8);
if (startConversion162(configRegister162))
{
if (mode162 == 0) pressure = readPressure162(configRegister162);
else altitude = readAltitude162(configRegister162);
temperature = readTemperature162(configRegister162);
}
UserVar[event->BaseVarIndex] = temperature;
UserVar[event->BaseVarIndex + 1] = pressure;
UserVar[event->BaseVarIndex + 2] = altitude;
String log = F("MPL3115A2 : Temperature : ");
log += UserVar[event->BaseVarIndex];
addLog(LOG_LEVEL_INFO, log);
if (mode162 == 0)
{
log = F("MPL3115A2 : Pressure : ");
log += UserVar[event->BaseVarIndex + 1];
}
else
{
log = F("MPL3115A2 : Altitude : ");
log += UserVar[event->BaseVarIndex + 2];
}
addLog(LOG_LEVEL_INFO, log);
success = true;
break;
}
}
return success;
}
////////////////////////////////////////////////////////////////////////////////
//// ////
//// MPL3115A2 system constants ////
//// ////
////////////////////////////////////////////////////////////////////////////////
//// ////
//// I2C ADDRESS/BITS
#define MPL3115A2_ADDRESS (0x60) // 1100000
//// REGISTERS
#define MPL3115A2_REGISTER_STATUS (0x00)
#define MPL3115A2_REGISTER_STATUS_TDR 0x02
#define MPL3115A2_REGISTER_STATUS_PDR 0x04
#define MPL3115A2_REGISTER_STATUS_PTDR 0x08
#define MPL3115A2_REGISTER_PRESSURE_MSB (0x01)
#define MPL3115A2_REGISTER_PRESSURE_CSB (0x02)
#define MPL3115A2_REGISTER_PRESSURE_LSB (0x03)
#define MPL3115A2_REGISTER_TEMP_MSB (0x04)
#define MPL3115A2_REGISTER_TEMP_LSB (0x05)
#define MPL3115A2_REGISTER_DR_STATUS (0x06)
#define MPL3115A2_OUT_P_DELTA_MSB (0x07)
#define MPL3115A2_OUT_P_DELTA_CSB (0x08)
#define MPL3115A2_OUT_P_DELTA_LSB (0x09)
#define MPL3115A2_OUT_T_DELTA_MSB (0x0A)
#define MPL3115A2_OUT_T_DELTA_LSB (0x0B)
#define MPL3115A2_WHOAMI (0x0C)
#define MPL3115A2_WHOAMI_DEVICE_ID (0xC4)
#define MPL3115A2_PT_DATA_CFG 0x13
#define MPL3115A2_PT_DATA_CFG_TDEFE 0x01
#define MPL3115A2_PT_DATA_CFG_PDEFE 0x02
#define MPL3115A2_PT_DATA_CFG_DREM 0x04
#define MPL3115A2_CTRL_REG1 (0x26)
#define MPL3115A2_CTRL_REG1_SBYB 0x01
#define MPL3115A2_CTRL_REG1_OST 0x02
#define MPL3115A2_CTRL_REG1_RST 0x04
#define MPL3115A2_CTRL_REG1_OS1 0x00
#define MPL3115A2_CTRL_REG1_OS2 0x08
#define MPL3115A2_CTRL_REG1_OS4 0x10
#define MPL3115A2_CTRL_REG1_OS8 0x18
#define MPL3115A2_CTRL_REG1_OS16 0x20
#define MPL3115A2_CTRL_REG1_OS32 0x28
#define MPL3115A2_CTRL_REG1_OS64 0x30
#define MPL3115A2_CTRL_REG1_OS128 0x38
#define MPL3115A2_CTRL_REG1_RAW 0x40
#define MPL3115A2_CTRL_REG1_ALT 0x80
#define MPL3115A2_CTRL_REG1_BAR 0x00
#define MPL3115A2_CTRL_REG2 (0x27)
#define MPL3115A2_CTRL_REG3 (0x28)
#define MPL3115A2_CTRL_REG4 (0x29)
#define MPL3115A2_CTRL_REG5 (0x2A)
#define MPL3115A2_REGISTER_STARTCONVERSION (0x12)
//// ////
////////////////////////////////////////////////////////////////////////////////
//// ////
//// Functions ////
//// ////
////////////////////////////////////////////////////////////////////////////////
//// Setup MPL3115A2 ////
void setup162(uint8_t _data) {
writeConfigRegister162(MPL3115A2_CTRL_REG1, _data);
writeConfigRegister162(MPL3115A2_PT_DATA_CFG, MPL3115A2_PT_DATA_CFG_TDEFE | MPL3115A2_PT_DATA_CFG_PDEFE | MPL3115A2_PT_DATA_CFG_DREM);
}
//// ////
////////////////////////////////////////////////////////////////////////////////
//// Write to the configuration register ////
void writeConfigRegister162(uint8_t _registerAddress, uint8_t _data) {
Wire.beginTransmission(MPL3115A2_ADDRESS);
Wire.write( _registerAddress);
Wire.write(_data);
Wire.endTransmission();
}
//// ////
////////////////////////////////////////////////////////////////////////////////
//// Read the configuration register ////
uint8_t readConfigRegister162(uint8_t _registerAddress) {
uint8_t _data;
Wire.beginTransmission(MPL3115A2_ADDRESS);
Wire.write( _registerAddress);
Wire.endTransmission(false);
Wire.requestFrom(MPL3115A2_ADDRESS, 1);
if (Wire.available()) {
_data = Wire.read();
}
Wire.endTransmission();
return _data;
}
//// ////
////////////////////////////////////////////////////////////////////////////////
//// check MPL3115A2 device ID ////
boolean checkDeviceID162(void){
uint8_t idChip;
idChip = readConfigRegister162(MPL3115A2_WHOAMI);
if (idChip == MPL3115A2_WHOAMI_DEVICE_ID) return true;
return false;
}
//// ////
////////////////////////////////////////////////////////////////////////////////
//// Start the temperature conversion ////
boolean startConversion162(uint8_t _data) {
uint8_t wait = 15;
uint8_t regData;
Wire.beginTransmission(MPL3115A2_ADDRESS);
Wire.write(MPL3115A2_CTRL_REG1);
Wire.write(_data | MPL3115A2_CTRL_REG1_OST);
Wire.endTransmission();
delay(((1 << osr162) * 4 + 2));
while (wait > 0) {
regData = readConfigRegister162(MPL3115A2_CTRL_REG1);
if (!(regData & MPL3115A2_CTRL_REG1_OST)) break;
delay(2);
-- wait;
}
if (wait <= 0) return false; // timeout
return true;
}
//// ////
////////////////////////////////////////////////////////////////////////////////
//// Read pressure and return float value ////
float readPressure162(uint8_t _data) {
uint8_t pressureMSB = 0;
uint8_t pressureCSB = 0;
uint8_t pressureLSB = 0;
float pressure;
startConversion162(_data);
Wire.beginTransmission(MPL3115A2_ADDRESS);
Wire.write(MPL3115A2_REGISTER_PRESSURE_MSB);
Wire.endTransmission(false); // I2C RESTART
Wire.requestFrom(MPL3115A2_ADDRESS, 3);
if (3 <= Wire.available()) {
pressureMSB = (uint8_t) Wire.read();
pressureCSB = (uint8_t) Wire.read();
pressureLSB = (uint8_t) Wire.read();
}
pressure = (float)pressureMSB * 1024 + (float)pressureCSB * 4 + (float)pressureLSB / 64;
pressureLSB &= 48;
pressureLSB /= 16;
pressure += (float)pressureLSB * 0.25;
return (float)pressure;
}
//// ////
////////////////////////////////////////////////////////////////////////////////
//// Read altitude and return float value ////
float readAltitude162(uint8_t _data) {
uint8_t altitudeMSB = 0;
uint8_t altitudeCSB = 0;
uint8_t altitudeLSB = 0;
float altitude;
startConversion162(_data);
Wire.beginTransmission(MPL3115A2_ADDRESS);
Wire.write(MPL3115A2_REGISTER_PRESSURE_MSB);
Wire.endTransmission(false); // I2C RESTART
Wire.requestFrom(MPL3115A2_ADDRESS, 3);
if (3 <= Wire.available()) {
altitudeMSB = (uint8_t) Wire.read();
altitudeCSB = (uint8_t) Wire.read();
altitudeLSB = (uint8_t) Wire.read();
}
altitude = (float)altitudeMSB;
if (altitudeMSB & 0x80) altitude -= 256; // negative altitude
altitude *= 256;
altitude += (float)altitudeCSB;
altitudeLSB /= 16;
altitude += (float)altitudeLSB * 0.0625;
return (float)altitude;
}
//// ////
////////////////////////////////////////////////////////////////////////////////
//// Read temperature and return float value ////
float readTemperature162(uint8_t _data) {
uint8_t temperatureMSB = 0;
uint8_t temperatureLSB = 0;
float temperature;
startConversion162(_data);
Wire.beginTransmission(MPL3115A2_ADDRESS);
Wire.write(MPL3115A2_REGISTER_TEMP_MSB);
Wire.endTransmission(false); // I2C RESTART
Wire.requestFrom(MPL3115A2_ADDRESS, 2);
if (2 <= Wire.available()) {
temperatureMSB = (uint8_t) Wire.read();
temperatureLSB = (uint8_t) Wire.read();
}
temperature = (float) temperatureMSB;
if (temperatureMSB & 0x80) temperature -= 256; // negative temperature
temperatureLSB /= 16;
temperature += (float)temperatureLSB * 0.0625;
return (float)temperature;
}