9
9
#define PLUGIN_VALUENAME1_031 " Temperature"
10
10
#define PLUGIN_VALUENAME2_031 " Humidity"
11
11
12
+ #define P031_IDLE 0
13
+ #define P031_WAIT_TEMP 1
14
+ #define P031_WAIT_HUM 2
15
+ #define P031_MEAS_READY 3
16
+ #define P031_COMMAND_NO_ACK 4
17
+ #define P031_NO_DATA 5
18
+
12
19
class P031_data_struct : public PluginTaskData_base
13
20
{
14
21
public:
@@ -25,69 +32,85 @@ public:
25
32
_dataPin = data_pin;
26
33
_clockPin = clock_pin;
27
34
input_mode = pullUp ? INPUT_PULLUP : INPUT;
35
+ state = P031_IDLE;
28
36
29
37
pinMode (_dataPin, input_mode); /* Keep Hi-Z except when sending data */
30
38
pinMode (_clockPin, OUTPUT);
31
39
resetSensor ();
32
40
return readStatus ();
33
41
}
34
42
43
+ bool process () {
44
+ switch (state) {
45
+ case P031_IDLE: return false ; // Nothing changed, nothing to do
46
+ case P031_WAIT_TEMP: {
47
+ if (digitalRead (_dataPin) == LOW) {
48
+ float tempRaw = readData (16 );
49
+ // Temperature conversion coefficients from SHT1X datasheet for version 4
50
+ const float d1 = -39.7 ; // 3.5V
51
+ const float d2 = 0.01 ; // 14-bit
52
+ tempC = d1 + (tempRaw * d2);
53
+ state = P031_WAIT_HUM; // Wait for humidity
54
+ sendCommand (SHT1X_CMD_MEASURE_RH);
55
+ }
56
+ break ;
57
+ }
58
+ case P031_WAIT_HUM:
59
+ {
60
+ if (digitalRead (_dataPin) == LOW) {
61
+ float raw = readData (16 );
62
+
63
+ // Temperature conversion coefficients from SHT1X datasheet for version 4
64
+ const float c1 = -2.0468 ;
65
+ const float c2 = 0.0367 ;
66
+ const float c3 = -1.5955E-6 ;
67
+ const float t1 = 0.01 ;
68
+ const float t2 = 0.00008 ;
69
+
70
+ float rhLinear = c1 + c2 * raw + c3 * raw * raw;
71
+ rhTrue = (tempC - 25 ) * (t1 + t2 * raw) + rhLinear;
72
+ /*
73
+ String log = F("SHT1X : Read humidity (raw): ");
74
+ log += String(raw);
75
+ log += F(" (Linear): ");
76
+ log += String(rhLinear);
77
+ log += F(" (True): ");
78
+ log += String(rhTrue);
79
+ addLog(LOG_LEVEL_DEBUG, log);
80
+ */
81
+ state = P031_MEAS_READY; // Measurement ready
82
+ return true ;
83
+ }
84
+ break ;
85
+ }
86
+ case P031_MEAS_READY: return true ;
87
+ default :
88
+ // It is already an error state, just return.
89
+ return false ;
90
+ }
91
+ // Compute timeout
92
+ if (timePassedSince (sendCommandTime) > 320 ) {
93
+ state = P031_NO_DATA; // No data after 320 msec
94
+ }
95
+ return false ;
96
+ }
35
97
36
- float readTemperature ()
37
- {
38
- float tempRaw, tempC;
39
-
98
+ void startMeasurement () {
99
+ state = P031_WAIT_TEMP; // Wait for temperature
40
100
sendCommand (SHT1X_CMD_MEASURE_TEMP);
41
- awaitResult ();
42
- tempRaw = readData (16 );
43
-
44
- // Temperature conversion coefficients from SHT1X datasheet for version 4
45
- const float d1 = -39.7 ; // 3.5V
46
- const float d2 = 0.01 ; // 14-bit
47
-
48
- tempC = d1 + (tempRaw * d2);
49
- /*
50
- String log = F("SHT1X : Read temperature (raw): ");
51
- log += String(tempRaw);
52
- log += F(" (Celcius): ");
53
- log += String(tempC);
54
- addLog(LOG_LEVEL_DEBUG, log);
55
- */
56
- return tempC;
57
101
}
58
102
59
- float readRelHumidity (float tempC)
60
- {
61
- float raw, rhLinear, rhTrue;
62
-
63
- sendCommand (SHT1X_CMD_MEASURE_RH);
64
- awaitResult ();
65
- raw = readData (16 );
66
-
67
- // Temperature conversion coefficients from SHT1X datasheet for version 4
68
- const float c1 = -2.0468 ;
69
- const float c2 = 0.0367 ;
70
- const float c3 = -1.5955E-6 ;
71
- const float t1 = 0.01 ;
72
- const float t2 = 0.00008 ;
73
-
74
- rhLinear = c1 + c2 * raw + c3 * raw * raw;
75
- rhTrue = (tempC - 25 ) * (t1 + t2 * raw) + rhLinear;
76
- /*
77
- String log = F("SHT1X : Read humidity (raw): ");
78
- log += String(raw);
79
- log += F(" (Linear): ");
80
- log += String(rhLinear);
81
- log += F(" (True): ");
82
- log += String(rhTrue);
83
- addLog(LOG_LEVEL_DEBUG, log);
84
- */
85
- return rhTrue;
103
+ bool measurementReady () {
104
+ return state == P031_MEAS_READY;
86
105
}
87
106
107
+ bool hasError () {
108
+ return state > P031_MEAS_READY;
109
+ }
88
110
89
111
void resetSensor ()
90
112
{
113
+ state = P031_IDLE;
91
114
delay (11 );
92
115
for (int i=0 ; i<9 ; i++) {
93
116
digitalWrite (_clockPin, HIGH);
@@ -105,6 +128,7 @@ public:
105
128
106
129
void sendCommand (const byte cmd)
107
130
{
131
+ sendCommandTime = millis ();
108
132
pinMode (_dataPin, OUTPUT);
109
133
110
134
// Transmission Start sequence
@@ -130,21 +154,8 @@ public:
130
154
delayMicroseconds (1 ); /* Give the sensor time to release the data line */
131
155
if (digitalRead (_dataPin) != HIGH) ackerror = true ;
132
156
}
133
-
134
157
if (ackerror) {
135
- // addLog(LOG_LEVEL_ERROR, F("SHT1X : Sensor did not ACK command"));
136
- }
137
- }
138
-
139
- void awaitResult ()
140
- {
141
- // Maximum 320ms for 14 bit measurement
142
- for (int i=0 ; i<16 ; i++) {
143
- if (digitalRead (_dataPin) == LOW) return ;
144
- delay (20 );
145
- }
146
- if (digitalRead (_dataPin) != LOW) {
147
- // addLog(LOG_LEVEL_ERROR, F("SHT1X : Data not ready"));
158
+ state = P031_COMMAND_NO_ACK;
148
159
}
149
160
}
150
161
@@ -175,9 +186,14 @@ public:
175
186
return val;
176
187
}
177
188
189
+ float tempC = 0.0 ;
190
+ float rhTrue = 0.0 ;
191
+ unsigned long sendCommandTime;
192
+
193
+ int input_mode;
178
194
byte _dataPin = 0 ;
179
195
byte _clockPin = 0 ;
180
- int input_mode ;
196
+ byte state = P031_IDLE ;
181
197
};
182
198
183
199
@@ -248,14 +264,46 @@ boolean Plugin_031(byte function, struct EventStruct *event, String& string)
248
264
break ;
249
265
}
250
266
267
+ case PLUGIN_TEN_PER_SECOND:
268
+ {
269
+ P031_data_struct *P031_data =
270
+ static_cast <P031_data_struct *>(getPluginTaskData (event->TaskIndex ));
271
+ if (nullptr != P031_data) {
272
+ if (P031_data->process ()) {
273
+ // Measurement ready, schedule new read.
274
+ schedule_task_device_timer (event->TaskIndex , millis () + 10 );
275
+ }
276
+ }
277
+ success = true ;
278
+ break ;
279
+ }
280
+
251
281
case PLUGIN_READ:
252
282
{
253
283
P031_data_struct *P031_data =
254
284
static_cast <P031_data_struct *>(getPluginTaskData (event->TaskIndex ));
255
285
if (nullptr != P031_data) {
256
- UserVar[event->BaseVarIndex ] = P031_data->readTemperature ();
257
- UserVar[event->BaseVarIndex +1 ] = P031_data->readRelHumidity (UserVar[event->BaseVarIndex ]);
258
- success = true ;
286
+ if (P031_data->measurementReady ()) {
287
+ UserVar[event->BaseVarIndex ] = P031_data->tempC ;
288
+ UserVar[event->BaseVarIndex +1 ] = P031_data->rhTrue ;
289
+ success = true ;
290
+ P031_data->state = P031_IDLE;
291
+ } else if (P031_data->state == P031_IDLE) {
292
+ P031_data->startMeasurement ();
293
+ } else if (P031_data->hasError ()) {
294
+ // Log error
295
+ switch (P031_data->state ) {
296
+ case P031_COMMAND_NO_ACK:
297
+ addLog (LOG_LEVEL_ERROR, F (" SHT1X : Sensor did not ACK command" ));
298
+ break ;
299
+ case P031_NO_DATA:
300
+ addLog (LOG_LEVEL_ERROR, F (" SHT1X : Data not ready" ));
301
+ break ;
302
+ default :
303
+ break ;
304
+ }
305
+ P031_data->state = P031_IDLE;
306
+ }
259
307
}
260
308
break ;
261
309
}
0 commit comments