Coder Social home page Coder Social logo

espsoftwareserial's Introduction

EspSoftwareSerial

Implementation of the Arduino software serial library for the ESP8266 / ESP32 family

This fork implements interrupt service routine best practice. In the receive interrupt, instead of blocking for whole bytes at a time - voiding any near-realtime behavior of the CPU - only level change and timestamp are recorded. The more time consuming phase detection and byte assembly are done in the main code.

Except at high bitrates, depending on other ongoing activity, interrupts in particular, this software serial adapter supports full duplex receive and send. At high bitrates (115200bps) send bit timing can be improved at the expense of blocking concurrent full duplex receives, with the EspSoftwareSerial::UART::enableIntTx(false) function call.

The same functionality is given as the corresponding AVR library but several instances can be active at the same time. Speed up to 115200 baud is supported. Besides a constructor compatible to the AVR SoftwareSerial class, and updated constructor that takes no arguments exists, instead the begin() function can handle the pin assignments and logic inversion. It also has optional input buffer capacity arguments for byte buffer and ISR bit buffer. This way, it is a better drop-in replacement for the hardware serial APIs on the ESP MCUs.

Please note that due to the fact that the ESPs always have other activities ongoing, there will be some inexactness in interrupt timings. This may lead to inevitable, but few, bit errors when having heavy data traffic at high baud rates.

This library supports ESP8266, ESP32, ESP32-S2 and ESP32-C3 devices.

Resource optimization

The memory footprint can be optimized to just fit the amount of expected incoming asynchronous data. For this, the EspSoftwareSerial::UART constructor provides two arguments. First, the octet buffer capacity for assembled received octets can be set. Read calls are satisfied from this buffer, freeing it in return. Second, the signal edge detection buffer of 32bit fields can be resized. One octet may require up to to 10 fields, but fewer may be needed, depending on the bit pattern. Any read or write calls check this buffer to assemble received octets, thus promoting completed octets to the octet buffer, freeing fields in the edge detection buffer.

Look at the swsertest.ino example. There, on reset, ASCII characters ' ' to 'z' are sent. This happens not as a block write, but in a single write call per character. As the example uses a local loopback wire, every outgoing bit is immediately received back. Therefore, any single write call causes up to 10 fields - depending on the exact bit pattern - to be occupied in the signal edge detection buffer. In turn, as explained before, each single write call also causes received bit assembly to be performed, promoting these bits from the signal edge detection buffer to the octet buffer as soon as possible. Explaining by way of contrast, if during a a single write call, perhaps because of using block writing, more than a single octet is received, there will be a need for more than 10 fields in the signal edge detection buffer. The necessary capacity of the octet buffer only depends on the amount of incoming data until the next read call.

For the swsertest.ino example, this results in the following optimized constructor arguments to spend only the minimum RAM on buffers required:

The octet buffer capacity (bufCapacity) is 95 (93 characters net plus two tolerance). The signal edge detection buffer capacity (isrBufCapacity) is 11, as each single octet can have up to 11 bits on the wire, which are immediately received during the write, and each write call causes the signal edge detection to promote the previously sent and received bits to the octet buffer.

In a more generalized scenario, calculate the bits (use message size in octets times 10) that may be asynchronously received to determine the value for isrBufCapacity in the constructor. Also use the number of received octets that must be buffered for reading as the value of bufCapacity. The more frequently your code calls write or read functions, the greater the chances are that you can reduce the isrBufCapacity footprint without losing data, and each time you call read to fetch from the octet buffer, you reduce the need for space there.

EspSoftwareSerial::Config and parity

The configuration of the data stream is done via a EspSoftwareSerial::Config argument to begin(). Word lengths can be set to between 5 and 8 bits, parity can be N(one), O(dd) or E(ven) and 1 or 2 stop bits can be used. The default is SWSERIAL_8N1 using 8 bits, no parity and 1 stop bit but any combination can be used, e.g. SWSERIAL_7E2. If using EVEN or ODD parity, any parity errors can be detected with the readParity() and parityEven() or parityOdd() functions respectively. Note that the result of readParity() always applies to the preceding read() or peek() call, and is undefined if they report no data or an error.

To allow flexible 9-bit and data/addressing protocols, the additional parity modes MARK and SPACE are also available. Furthermore, the parity mode can be individually set in each call to write().

This allows a simple implementation of protocols where the parity bit is used to distinguish between data and addresses/commands ("9-bit" protocols). First set up EspSoftwareSerial::UART with parity mode SPACE, e.g. SWSERIAL_8S1. This will add a parity bit to every byte sent, setting it to logical zero (SPACE parity).

To detect incoming bytes with the parity bit set (MARK parity), use the readParity() function. To send a byte with the parity bit set, just add MARK as the second argument when writing, e.g. write(ch, SWSERIAL_PARITY_MARK).

Checking for correct pin selection / configuration

In general, most pins on the ESP8266 and ESP32 devices can be used by EspSoftwareSerial, however each device has a number of pins that have special functions or require careful handling to prevent undesirable situations, for example they are connected to the on-board SPI flash memory or they are used to determine boot and programming modes after powerup or brownouts. These pins are not able to be configured by this library.

The exact list for each device can be found in the ESP32 data sheet in sections 2.2 (Pin Descriptions) and 2.4 (Strapping pins). There is a discussion dedicated to the use of GPIO12 in this note about GPIO12. Refer to the isValidPin(), isValidRxPin() and isValidTxPin() functions in the EspSoftwareSerial::GpioCapabilities class for the GPIO restrictions enforced by this library by default.

The easiest and safest method is to test the object returned at runtime, to see if it is valid. For example:

#include <SoftwareSerial.h>

#define MYPORT_TX 12
#define MYPORT_RX 13

EspSoftwareSerial::UART myPort;

[...]

Serial.begin(115200); // Standard hardware serial port

myPort.begin(38400, SWSERIAL_8N1, MYPORT_RX, MYPORT_TX, false);
if (!myPort) { // If the object did not initialize, then its configuration is invalid
  Serial.println("Invalid EspSoftwareSerial pin configuration, check config"); 
  while (1) { // Don't continue with invalid configuration
    delay (1000);
  }
} 

[...]

Using and updating EspSoftwareSerial in the esp8266com/esp8266 Arduino build environment

EspSoftwareSerial is both part of the BSP download for ESP8266 in Arduino, and it is set up as a Git submodule in the esp8266 source tree, specifically in .../esp8266/libraries/SoftwareSerial when using a Github repository clone in your Arduino sketchbook hardware directory. This supersedes any version of EspSoftwareSerial installed for instance via the Arduino library manager, it is not required to install EspSoftwareSerial for the ESP8266 separately at all, but doing so has ill effect.

The responsible maintainer of the esp8266 repository has kindly shared the following command line instructions to use, if one wishes to manually update EspSoftwareSerial to a newer release than pulled in via the ESP8266 Arduino BSP:

To update esp8266/arduino EspSoftwareSerial submodule to latest main:

Clean it (optional):

$ rm -rf libraries/SoftwareSerial
$ git submodule update --init

Now update it:

$ cd libraries/SoftwareSerial
$ git checkout main
$ git pull

espsoftwareserial's People

Contributors

arcao avatar bobotig avatar d-a-v avatar dok-net avatar earlephilhower avatar hallard avatar issalig avatar ivankravets avatar jueff avatar luisesn avatar marvinroger avatar michaelkoetter avatar per1234 avatar plerup avatar super169 avatar tchilton avatar x29a avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

espsoftwareserial's Issues

GPIO0, GPIO2, and GPIO15 are boot select pins in Arduino style

Hello,

I have determined an inconsistent boot cause to be due to the way the way this library configures pins for interrupt. This is especially apparent when using the built-in-led on gpio2 of the ESP-12e board.

#define BUILT_IN_LED 2

SoftwareSerial softs(4,5,false,128);

void setup(){
  softs.begin(38400);  
  pinMode(BUILT_IN_LED, OUTPUT); <<-- Crash. Module will then go into UART boot mode as 0, and 2 will go high
}

These pins go high when void ICACHE_RAM_ATTR sws_isr_0() { ObjList[0]->rxRead(); }; is called.

-sk1

Calling constructor twice

When calling constructor twice the library stops working.

I would like an empty constructor because my device gets the pin profiles from my site....

Thank you!

Multiple soft serial port does not support?

CODE:

include <SoftwareSerial.h>

//SoftwareSerial swSer(14, 12, 128);
SoftwareSerial swSer(12, 13,false, 128);
SoftwareSerial swSer2(14, 16,false, 128);

void setup() {
Serial.begin(115200);
swSer.begin(115200);
swSer2.begin(115200);
//Serial.begin(9600);
//swSer.begin(9600);

Serial.println("\nSoftware serial test started");

for (char ch = ' '; ch <= 'z'; ch++) {
swSer.write(ch);
}
swSer.println("");

}

void loop() {
if (swSer.available()) {
Serial.write(swSer.read());
}
if (Serial.available()) {
int buf = Serial.read();
swSer.write(buf);
swSer2.write(buf);
}
if (swSer2.available()) {
Serial.write(swSer2.read());
}
}

OUTPUT:
ets Jan 8 2013,rst cause:4, boot mode:(1,6)

wdt reset

SoftwareSerial avr vs SoftwareSerial esp incompatibility

I ran into a problem , there's a simple communications program using the gt511 fingerprint sensor which works on avr , but I'd like to use an ESP8266 to communicate to it and the basic test programs can't even compile . is there an incompatibility in calls between the two ?
here's the lib for the gt511:
http://wordpress.hawleyhosting.com/ramblings/Downloads/FPS_GT511C3.zip
http://wordpress.hawleyhosting.com/ramblings/?p=375
the error codes I receive are : "error: SoftwareSerial has no member named 'end' , 'listen'
thanks in advance

available() returns only 0 or 1

Hi,
there is a small problem with available() method.
It returns 0 if there's no bytes waiting in the buffer or 1 if there is one or more bytes.
This causes problems if user is checking this method to see if there is enough data in the buffer.
To solve this issue available() should look more like this:

int SoftwareSerial::available() {
    if (m_rxValid && ((m_inPos-m_outPos) > 0))
        return (m_inPos-m_outPos);
    else
        return -1;
}

Best regards
Mateusz

SoftwareSerial Rx data error

SoftwareSerial Rx data error.

Code:

include <SoftwareSerial.h>

//SoftwareSerial swSer(14, 12, 128);
SoftwareSerial swSer(12, 13, 128);

void setup() {
Serial.begin(115200);
swSer.begin(115200);
//Serial.begin(9600);
//swSer.begin(9600);

Serial.println("\nSoftware serial test started");

for (char ch = ' '; ch <= 'z'; ch++) {
swSer.write(ch);
}
swSer.println("");

}

void loop() {
if (swSer.available()) {
Serial.write(swSer.read());
}
if (Serial.available()) {
swSer.write(Serial.read());
}

}

tx "ee", rx "de"

see picture:
espsoftserialrxerror

Check softwareserial data

how can i check, waht is come from esp8266 .
when i chak like this in arduino uno

if(mySerial.read() == "1"){
Serial.println("mySerial.available Stav 1");
}

i have output some hyroglifics )))

EspSoftwareSerial and ESP8266HTTPClient broken

Basic Infos

Hardware

Hardware: NodeMCU
Core Version: e9dea9af999c324c55fe2f4ecfb16fa2f9e867c5 (also tested at 2.3.0)

Description

when i use EspSoftwareSerial and ESP8266HTTPClient Frequent call,The WiFi Connection be broken

Settings in IDE

Module: NodeMCU 1.0
Flash Size: 4MB
CPU Frequency: 80Mhz
Upload Using: Serial

NodeMCU Sketch

#include <Arduino.h>
#include <SoftwareSerial.h>
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>

SoftwareSerial Serial2(12, 14, false, 2048);

void setup()
{
  Serial2.setTimeout(50);
  Serial2.begin(9600);
  Serial.begin(115200);
  WiFi.mode(WIFI_AP_STA);
  WiFi.begin("SSID", "password");
}

void loop()
{
  if (Serial2.available()) {
    Serial.printf("WiFi.getMode(): %d\r\n", WiFi.getMode());
    Serial.printf("IP address: %s\r\n", WiFi.localIP().toString().c_str());
    Serial.printf("[B] ESP FreeHeap: %d\r\n", ESP.getFreeHeap());
    String payload = Serial2.readString();
    HTTPClient client;
    client.begin("http://www.wuweixin.com/iot");
    client.GET();
    client.end();
    Serial.printf("[A] ESP FreeHeap: %d\r\n", ESP.getFreeHeap());
  }
  
}

Debug Messages

Console Log

IP address: 0.0.0.0
[B] ESP FreeHeap: 39840
[A] ESP FreeHeap: 38544
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 38904
[A] ESP FreeHeap: 38120
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 38856
[A] ESP FreeHeap: 38200
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 38840
[A] ESP FreeHeap: 38264
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 38744
[A] ESP FreeHeap: 38032
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 38528
[A] ESP FreeHeap: 38392
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 38744
[A] ESP FreeHeap: 38456
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 39136
[A] ESP FreeHeap: 38680
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 39328
[A] ESP FreeHeap: 38808
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 39280
[A] ESP FreeHeap: 38240
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 38592
[A] ESP FreeHeap: 38752
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 39040
[A] ESP FreeHeap: 38808
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 39280
[A] ESP FreeHeap: 38064
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 39112
[A] ESP FreeHeap: 38944
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 39232
[A] ESP FreeHeap: 37976
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 38968
[A] ESP FreeHeap: 38552
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 38968
[A] ESP FreeHeap: 38672
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 39088
[A] ESP FreeHeap: 38632
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 39048
[A] ESP FreeHeap: 37528
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 39072
[A] ESP FreeHeap: 38392
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 38864
[A] ESP FreeHeap: 38480
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 38960
[A] ESP FreeHeap: 37952
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 38816
[A] ESP FreeHeap: 37568
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 38744
[A] ESP FreeHeap: 38928
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 39280
[A] ESP FreeHeap: 38224
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 39328
[A] ESP FreeHeap: 38928
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 39280
[A] ESP FreeHeap: 38480
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 39280
[A] ESP FreeHeap: 38048
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 38976
[A] ESP FreeHeap: 38504
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 39048
[A] ESP FreeHeap: 37624
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 38864
[A] ESP FreeHeap: 37872
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 38536
[A] ESP FreeHeap: 38672
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 39120
[A] ESP FreeHeap: 38112
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 39096
[A] ESP FreeHeap: 38136
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 38864
[A] ESP FreeHeap: 38240
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 39024
[A] ESP FreeHeap: 38360
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 38712
[A] ESP FreeHeap: 38480
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 38952
[A] ESP FreeHeap: 38736
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 39208
[A] ESP FreeHeap: 38488
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 39328
[A] ESP FreeHeap: 38752
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 39232
[A] ESP FreeHeap: 38528
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 38880
[A] ESP FreeHeap: 38752
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 39232
[A] ESP FreeHeap: 37616
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 38736
[A] ESP FreeHeap: 38568
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 39048
[A] ESP FreeHeap: 37888
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 38816
[A] ESP FreeHeap: 38152
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 38632
[A] ESP FreeHeap: 37664
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 38016
[A] ESP FreeHeap: 38232
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 38584
[A] ESP FreeHeap: 38040
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 38584
[A] ESP FreeHeap: 37952
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 38304
[A] ESP FreeHeap: 38096
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 38448
[A] ESP FreeHeap: 37624
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 38168
[A] ESP FreeHeap: 38088
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 38680
[A] ESP FreeHeap: 38088
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 38560
[A] ESP FreeHeap: 38560
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 38976
[A] ESP FreeHeap: 38000
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 38720
[A] ESP FreeHeap: 38680
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 39096
[A] ESP FreeHeap: 38008
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 38672
[A] ESP FreeHeap: 38696
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 39048
[A] ESP FreeHeap: 37912
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 38648
[A] ESP FreeHeap: 38448
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 38736
[A] ESP FreeHeap: 38792
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 39208
[A] ESP FreeHeap: 38608
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 39088
[A] ESP FreeHeap: 38328
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 38928
[A] ESP FreeHeap: 37896
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 38624
[A] ESP FreeHeap: 38368
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 38720
[A] ESP FreeHeap: 37960
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 38864
[A] ESP FreeHeap: 38152
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 38840
[A] ESP FreeHeap: 36600
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 36952
[A] ESP FreeHeap: 36120
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 37048
[A] ESP FreeHeap: 36360
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 37416
[A] ESP FreeHeap: 36296
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 37416
[A] ESP FreeHeap: 36296
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 37416
[A] ESP FreeHeap: 36232
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 37416
[A] ESP FreeHeap: 36296
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 37416
[A] ESP FreeHeap: 36296
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 37416
[A] ESP FreeHeap: 36296
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 37416
[A] ESP FreeHeap: 36296
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 37416
[A] ESP FreeHeap: 36296
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 37416
[A] ESP FreeHeap: 36296
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 37416
[A] ESP FreeHeap: 36296
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 37416
[A] ESP FreeHeap: 36296
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 37416
[A] ESP FreeHeap: 36296
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 37416
[A] ESP FreeHeap: 36296
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 37416
[A] ESP FreeHeap: 36296
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 37416
[A] ESP FreeHeap: 36232
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 37416
[A] ESP FreeHeap: 36296
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 37416
[A] ESP FreeHeap: 36296
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 37416
[A] ESP FreeHeap: 36296
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 37416
[A] ESP FreeHeap: 36232
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 37416
[A] ESP FreeHeap: 36296
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 37416
[A] ESP FreeHeap: 36296
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 37416
[A] ESP FreeHeap: 36296
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 37416
[A] ESP FreeHeap: 36296
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 37416
[A] ESP FreeHeap: 36296
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 37416
[A] ESP FreeHeap: 36296
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 37416
[A] ESP FreeHeap: 36296
WiFi.getMode(): 3
IP address: 192.168.38.149
[B] ESP FreeHeap: 37416

Ping Log

64 bytes from 192.168.38.149: icmp_seq=151 ttl=128 time=1.325 ms
64 bytes from 192.168.38.149: icmp_seq=152 ttl=128 time=1.235 ms
64 bytes from 192.168.38.149: icmp_seq=153 ttl=128 time=2.777 ms
64 bytes from 192.168.38.149: icmp_seq=154 ttl=128 time=1.428 ms
64 bytes from 192.168.38.149: icmp_seq=155 ttl=128 time=1.385 ms
64 bytes from 192.168.38.149: icmp_seq=156 ttl=128 time=2.123 ms
64 bytes from 192.168.38.149: icmp_seq=157 ttl=128 time=1.825 ms
64 bytes from 192.168.38.149: icmp_seq=158 ttl=128 time=17.252 ms
64 bytes from 192.168.38.149: icmp_seq=159 ttl=128 time=1.172 ms
64 bytes from 192.168.38.149: icmp_seq=160 ttl=128 time=2.287 ms
64 bytes from 192.168.38.149: icmp_seq=161 ttl=128 time=2.456 ms
Request timeout for icmp_seq 162
Request timeout for icmp_seq 163
Request timeout for icmp_seq 164
Request timeout for icmp_seq 165
Request timeout for icmp_seq 166
Request timeout for icmp_seq 167
Request timeout for icmp_seq 168
Request timeout for icmp_seq 169
Request timeout for icmp_seq 170

Another Arduino Uno Sketch

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  digitalWrite(LED_BUILTIN, HIGH);
  for (int i = 0; i < 64; i++) {
    Serial.write(0x0A);
  }
  digitalWrite(LED_BUILTIN, LOW);
  delay(500);
}

the wifi connection lost is not immediately
need waiting some minutes
just like unstable

if only call Serial2.readString()
the nodemcuv2 WiFi also disconnect after about 30minutes

#include <Arduino.h>
#include <SoftwareSerial.h>
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>

SoftwareSerial Serial2(12, 14, false, 2048);

void setup()
{
  Serial2.setTimeout(50);
  Serial2.begin(9600);
  Serial.begin(115200);
  WiFi.mode(WIFI_AP_STA);
  WiFi.begin("SSID", "password");
}

void loop()
{
  if (Serial2.available()) {
    Serial.printf("WiFi.getMode(): %d\r\n", WiFi.getMode());
    Serial.printf("IP address: %s\r\n", WiFi.localIP().toString().c_str());
    Serial.printf("[B] ESP FreeHeap: %d\r\n", ESP.getFreeHeap());
    String payload = Serial2.readString();
    Serial.printf("[A] ESP FreeHeap: %d\r\n", ESP.getFreeHeap());
  }
  
}

ping log

64 bytes from 192.168.38.149: icmp_seq=2000 ttl=128 time=3.109 ms
64 bytes from 192.168.38.149: icmp_seq=2001 ttl=128 time=1.281 ms
64 bytes from 192.168.38.149: icmp_seq=2002 ttl=128 time=4.404 ms
64 bytes from 192.168.38.149: icmp_seq=2003 ttl=128 time=1.326 ms
64 bytes from 192.168.38.149: icmp_seq=2004 ttl=128 time=1.365 ms
64 bytes from 192.168.38.149: icmp_seq=2005 ttl=128 time=3.335 ms
64 bytes from 192.168.38.149: icmp_seq=2006 ttl=128 time=1.325 ms
64 bytes from 192.168.38.149: icmp_seq=2007 ttl=128 time=1.383 ms
64 bytes from 192.168.38.149: icmp_seq=2008 ttl=128 time=1.437 ms
64 bytes from 192.168.38.149: icmp_seq=2009 ttl=128 time=26.724 ms
64 bytes from 192.168.38.149: icmp_seq=2010 ttl=128 time=2.393 ms
64 bytes from 192.168.38.149: icmp_seq=2011 ttl=128 time=2.183 ms
64 bytes from 192.168.38.149: icmp_seq=2012 ttl=128 time=2.496 ms
64 bytes from 192.168.38.149: icmp_seq=2013 ttl=128 time=2.271 ms
64 bytes from 192.168.38.149: icmp_seq=2014 ttl=128 time=1.422 ms
64 bytes from 192.168.38.149: icmp_seq=2015 ttl=128 time=2.294 ms
64 bytes from 192.168.38.149: icmp_seq=2016 ttl=128 time=1.539 ms
64 bytes from 192.168.38.149: icmp_seq=2017 ttl=128 time=12.928 ms
Request timeout for icmp_seq 2018
Request timeout for icmp_seq 2019
Request timeout for icmp_seq 2020
Request timeout for icmp_seq 2021
Request timeout for icmp_seq 2022
Request timeout for icmp_seq 2023
Request timeout for icmp_seq 2024
Request timeout for icmp_seq 2025
Request timeout for icmp_seq 2026
Request timeout for icmp_seq 2027
Request timeout for icmp_seq 2028
Request timeout for icmp_seq 2029
Request timeout for icmp_seq 2030
Request timeout for icmp_seq 2031
Request timeout for icmp_seq 2032
Request timeout for icmp_seq 2033
Request timeout for icmp_seq 2034
Request timeout for icmp_seq 2035
Request timeout for icmp_seq 2036
Request timeout for icmp_seq 2037
Request timeout for icmp_seq 2038
Re

EspSoftwareSerial stop wifi

Hi there,

I'm programming an Esp8266 from Espressif (vroom-02).
The project is to sense with an Arduino Uno and then send data to Esp8266 which will send to computer over wifi.

The wifi alone is working, the softwareserial alone as well.
But the combination of both stops wifi.
I think it is because fo interrupts attached to Rx pin for communication communication.

So I tried to use stopListening but I didn't solve my issue.

Maybe it is linked to that #1020
Have an idea ?

Chris

Incorrect Read Buffer Overflow Handling

The read buffer overflow handling should compare next with m_outPos, like ...
int next = (m_inPos+1) % m_buffSize;
if (next != m_outPos) {
m_buffer[m_inPos] = rec;
m_inPos = next;
}

SoftwareSerial::Write() does not use inverse logic

SoftwareSerial::write(uint8_t b) does not use "inverse logic". Need to change some lines:

163c163
<    digitalWrite(m_txPin, HIGH);
---
>    digitalWrite(m_txPin,!m_invert ? HIGH : LOW);
166c166
<    digitalWrite(m_txPin, LOW);
---
>    digitalWrite(m_txPin, !m_invert ? LOW : HIGH );
174c174
<    digitalWrite(m_txPin, HIGH);
---
>    digitalWrite(m_txPin, !m_invert ? HIGH : LOW);
175a176
>    digitalWrite(m_txPin, !m_invert);

I'm adding Wifi to my Scribbler2 robot using a NodeMCU and that fix the problem

Saludos
RCR

TX-only serial not possible

It would be useful to allow out-only serial. Useful for logging purposes, uses only 1 pin. Anyone interested in picking this up?

WDT Reset when using mDNS and ESP8266WebServer

So I'm seeing the following wdt reset very occasionally (3-5 times in a 12 hour period) when using both espsoftwareserial, mDNS, and ESP8266WebServer together continuously:

dev 1143

 ets Jan  8 2013,rst cause:4, boot mode:(3,7)

wdt reset
load 0x4010f000, len 1384, room 16 
tail 8
chksum 0x2d
csum 0x2d
v5b34dc19
~ld

Disabling espsoftwareserial allows the program to run fine indefinitely. Now, the only thing helpful here seems to be the rather obscure "dev 1143" line, which leads to a single forum post on Espressif's site here: http://bbs.espressif.com/viewtopic.php?t=1205 - But, the OP states he could reproduce it via os_intr_lock/unlock - I tried disabling the sei() / cli() calls, but, that made no difference, so I'm rather stumped on what else it could be other than the receive interrupt being slow.

Now, this wdt reset always happens when I'm waiting for a response on the software serial line. Immediately before this I would have answered and completed an HTTP response - But, I do not know if they're necessarily related.

I'm running this on an ESP-12F, clocked at 80MHz, baud 38400, and git version of the ESP8266 Arduino project.

Exceptions with baudrate 9600

Hi,
I'm using espsoftwareserial to communicate with a PZEM-004T using library https://github.com/olehs/PZEM004T.

I got a lot of reading errors and mostly an exceptions occured after a few seconds. Somtimes it was stable for nearly a minute, but never longer than two minutes. When I got an exception epc1 mostly pointed to optimistic_yield().

In the interrupt-handler rxRead I found the line WAIT;. This macro expands to
#define WAIT { while (ESP.getCycleCount()-start < wait) if (!m_highSpeed) optimistic_yield(1); wait += m_bitTime; }

m_highSpeed is set in begin(): m_highSpeed = speed > 9600;. The baudrate for the PZEM-004T is 9600 bps. So m_highSpeed is set to false and optimistic_yield() is called.

I set m_highSpeed to true for my special case. All the communication errors disappeared. And now more exceptions occured. Currently my software is running stable for more than a hour.

Yous should revise the definition of WAIT. In the code for WAIT in the original library is #define WAIT { while (ESP.getCycleCount()-start < wait); wait += m_bitTime; }

Kind regards
UlliBien

Need help: fatal error: gpio.h: No such file or directory

Please help me to fix the following compilation error, I am trying to communicate an Arduino Pro Mini with a ESP8266 ESP-01 Version 2 (leds next to antenna), but I get the following error just trying to run the example swsertest that comes with the .zip download:

C:\Users\Enrique\Documents\Arduino\libraries\espsoftwareserial-master\SoftwareSerial.cpp:27:18: fatal error: gpio.h: No such file or directory
#include "gpio.h"
^
compilation terminated.
Multiple libraries were found for "SoftwareSerial.h"
Used: C:\Users\Enrique\Documents\Arduino\libraries\espsoftwareserial-master
Not used: C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\SoftwareSerial
Error compiling.

Can't communicate with Nextion display

Hi,

I've got a NodeMCU v0.9 and a 3.2" Nextion HMI display. The display uses UART for communication, eg.: change some text on the display.
What I would like to achieve: Using Arduino IDE, see debug information in Serial monitor. Communication between Nextion display and NodeMCU is also a serial communication.

A simplified version of my sketch looks like this:

#include "SoftwareSerial.h"
SoftwareSerial nextionSerial(D9, D10); // NodeMCU D9 and D10 pins
void setup() {
    Serial.begin(115200);
    nextionSerial.begin(9600);
}
void loop() {
    while (nextionSerial.available()) {
        Serial.write(nextionSerial.read());
    }
}

If I touch a button on the Nextion display it sends data to its Serial ports, which I should be able to read in Serial Monitor using the code above, but I see nothing.

Any clue on what's wrong?

Thank you!

isValidGPIOpin too limited

So, is there any reason why you don't want pins 6-11 mapped to this software serial?
I don't use an SD card, so I'd like to use the gpio pins normally reserved for SD functionality.
In my opinion, the function isValidGPIOpin should just check if 0<=pin<=15 or am I missing something?

BTW, thanks for this library :D

SoftwareSerial WiFi

As discussed by a few others, I have experienced the conflict between Wifi/SoftwareSerial
This library supports the end() API, and I think I can code around this issue by possibly protecting the code

but, this probably sounds a dumb question.
How do I install this library to be used in preference to the standard esp8266/2.3.0 installation - which does not give me the end() call ?

missing methods - end and listen

Hi, I am playing with a fingerprint scanner (FPS GT511C3) that communicates over serial. It seems that the version of epssoftwareserial is missing some methods; "end" and "listen" for example. Anyone have an idea how this could be fixed (I mean, before I go and alter the FPS library)?

Inverted bits missing

Hi there,

Love your work, but can't use your softserial library without an inverter, because galvanic isolators sometimes invert the 1's and 0's.

The Arduino SoftSerial in the core library supports this. Could you implement this as well?
Great advantage of soft serial over UART is the ability to support this by interpreting inverted.

Please add a boolean with a default false in the constructor so inverted logic can be selected at time of creation.

Kind regards,
TeaZee

Buffer data remains after flush() called.

I have a local clone of this repo and noticed that when I call flush there's still data in the buff, you just set the index to 0. I added memset(m_buffer,0,m_buffSize); - Results in slightly more predictable behavior when write->read->write->read operations are being performed.

-sk

Data Corruption

Hi

Firstly thanks for the contribution, great effort!

I have a small problem that theres quite a bit of data corruption coming in from a GPS device.

Have played with the buffer size and trying flush before read or write but still the problem remains?

Seems adding a delay around the read and write time definately helps but doesnt clear the problem completely.

Any ideas, I have this one problem left in a big project, so close but so far ! :)

Thanks for any help !

SoftwareSerial is unstable in 2.4.0

I've installed ESP8266 core 2.4.0 for Arduino 1.8.5 (Windows 7 SP1 64-bit) and immediately encountered problems when comminucating with one of my sensors (MH-Z19) which is utilized through SoftwareSerial library: readings return 0 (zeros) in some uncertain conditions (probably when WiFi-connection is active).
I had to downgrade ESP8266 core to 2.3.0 to restore stable work with the sensor.

MCU: LoLin (NodeMCU, esp8266, ESP12-E)

The reading code is more-less standard (I haven't changed it for months) - here are few fragments:

#  include <SoftwareSerial.h>

SoftwareSerial co2Serial(MH_Z19_TX, MH_Z19_RX); // define MH-Z19

void CO2_begin()
{
  LOG_println(Fx("CO2-sensor: begin(9600)"));
  co2Serial.begin(9600); //Init sensor MH-Z19(14)
}

int readCO2()
{
  // command to ask for data (0x86)
  const byte cmd[9] = {0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79};
  byte response[9] = { 0 }; // for answer

  co2Serial.write(cmd, sizeof(cmd)); //request PPM CO2
  co2Serial.readBytes(response, sizeof(response));
#ifdef ENABLE_DIAG
  char raw[64];
  sprintf(raw, "CO2 RAW: %02X %02X %02X %02X %02X %02X %02X %02X %02X"
         , response[0], response[1], response[2], response[3]
         , response[4], response[5], response[6], response[7], response[8]);
  LOG_println(raw);
#endif
  if (response[0] != 0xFF)
  {
    LOG_print  (F("Wrong starting byte from co2 sensor: 0x"));
    LOG_println(response[0], HEX);
    return -1;
  }

  if (response[1] != 0x86)
  {
    LOG_print  (F("Wrong command from co2 sensor: 0x"));
    LOG_println(response[1], HEX);
    return -1;
  }

  const int responseHigh = response[2];
  const int responseLow  = response[3];
  const int ppm = (256 * responseHigh) + responseLow;
  return ppm;
}

With SoftwareSerial from 2.4.0 the sensor in some situations just returns all zeros:

348086: loop: millis() = 348086, 2018-02-22 21:44:40, Thursday
348141: reading data:
349150: CO2 RAW: 00 00 00 00 00 00 00 00 00
349150: Wrong starting byte from co2 sensor: 0x0
349151:   CO2 = -1
349151: CO2 not valid
349479: DHT #1 Humidity = 40.7
349533: DHT #1 Temperature = 18.8
349586:   Free RAM: 19952
349586:   Online Queue: 0
349587: Data reading error #3/15
349587: loop finished, 1501 millis spent

I guess, the problem may be caused by other parts of ESP8266 core, but it reveals itself through SoftwareSerial class.
And it may be related to WiFi-part, since there were similar issues like esp8266/Arduino#2937, esp8266/Arduino#4315

Set data, parity and stop bits

I try to acquire signals from a device with data bit=7, parity=Even, and stop bit=2.

Is there a way to configure these parameters?

ESP8266 soft reset continuously

I am using a Modbus master library with the ESP8266 , for the modbus coms I setup softwareSerial.
[II am able to read modbus registers without problem , the only problem that I have is, if I disconnect the RS485 conection from the MAX485 then the ESP8266 crash and reset over and over again]
I tried several GPIO on the ESP for the software serial, but always I got the same problem.

###THE CODE ###
#include <ModbusMaster.h>
#include <SoftwareSerial.h>

/*!
We're using a MAX485-compatible RS485 Transceiver.
Rx/Tx is hooked up to the hardware serial port at 'Serial'.
The Data Enable and Receiver Enable pins are hooked up as follows:
*/
#define MAX485_DE 5 // was 5(moteino) //and was 2(d4) on esp8266 but have trouble
#define MAX485_RE_NEG 4 // was 6
#define NANO_HSP(m,n) (m *100+ n-1) ///<

ModbusMaster node;

SoftwareSerial mySerial(14, 12, false,256); //esp8266
void preTransmission()
{
digitalWrite(MAX485_RE_NEG, 1);
digitalWrite(MAX485_DE, 1);
}

void postTransmission()
{
digitalWrite(MAX485_RE_NEG, 0);
digitalWrite(MAX485_DE, 0);
}

void setup()
{
pinMode(MAX485_RE_NEG, OUTPUT);
pinMode(MAX485_DE, OUTPUT);

// Init in receive mode
digitalWrite(MAX485_RE_NEG, 0);
digitalWrite(MAX485_DE, 0);
Serial.begin(19200);
// Commander SK @ 19200
mySerial.begin(19200);
Serial.println("Modbus-Master");

// Modbus slave ID 1
node.begin(1, mySerial);
// Callbacks allow us to configure the RS485 transceiver correctly
node.preTransmission(preTransmission);
node.postTransmission(postTransmission);
}

bool state = true;

void loop()
{
uint8_t result;

result=node.readHoldingRegisters(NANO_HSP(18,11), 10); //

if (result == node.ku8MBSuccess)
{
Serial.println("Data: ");
// Serial.println(node.getResponseBuffer(1));
for (uint8_t j = 0; j < 10; j++) Serial.println(node.getResponseBuffer(j),DEC);

          mySerial.flush();
         // node.clearTransmitBuffer();

}
else {
Serial.println("NO- RESPONSE");
//mySerial.flush();
}

delay(3000);
Serial.println("running...");
}

#############
#####THE Crash from the ESP8266###
Soft WDT reset

ctx: cont
sp: 3ffef4f0 end: 3ffef820 offset: 01b0

stack>>>
3ffef6a0: feefeffe feefeffe feefeffe 00000008
3ffef6b0: 00000008 00000003 3ffee4f4 402020ba
3ffef6c0: 12070301 bc640a00 006f0000 014d01de
3ffef6d0: 7f0080bc c03930ff feefefda feefeffe
3ffef6e0: feefeffe feefeffe feefeffe feefeffe
3ffef6f0: feefeffe feefeffe feefeffe feefeffe
3ffef700: feefeffe feefeffe feefeffe feefeffe
3ffef710: feefeffe feefeffe feefeffe feefeffe
3ffef720: feefeffe 00000004 3ffef78f 40202e18
3ffef730: feefeffe feefeffe feefeffe 3ffee73c
3ffef740: 00000031 0000000a 3ffee73c 40202721
3ffef750: 3ffef78b feefeffe feefeffe feefeffe
3ffef760: feefeffe feefeffe 3ffef78a 402027d5
3ffef770: feefeffe feefeffe feefeffe 00004b00
3ffef780: 0000001c 00000000 31fee73c 35343332
3ffef790: feefef00 00000001 3ffe8669 40202e18
3ffef7a0: 00000009 00000009 3ffe8459 3ffee7f0
3ffef7b0: 3ffee4f4 0000000a 3ffee73c 40202721
3ffef7c0: 0000381a 000000e2 3ffee73c 40202721
3ffef7d0: 3ffe8450 3ffee7f0 3ffee73c 3ffee7f0
3ffef7e0: 3ffee4f4 00000000 3ffee4f4 40202260
3ffef7f0: 00000000 00000000 00000001 40201d38
3ffef800: 3fffdad0 00000000 3ffee7e8 40202ba4
3ffef810: feefeffe feefeffe 3ffee800 40100708
<<<stack<<<
##############################

One Wire Half Duplex Serial communication

Will you consider to add the support of one wire half duplex serial communication in the SoftwereSerial library?

I have modified the library and tested with the servo of UBTech Alpha 1S robot using one wire half duplex communication in 115200 bps. (https://github.com/Super169/espsoftwareserial/tree/dev )

One wire communication will be enabled if receivePin == transmitPin, the data pin is set to Rx mode by default, and a new method enableTx has been added set the data pin to Tx mode, it must be called before calling write method. I have tried to put the enableTx logic inside write method, but it will toggle the interrupt frequently, so I decided to have a separate method, and called before and after the whole transmission.

I'm a newbie in ESP8266 programming, there should have better approach to handle such communication. It'd be better if the SoftwareSerial library can be enhance to support it officially.

Thanks in advance.
James

Data corruption when send SoftwareSerial data

Hi
I have to create a simple SoftwareSerial test with PIN4 and PIN5 with ESP12F DEVKIT V3
My code is sending out data every 100ms with baud rate 9600, my serial connect to Docklight program.
Data that i want to send is 0x01 0x02 0x03 0x04 0x05 0x06 0x07, when Docklight receive data program will answer back with 0x0A 0x0B 0x0C

So the problem is I found a random data corruption when send out data.
Please advice me, if you have any suggestion.

image

image

Here is my simple code:

#include <SoftwareSerial.h>
#define SSerial2_PINRX      (5)
#define SSerial2_PINTX      (4)
 
SoftwareSerial SSerial2(SSerial2_PINRX, SSerial2_PINTX, false, 256);  // RX, TX, inverse_logic, buffSize  

static uint8_t send_data[20];
static int tmp_size = 0;
static int tx_i;

static uint32_t currentMillis = 0;
static uint32_t previousMillis = 0;
static uint32_t interval = 10;
static uint32_t timer_20ms = 0;
static uint32_t timer_100ms = 0;
static uint8_t timer_20ms_tick = 0;
static uint8_t timer_100ms_tick = 0;

void setup() {
  // init serial
  SSerial2.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:

  currentMillis = millis();
  if(currentMillis - previousMillis > interval) {
    previousMillis = currentMillis;

    timer_20ms++;
    if(timer_20ms >= 2){
      timer_20ms = 0;
      timer_20ms_tick = 1;
    }

    timer_100ms++;
    if(timer_100ms >= 10){
      timer_100ms = 0;
      timer_100ms_tick = 1;
    }
  }

  if(timer_20ms_tick){
    timer_20ms_tick = 0;
  }
  
  if(timer_100ms_tick){
    timer_100ms_tick = 0;
    memset(send_data, 0, sizeof(uint8_t)*20);
    tmp_size = 0;

    send_data[0] = 0x01;
    send_data[1] = 0x02;
    send_data[2] = 0x03;
    send_data[3] = 0x04;
    send_data[4] = 0x05;
    send_data[5] = 0x06;
    send_data[6] = 0x07;

    tmp_size = 7;

    for(tx_i=0; tx_i<tmp_size; tx_i++){
      SSerial2.write(send_data[tx_i]);
    }
  }
}

Transmission errors at 115200 baud

At 115200 baud i get random transmission corruption. Sometimes there are only single bytes/bits corrupted, somtimes whole lines are affected. Most of the time it works great! Is this a known limitation, a software Issue or should i check for new Hardware?

1200 Baud returns null bytes

Not sure if is an issue or I'm doing something wrong, but I'm attempting to read data off a very slow device (1200baud) and am only receiving null bytes, though it is the correct amount.

I verified the data plugging the line and ground from the device into my FTDI and setting the baud to 1200 and received expected values.

SoftwareSerial swSer(13,SW_SERIAL_UNUSED_PIN); //tried setting to 13,12 as well. Only have RX from device though.
void setup() {
Serial.begin(1200); //according to some posts mixed baud can cause oddities.
swSer.begin(1200);
pinMode(ESP8266_LED, OUTPUT);
delay(100);
}

void loop() {
while(swSer.available()){
Serial.print(swSer.read()); //null bytes (the correct amount though)
}
delay(100); //raising and lowering doesn't seem to help
}

NtpclientEsp8266 lib and espsoftwareserial don't like to work together

Hi, I like to send the Ntp time by softwareserial to a other esp8266 node.
If I setup a esp8266 with a NTP program everthing works fine ( using Ntpclientlib ). The moment I add -> SoftwareSerial swSer(14, 2, false, 256); <- the esp8266 goes to reset itself and goes on resetting.

Any idea to avoid that problem?

Peter

Doesn't RX doesn't work inside of another C++ class?

I've been trying to use the ESP8266 to control an iRobot Create 2 (via software serial). I can interact with the Create directly if I import this library into an Arduino sketch and upload to my Adafruit HUZZAH, however if I try to incorporate this code into another C++ class, I can send but not receive. Here is a trivial example:

// SSWrapper.h

#include "SoftwareSerial.h"

#ifndef SSWrapper_h
#define SSWrapper_h

class SSWrapper {
public:

    SSWrapper();

    // just wrap the basics
    void begin();
    void swWrite(uint8_t b);
    int swRead();
    int swAvailable();

private:
    SoftwareSerial softSerial;
};

#endif /* SSWrapper_h */
// SSWrapper.cpp

#include "SSWrapper.h"
#include <inttypes.h>


SSWrapper::SSWrapper() {
}

void SSWrapper::begin() {
    // just hard code in some values, because that's how I had it set up
    softSerial = SoftwareSerial(12, 5, false, 64);
    softSerial.begin(19200);
}

// these are just pass through
void SSWrapper::swWrite(uint8_t b) {
    softSerial.write(b);
}

int SSWrapper::swRead() {
    return softSerial.read();
}

int SSWrapper::swAvailable() {
    return softSerial.available();
}

And finally, an Arduino Sketch:

#include <SSWrapper.h>

SSWrapper ssw;
void setup() {
  ssw.begin();
}

void loop() {
  // now, the other side has sent some bytes to the ESP, so I expect ssw.swAvailable()
  // to be > 1, but it isn't, it's always 0.

  if (ssw.swAvailable() > 0) {
    byte inByte = ssw.swRead();
    Serial.println("some data:");
    Serial.println(int(inByte));
  }
}

I also tried adding some debug code to the interrupt handler readRx function and it doesn't seem to be getting called.

Frequent WDT resets

Console shows periodic WDT resets. SoftwareSerial intialized as 12,14,false,128. I'm using the newest library from this repos.

The software serial connects at 9600. I cannot find the definition for rst cause code 4 (so far).
The console-to-onboard serial is 115.2k.

WDT output

ets Jan  8 2013,rst cause:4, boot mode:(3,7)

wdt reset
load 0x4010f000, len 1264, room 16 
tail 0
chksum 0x42
csum 0x42
~ld

SoftwareSerial causing spurious resets

I'm having a problem with SofwareSerial causing resets on my ESP8266 (NodeMcu 12E). I have a sensor which sends data via serial connection, which I'm reading using SoftwareSerial on pins D7 and D8, at 9600bps, with a 1024 byte buffer (I've experimented with different buffer sizes with no apparent change of behavior). Typically, the device will run for 30-90 minutes, and then reset due to a triggering of the hardware watchdog. It will sometimes reset sooner (10 minutes), but I've never seen it live longer than 2 hours before resetting.

The data being sent by the sensor is small packets (< 64 bytes), spaced out about a second or two apart.

If I disconnect the serial device, the resets go away (probably because there is no data being read). This would seem to eliminate everything except the code that actually reads the data.

If I leave the device connected, but remove the SoftwareSerial code, the resets go away. This would seem to eliminate electrical faults or overloading, or similar problems.

I'm working with the current version, but have tried older versions as well (2.0.0 and 2.1.1) with no change in behavior.

My latest experiment involves removing the WAIT code in SoftwareSerial::rxRead(). This, of course, makes the data read garbage, but it also cures the crashes.

My hyphothesis is that something in the WAIT function is causing the device to go into a long loop (or lock) such that the hardware watchdog steps in and reboots the device.

Any ideas?

My code is long and mostly irrelevant, but it is available here:

https://github.com/eykamp/birdhouse/blob/master/firmware/firmware.ino

Adafruit_ILI9341 library breaks SoftwareSerial

Using SoftwareSerial without the Adafruit_ILI9341 library and SoftwareSerial works as it should. As soon as I've included the Adafruit_ILI9341 library SoftwareSerial just does't respond / work at all. As soon as I call begin() on the Adafruit_ILI9341, SoftwareSerial just isn't working.

This is on the RX side, I haven't had chance to see if TX still works.

why GPIO 9 and GPIO 10 can not be used for software serial

Hi, I tried this lib for nodemcu v1.0 which is based on esp8266-12e, it working well for most of GPIO, but when I use GPIO 9 and GPIO 10, it stop working, I checked your code, GPIO9 and GPIO10 are not valid IO for soft serial, and I add the 9 and 10 in the code, it still can not working. I have test GPIO9 and GPIO 10, they could be used for I2C interface. This is really strange, do you happen to know why GPIO 9 and 10 can not be used for soft serial interface? Thanks.

Rename the library

Hi!

Please rename the library to prevent this type of error.

capturar

Best regards.

[BUGFIX] SoftwareSerial locks up when data is present during boot

If there is data present on an rx pin during startup, the ESP8266 locks up and eventually restarts.

I think this is caused by enableRx(true); on line 84. This is called before calling begin(9600); on line 94.
enableRx(true) starts the interupthandler for the rx pin, but m_bitTime has not been set yet! So m_bitTime will effectively be 0. This causes the WAIT to be very busy, hanging up the system.

If I comment out line 84, my ESP8266 starts up as expected when data is present on the rx pin. enableRx(true) will be called when begin(9600); on line 94 is called, so that doesn't change anything other than initalizing m_bitTime properly.

Using SoftwareSerial and other interrups

I tried to use SoftwareSerial along with attaching to one other interrupt, via attachInterrupt(5, xxx, CHANGE);
This results in rebooting the ESP.
Is it possible in general to use interrupts when using this module ?

No .listen() or .isListening()

Cannot use .listen() or .isListening() in an esp-12E project.

'class SoftwareSerial' has no member named 'listen'

Any clue to fix this?

Cannot get it to work at < 14400 baud

I have an old device that uses 300 baud and inverted logic on its serial interface. I would like to network it. The default Arduino SoftwareSerial for an UNO works fine at 300 baud. Using this library on my Sparkfun Thing dev board does not seem to work at anything less than 14400 baud. I a testing it with an OSEP FTDI board just connecting ground and TX/RX pins. This works at higher baud rates. Just nothing below 14400.

Have you tested this library at lower speeds? (I guess I'm just looking for hope.) Thanks.

SoftwareSerial buffer > 255 corrupts data

I am sorry, I placed this before here:
esp8266/Arduino#1234
But I now think that was not the right place?

I have a serial device that sends roughly 1200 bytes every 10 sec.
During waiting for that, other code needs to keep running, so I need to buffer it all and process it in one call. I then check every 15 sec to fetch all buffered data from the serial buffer.

Example with just a delay to fill the buffer, based on the SoftwareSerial example file:

include

SoftwareSerial swSer(14, 12, true, 250);

void setup() {
Serial.begin(115200);
swSer.begin(115200);
Serial.println("\nSoftware serial test started");

for (char ch = ' '; ch <= 'z'; ch++) {
swSer.write(ch);
}
swSer.println("");

}

void loop() {
delay(15000);
while (swSer.available() > 0) {
Serial.write(swSer.read());
}
while (Serial.available() > 0) {
swSer.write(Serial.read());
}
}

As long as I use SoftwareSerial swSer(14, 12, true, 250); all goes fine but I lose a lot of data.
(yes, I use inverted = true. that works fine, thank you for that!)
0-1:24.2.1(151217110000W)(00700.778*m3)
0-1:24.4.0(1)
!12C9

When going to a buffer of 260 or higher (need about 1200), data gets corrupted.
¡48224.2.1(151217110000W)(00700.778*m3)
0-1:24.4.0(1)
H&T¦Hø
E72

This is not just because of bad connection. I have tested many times with higher and lower.
Without the delay, nearly no corruption at all. So my data transfers are good.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.