Teensy3.1 had already faced this delima here: https://forum.pjrc.com/threads/17461-So … 3-it-seems
I took Paul’s changes and adapted it to the Maple STM32. This was a quick hack, but I can run the Adafruit GPS code on the Maple Mini without issues from SoftwareSerial. I have attached the .h and .cpp files that compile; additional modifications may be required for other 3rd party libraries.
The final bench project is here: http://www.hackster.io/rayburne/color-b … time-clock
Ray

I’m currently found a mess on (arduino) sketches or libs including this “SW serial” and it was annoying to eliminate those lines from every sketch!
thank you!
One question. I noticed you are using .\ instead of ./ for your #includes ..
... much deleted
-I/mnt/vbox/shared/Arduino_STM32_Sketch/hardware/Arduino_STM32/STM32F1/libraries/SPI/src -I/mnt/vbox/shared/Arduino_STM32_Sketch/hardware/Arduino_STM32/STM32F1/libraries/Wire /tmp/build2989123648752632366.tmp/Adafruit_GPS.cpp -o /tmp/build2989123648752632366.tmp/Adafruit_GPS.cpp.o
/tmp/build2989123648752632366.tmp/Adafruit_GPS.cpp:6:28: fatal error: .\Adafruit_GPS.h: No such file or directory
#include ".\Adafruit_GPS.h"
^
compilation terminated.
Error compiling.
Could also be useful for STM32 as you can do any baud rate then
See discussion – http://forum.arduino.cc/index.php?topic=138497.0 –
I don’t see any point in doing true software serial with the number of hardware ports on the board, apart from you can’t specify the pins you want to use.
At least stuff would compile.
Ray, so you have an example of a class that inherits from SoftwareSerial that we could look at ?
I don’t see any point in doing true software serial with the number of hardware ports on the board, apart from you can’t specify the pins you want to use.
At least stuff would compile.
Ray, so you have an example of a class that inherits from SoftwareSerial that we could look at ?
It looks like you are just passing a pointer to the Serial class, (actually a pointer to an instance of the HardwareSerial class), rather than using a library that inherits from Software Serial
What we have at the moment works fine for this, doesn’t it ?
It looks like you are just passing a pointer to the Serial class, (actually a pointer to an instance of the HardwareSerial class), rather than using a library that inherits from Software Serial
What we have at the moment works fine for this, doesn’t it ?
That sounds like a good solution
I like the way it switches port based on pin selection.
Though you would need to know that’s what it’s doing, but at least it returns null if you specify a pin it can’t use
Anyhow, before I dive in, has anyone ported a software serial to STM32 yet? The simple modification mentioned in this thread obviously won’t work for my application since I need the equivalent of 5 independent serial ports to get all the outputs I need.
Thanks!
Software serial could be handy, especially if it will operate at low speeds e.g. 1200 baud, as I recall someone else having issues on low speeds because it was not possible to set the serial clock dividers to a value that would give really low baud rates
Re: Folder organisation
Its got bloated over time.
I think I could ditch the F3 stuff, no one is using it at all.
I did think of having everything core as a separate sub module on GitHub, but I’ve realised that GitHub doesnt automatically put submodules in the zip file
So I now think that it would be better to use the GitHub “Releases” system to script up individual downloads eg. for the F1 and for the GD32 etc separately, and probably do a Boards Manager package
When I have time…
I thought I did… for the Adafruit GPS lib stuff…
I need to check.
Ray
Yes,
Originally posted here:
http://www.stm32duino.com/viewtopic.php?t=6
The lesson to learn here is that this forum is now large enough that a Google search by site is highly recommended before asking a question… even those of us here since the dark ages cannot remember everything. If you do notknow how to search Google by site, just ask Google.
It is downloadable from here: https://www.hackster.io/rayburne/color- … time-clock
the STM32 Maple Mini board and microcontroller. The current directory name is GPS_Time_Baro
Untitled file
/*Please review License.h tab for use/rights information regarding included libraries
GPS_Time_Baro based on original sketch by M. Ray Burnette 3/02/2014
Arduino 1.6.1 - Maple Mini Port STM32F103 by Ray Burnette 3/09/2015 PUBLIC DOMAIN by Author
Sketch uses 46,360 bytes (42%) of program storage space. Maximum is 108,000 bytes.
Global variables use 5,752 bytes of dynamic memory.
*/
#include <SPI.h> // \Documents\Arduino\hardware\STM32\STM32F1\libraries\SPI
#include <Wire.h> // I2C \Documents\Arduino\hardware\STM32\STM32F1\libraries\Wire (legacy)
#include <Streaming.h> // \Documents\Arduino\libraries\Streaming (legacy)
#include ".\BMP085.h" // #include "I2Cdev.h" is pulled in also
#include ".\Adafruit_GPS.h"
#include ".\Adafruit_GFX.h"
#include ".\Adafruit_ILI9341.h"
#include ".\SoftwareSerial.h" // faux version only for STM32 Maple
#include ".\Utilities.h"
I thought I did… for the Adafruit GPS lib stuff…
I need to check.
Ray
Yes,
Originally posted here:
http://www.stm32duino.com/viewtopic.php?t=6
The lesson to learn here is that this forum is now large enough that a Google search by site is highly recommended before asking a question… even those of us here since the dark ages cannot remember everything. If you do notknow how to search Google by site, just ask Google.
I have never seen that before. Its a shame that people write libraries like this and publish them, but dont tell anyone.
there are a lot of side projects, and I dont seem to be able to remember them all
There is some kind of problem with this library. It seems that it relay on the cpu cycles or whatever. Sometimes it is working and sometimes not. Sometimes it is enough to add 1 line to the code in main loop and sometimes a delay need to be added. For example this code is working:
#include <SoftSerialSTM32.h>
#include <string.h>
#include <SPI.h>
#define SIM800_TX_PIN PC14
#define SIM800_RX_PIN PC15
SoftSerialSTM32 mySerial(SIM800_RX_PIN, SIM800_TX_PIN);
#define RFID_TX_PIN PA4
#define RFID_RX_PIN PA5
SoftSerialSTM32 mySerialRFID(RFID_RX_PIN, RFID_TX_PIN);
int x = 100;
void setup() {
Serial.begin(115200);
mySerial.begin(9600);
//mySerialRFID.begin(9600);
}
void loop() {
delay(x);
String strsim = "";
if (mySerial.available () > 0) {
strsim = mySerial.readStringUntil('\n');
Serial.print("SIM800L: ");
for (int xi=0; xi<strsim.length(); xi++) {
Serial.print(char(strsim[xi]));
}
Serial.print("\n");
}
String strser = "";
while (Serial.available () > 0) {
strser += char(Serial.read ());
}
if (strser != ""){
if (strser.startsWith("test")){ //check hw serial response
Serial.println("serial ok");
// } else if (strser.startsWith("D")){ //change delay
// strser.replace("\n","");
// strser.replace("\r","");
// strser.replace("D","");
// int outint = strser.toInt();
// x = outint;
// Serial.println("New delay: "+String(outint));
// mySerial.print("AT"); //send command after delay change and wait for answer
} else {
mySerial.print(strser); //send command
}
}
}

Why do you need to use software serial. There are plenty of hardware serial ports available.

BTW : Now I’m also using multiprocessors with I2C communication (trying to use as it can be seen in other thread) but this time in different way
http://www.stm32duino.com/viewtopic.php … ycle+delay
Although I’m sure using a timer would be a better approach if you really want more than 3 uarts. How many uarts do you actually need?
-rick
https://github.com/wingspinner/SoftSerialIntAP
or
https://github.com/wingspinner/SoftSerialIntCC/
... and someplace else I defined cycle_timer as dwt_timer and initialized it
inline void SoftSerialSTM32::tunedDelay(uint32_t delay) {
cycle_timer.delay_cycles(delay);
}
I could imagine the solution above using the dwt_timer maybe working. You could use software serial for devices that are output only. Devices that use a command response protocol where you send data and then wait for a response might also be OK. If you limit the hardware UARTs to those peripherals that send you unsolicited data, like say a user typing data in a terminal, it might all work.
-rick

BTW : Now I’m also using multiprocessors with I2C communication (trying to use as it can be seen in other thread) but this time in different way

#include <SoftSerialIntCC.h>
//#include <SoftSerialSTM32.h>
#define TX_PIN PC14
#define RX_PIN PC15
SoftSerialInt mySerial(RX_PIN, TX_PIN, 4);
//SoftSerialSTM32 mySerial(RX_PIN, TX_PIN);
unsigned long previousMillis = 0;
const long interval = 2000;
void setup() {
Serial.begin(115200);
mySerial.begin(9600);
}
void loop() {
unsigned long currentMillis = millis();
if (mySerial.available() > 0){
Serial.println(mySerial.readStringUntil('\n'));
}
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
mySerial.println("AT");
Serial.println("Sent");
}
}
If I use softserialSTM it is working while if I change to softserialCC it is not. I’ve tried all 4 timers. Where is the problem? Does it mean that I can use only those pins which has a timer attached to them and PWM option? Then It should work with UART 1 which I’ve tried and I also cannot get this working.
<…>?
<…>
Your best path to success is to start with a maple mini board. The original maple arduino core was written for the maple mini and its big brother. The configuration and most problems have been worked out by the people long before we ever arrived here. When there are problems with the maple mini, it is most likely your code. The stm32duino core started with the maple core code and was ported to Arduino 1.5.x. Along the way we might have created new problems however that is less likely with the maple mini than any other board that is supported.
If this is your first rodeo with an stm32, your first step should be to obtain a maple mini clone. Once you move to the next level of using a generic stm32 (bluepill/redpill any other board) you are going to be much more on your own. As a community we are hoping people will become subject matter experts on the things near and dear to their hearts and come here more to share how you fixed something than to ask for questions.
I find the software serial a somewhat interesting problem and it is why I’ve bothered to delve into the issues.
-rick
I find the software serial a somewhat interesting problem and it is why I’ve bothered to delve into the issues.
With 3 physical USARTS there is little need in the past. The current problem seems to be that one of Ron’s version does not support multi-instance – or the Op has had issues configuring a multi-instance, leaving one serial port short for the port.
I am having a difficult time with the port because every step appears to involve some critical issue to be solved and the Op is having to rely solely upon the forum since this is their first experience with the STM32. It appears from posts that the Op has a Maple Mini from Baite but also is using a Blue Pill which seems to be the final target. But precious little is being provided in the overall port process except on a Q/A piecemeal basis.
I want every STM32 project to be successful; extending that to even AVR and ESP8266.
Ray
With 3 physical USARTS there is little need in the past. The current problem seems to be that one of Ron’s version does not support multi-instance – or the Op has had issues configuring a multi-instance, leaving one serial port short for the port.
<…>
The examples provided by @RonC only work for some unknown board. To get this stuff to work with a bluepill or any other board you have to pick specific pins as I outlined in that longish post about the pin_map table. There doesn’t seem to be anything wrong with multiple instance as long as you are picking the right pins and timers.
This multi instance example works fine:
<…>
The code above works for me and shows you can use different instances and even different speeds without failing.
This SoftSerialIntCC timer based code actually works quite nicely. I looked at the pulses on a scope and the bit times are right on the money. However, this code does chew up a bunch of timers and timer channels (1,2, and 3). Making it work properly requires an understanding of the pin map table for your board and how timer capture / compare works on the STM32. Knowing where to look in stm32f103 datasheet is also important to make sure your pin map table is using the right timer and channel for each pin.
-rick
/*
TimerSerial.h - simple wrapper for SoftSerialIntCC.h
As SoftSerialIntCC only works on specific pins and timer combinations
this header declares the valid TimerxSerial pins that work on both the
bluepill and the maple_mini
The 'x' indicates which timer is being used. SoftSerialIntCC
uses 3 of the timer channels (1,2, and 3)
Channel 1 must be the tx pin
Channel 2 must be the rx pin,
Channel 3 is used for a timeout
Seeo:
https://github.com/wingspinner/SoftSerialIntCC/
*/
#ifndef _TIMERSERIAL_H_
#define _TIMERSERIAL_H_
#include <SoftSerialIntCC.h>
SoftSerialInt Timer1Serial(PA9, PA8, 1); // 26, 27 on maple mini
SoftSerialInt Timer2Serial(PA1, PA0, 2); // 10, 11 on maple mini
SoftSerialInt Timer3Serial(PA7, PA6, 3); // 4, 5 on maple mini
SoftSerialInt Timer4Serial(PB7, PB6, 4); // 15, 16 on maple mini
#endif


Its there and the location that says its not found the library has the library in there… Im a bit stumped.
Any ideas?
stephen

contents are
name=Adafruit GFX Library
version=1.1.5
author=Adafruit
maintainer=Adafruit <[email protected]>
sentence=Adafruit GFX graphics core library, this is the 'core' class that all our other graphics libraries derive from.
paragraph=Install this library in addition to the display library for your hardware.
category=Display
url=https://github.com/adafruit/Adafruit-GFX-Library
architectures=*
srp
It does not work correctly. The example showed a corner case where it did work. However if you try to test it the other way around where the other port are trying to receive data it does not work.
The platform I am using is a BluePill STM32F103 running at 72MHz.
In this example I have used a single hardware Uart (Serial 1) and one software UART. I have added LED on and off statements and a 100ms delay so that you can see when a character has been received by the respective UART.
The symptoms of this example is when the processor is reset, the initial start messages are correctly sent out of both Serial ports. When characters are typed on the terminal connected to the HW UART receive input, the character is echoed both to the terminal attached to the HW Uart and the Software Uart and the LED flashes appropriately indicating a character was received by the HW Uart.
When characters are typed on the terminal connected to the SW UART receive input, the character are NOT echoed to either terminal HOWEVER the LED flashes appropriately indicating a character was received by the SW Uart. My conclusion for this specific example is the timing for the SW read is broken.
#include "TimerSerial.h"
#define ConsoleSerial Serial1
#define StatusLed PC13
#define StatusLedOn digitalWrite(StatusLed, LOW)
#define StatusLedOff digitalWrite(StatusLed, HIGH)
void setup()
{
pinMode(StatusLed, OUTPUT);
ConsoleSerial.begin(57600);
// set the data rate for the SoftwareSerial port
Timer2Serial.begin(9600); // (PA1,PA0)
}
void loop() // run over and over
{
ConsoleSerial.println("");
ConsoleSerial.println("ConsoleSerial is active");
Timer2Serial.println("Timer2Serial is active");
while (1) {
if (ConsoleSerial.available()) {
digitalWrite(StatusLed, LOW);
int c = ConsoleSerial.read();
ConsoleSerial.write(c);
Timer2Serial.write(c);
delay(100);
digitalWrite(StatusLed, HIGH);
}
if (Timer2Serial.available()){
digitalWrite(StatusLed, LOW);
int c = Timer2Serial.read();
Timer2Serial.write(c);
ConsoleSerial.write(c);
delay(100);
digitalWrite(StatusLed, HIGH);
}
}
}
I also looped until I exhaust the available input instead of grabbing one character at a time from each. I’m assuming your real world usage of this will be a command send and then a response type of situation. Adjust for your case if it isn’t
#include "TimerSerial.h"
#define ConsoleSerial Serial
#define SlaveSerial Timer4Serial
#define StatusLed PC13
#define StatusLedOn digitalWrite(StatusLed, LOW)
#define StatusLedOff digitalWrite(StatusLed, HIGH)
void setup()
{
pinMode(StatusLed, OUTPUT);
ConsoleSerial.begin(115200);
// set the data rate for the SoftwareSerial port
SlaveSerial.begin(115200); // (PB7,PB6)
while(!ConsoleSerial.isConnected());
}
void loop() // run over and over
{
ConsoleSerial.println("");
ConsoleSerial.println("ConsoleSerial is active");
SlaveSerial.println("SlaveSerial is active");
while (1) {
if (ConsoleSerial.available()) {
//digitalWrite(StatusLed, LOW);
int c;
while((c = ConsoleSerial.read()) != -1 ) {
SlaveSerial.write(c&0xff);
ConsoleSerial.write(c&0xff);
}
//digitalWrite(StatusLed, HIGH);
}
if (SlaveSerial.available()){
digitalWrite(StatusLed, LOW);
int c;
while( (c=SlaveSerial.read()) != -1 ) {
//SlaveSerial.write(c);
ConsoleSerial.write(c);
}
digitalWrite(StatusLed, HIGH);
}
}
}
The testing was done by manually by slowing typing characters on the keyboard. There was no chance to overflow a buffer. The LED code and delay was added to flash a LED when a character was processed. This showed me a character was received from the receive logic. The reason I echoed the character was to specifically see if the echo character was the same as the transmitted character – it was not.
I found the code to be very flacky, sometimes it worked for a a few minutes, sometimes it failed quickly.