From 44eb923e1ac90e65f527160f43138c9e2b7230cb Mon Sep 17 00:00:00 2001 From: heX Date: Wed, 3 Mar 2021 22:35:38 +0300 Subject: [PATCH 1/4] FIX: SoftwareSerial bug - https://github.com/avaldebe/PMserial/issues/19 --- src/PMserial.cpp | 3 +++ src/PMserial.h | 6 ++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/PMserial.cpp b/src/PMserial.cpp index 748b5ef..c86b0d2 100644 --- a/src/PMserial.cpp +++ b/src/PMserial.cpp @@ -107,6 +107,9 @@ void SerialPM::wake() { SerialPM::STATUS SerialPM::trigRead() { + if (hwSerial == false) + static_cast(uart)->listen(); // when you want to listen on a port, explicitly select it. (https://www.arduino.cc/en/Tutorial/LibraryExamples/TwoPortReceive) + while (uart->available()) { uart->read(); // empty the RX buffer diff --git a/src/PMserial.h b/src/PMserial.h index 3a97312..d0f884f 100644 --- a/src/PMserial.h +++ b/src/PMserial.h @@ -77,6 +77,7 @@ class SerialPM float temp, rhum, hcho; }; }; + #ifdef HAS_HW_SERIAL SerialPM(PMS sensor, HardwareSerial &serial) : pms(sensor) { @@ -84,10 +85,10 @@ class SerialPM hwSerial = true; } #endif + #ifdef HAS_SW_SERIAL - SerialPM(PMS sensor, uint8_t rx, uint8_t tx) : pms(sensor) + SerialPM(PMS sensor, Stream &serial) : pms(sensor) { - SoftwareSerial serial(rx, tx); uart = &serial; hwSerial = false; } @@ -98,6 +99,7 @@ class SerialPM hwSerial = true; } #endif + void init(); #define PMS_ERROR_TIMEOUT "Sensor read timeout" #define PMS_ERROR_PMS_TYPE "Wrong PMSx003 sensor type" From f2e684ed1d79fd85643f821fb5e81d1720001c63 Mon Sep 17 00:00:00 2001 From: heX Date: Wed, 3 Mar 2021 22:37:17 +0300 Subject: [PATCH 2/4] ADD: Update examples ADD: "lib_dir = ../../../" - this is a dirty hack to make projects use the local library to which they belong (PlatformIO did not have the right option) ADD: special "ifdef" for ESP32 (It is possible to create a universal code for this MC. Maybe I'll do it later.) DEL: "lib_deps = EspSoftwareSerial@>=6.7.1" - this lib integrated to Arduino-ESP8266-framework. See: https://github.com/plerup/espsoftwareserial/issues/200 --- examples/HardwareSerial/platformio.ini | 1 + examples/OLED_64x48/platformio.ini | 2 +- examples/SoftwareSerial/.gitignore | 1 + examples/SoftwareSerial/SoftwareSerial.ino | 11 ++++++++++- examples/SoftwareSerial/platformio.ini | 13 ++++++------- examples/debug/platformio.ini | 6 ++---- 6 files changed, 21 insertions(+), 13 deletions(-) diff --git a/examples/HardwareSerial/platformio.ini b/examples/HardwareSerial/platformio.ini index 621c48a..582ff2b 100644 --- a/examples/HardwareSerial/platformio.ini +++ b/examples/HardwareSerial/platformio.ini @@ -10,6 +10,7 @@ [platformio] src_dir = ./ +lib_dir = ../../../ [env] framework = arduino diff --git a/examples/OLED_64x48/platformio.ini b/examples/OLED_64x48/platformio.ini index 57b2d5b..81cbe96 100644 --- a/examples/OLED_64x48/platformio.ini +++ b/examples/OLED_64x48/platformio.ini @@ -10,6 +10,7 @@ [platformio] src_dir = ./ +lib_dir = ../../../ [env] framework = arduino @@ -17,7 +18,6 @@ lib_deps = ESP8266_SSD1306 [env:d1_mini] platform = espressif8266 -lib_deps = ${env.lib_deps}, EspSoftwareSerial@>=6.7.1 board = d1_mini [env:mhetesp32minikit] diff --git a/examples/SoftwareSerial/.gitignore b/examples/SoftwareSerial/.gitignore index f152028..ad0070f 100644 --- a/examples/SoftwareSerial/.gitignore +++ b/examples/SoftwareSerial/.gitignore @@ -1,3 +1,4 @@ +.vscode .pio .pioenvs .piolibdeps diff --git a/examples/SoftwareSerial/SoftwareSerial.ino b/examples/SoftwareSerial/SoftwareSerial.ino index 35ffcba..40f6b1c 100644 --- a/examples/SoftwareSerial/SoftwareSerial.ino +++ b/examples/SoftwareSerial/SoftwareSerial.ino @@ -4,10 +4,18 @@ #include #endif #include // Arduino library for PM sensors with serial interface + #if !defined(PMS_RX) && !defined(PMS_TX) -const uint8_t PMS_RX = 10, PMS_TX = 11; +constexpr auto PMS_RX = 10; +constexpr auto PMS_TX = 11; #endif + +#ifndef ESP32 +SoftwareSerial SoftSerial1(PMS_RX, PMS_TX); +SerialPM pms(PMS5003, SoftSerial1); // PMSx003, RX, TX +#else SerialPM pms(PMS5003, PMS_RX, PMS_TX); // PMSx003, RX, TX +#endif void setup() { @@ -19,6 +27,7 @@ void setup() Serial.println(PMS_RX); Serial.print(F(" TX:")); Serial.println(PMS_TX); + pms.init(); } diff --git a/examples/SoftwareSerial/platformio.ini b/examples/SoftwareSerial/platformio.ini index a238ed3..ff46a70 100644 --- a/examples/SoftwareSerial/platformio.ini +++ b/examples/SoftwareSerial/platformio.ini @@ -10,36 +10,31 @@ [platformio] src_dir = ./ +lib_dir = ../../../ +default_envs = [env] framework = arduino [env:uno] -; ATmega328, 5V/16MHz platform = atmelavr board = uno [env:mini168_3V3] -; ATmega168, 3.3V/8MHz platform = atmelavr board = pro8MHzatmega168 [env:mini328_3V3] -; ATmega328, 3.3V/8MHz platform = atmelavr board = pro8MHzatmega328 [env:esp01] -; ESP8266, 512kB flash platform = espressif8266 -lib_deps = EspSoftwareSerial@>=6.7.1 board = esp01 build_flags = -D PMS_RX=2 -D PMS_TX=0 [env:d1_mini] -; ESP8266, 4096kB flash platform = espressif8266 -lib_deps = EspSoftwareSerial@>=6.7.1 board = d1_mini build_flags = -D PMS_RX=D7 -D PMS_TX=D6 @@ -47,3 +42,7 @@ build_flags = -D PMS_RX=D7 -D PMS_TX=D6 platform = espressif32 board = mhetesp32minikit build_flags = -D PMS_RX=23 -D PMS_TX=19 + +[env:diecimilaatmega328] +board = diecimilaatmega328 +platform = atmelavr diff --git a/examples/debug/platformio.ini b/examples/debug/platformio.ini index 3a91586..f9f6e4b 100644 --- a/examples/debug/platformio.ini +++ b/examples/debug/platformio.ini @@ -10,6 +10,7 @@ [platformio] src_dir = ./ +lib_dir = ../../../ [env] framework = arduino @@ -48,13 +49,11 @@ board = maple_mini_b20 [env:esp01] ; esp8266 (512Kb) platform = espressif8266 -lib_deps = EspSoftwareSerial@>=6.7.1 board = esp01 [env:aqmon] ; esp8266 (1Mb) platform = espressif8266 -lib_deps = EspSoftwareSerial@>=6.7.1 board = esp01_1m upload_resetmethod = nodemcu build_flags = -D USE_HWSERIAL @@ -62,7 +61,6 @@ build_flags = -D USE_HWSERIAL [env:d1_mini] ; esp8266 (4Mb) platform = espressif8266 -lib_deps = EspSoftwareSerial@>=6.7.1 board = d1_mini build_flags = -D PMS_RX=D7 -D PMS_TX=D6 @@ -80,4 +78,4 @@ board = m5stack-core-esp32 [env:mkrwifi1010] platform = atmelsam board = mkrwifi1010 -build_flags = -D USE_HWSERIAL1 \ No newline at end of file +build_flags = -D USE_HWSERIAL1 From 153efda5d7dd55dfbbbbc249f7d3e13dc1fc6748 Mon Sep 17 00:00:00 2001 From: heX Date: Wed, 10 Mar 2021 21:09:22 +0300 Subject: [PATCH 3/4] UPD: returned constructor `SerialPM(PMS sensor, uint8_t rx, uint8_t tx)` (see: https://github.com/avaldebe/PMserial/pull/20#pullrequestreview-603848882) ADD: manual mode - constructor `SerialPM(PMS sensor)` (work in progress!) UPD: `hwSerial` - change to enum ADD: getter/setter for `uart` variable. (setSerialPort, getSerialPort) UPD: `SerialPM::init()` - updating for manual mode FIX: `SerialPM::trigRead()` - add `#ifdef` for `listen` --- examples/SoftwareSerial/SoftwareSerial.ino | 7 ++++-- src/PMserial.cpp | 23 +++++++++---------- src/PMserial.h | 26 +++++++++++++++++++--- 3 files changed, 39 insertions(+), 17 deletions(-) diff --git a/examples/SoftwareSerial/SoftwareSerial.ino b/examples/SoftwareSerial/SoftwareSerial.ino index 40f6b1c..9a4611a 100644 --- a/examples/SoftwareSerial/SoftwareSerial.ino +++ b/examples/SoftwareSerial/SoftwareSerial.ino @@ -11,8 +11,11 @@ constexpr auto PMS_TX = 11; #endif #ifndef ESP32 -SoftwareSerial SoftSerial1(PMS_RX, PMS_TX); -SerialPM pms(PMS5003, SoftSerial1); // PMSx003, RX, TX +SerialPM pms(PMS5003, PMS_RX, PMS_TX); // PMSx003, RX, TX + +// Alternative: +//SoftwareSerial SoftSerial1(PMS_RX, PMS_TX); +//SerialPM pms(PMS5003, SoftSerial1); #else SerialPM pms(PMS5003, PMS_RX, PMS_TX); // PMSx003, RX, TX #endif diff --git a/src/PMserial.cpp b/src/PMserial.cpp index c86b0d2..b2260be 100644 --- a/src/PMserial.cpp +++ b/src/PMserial.cpp @@ -66,25 +66,22 @@ const uint8_t void SerialPM::init() { #ifdef ESP32 - if (hwSerial && rx && tx) - { + if ((hwSerial == serModeHardware) && rx && tx) static_cast(uart)->begin(9600, SERIAL_8N1, rx, tx); - } - else if (hwSerial) #else - if (hwSerial) -#endif - { + #ifdef HAS_HW_SERIAL + if (hwSerial == serModeHardware) static_cast(uart)->begin(9600, SERIAL_8N1); #endif - } - else - { + +#endif // ESP32 + #ifdef HAS_SW_SERIAL + if (hwSerial == serModeSoftware) static_cast(uart)->begin(9600); #endif - } + uart->write(cfg, msgLen); // set passive mode uart->flush(); delay(max_wait_ms * 2); @@ -107,8 +104,10 @@ void SerialPM::wake() { SerialPM::STATUS SerialPM::trigRead() { - if (hwSerial == false) + #ifdef HAS_SW_SERIAL + if (hwSerial == serModeSoftware) static_cast(uart)->listen(); // when you want to listen on a port, explicitly select it. (https://www.arduino.cc/en/Tutorial/LibraryExamples/TwoPortReceive) + #endif while (uart->available()) { diff --git a/src/PMserial.h b/src/PMserial.h index d0f884f..d94d987 100644 --- a/src/PMserial.h +++ b/src/PMserial.h @@ -78,19 +78,34 @@ class SerialPM }; }; + // manual mode - you need configure SerialPort manual and link to this object (function "setSerialPort") + SerialPM(PMS sensor) : pms(sensor) + { + uart = nullptr; + hwSerial = serModeManual; + } + #ifdef HAS_HW_SERIAL SerialPM(PMS sensor, HardwareSerial &serial) : pms(sensor) { uart = &serial; - hwSerial = true; + hwSerial = serModeHardware; } #endif #ifdef HAS_SW_SERIAL + SerialPM(PMS sensor, uint8_t rx, uint8_t tx) : pms(sensor) + { + static SoftwareSerial serial(rx, tx); + uart = &serial; + hwSerial = serModeSoftware; + } + SerialPM(PMS sensor, Stream &serial) : pms(sensor) { uart = &serial; - hwSerial = false; + //TODO: WIP!!! + hwSerial = serModeManual; } #elif defined(ESP32) SerialPM(PMS sensor, uint8_t rx, uint8_t tx) : pms(sensor), rx(rx), tx(tx) @@ -101,6 +116,7 @@ class SerialPM #endif void init(); + #define PMS_ERROR_TIMEOUT "Sensor read timeout" #define PMS_ERROR_PMS_TYPE "Wrong PMSx003 sensor type" #define PMS_ERROR_MSG_UNKNOWN "Unknown message protocol" @@ -109,6 +125,7 @@ class SerialPM #define PMS_ERROR_MSG_START "Wrong message start" #define PMS_ERROR_MSG_LENGTH "Message too long" #define PMS_ERROR_MSG_CKSUM "Wrong message checksum" + enum STATUS { OK, @@ -121,6 +138,7 @@ class SerialPM ERROR_MSG_LENGTH, ERROR_MSG_CKSUM }; + STATUS status; STATUS read(bool tsi_mode = false, bool truncated_num = false); operator bool() { return status == OK; } @@ -130,6 +148,8 @@ class SerialPM inline bool has_number_concentration() { return (status == OK) && (pms != PMS3003); } inline bool has_temperature_humidity() { return (status == OK) && ((pms == PMS5003T) || (pms == PMS5003ST)); } inline bool has_formaldehyde() { return (status == OK) && ((pms == PMS5003S) || (pms == PMS5003ST)); } + inline Stream * getSerialPort() { return uart; } + inline void setSerialPort(Stream * serial) { uart = serial; hwSerial = serModeManual; } // adding offsets works well in normal range // might introduce under- or overflow at the ends of the sensor range @@ -158,7 +178,7 @@ class SerialPM protected: Stream *uart; // hardware/software serial PMS pms; // sensor type/message protocol - bool hwSerial; // Is uart hardware serial? (or software serial) + enum {serModeHardware, serModeSoftware, serModeManual} hwSerial; // Is uart hardware serial? (or software serial) #ifdef ESP32 uint8_t rx, tx; // Serial1 pins on ESP32 #endif From 6e9f2d925b308f4d241469664be1d9a72552b405 Mon Sep 17 00:00:00 2001 From: heX Date: Wed, 10 Mar 2021 22:09:05 +0300 Subject: [PATCH 4/4] FIX: small fix for ESP32 --- src/PMserial.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PMserial.h b/src/PMserial.h index d94d987..6fddc60 100644 --- a/src/PMserial.h +++ b/src/PMserial.h @@ -111,7 +111,7 @@ class SerialPM SerialPM(PMS sensor, uint8_t rx, uint8_t tx) : pms(sensor), rx(rx), tx(tx) { uart = &Serial1; - hwSerial = true; + hwSerial = serModeHardware; } #endif