[EN] Arduino: SoftwareSerial with STM32F030F4

From the article recommending the use of the board STM32F030F4P6 that uses serial communication with the use of additional libraries that do not have enough memory. So we try to use SoftwareSerial of Arduino framework and use pins PA10 and PA9 to connect to RX and TX of USB-RS232 Converter Module as shown in Figure 1 and try to use it according to the settings of Arduino IDE as shown in Figure 2 and order toggle LED connected to pin PA4 found that when compiling the sample program is used, the ROM and RAM usage are 80% and 21% respectively as reported by the Arduino IDE as follows.

Sketch uses 13188 bytes (80%) of program storage space. Maximum is 16384 bytes.
Global variables use 876 bytes (21%) of dynamic memory, leaving 3220 bytes for local variables. Maximum is 4096 bytes.
Figure 1 STM32F030F4P6 with CH340E module
Figure 2 Arduino IDE setting


  1. STM32F030F4P6
  2. RS232 module, we use CH340E with CH340 chip to convert USB signal TO TTL
  3. 4 wires

The connection between the microcontroller board and the CH340E module is as follows.

  1. 3V3 pin of the board connected to 3V3 of CH340E module or 5V Pin of the board connected to 5V of CH340E module.
  2. GND of both board connected with each other
  3. PA9 of microcontroller connected to RX of CH340E
  4. PA10 of ST32F030F4P6 connected to TX of CH340E

or connect to pin in the RS232 of the microcontroller board

  1. 3V3 of the board connected to 3V3 of RS232 module
  2. GND of the board connected to GND of CH340E
  3. TX of the board connected to RX of RS232 module
  4. RX of the board connected to TX of CH340E module


SoftwareSerial class is a class for serial communication with software libraries. 64 bytes of RAM is used as a buffer as well as specifying the pin for acting as TX and RX with a maximum communication speed of 115200bps

The invocation must import the header file SoftwareSerial.h as in the coding format as follows:

#include <SoftwareSerial.h>

Commands for creating objects of type SoftwareSerial, the duty of the pin for RX and TX must be configured as follows.

SoftwareSerial obj( RX, TX )

For other commands, see the article Arduino: Serial Class. SoftwareSerial inherited from the Serial class of the Arduino framework, it is possible to use methods or commands as well.

Example Code

Example program for setting communication rate 9600bps to send Hi message every 1 second and to flash LED on STM32F030F4P6 every 500ms can be written as follows

#include <SoftwareSerial.h>

#define PIN_LED PA4
SoftwareSerial mySerial(PA10, PA9); // RX, TX

void setup() {
  pinMode( PIN_LED, OUTPUT );

void loop() {
  digitalWrite( PIN_LED, HIGH );
  digitalWrite( PIN_LED, LOW );

From the code, the program has created an object named mySerial that sets pin PA10 to act as RX and PA9 as the pin for the receiver or TX inherited from the class SoftwareSerial. After that in setup(), the communication speed is specified as 9600 and the important thing is readers must enable UART but do not select no seneric “serial” as shown in Figure 2, because if disabled it will result in the inability to use serial classes. If using generic serial it will enable HW to run (then It won’t work … don’t be confused …)

The loop() function is divided into two parts:

  1. Send Hi to mySerial
  2. Flashing the LED that is connected to Pin PA4 which is already included with the microcontroller board by sending HIGH and waiting for 500 milliseconds, followed by LOW and waiting for another 500 milliseconds.

The next example is to convert prime numbers to use with SoftwareSerial. Found that if compiling with -Os to save ROM space but was the slowest speed with -O1, -O2 and O3 for maximum running speed but file size larger than the first. The result is as follows

  1. The -Os type consumes 13560 and 888 bytes of ROM and RAM, while the performance is 432 milliseconds.
  2. Type -O1 uses 15708 and 888 bytes of ROM and RAM, with a prime time of 412 milliseconds.
  3. The -O2 type uses 15192 and 888 bytes of ROM and RAM, taking 402 milliseconds.
  4. The -O3 part cannot be compiled due to insufficient ROM space.
#include <math.h>
#include <SoftwareSerial.h>

SoftwareSerial mySerial(PA10, PA9);
#define PIN_LED PA4

bool isPrimeNumber(uint16_t x) {
  uint16_t i;
  for (i = 2; i < x; i++) {
    if (x % i == 0) {
      return false;
  if (i == x)
    return true;
  return false;

int counter = 0;
uint32_t t0, t1;

void testPrimeNumber(uint16_t maxN) {
  t0 = millis();
  for (uint16_t n = 2; n < maxN; n++) {
    if (isPrimeNumber(n)) {
  t1 = millis();

void setup(void)
  pinMode( PIN_LED, OUTPUT );
  mySerial.print("Found ");
  mySerial.print(counter, DEC);
  mySerial.print(" in ");
  mySerial.print(int(fabs(t1 - t0)), DEC);
  mySerial.println(" milliseconds.");
void loop(void)
  digitalWrite( PIN_LED, HIGH );
  digitalWrite( PIN_LED, LOW );

From example 2, -Os is the best choice, and -O1 makes it faster but the amount of ROM is used more which must see if there is a lot of code running.


From this article, you will find that when using SoftwareSerial, the use of STM32F030F4P6 for serial communication is more convenient, or using other pins as additional communication pins would be done as well. For example, to increase communication with ESP32/ESP8266 to 2 pins and another 2 pins for GPS, etc., allowing our system to connect to WiFi and use GPS at the same time. Finally, have fun with programming.

(C) 2020-2022, By Jarut Busarathid and Danai Jedsadathitikul
Updated 2022-02-22

Leave a Reply

Your email address will not be published. Required fields are marked *