3
3
#include < SoftwareSerial.h>
4
4
#include < LiquidCrystal_I2C.h>
5
5
6
- int data_ready_signal_pin = 2 ;
7
- int sensor_receiver_pin = 3 ;
8
- int sensor_transmitter_pin = 4 ;
9
- uint8_t sensor_data_head = 0xAA ;
10
- uint8_t sensor_measurement_answer_id = 0xC0 ;
11
-
12
- uint8_t sleep_mode_command[] = {
13
- 0xAA , 0xB4 , 0x06 , 0x01 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0xFF , 0xFF , 0x05 , 0xAB
6
+ class PmResult {
7
+ public:
8
+ float pm25;
9
+ float pm10;
10
+
11
+ PmResult (float pm25, float pm10) {
12
+ this ->pm25 = pm25;
13
+ this ->pm10 = pm10;
14
+ }
14
15
};
15
16
16
- uint8_t work_mode_command[] = {
17
- 0xAA , 0xB4 , 0x06 , 0x01 , 0x01 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0xFF , 0xFF , 0x06 , 0xAB
18
- };
17
+ class Sds011SensorHandler {
18
+ public:
19
+ SoftwareSerial& sensorSerial;
20
+
21
+ Sds011SensorHandler (SoftwareSerial& sensorSerial)
22
+ : sensorSerial(sensorSerial) {}
23
+
24
+ private:
25
+ uint8_t sleep_mode_command[19 ] = {
26
+ 0xAA , 0xB4 , 0x06 , 0x01 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0xFF , 0xFF , 0x05 , 0xAB
27
+ };
28
+
29
+ private:
30
+ uint8_t work_mode_command[19 ] = {
31
+ 0xAA , 0xB4 , 0x06 , 0x01 , 0x01 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0xFF , 0xFF , 0x06 , 0xAB
32
+ };
33
+
34
+ private:
35
+ uint8_t query_report_mode_command[19 ] = {
36
+ 0xAA , 0xB4 , 0x02 , 0x01 , 0x01 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0xFF , 0xFF , 0x02 , 0xAB
37
+ };
38
+
39
+ private:
40
+ uint8_t query_data_command[19 ] = {
41
+ 0xAA , 0xB4 , 0x04 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0xFF , 0xFF , 0x02 , 0xAB
42
+ };
43
+
44
+ private:
45
+ uint8_t active_report_mode_command[19 ] = {
46
+ 0xAA , 0xB4 , 0x02 , 0x01 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0xFF , 0xFF , 0x01 , 0xAB
47
+ };
48
+
49
+ private:
50
+ uint8_t sensor_data_head = 0xAA ;
51
+ private:
52
+ uint8_t sensor_measurement_answer_id = 0xC0 ;
53
+
54
+ public:
55
+ PmResult readPmResult () {
56
+ waitUntilSensorDataIsAvailable ();
57
+ readUntilDataHead ();
19
58
20
- uint8_t query_report_mode_command[] = {
21
- 0xAA , 0xB4 , 0x02 , 0x01 , 0x01 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0xFF , 0xFF , 0x02 , 0xAB
22
- };
59
+ if (isSerialDataSensorMeasurement ()) {
60
+ int pm25Low = sensorSerial.read ();
61
+ int pm25High = sensorSerial.read ();
62
+ int pm10Low = sensorSerial.read ();
63
+ int pm10High = sensorSerial.read ();
64
+ float pm25 = convertHighLowByteToDecimal (pm25High, pm25Low) / 10.0 ;
65
+ float pm10 = convertHighLowByteToDecimal (pm10High, pm10Low) / 10.0 ;
66
+
67
+ return PmResult (pm25, pm10);
68
+ }
69
+ }
70
+
71
+ private:
72
+ void sendCommand (uint8_t * cmd, size_t len) {
73
+ for (size_t i = 0 ; i < len; ++i) {
74
+ sensorSerial.write (cmd[i]);
75
+ }
76
+ }
77
+
78
+ public:
79
+ void sendSleepModeCommand () {
80
+ sendCommand (sleep_mode_command, sizeof (sleep_mode_command));
81
+ }
82
+
83
+ public:
84
+ void sendWorkModeCommand () {
85
+ sendCommand (work_mode_command, sizeof (work_mode_command));
86
+ }
87
+
88
+ public:
89
+ void sendQueryReportModeCommand () {
90
+ sendCommand (query_report_mode_command, sizeof (query_report_mode_command));
91
+ }
92
+
93
+ public:
94
+ void sendActiveReportModeCommand () {
95
+ sendCommand (active_report_mode_command, sizeof (active_report_mode_command));
96
+ }
97
+
98
+ public:
99
+ void sendQueryDataCommand () {
100
+ sendCommand (query_data_command, sizeof (query_data_command));
101
+ }
102
+
103
+ int convertHighLowByteToDecimal (uint8_t high, uint8_t low) {
104
+ return (high << 8 ) | low;
105
+ }
106
+
107
+ private:
108
+ uint8_t mod256 (uint16_t value) {
109
+ return value % 256 ;
110
+ }
111
+
112
+ private:
113
+ bool isSensorDataAvailable () {
114
+ return sensorSerial.available () >= 10 ;
115
+ }
116
+ private:
117
+ bool waitUntilSensorDataIsAvailable () {
118
+ while (sensorSerial.available () < 10 )
119
+ ;
120
+ }
121
+
122
+ private:
123
+ void readUntilDataHead () {
124
+ while (sensorSerial.read () != sensor_data_head)
125
+ ;
126
+ }
127
+
128
+ private:
129
+ bool isSerialDataSensorMeasurement () {
130
+ return sensorSerial.read () == sensor_measurement_answer_id;
131
+ }
23
132
24
- uint8_t active_report_mode_command[] = {
25
- 0xAA , 0xB4 , 0x02 , 0x01 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0xFF , 0xFF , 0x01 , 0xAB
133
+ private:
134
+ void readRawCommandResponse () {
135
+ while (sensorSerial.available ()) {
136
+ uint8_t b = sensorSerial.read ();
137
+ Serial.print (" 0x" );
138
+ Serial.print (b, HEX);
139
+ Serial.print (" " );
140
+ }
141
+ Serial.println ();
142
+ }
26
143
};
27
144
145
+ int data_ready_signal_pin = 2 ;
146
+ int sensor_receiver_pin = 3 ;
147
+ int sensor_transmitter_pin = 4 ;
148
+
28
149
SoftwareSerial sensorSerial (sensor_receiver_pin, sensor_transmitter_pin);
29
150
LiquidCrystal_I2C lcd (0x27 , 16 , 2 );
151
+ Sds011SensorHandler sensorHandler (sensorSerial);
30
152
31
153
void setup () {
32
154
Serial.begin (115200 );
33
155
sensorSerial.begin (9600 );
34
- setTime (13 , 01 , 0 , 27 , 5 , 2025 ); // Set current time for arduino
156
+ setTime (13 , 49 , 0 , 28 , 5 , 2025 ); // Set current time for arduino
35
157
pinMode (data_ready_signal_pin, OUTPUT);
36
158
lcd.begin (16 , 2 );
37
- // sendCommand(query_report_mode_command, sizeof(query_report_mode_command));
38
- // delay(1000);
39
- // sendCommand(work_mode_command, sizeof(work_mode_command));
40
- // delay(1000);
41
- // sendCommand(active_report_mode_command, sizeof(active_report_mode_command));
42
- // delay(1000);
43
- }
44
-
45
- void sendCommand (uint8_t * cmd, size_t len) {
46
- for (size_t i = 0 ; i < len; ++i) {
47
- sensorSerial.write (cmd[i]);
48
- }
159
+ sensorHandler.sendQueryReportModeCommand ();
160
+ delay (1000 );
49
161
}
50
162
51
163
String getDateTime () {
@@ -63,28 +175,23 @@ String getDateTime() {
63
175
}
64
176
65
177
void loop () {
66
- measureParticle ();
67
- }
68
-
69
- void measureParticle () {
70
- if (isSensorDataAvailable ()) {
71
- readUntilDataHead ();
72
- if (isSerialDataSensorMeasurement ()) {
73
- readMeasurementData ();
74
- }
75
- }
178
+ Serial.println (" Send work mode command." );
179
+ sensorHandler.sendWorkModeCommand ();
180
+ delay (30000 );
181
+ Serial.println (" Send query data command." );
182
+ sensorHandler.sendQueryDataCommand ();
183
+ delay (1000 );
184
+ Serial.println (" Read measurement command." );
185
+ readMeasurementData ();
186
+ Serial.println (" Send sleep mode command." );
187
+ sensorHandler.sendSleepModeCommand ();
188
+ delay (60000 );
76
189
}
77
190
78
191
void readMeasurementData () {
79
- int pm25Low = sensorSerial.read ();
80
- int pm25High = sensorSerial.read ();
81
- int pm10Low = sensorSerial.read ();
82
- int pm10High = sensorSerial.read ();
83
- float pm25 = convertHighLowByteToDecimal (pm25High, pm25Low) / 10.0 ;
84
- float pm10 = convertHighLowByteToDecimal (pm10High, pm10Low) / 10.0 ;
85
-
86
- String pm25Output = " PM2.5: " + String (pm25) + " ug/m3" ;
87
- String pm10Output = " PM10: " + String (pm10) + " ug/m3" ;
192
+ PmResult pmResult = sensorHandler.readPmResult ();
193
+ String pm25Output = " PM2.5: " + String (pmResult.pm25 ) + " ug/m3" ;
194
+ String pm10Output = " PM10: " + String (pmResult.pm10 ) + " ug/m3" ;
88
195
89
196
lcd.clear ();
90
197
lcd.setCursor (0 , 0 );
@@ -93,67 +200,11 @@ void readMeasurementData() {
93
200
lcd.print (pm10Output);
94
201
95
202
Serial.println (getDateTime () + " :" + " \n " + pm25Output + " \n " + pm10Output);
96
- sendDataIsReadySignal ();
203
+ sendDataIsReadySignalForEsp32 ();
97
204
}
98
205
99
- void readRawCommandResponse () {
100
- while (sensorSerial.available ()) {
101
- uint8_t b = sensorSerial.read ();
102
- Serial.print (" 0x" );
103
- Serial.print (b, HEX);
104
- Serial.print (" " );
105
- }
106
- Serial.println ();
107
- }
108
-
109
- bool isSensorDataAvailable () {
110
- return sensorSerial.available () >= 10 ;
111
- }
112
-
113
- void readUntilDataHead () {
114
- while (sensorSerial.read () != sensor_data_head)
115
- ;
116
- }
117
-
118
- bool isSerialDataSensorMeasurement () {
119
- return sensorSerial.read () == sensor_measurement_answer_id;
120
- }
121
-
122
- void sendDataIsReadySignal () {
206
+ void sendDataIsReadySignalForEsp32 () {
123
207
digitalWrite (data_ready_signal_pin, HIGH); // Data is ready signal for esp32
124
208
delay (10 ); // Short amount of time for signal detection
125
209
digitalWrite (data_ready_signal_pin, LOW); // Reset signal
126
210
}
127
-
128
- int convertHighLowByteToDecimal (uint8_t high, uint8_t low) {
129
- return (high << 8 ) | low;
130
- }
131
-
132
- void scanScreenAddress () {
133
- Wire.begin ();
134
- Serial.begin (4800 );
135
- while (!Serial)
136
- ; // Needed for some cards, No problem for Nano
137
-
138
- Serial.println (" Scanning I2C devices..." );
139
-
140
- byte count = 0 ;
141
- for (byte addr = 1 ; addr < 127 ; addr++) {
142
- Wire.beginTransmission (addr);
143
- if (Wire.endTransmission () == 0 ) {
144
- Serial.print (" Device found: 0x" );
145
- Serial.println (addr, HEX);
146
- count++;
147
- }
148
- }
149
-
150
- if (count == 0 ) {
151
- Serial.println (" No I2C device found." );
152
- } else {
153
- Serial.println (" Scan has been finished." );
154
- }
155
- }
156
-
157
- uint8_t mod256 (uint16_t value) {
158
- return value % 256 ;
159
- }
0 commit comments