8 years, 2 months ago.

Usage of (Buffered)SoftSerial

Hi,

i would like to use some gpio pins for serial communication and i found the mbed libraries mentioned in the title. The SoftSerial lib found here https://developer.mbed.org/users/Sissors/code/SoftSerial/ mentions "Software serial, for when you are out of serial pins" and if i understand it right, this is exactly my case. I do not have any serial pins free thats why i wanted to use general gpio pins for serial communication (hence emulate the serial communication through the gpio pins)

Here is what i have tested so far

the working code without (Buffered)SoftSerial

#include "mbed.h"
#include <string>

Serial pc(SERIAL_TX, SERIAL_RX);

Serial gprs_AsSerial(PA_9, PA_10);          //line X1: this pins are normal tx, rx pins on stm32f401RE and work fine
//Serial gprs_AsSerial(PC_1, PC_0);         //line X2: this pins are gpio pins and if i uncomment this line i get "pinmap not found for peripheral"
//SoftSerial gprs_AsSerial(PC_1, PC_0);  //line X3: no error but also no response from gprs
Timer timeCnt;
int timeout = 1;

void showResponse() {
	std::string buffer = "";
	timeCnt.start();

	while(1) {
		if(gprs_AsSerial.readable()) {
			char newChar = gprs_AsSerial.getc();
			buffer += newChar;
		}
		if(timeCnt.read() > timeout) {
			timeCnt.stop();
			timeCnt.reset();
			break;
		}
	}
	timeCnt.stop();
	timeCnt.reset();

	while(gprs_AsSerial.readable()) {
		char c = gprs_AsSerial.getc();
	}

	pc.printf("received: %s\n", buffer.c_str());

}

int main() {
	gprs_AsSerial.baud(115200);

	pc.printf("started\n");
	gprs_AsSerial.puts("ATE0\r\n");	//shut down echo
	showResponse();

	pc.puts("Sending AT...\n");
	gprs_AsSerial.puts("AT\r\n");
	showResponse();

	pc.puts("Sending AT+CPIN?...\n");
	gprs_AsSerial.puts("AT+CPIN?\r\n");
	showResponse();

	pc.puts("Finished\n");
}

if i use line X1 the output is correct:

started
received: 
OK

Sending AT...
received: 
OK

Sending AT+CPIN?...
received: 
+CPIN: READY

OK

Finished

if i use line X2 the output is also correct since those pins are not normal tx, rx pins:

pinmap not found for peripheral

if i use line X3 the output is:

started
received: 
Sending AT...
received: 
Sending AT+CPIN?...
received: 
Finished

And of course when using the different lines i also made sure that the right pins are connected to the gprs device.

My question is: have i understood something wrong in using those libs? If the libs are not for that purpose how can i achieve that on mbed?

2 Answers

8 years, 2 months ago.

The SoftSerial library is indeed used on gpio pins to add more serial ports, so in theory you are using it correctly, but I'm unsure of consequence to performance as it has to manage all the timing on the mcu. 115200baud may be too fast depending on your microcontroller, do you have a way of testing what is being output on the softserial pins? such as connecting them to your computer or another microcontroller? Also the gpio pin you choose as the rx pin needs to work with interrupts.

Accepted Answer

Thnx Chris, i tested it with 9600 and worked ok

posted by anteo c 14 Sep 2016
8 years, 2 months ago.

I see I was a bit limited on the documentation there :P.

But yeah, Chris Pepper is most likely correct, your speed is quite high for a software serial, especially since it is interrupt based. The advantage of that is that it is non-blocking when active, the disadvantage is that the maximum speed is a bit lower. In general my advice is to only use SoftSerial on your lowest speed connection, for the other use regular Serial.

115200 via a software serial is definately possible. However with a library build on top of the standard mbed libraries it would be quite a challenge ;). For example it uses a (modified) Ticker, which has 1us resolution. Yet the bit time for 115200 baudrate is 8.68us, so there is already a problem.

Thanks Erik for the clear explanation. I think it would not be bad to add this in the documentation of the lib ;)

posted by anteo c 14 Sep 2016