Skip to content

Commit 8657c34

Browse files
committed
Increase SEN44 read measurement time from 5 ms to 10 ms; Add SEN44 T offset example
1 parent d7e7d54 commit 8657c34

File tree

3 files changed

+213
-4
lines changed

3 files changed

+213
-4
lines changed
Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
/*
2+
* Copyright (c) 2020, Sensirion AG
3+
* All rights reserved.
4+
*
5+
* Redistribution and use in source and binary forms, with or without
6+
* modification, are permitted provided that the following conditions are met:
7+
*
8+
* * Redistributions of source code must retain the above copyright notice, this
9+
* list of conditions and the following disclaimer.
10+
*
11+
* * Redistributions in binary form must reproduce the above copyright notice,
12+
* this list of conditions and the following disclaimer in the documentation
13+
* and/or other materials provided with the distribution.
14+
*
15+
* * Neither the name of Sensirion AG nor the names of its
16+
* contributors may be used to endorse or promote products derived from
17+
* this software without specific prior written permission.
18+
*
19+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29+
* POSSIBILITY OF SUCH DAMAGE.
30+
*/
31+
32+
#include <Wire.h>
33+
34+
// SEN44
35+
const int16_t SEN44_ADDRESS = 0x69;
36+
37+
void setup() {
38+
int16_t t_offset;
39+
uint8_t data[3], counter;
40+
41+
Serial.begin(115200);
42+
// wait for serial connection from PC
43+
// comment the following line if you'd like the output
44+
// without waiting for the interface being ready
45+
while(!Serial);
46+
47+
// output format
48+
Serial.println("PM1.0\tPM2.5\tPM4.0\tPM10.0\tVOC_Index\tRH\tT");
49+
50+
// init I2C
51+
Wire.begin();
52+
53+
// wait until sensors startup, > 1 ms according to datasheet
54+
delay(100);
55+
56+
// read t offset from flash memory
57+
Wire.beginTransmission(SEN44_ADDRESS);
58+
Wire.write(0x60);
59+
Wire.write(0x14);
60+
Wire.endTransmission();
61+
62+
// wait 10 ms to allow the sensor to fill the internal buffer
63+
delay(10);
64+
65+
// read offset data, after two bytes a CRC follows
66+
Wire.requestFrom(SEN44_ADDRESS, 3);
67+
counter = 0;
68+
while (Wire.available()) {
69+
data[counter++] = Wire.read();
70+
}
71+
72+
t_offset = (uint16_t)data[0] << 8 | data[1];
73+
74+
// print value, as all temperature values, this one is also scaled by 200
75+
Serial.print("Default T Offset: ");
76+
Serial.print(String(float(t_offset)/200));
77+
Serial.println();
78+
79+
// set t offset to new value (-5 degC) and scale it accordingly by a factor of 200
80+
t_offset = -5 * 200;
81+
82+
// prepare buffer with t offset data
83+
// calculate CRC for each 2 bytes of data
84+
data[0] = (t_offset & 0xff00) >> 8;
85+
data[1] = t_offset & 0x00ff;
86+
data[2] = CalcCrc(data);
87+
88+
// send new value for t offset to sensor (will be hold in RAM, not persistent)
89+
Wire.beginTransmission(SEN44_ADDRESS);
90+
Wire.write(0x60);
91+
Wire.write(0x14);
92+
Wire.write(data[0]);
93+
Wire.write(data[1]);
94+
Wire.write(data[2]);
95+
Wire.endTransmission();
96+
97+
// wait 10 ms to allow the sensor to fill the internal buffer
98+
delay(10);
99+
100+
// now send command to save parameter in the flash (NVM memory) of the sensor to have persistence
101+
Wire.beginTransmission(SEN44_ADDRESS);
102+
Wire.write(0x60);
103+
Wire.write(0x02);
104+
Wire.endTransmission();
105+
106+
// wait 20 ms to allow the sensor to write the data into the flash
107+
delay(20);
108+
109+
// repeat read offset data to make sure that the values are applied correctly
110+
Wire.beginTransmission(SEN44_ADDRESS);
111+
Wire.write(0x60);
112+
Wire.write(0x14);
113+
Wire.endTransmission();
114+
115+
// wait 10 ms to allow the sensor to fill the internal buffer
116+
delay(10);
117+
118+
// read offset data, after two bytes a CRC follows
119+
Wire.requestFrom(SEN44_ADDRESS, 3);
120+
counter = 0;
121+
while (Wire.available()) {
122+
data[counter++] = Wire.read();
123+
}
124+
125+
t_offset = (uint16_t)data[0] << 8 | data[1];
126+
127+
Serial.print("New T Offset: ");
128+
Serial.print(String(float(t_offset)/200));
129+
Serial.println();
130+
131+
// start up sensor, sensor will go to continous measurement mode
132+
// each second there will be new measurement values
133+
Wire.beginTransmission(SEN44_ADDRESS);
134+
Wire.write(0x00);
135+
Wire.write(0x21);
136+
Wire.endTransmission();
137+
138+
// wait until sensors is ready, fan is initialized
139+
delay(2000);
140+
}
141+
142+
void loop() {
143+
uint16_t pm1p0, pm2p5, pm4p0, pm10p0;
144+
int16_t voc, humidity, temperature;
145+
uint8_t data[21], counter;
146+
147+
// read measurement data
148+
Wire.beginTransmission(SEN44_ADDRESS);
149+
Wire.write(0x03);
150+
Wire.write(0x74);
151+
Wire.endTransmission();
152+
153+
// wait 10 ms to allow the sensor to fill the internal buffer
154+
delay(10);
155+
156+
// read measurement data sen44, after two bytes a CRC follows
157+
Wire.requestFrom(SEN44_ADDRESS, 21);
158+
counter = 0;
159+
while (Wire.available()) {
160+
data[counter++] = Wire.read();
161+
}
162+
163+
// PM1.0 to PM10 are unscaled unsigned integer values in ug / um3
164+
// VOC level is a signed int and scaled by a factor of 10 and needs to be divided by 10
165+
// VOC raw value is an uint16_t and has no scaling
166+
// humidity is a signed int and scaled by 100 and need to be divided by 100
167+
// temperature is a signed int and scaled by 200 and need to be divided by 200
168+
pm1p0 = (uint16_t)data[0] << 8 | data[1];
169+
pm2p5 = (uint16_t)data[3] << 8 | data[4];
170+
pm4p0 = (uint16_t)data[6] << 8 | data[7];
171+
pm10p0 = (uint16_t)data[9] << 8 | data[10];
172+
voc = (uint16_t)data[12] << 8 | data[13];
173+
humidity = (uint16_t)data[15] << 8 | data[16];
174+
temperature = (uint16_t)data[18] << 8 | data[19];
175+
176+
Serial.print(pm1p0);
177+
Serial.print("\t");
178+
Serial.print(pm2p5);
179+
Serial.print("\t");
180+
Serial.print(pm4p0);
181+
Serial.print("\t");
182+
Serial.print(pm10p0);
183+
Serial.print("\t");
184+
Serial.print(String(float(voc) / 10));
185+
Serial.print("\t");
186+
Serial.print(String(float(humidity) / 100));
187+
Serial.print("\t");
188+
Serial.print(String(float(temperature) / 200));
189+
Serial.println();
190+
191+
// wait 1 s for next measurement
192+
delay(1000);
193+
}
194+
195+
// calculate CRC according to datasheet
196+
uint8_t CalcCrc(uint8_t data[2]) {
197+
uint8_t crc = 0xFF;
198+
for(int i = 0; i < 2; i++) {
199+
crc ^= data[i];
200+
for(uint8_t bit = 8; bit > 0; --bit) {
201+
if(crc & 0x80) {
202+
crc = (crc << 1) ^ 0x31u;
203+
} else {
204+
crc = (crc << 1);
205+
}
206+
}
207+
}
208+
return crc;
209+
}

SEN44_I2C_minimal_example/SEN44_I2C_minimal_example.ino

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,8 @@ void loop() {
7373
Wire.write(0x74);
7474
Wire.endTransmission();
7575

76-
// wait 5 ms to allow the sensor to fill the internal buffer
77-
delay(5);
76+
// wait 10 ms to allow the sensor to fill the internal buffer
77+
delay(10);
7878

7979
// read measurement data SEN44, after two bytes a CRC follows
8080
Wire.requestFrom(SEN44_ADDRESS, 21);

SEN44_SCD40_I2C_example/SEN44_SCD40_I2C_example.ino

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,8 @@ void loop() {
112112
Wire.write(0x74);
113113
Wire.endTransmission();
114114

115-
// wait 5 ms to allow the sensor to fill the internal buffer
116-
delay(5);
115+
// wait 10 ms to allow the sensor to fill the internal buffer
116+
delay(10);
117117

118118
// read measurement data SEN44, after two bytes a CRC follows
119119
Wire.requestFrom(SEN44_ADDRESS, 21);

0 commit comments

Comments
 (0)