STM32F103C8T6 and Arduino nano serial communication

I have a next code in in my Arduino nano:

#include <SoftwareSerial.h>

SoftwareSerial mySerial(2, 3);
void setup()
// Open serial communications and wait for port to open:
// set the data rate for the SoftwareSerial port
void loop() // run over and over
mySerial.write(“Software serial from Arduino Nano\n”);

If i connect the D2 and D3 to my TTL, i can read the message at 9600 baud, but if i connect the Tx->Rx and Rx->Tx to my STM32F103C8T6 (Blue pill) with a next code:

#include “stm32f103c8t6.h”
#include “mbed.h”
#include “USBSerial.h”
#include “Crypto.h”

int main() {
Serial pc(PA_2, PA_3);
Serial nano(PA_9, PA_10);
//AES data here

        printf("Nano is here!\n");
        char c[128];
        nano.gets(c, 4);
        pc.printf("I got c line: %s \n", c);
        pc.printf("Nano is unreadable\n");


On the PA_2, PA_3 is an USB TTL, that send some encrypted data to one PC. The PA_9 and PA10 are connected to Arduino Nano, and i wish to read the data from Nano on the BluePill with this UART, but i always receive that a Nano in unreadable. Have try to change the Tx-Rx wires, but nothing. Why will not work a simultaneous use of two serials?
The pc.printf function works like a charm, i can read it on my PC, but the STM32 can’t receive the data from the Nano.
I use the mbed online ide tool to compile for STM32 and the standard arduino IDE for work with a arduino.

I have tried your example with mbed-os5 and it works. The pinnames and pinmapping is the same, but it should also with mbed2.

to compile with mbed5, you can add a mbed_app.json to reduce the code size:

    "requires": ["bare-metal", "events"],
    "target_overrides": {
        "BLUEPILL_F103C8": {
            "target.c_lib": "small"

I don’t know if it works with onlince compiler, haven’t used it for long time. With mbed-cli, the Bluepill is a supported target.

I have also no problem to compile it, but the problem is the communicaton. Have You test it with arduino to send over serial to bluepill?

I have connected two USB-TTL converters and opened two terminal programs on the pc. One connected to the pc side, one to the nano side. I send one char on the nano terminal, then I get the ‘Nano is here!’ msg, after two more chars the ‘i got c line:’ is printed.

There is another uart3 on PB_10 / PB_11, maybe you can try this for the pc? PA_2 / PA_3 is also used for stdio, maybe it is locked? Although, I’m using a printf and pc.printf and both are working.

I will tomorrow search for one more TTL, i have now just one.
How can i check is my uart locked? How to unlock it?

@ JojoS
Can i please You to test it with the online tool to to compile?
Have now tested with my TTL, but still not work, not with PB10 11 nor with PA9 10.
I have no idea how to send a sensor data from Nano to BluePill on a efficient way, because UART is fast enough, but simply i can’t configure a monidirectional communication from Nano to BluePill over an UART.

I have tested now, i can can now read from the Nano, but the

returns that is not readable, even if a have readed the string.

Try using interrupt serial, here’s an example;

Otherwise you will loose some if not all your data traffic during that wait_ms(1000) function depending at what point the serial data comes in.

Also depending on whats contained in

//AES data here

You may need to use an interrupt serial ring buffer and filter start/stop positions.

I have read this example and try to implement it, but as i see, RawSerial don’t support gets()
How can i read a string, and not just a character with RawSerial?

You could do something like this to read a bunch of characters into a buffer.
The while(1) loops ends as soon as the ‘\n’ character comes in.

char buffer[128];
uint32_t i=0;
while(1) {
    if(nano.readable()) {
        buffer[i] = nano.getc();
        // break at this point, \n character means end of line
        // but you have to transmit that character!!

pc.printf("I got c line: %s \n", buffer);

You could use other end of line characters, for instance some devices will use the characters “OK” (the ESP8266 wi-fi module uses OK) so we need to look for two characters. Something this:

if (buffer[i-1] == 0x4f &&buffer[i] == 0x4b){break;}

But make sure the counter i does not go negative.

The Serial class is already marked deprecated and will be removed in mbed6. It would recommend to use the BufferedSerial, this contains already a buffer as Paul suggested.
I did not manage to compile an example with the online compiler, can you use the mbed-cli or MbedStudio? Using the Bluepill with MbedStudio is a little bit tricky, but it works also.

BufferSerial has a write() and read() function, as well as the readable()/writeable() members. And also async handling which would be even better. To use printf with BufferedSerial, it can be handled with posix like functions:

#include "mbed.h"

DigitalOut led1(LED1);
BufferedSerial ser(PA_9, PA_10, 115200);

int main() 
    printf("hello world\n");  // using STDIO_TX/RX PA_2/PA_3 on Bluepill

    FILE *f = fdopen(&ser, "w+");

    fprintf(f, "hello from ser\n");
    while(1) {
        led1 = !led1;

You can also have a look how the BufferedSerial class ist tested.
In mbed-os/TESTS/mbed_drivers/buffered_serial/main.cpp you find

static BufferedSerial buffered_serial_obj(

FileHandle *mbed::mbed_override_console(int fd)
return &buffered_serial_obj;

So after adding this code you might be able to use printf() as before!