Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improving the binding to the Serial object and fix SoftwareSerial bug #20

Merged
merged 5 commits into from
Mar 11, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions examples/HardwareSerial/platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

[platformio]
src_dir = ./
lib_dir = ../../../

[env]
framework = arduino
Expand Down
1 change: 1 addition & 0 deletions examples/OLED_64x48/platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

[platformio]
src_dir = ./
lib_dir = ../../../

[env]
framework = arduino
Expand Down
1 change: 1 addition & 0 deletions examples/SoftwareSerial/.gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.vscode
.pio
.pioenvs
.piolibdeps
Expand Down
14 changes: 13 additions & 1 deletion examples/SoftwareSerial/SoftwareSerial.ino
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,21 @@
#include <SoftwareSerial.h>
#endif
#include <PMserial.h> // 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
avaldebe marked this conversation as resolved.
Show resolved Hide resolved

#ifndef ESP32
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

void setup()
{
Expand All @@ -19,6 +30,7 @@ void setup()
Serial.println(PMS_RX);
Serial.print(F(" TX:"));
Serial.println(PMS_TX);

pms.init();
}

Expand Down
13 changes: 6 additions & 7 deletions examples/SoftwareSerial/platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -10,40 +10,39 @@

[platformio]
src_dir = ./
lib_dir = ../../../
default_envs =

[env]
framework = arduino

[env:uno]
; ATmega328, 5V/16MHz
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please leave the comments like this one, I find them useful to keep track of what each env support

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately PlatformIO erases comments when you change a file from GUI. I hope they ever fix this bug.

Copy link
Contributor Author

@heX16 heX16 Mar 11, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can add back these comments at a later stage

You can use custom fields in environment sections. Just add custom_ prefix.

platformio/platformio-core#3862 (comment)

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I'll do that whenever I came around to add the comments back

platform = atmelavr
board = uno

[env:mini168_3V3]
; ATmega168, 3.3V/8MHz
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

platform = atmelavr
board = pro8MHzatmega168

[env:mini328_3V3]
; ATmega328, 3.3V/8MHz
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

...

platform = atmelavr
board = pro8MHzatmega328

[env:esp01]
; ESP8266, 512kB flash
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

...

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
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

...

platform = espressif8266
lib_deps = EspSoftwareSerial@>=6.7.1
board = d1_mini
build_flags = -D PMS_RX=D7 -D PMS_TX=D6

[env:esp32minikit]
platform = espressif32
board = mhetesp32minikit
build_flags = -D PMS_RX=23 -D PMS_TX=19

[env:diecimilaatmega328]
board = diecimilaatmega328
platform = atmelavr
6 changes: 2 additions & 4 deletions examples/debug/platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

[platformio]
src_dir = ./
lib_dir = ../../../

[env]
framework = arduino
Expand Down Expand Up @@ -48,21 +49,18 @@ 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

[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

Expand All @@ -80,4 +78,4 @@ board = m5stack-core-esp32
[env:mkrwifi1010]
platform = atmelsam
board = mkrwifi1010
build_flags = -D USE_HWSERIAL1
build_flags = -D USE_HWSERIAL1
24 changes: 13 additions & 11 deletions src/PMserial.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,25 +66,22 @@ const uint8_t
void SerialPM::init()
{
#ifdef ESP32
if (hwSerial && rx && tx)
{
if ((hwSerial == serModeHardware) && rx && tx)
static_cast<HardwareSerial *>(uart)->begin(9600, SERIAL_8N1, rx, tx);
}
else if (hwSerial)
#else
if (hwSerial)
#endif
{

#ifdef HAS_HW_SERIAL
if (hwSerial == serModeHardware)
static_cast<HardwareSerial *>(uart)->begin(9600, SERIAL_8N1);
#endif
}
else
{

#endif // ESP32

#ifdef HAS_SW_SERIAL
if (hwSerial == serModeSoftware)
static_cast<SoftwareSerial *>(uart)->begin(9600);
#endif
}

uart->write(cfg, msgLen); // set passive mode
uart->flush();
delay(max_wait_ms * 2);
Expand All @@ -107,6 +104,11 @@ void SerialPM::wake() {

SerialPM::STATUS SerialPM::trigRead()
{
#ifdef HAS_SW_SERIAL
if (hwSerial == serModeSoftware)
static_cast<SoftwareSerial *>(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())
{
uart->read(); // empty the RX buffer
Expand Down
32 changes: 27 additions & 5 deletions src/PMserial.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,28 +77,46 @@ class SerialPM
float temp, rhum, hcho;
};
};

// 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)
{
SoftwareSerial serial(rx, tx);
static SoftwareSerial serial(rx, tx);
uart = &serial;
hwSerial = false;
hwSerial = serModeSoftware;
}

SerialPM(PMS sensor, Stream &serial) : pms(sensor)
avaldebe marked this conversation as resolved.
Show resolved Hide resolved
{
uart = &serial;
//TODO: WIP!!!
hwSerial = serModeManual;
}
#elif defined(ESP32)
SerialPM(PMS sensor, uint8_t rx, uint8_t tx) : pms(sensor), rx(rx), tx(tx)
{
uart = &Serial1;
hwSerial = true;
hwSerial = serModeHardware;
}
#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"
Expand All @@ -107,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,
Expand All @@ -119,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; }
Expand All @@ -128,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
Expand Down Expand Up @@ -156,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
Expand Down