mirror of
https://github.com/letscontrolit/ESPEasy.git
synced 2026-07-28 04:07:47 +00:00
Rework of Plugin _P056_SDS011-Dust (#451)
* First rework * Moved classes to library * Finished rework
This commit is contained in:
@@ -1,22 +0,0 @@
|
||||
# SDS011
|
||||
|
||||
Arduino library for dust Sensor SDS011 (Nova Fitness Co.,Ltd)
|
||||
This library uses SoftSerial to connect to the SDS011.
|
||||
|
||||
## Usage
|
||||
|
||||
* Define SDS object:
|
||||
SDS011(uint8_t pin_rx, uint8_t pin_tx);
|
||||
i.e. SDS011 mySDS(pinRX,pinTX);
|
||||
|
||||
* Start object:
|
||||
void begin(void);
|
||||
i.e. mySDS.begin();
|
||||
|
||||
* Read values:
|
||||
int read(float *p25, float *p10);
|
||||
i.e. error = mySDS(pm25,pm10);
|
||||
|
||||
Reads the PM2.5 and PM10 values, return code is 0, if new values were read, and 1 if there were no new values.
|
||||
|
||||
|
||||
@@ -1,110 +0,0 @@
|
||||
// SDS011 dust sensor PM2.5 and PM10
|
||||
// ---------------------
|
||||
//
|
||||
// By R. Zschiegner (rz@madavi.de)
|
||||
// April 2016
|
||||
//
|
||||
// Documentation:
|
||||
// - The iNovaFitness SDS011 datasheet
|
||||
//
|
||||
|
||||
#include "SDS011.h"
|
||||
|
||||
static const byte SLEEPCMD[19] = {
|
||||
0xAA, // head
|
||||
0xB4, // command id
|
||||
0x06, // data byte 1
|
||||
0x01, // data byte 2 (set mode)
|
||||
0x00, // data byte 3 (sleep)
|
||||
0x00, // data byte 4
|
||||
0x00, // data byte 5
|
||||
0x00, // data byte 6
|
||||
0x00, // data byte 7
|
||||
0x00, // data byte 8
|
||||
0x00, // data byte 9
|
||||
0x00, // data byte 10
|
||||
0x00, // data byte 11
|
||||
0x00, // data byte 12
|
||||
0x00, // data byte 13
|
||||
0xFF, // data byte 14 (device id byte 1)
|
||||
0xFF, // data byte 15 (device id byte 2)
|
||||
0x05, // checksum
|
||||
0xAB // tail
|
||||
};
|
||||
|
||||
SDS011::SDS011(void) {
|
||||
|
||||
}
|
||||
|
||||
// --------------------------------------------------------
|
||||
// SDS011:read
|
||||
// --------------------------------------------------------
|
||||
int SDS011::read(float *p25, float *p10) {
|
||||
byte buffer;
|
||||
int value;
|
||||
int len = 0;
|
||||
int pm10_serial = 0;
|
||||
int pm25_serial = 0;
|
||||
int checksum_is;
|
||||
int checksum_ok = 0;
|
||||
int error = 1;
|
||||
while ((sds_data->available() > 0) && (sds_data->available() >= (10-len))) {
|
||||
buffer = sds_data->read();
|
||||
value = int(buffer);
|
||||
switch (len) {
|
||||
case (0): if (value != 170) { len = -1; }; break;
|
||||
case (1): if (value != 192) { len = -1; }; break;
|
||||
case (2): pm25_serial = value; checksum_is = value; break;
|
||||
case (3): pm25_serial += (value << 8); checksum_is += value; break;
|
||||
case (4): pm10_serial = value; checksum_is += value; break;
|
||||
case (5): pm10_serial += (value << 8); checksum_is += value; break;
|
||||
case (6): checksum_is += value; break;
|
||||
case (7): checksum_is += value; break;
|
||||
case (8): if (value == (checksum_is % 256)) { checksum_ok = 1; } else { len = -1; }; break;
|
||||
case (9): if (value != 171) { len = -1; }; break;
|
||||
}
|
||||
len++;
|
||||
if (len == 10 && checksum_ok == 1) {
|
||||
*p10 = (float)pm10_serial/10.0;
|
||||
*p25 = (float)pm25_serial/10.0;
|
||||
len = 0; checksum_ok = 0; pm10_serial = 0.0; pm25_serial = 0.0; checksum_is = 0;
|
||||
error = 0;
|
||||
}
|
||||
yield();
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------
|
||||
// SDS011:sleep
|
||||
// --------------------------------------------------------
|
||||
void SDS011::sleep() {
|
||||
for (uint8_t i = 0; i < 19; i++) {
|
||||
sds_data->write(SLEEPCMD[i]);
|
||||
}
|
||||
sds_data->flush();
|
||||
while (sds_data->available() > 0) {
|
||||
sds_data->read();
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------
|
||||
// SDS011:wakeup
|
||||
// --------------------------------------------------------
|
||||
void SDS011::wakeup() {
|
||||
sds_data->write(0x01);
|
||||
sds_data->flush();
|
||||
}
|
||||
|
||||
void SDS011::begin(uint8_t pin_rx, uint8_t pin_tx) {
|
||||
_pin_rx = pin_rx;
|
||||
_pin_tx = pin_tx;
|
||||
|
||||
SoftwareSerial *softSerial = new SoftwareSerial(_pin_rx, _pin_tx);
|
||||
|
||||
//Initialize the 'Wire' class for I2C-bus communication.
|
||||
softSerial->begin(9600);
|
||||
|
||||
sds_data = softSerial;
|
||||
}
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
// SDS011 dust sensor PM2.5 and PM10
|
||||
// ---------------------------------
|
||||
//
|
||||
// By R. Zschiegner (rz@madavi.de)
|
||||
// April 2016
|
||||
//
|
||||
// Documentation:
|
||||
// - The iNovaFitness SDS011 datasheet
|
||||
//
|
||||
|
||||
#if ARDUINO >= 100
|
||||
#include "Arduino.h"
|
||||
#else
|
||||
#include "WProgram.h"
|
||||
#endif
|
||||
|
||||
#include <SoftwareSerial.h>
|
||||
|
||||
|
||||
class SDS011 {
|
||||
public:
|
||||
SDS011(void);
|
||||
void begin(uint8_t pin_rx, uint8_t pin_tx);
|
||||
int read(float *p25, float *p10);
|
||||
void sleep();
|
||||
void wakeup();
|
||||
private:
|
||||
uint8_t _pin_rx, _pin_tx;
|
||||
Stream *sds_data;
|
||||
};
|
||||
@@ -1,26 +0,0 @@
|
||||
// SDS011 dust sensor example
|
||||
// -----------------------------
|
||||
//
|
||||
// By R. Zschiegner (rz@madavi.de).
|
||||
// April 2016
|
||||
|
||||
#include <SDS011.h>
|
||||
|
||||
float p10,p25;
|
||||
int error;
|
||||
|
||||
SDS011 my_sds;
|
||||
|
||||
void setup() {
|
||||
my_sds.begin(D1,D2);
|
||||
Serial.begin(9600);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
error = my_sds.read(&p25,&p10);
|
||||
if (! error) {
|
||||
Serial.println("P2.5: "+String(p25));
|
||||
Serial.println("P10: "+String(p10));
|
||||
}
|
||||
delay(100);
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
name=SDS011 sensor Library
|
||||
version=0.0.5
|
||||
author=R. Zschiegner
|
||||
maintainer=R.Zschiegner <rz@madavi.de>
|
||||
sentence=Nova Fitness SDS011 dust sensor library
|
||||
paragraph=Nova Fitness SDS011 dust sensor library
|
||||
category=Sensors
|
||||
url=https://github.com/ricki-z/SDS011
|
||||
architectures=esp8266,avr
|
||||
@@ -0,0 +1,165 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
|
||||
This version of the GNU Lesser General Public License incorporates
|
||||
the terms and conditions of version 3 of the GNU General Public
|
||||
License, supplemented by the additional permissions listed below.
|
||||
|
||||
0. Additional Definitions.
|
||||
|
||||
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||
General Public License.
|
||||
|
||||
"The Library" refers to a covered work governed by this License,
|
||||
other than an Application or a Combined Work as defined below.
|
||||
|
||||
An "Application" is any work that makes use of an interface provided
|
||||
by the Library, but which is not otherwise based on the Library.
|
||||
Defining a subclass of a class defined by the Library is deemed a mode
|
||||
of using an interface provided by the Library.
|
||||
|
||||
A "Combined Work" is a work produced by combining or linking an
|
||||
Application with the Library. The particular version of the Library
|
||||
with which the Combined Work was made is also called the "Linked
|
||||
Version".
|
||||
|
||||
The "Minimal Corresponding Source" for a Combined Work means the
|
||||
Corresponding Source for the Combined Work, excluding any source code
|
||||
for portions of the Combined Work that, considered in isolation, are
|
||||
based on the Application, and not on the Linked Version.
|
||||
|
||||
The "Corresponding Application Code" for a Combined Work means the
|
||||
object code and/or source code for the Application, including any data
|
||||
and utility programs needed for reproducing the Combined Work from the
|
||||
Application, but excluding the System Libraries of the Combined Work.
|
||||
|
||||
1. Exception to Section 3 of the GNU GPL.
|
||||
|
||||
You may convey a covered work under sections 3 and 4 of this License
|
||||
without being bound by section 3 of the GNU GPL.
|
||||
|
||||
2. Conveying Modified Versions.
|
||||
|
||||
If you modify a copy of the Library, and, in your modifications, a
|
||||
facility refers to a function or data to be supplied by an Application
|
||||
that uses the facility (other than as an argument passed when the
|
||||
facility is invoked), then you may convey a copy of the modified
|
||||
version:
|
||||
|
||||
a) under this License, provided that you make a good faith effort to
|
||||
ensure that, in the event an Application does not supply the
|
||||
function or data, the facility still operates, and performs
|
||||
whatever part of its purpose remains meaningful, or
|
||||
|
||||
b) under the GNU GPL, with none of the additional permissions of
|
||||
this License applicable to that copy.
|
||||
|
||||
3. Object Code Incorporating Material from Library Header Files.
|
||||
|
||||
The object code form of an Application may incorporate material from
|
||||
a header file that is part of the Library. You may convey such object
|
||||
code under terms of your choice, provided that, if the incorporated
|
||||
material is not limited to numerical parameters, data structure
|
||||
layouts and accessors, or small macros, inline functions and templates
|
||||
(ten or fewer lines in length), you do both of the following:
|
||||
|
||||
a) Give prominent notice with each copy of the object code that the
|
||||
Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
4. Combined Works.
|
||||
|
||||
You may convey a Combined Work under terms of your choice that,
|
||||
taken together, effectively do not restrict modification of the
|
||||
portions of the Library contained in the Combined Work and reverse
|
||||
engineering for debugging such modifications, if you also do each of
|
||||
the following:
|
||||
|
||||
a) Give prominent notice with each copy of the Combined Work that
|
||||
the Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
c) For a Combined Work that displays copyright notices during
|
||||
execution, include the copyright notice for the Library among
|
||||
these notices, as well as a reference directing the user to the
|
||||
copies of the GNU GPL and this license document.
|
||||
|
||||
d) Do one of the following:
|
||||
|
||||
0) Convey the Minimal Corresponding Source under the terms of this
|
||||
License, and the Corresponding Application Code in a form
|
||||
suitable for, and under terms that permit, the user to
|
||||
recombine or relink the Application with a modified version of
|
||||
the Linked Version to produce a modified Combined Work, in the
|
||||
manner specified by section 6 of the GNU GPL for conveying
|
||||
Corresponding Source.
|
||||
|
||||
1) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (a) uses at run time
|
||||
a copy of the Library already present on the user's computer
|
||||
system, and (b) will operate properly with a modified version
|
||||
of the Library that is interface-compatible with the Linked
|
||||
Version.
|
||||
|
||||
e) Provide Installation Information, but only if you would otherwise
|
||||
be required to provide such information under section 6 of the
|
||||
GNU GPL, and only to the extent that such information is
|
||||
necessary to install and execute a modified version of the
|
||||
Combined Work produced by recombining or relinking the
|
||||
Application with a modified version of the Linked Version. (If
|
||||
you use option 4d0, the Installation Information must accompany
|
||||
the Minimal Corresponding Source and Corresponding Application
|
||||
Code. If you use option 4d1, you must provide the Installation
|
||||
Information in the manner specified by section 6 of the GNU GPL
|
||||
for conveying Corresponding Source.)
|
||||
|
||||
5. Combined Libraries.
|
||||
|
||||
You may place library facilities that are a work based on the
|
||||
Library side by side in a single library together with other library
|
||||
facilities that are not Applications and are not covered by this
|
||||
License, and convey such a combined library under terms of your
|
||||
choice, if you do both of the following:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work based
|
||||
on the Library, uncombined with any other library facilities,
|
||||
conveyed under the terms of this License.
|
||||
|
||||
b) Give prominent notice with the combined library that part of it
|
||||
is a work based on the Library, and explaining where to find the
|
||||
accompanying uncombined form of the same work.
|
||||
|
||||
6. Revised Versions of the GNU Lesser General Public License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions
|
||||
of the GNU Lesser General Public License from time to time. Such new
|
||||
versions will be similar in spirit to the present version, but may
|
||||
differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Library as you received it specifies that a certain numbered version
|
||||
of the GNU Lesser General Public License "or any later version"
|
||||
applies to it, you have the option of following the terms and
|
||||
conditions either of that published version or of any later version
|
||||
published by the Free Software Foundation. If the Library as you
|
||||
received it does not specify a version number of the GNU Lesser
|
||||
General Public License, you may choose any version of the GNU Lesser
|
||||
General Public License ever published by the Free Software Foundation.
|
||||
|
||||
If the Library as you received it specifies that a proxy can decide
|
||||
whether future versions of the GNU Lesser General Public License shall
|
||||
apply, that proxy's public statement of acceptance of any version is
|
||||
permanent authorization for you to choose that version for the
|
||||
Library.
|
||||
@@ -0,0 +1,81 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
Arduino library to ...
|
||||
|
||||
Written by Jochen Krapf,
|
||||
contributions by ... and other members of the open
|
||||
source community.
|
||||
|
||||
-------------------------------------------------------------------------
|
||||
This file is part of the MechInputs library.
|
||||
|
||||
MechInputs is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
MechInputs is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with MechInputs. If not, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
-------------------------------------------------------------------------*/
|
||||
|
||||
#include <SensorSerial.h>
|
||||
|
||||
|
||||
SensorSerial::SensorSerial(int receivePin, int transmitPin, bool inverse_logic, unsigned int buffSize) : SoftwareSerial(receivePin, transmitPin, inverse_logic, buffSize)
|
||||
{
|
||||
//boolean sws = isValidGPIOpin(receivePin);
|
||||
_hw = receivePin < 0;
|
||||
}
|
||||
|
||||
void SensorSerial::begin(long speed)
|
||||
{
|
||||
if (_hw)
|
||||
Serial.begin(speed);
|
||||
else
|
||||
SoftwareSerial::begin(speed);
|
||||
}
|
||||
|
||||
int SensorSerial::peek()
|
||||
{
|
||||
if (_hw)
|
||||
return Serial.peek();
|
||||
else
|
||||
return SoftwareSerial::peek();
|
||||
}
|
||||
|
||||
size_t SensorSerial::write(uint8_t byte)
|
||||
{
|
||||
if (_hw)
|
||||
return Serial.write(byte);
|
||||
else
|
||||
return SoftwareSerial::write(byte);
|
||||
}
|
||||
|
||||
int SensorSerial::read()
|
||||
{
|
||||
if (_hw)
|
||||
return Serial.read();
|
||||
else
|
||||
return SoftwareSerial::read();
|
||||
}
|
||||
|
||||
int SensorSerial::available()
|
||||
{
|
||||
if (_hw)
|
||||
return Serial.available();
|
||||
else
|
||||
return SoftwareSerial::available();
|
||||
}
|
||||
|
||||
void SensorSerial::flush()
|
||||
{
|
||||
if (_hw)
|
||||
Serial.flush();
|
||||
else
|
||||
SoftwareSerial::flush();
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
Arduino library to ...
|
||||
|
||||
Written by Jochen Krapf,
|
||||
contributions by ... and other members of the open
|
||||
source community.
|
||||
|
||||
-------------------------------------------------------------------------
|
||||
This file is part of the MechInputs library.
|
||||
|
||||
MechInputs is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
MechInputs is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with MechInputs. If not, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
-------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _SENSORSERIAL_H_
|
||||
#define _SENSORSERIAL_H_
|
||||
|
||||
#include "Arduino.h"
|
||||
#include <SoftwareSerial.h>
|
||||
|
||||
class SensorSerial : public SoftwareSerial
|
||||
{
|
||||
public:
|
||||
SensorSerial(int receivePin, int transmitPin = -1, bool inverse_logic = false, unsigned int buffSize = 64);
|
||||
|
||||
void begin(long speed);
|
||||
|
||||
int peek();
|
||||
|
||||
virtual size_t write(uint8_t byte);
|
||||
|
||||
virtual int read();
|
||||
|
||||
virtual int available();
|
||||
|
||||
virtual void flush();
|
||||
|
||||
protected:
|
||||
boolean _hw;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,59 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
Arduino library to ...
|
||||
|
||||
Written by Jochen Krapf,
|
||||
contributions by ... and other members of the open
|
||||
source community.
|
||||
|
||||
-------------------------------------------------------------------------
|
||||
This file is part of the MechInputs library.
|
||||
|
||||
MechInputs is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
MechInputs is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with MechInputs. If not, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
-------------------------------------------------------------------------*/
|
||||
|
||||
#include "SensorSerialBuffer.h"
|
||||
|
||||
CSensorSerialBuffer::CSensorSerialBuffer()
|
||||
{
|
||||
_writeIndex = 0;
|
||||
_packetLength = 0;
|
||||
Clear();
|
||||
}
|
||||
|
||||
void CSensorSerialBuffer::Clear ()
|
||||
{
|
||||
for (byte i=0; i<SERIALBUFFER_SIZE; i++)
|
||||
_buffer[i] = 0;
|
||||
}
|
||||
|
||||
void CSensorSerialBuffer::AddData (byte b)
|
||||
{
|
||||
_buffer[_writeIndex] = b;
|
||||
_writeIndex++;
|
||||
_writeIndex &= SERIALBUFFER_MASK;
|
||||
}
|
||||
|
||||
void CSensorSerialBuffer::SetPacketLength (byte len)
|
||||
{
|
||||
_packetLength = len;
|
||||
}
|
||||
|
||||
byte& CSensorSerialBuffer::operator[] (byte x)
|
||||
{
|
||||
x += _writeIndex;
|
||||
x -= _packetLength;
|
||||
x &= SERIALBUFFER_MASK;
|
||||
return _buffer[x];
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
Arduino library to ...
|
||||
|
||||
Written by Jochen Krapf,
|
||||
contributions by ... and other members of the open
|
||||
source community.
|
||||
|
||||
-------------------------------------------------------------------------
|
||||
This file is part of the MechInputs library.
|
||||
|
||||
MechInputs is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
MechInputs is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with MechInputs. If not, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
-------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _SENSORSERIALBUFFER_H_
|
||||
#define _SENSORSERIALBUFFER_H_
|
||||
|
||||
#include "Arduino.h"
|
||||
|
||||
#define SERIALBUFFER_SIZE 32
|
||||
#define SERIALBUFFER_MASK 31
|
||||
|
||||
class CSensorSerialBuffer
|
||||
{
|
||||
public:
|
||||
CSensorSerialBuffer();
|
||||
|
||||
void Clear ();
|
||||
|
||||
void AddData (byte b);
|
||||
|
||||
void SetPacketLength (byte len);
|
||||
|
||||
byte& operator[] (byte x);
|
||||
|
||||
private:
|
||||
byte _buffer[SERIALBUFFER_SIZE];
|
||||
byte _writeIndex;
|
||||
byte _packetLength;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,101 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
Arduino library to ...
|
||||
|
||||
Written by Jochen Krapf,
|
||||
contributions by ... and other members of the open
|
||||
source community.
|
||||
|
||||
-------------------------------------------------------------------------
|
||||
This file is part of the MechInputs library.
|
||||
|
||||
MechInputs is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
MechInputs is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with MechInputs. If not, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
-------------------------------------------------------------------------*/
|
||||
|
||||
#include "jkSDS011.h"
|
||||
|
||||
CjkSDS011::CjkSDS011(int16_t pinRX, int16_t pinTX) : _serial(pinRX, pinTX)
|
||||
{
|
||||
_sws = ! ( pinRX < 0 || pinRX == 3 );
|
||||
_pm2_5 = NAN;
|
||||
_pm10_ = NAN;
|
||||
_available = false;
|
||||
_pm2_5avr = 0;
|
||||
_pm10_avr = 0;
|
||||
_avr = 0;
|
||||
_data.SetPacketLength(10);
|
||||
|
||||
_serial.begin(9600);
|
||||
}
|
||||
|
||||
void CjkSDS011::Process()
|
||||
{
|
||||
while (_serial.available())
|
||||
{
|
||||
_data.AddData(_serial.read());
|
||||
|
||||
if (_data[0] == 0xAA && _data[9] == 0xAB && (_data[1] == 0xC0 || _data[1] == 0xCF)) // correct packet frame?
|
||||
{
|
||||
byte checksum = 0;
|
||||
for (byte i=2; i<= 7; i++)
|
||||
checksum += _data[i];
|
||||
if (checksum != _data[8])
|
||||
continue;
|
||||
|
||||
if (_data[1] == 0xC0) // SDS011 or SDS018?
|
||||
{
|
||||
_pm2_5 = (float)((_data[3] << 8) | _data[2]) * 0.1;
|
||||
_pm10_ = (float)((_data[5] << 8) | _data[4]) * 0.1;
|
||||
_available = true;
|
||||
}
|
||||
else if (_data[1] == 0xCF) // SDS198?
|
||||
{
|
||||
_pm2_5 = (float)((_data[5] << 8) | _data[4]);
|
||||
_pm10_ = (float)((_data[3] << 8) | _data[2]);
|
||||
_available = true;
|
||||
}
|
||||
else
|
||||
continue;
|
||||
|
||||
_pm2_5avr += _pm2_5;
|
||||
_pm10_avr += _pm10_;
|
||||
_avr++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean CjkSDS011::available()
|
||||
{
|
||||
boolean ret = _available;
|
||||
_available = false;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void CjkSDS011::ReadAverage(float &pm25, float &pm10)
|
||||
{
|
||||
if (_avr)
|
||||
{
|
||||
pm25 = _pm2_5avr / _avr;
|
||||
pm10 = _pm10_avr / _avr;
|
||||
_pm2_5avr = 0;
|
||||
_pm10_avr = 0;
|
||||
_avr = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
pm25 = NAN;
|
||||
pm10 = NAN;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
Arduino library to ...
|
||||
|
||||
Written by Jochen Krapf,
|
||||
contributions by ... and other members of the open
|
||||
source community.
|
||||
|
||||
-------------------------------------------------------------------------
|
||||
This file is part of the MechInputs library.
|
||||
|
||||
MechInputs is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
MechInputs is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with MechInputs. If not, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
-------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _jkSDS011_H_
|
||||
#define _jkSDS011_H_
|
||||
|
||||
#include "Arduino.h"
|
||||
#include "SensorSerial.h"
|
||||
#include "SensorSerialBuffer.h"
|
||||
|
||||
class CjkSDS011
|
||||
{
|
||||
public:
|
||||
CjkSDS011(int16_t pinRX, int16_t pinTX);
|
||||
|
||||
void Process();
|
||||
|
||||
boolean available();
|
||||
|
||||
float GetPM2_5() { return _pm2_5; };
|
||||
float GetPM10_() { return _pm10_; };
|
||||
|
||||
void ReadAverage(float &pm25, float &pm10);
|
||||
|
||||
private:
|
||||
SensorSerial _serial;
|
||||
CSensorSerialBuffer _data;
|
||||
float _pm2_5;
|
||||
float _pm10_;
|
||||
float _pm2_5avr;
|
||||
float _pm10_avr;
|
||||
uint16_t _avr;
|
||||
boolean _available;
|
||||
boolean _sws;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,9 @@
|
||||
name=SerialSensors
|
||||
version=0.0.1
|
||||
author=Jochen Krapf
|
||||
maintainer=Jochen Krapf <jk@nerd2nerd.org>
|
||||
sentence=Library for Reading and Serial Data from Sensor Devices.
|
||||
paragraph=Library for Reading and Serial Data from Sensor Devices.
|
||||
category=Input
|
||||
url=https://github.com/jkDesignDE/SerialSensors
|
||||
architectures=esp8266,avr
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
#define PLUGIN_053
|
||||
#define PLUGIN_ID_053 53
|
||||
#define PLUGIN_NAME_053 "Particle Sensor - PMSx003"
|
||||
#define PLUGIN_NAME_053 "Dust Sensor - PMSx003"
|
||||
#define PLUGIN_VALUENAME1_053 "pm1.0"
|
||||
#define PLUGIN_VALUENAME2_053 "pm2.5"
|
||||
#define PLUGIN_VALUENAME3_053 "pm10"
|
||||
@@ -139,6 +139,14 @@ boolean Plugin_053(byte function, struct EventStruct *event, String& string)
|
||||
break;
|
||||
}
|
||||
|
||||
case PLUGIN_GET_DEVICEGPIONAMES:
|
||||
{
|
||||
event->String1 = F("GPIO ← TX");
|
||||
event->String2 = F("GPIO → RX");
|
||||
event->String3 = F("GPIO → Reset");
|
||||
break;
|
||||
}
|
||||
|
||||
case PLUGIN_INIT:
|
||||
{
|
||||
int rxPin = Settings.TaskDevicePin1[event->TaskIndex];
|
||||
|
||||
+48
-31
@@ -2,26 +2,25 @@
|
||||
//#################################### Plugin 056: Dust Sensor SDS011 / SDS018 ##########################
|
||||
//#######################################################################################################
|
||||
/*
|
||||
Plugin is based upon SDS011 dust sensor PM2.5 and PM10 lib (https://github.com/ricki-z/SDS011.git) by R. Zschiegner (rz@madavi.de)
|
||||
This plug in is written by Jochen Krapf (jk@nerd2nerd.org)
|
||||
Plugin is based upon SDS011 dust sensor PM2.5 and PM10 lib
|
||||
This plugin and lib was written by Jochen Krapf (jk@nerd2nerd.org)
|
||||
|
||||
This plugin reads the particle concentration from SDS011 Sensor
|
||||
DevicePin1 - RX on ESP, TX on SDS
|
||||
DevicePin2 - TX on ESP, RX on SDS
|
||||
*/
|
||||
|
||||
#ifdef PLUGIN_BUILD_DEV
|
||||
#ifdef PLUGIN_BUILD_TESTING
|
||||
|
||||
#define PLUGIN_056
|
||||
#define PLUGIN_ID_056 56
|
||||
#define PLUGIN_NAME_056 "Dust Sensor - SDS011/SDS018 [DEVELOPMENT]"
|
||||
#define PLUGIN_VALUENAME1_056 "PM2.5" // Dust <2.5µm in µg/m³
|
||||
#define PLUGIN_NAME_056 "Dust Sensor - SDS011/018/198 [TESTING]"
|
||||
#define PLUGIN_VALUENAME1_056 "PM2.5" // Dust <2.5µm in µg/m³ SDS198:<100µm in µg/m³
|
||||
#define PLUGIN_VALUENAME2_056 "PM10" // Dust <10µm in µg/m³
|
||||
#define PLUGIN_READ_TIMEOUT 3000
|
||||
|
||||
#include <SDS011.h> //https://github.com/ricki-z/SDS011.git
|
||||
#include <jkSDS011.h>
|
||||
|
||||
SDS011 *Plugin_056_SDS = NULL;
|
||||
|
||||
CjkSDS011 *Plugin_056_SDS = NULL;
|
||||
|
||||
|
||||
boolean Plugin_056(byte function, struct EventStruct *event, String& string)
|
||||
@@ -34,7 +33,7 @@ boolean Plugin_056(byte function, struct EventStruct *event, String& string)
|
||||
case PLUGIN_DEVICE_ADD:
|
||||
{
|
||||
Device[++deviceCount].Number = PLUGIN_ID_056;
|
||||
Device[deviceCount].Type = DEVICE_TYPE_DUAL;
|
||||
Device[deviceCount].Type = DEVICE_TYPE_SINGLE;
|
||||
Device[deviceCount].VType = SENSOR_TYPE_DUAL;
|
||||
Device[deviceCount].Ports = 0;
|
||||
Device[deviceCount].PullUpOption = false;
|
||||
@@ -43,6 +42,7 @@ boolean Plugin_056(byte function, struct EventStruct *event, String& string)
|
||||
Device[deviceCount].ValueCount = 2;
|
||||
Device[deviceCount].SendDataOption = true;
|
||||
Device[deviceCount].TimerOption = true;
|
||||
Device[deviceCount].TimerOptional = true;
|
||||
Device[deviceCount].GlobalSyncOption = true;
|
||||
break;
|
||||
}
|
||||
@@ -60,40 +60,57 @@ boolean Plugin_056(byte function, struct EventStruct *event, String& string)
|
||||
break;
|
||||
}
|
||||
|
||||
case PLUGIN_GET_DEVICEGPIONAMES:
|
||||
{
|
||||
event->String1 = F("GPIO ← TX");
|
||||
//event->String2 = F("GPIO ⇢ RX (optional)");
|
||||
break;
|
||||
}
|
||||
|
||||
case PLUGIN_INIT:
|
||||
{
|
||||
if (!Plugin_056_SDS)
|
||||
Plugin_056_SDS = new SDS011();
|
||||
Plugin_056_SDS->begin(Settings.TaskDevicePin1[event->TaskIndex], Settings.TaskDevicePin2[event->TaskIndex]);
|
||||
if (Plugin_056_SDS)
|
||||
delete Plugin_056_SDS;
|
||||
Plugin_056_SDS = new CjkSDS011(Settings.TaskDevicePin1[event->TaskIndex], -1);
|
||||
addLog(LOG_LEVEL_INFO, F("SDS : Init OK "));
|
||||
|
||||
//delay first read, because hardware needs to initialize on cold boot
|
||||
//otherwise we get a weird value or read error
|
||||
timerSensor[event->TaskIndex] = millis() + 15000;
|
||||
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case PLUGIN_WRITE:
|
||||
case PLUGIN_EXIT:
|
||||
{
|
||||
if (Plugin_056_SDS)
|
||||
delete Plugin_056_SDS;
|
||||
addLog(LOG_LEVEL_INFO, F("SDS : Exit"));
|
||||
break;
|
||||
}
|
||||
|
||||
case PLUGIN_FIFTY_PER_SECOND:
|
||||
{
|
||||
if (!Plugin_056_SDS)
|
||||
break;
|
||||
|
||||
String command = parseString(string, 1);
|
||||
Plugin_056_SDS->Process();
|
||||
|
||||
if (command == F("sdssleep"))
|
||||
if (Plugin_056_SDS->available())
|
||||
{
|
||||
Plugin_056_SDS->sleep();;
|
||||
addLog(LOG_LEVEL_INFO, F("SDS : sleep"));
|
||||
success = true;
|
||||
}
|
||||
if (command == F("sdswakeup"))
|
||||
{
|
||||
Plugin_056_SDS->wakeup();;
|
||||
addLog(LOG_LEVEL_INFO, F("SDS : wake up"));
|
||||
success = true;
|
||||
String log = F("SDS : act ");
|
||||
log += Plugin_056_SDS->GetPM2_5();
|
||||
log += F(" ");
|
||||
log += Plugin_056_SDS->GetPM10_();
|
||||
addLog(LOG_LEVEL_DEBUG, log);
|
||||
|
||||
if (Settings.TaskDeviceTimer[event->TaskIndex] == 0)
|
||||
{
|
||||
UserVar[event->BaseVarIndex + 0] = Plugin_056_SDS->GetPM2_5();
|
||||
UserVar[event->BaseVarIndex + 1] = Plugin_056_SDS->GetPM10_();
|
||||
event->sensorType = SENSOR_TYPE_DUAL;
|
||||
sendData(event);
|
||||
}
|
||||
}
|
||||
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -103,7 +120,7 @@ boolean Plugin_056(byte function, struct EventStruct *event, String& string)
|
||||
break;
|
||||
|
||||
float pm25, pm10;
|
||||
Plugin_056_SDS->read(&pm25,&pm10);;
|
||||
Plugin_056_SDS->ReadAverage(pm25, pm10);
|
||||
|
||||
UserVar[event->BaseVarIndex + 0] = pm25;
|
||||
UserVar[event->BaseVarIndex + 1] = pm10;
|
||||
@@ -115,4 +132,4 @@ boolean Plugin_056(byte function, struct EventStruct *event, String& string)
|
||||
return success;
|
||||
}
|
||||
|
||||
#endif //PLUGIN_BUILD_DEV
|
||||
#endif //PLUGIN_BUILD_TESTING
|
||||
|
||||
Reference in New Issue
Block a user