Big STM32 boards topic

@bluejedi
Ok, I will. Thanks for the warning.
I switched over to the LMIC from matthijskooijman and with your modifications, of course it runs.

However, nothing is ever free in the Arduino world: Now, as soon as I add the os_init(); into my code, the u8g2-library stops working. I need to investigate further if I messed something up or if there is a real problem … or use a different library for the OLED.

Tom added some other changes related to STM32 deep sleep. These may be useful also for a HAL based core (but I have not looked at that yet).

I have the normal LMIC-Arduino library (with my above fix) running with BSFrance-stm32 with normally working OLED display using U8g2 on the LoRaM3-D boards.

I plan to post some complete samples that will work out of the box for several boards / MCU’s, including the LoRaM3-D boards (only the TTN related parameters need to be configured).

1 Like

@bluejedi
Very strange. I must be doing something wrong.
What pinmapping do you use then? Did you connect Pin 101 which I interpret as being DIO1?

I connect DIO1 to PB0. Yes the “IO” actually means “DIO” (little space for the text labels).

I use U8x8. SSD1306 hardware I2C constructor.
I only specify the reset pin (check U8g2/U8x8 docs for proper constructor syntax).
SCL and SDA are already defined in the board definition.

Please note BSFrance-stm32 currently has a bug in the F303 board definition. It specifies PB9 for SDA which must be PB7. So you must either specify SCL, SDA and Reset in the U8x8 constructor explicitly or fix the board definition.
Also note that the LED is ON when HIGH (current F151 and F103 board definitions incorrectly indicate that LOW is ON which is not true).

2 Likes

Wow. You are a genius! Not specifying the SDA and SCL Pins (leaving SDA, SCL in) did the trick.
I thought it does not matter as without the os_init() it worked like that:
U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=/ PB6, / data=/ PB7, / reset=*/ PB5);
But with it only works with:
U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=/ SCL, / data=/ SDA, / reset=*/ PB5);

U8g2 and U8x8 constructors

For the display on the BSFrance LoRaM3-D boards, the following U8g2 and U8x8 constructors can be used (they use hardware I2C).

Tip: Use default values / automatic configuration where possible.

For U8x8:

    // No need to specify SCL and SDA, the default values
    // are already defined in the board definition.
    U8X8_SSD1306_128X64_NONAME_HW_I2C display(/*reset*/ PB5); 

    // This is in fact identical to the above.
    U8X8_SSD1306_128X64_NONAME_HW_I2C display(/*reset*/ PB5, /*clock*/ SCL, /*data*/ SDA);

    // Same as above but explicitly specifies the GPIO ports to use for SCL and SDA.
    U8X8_SSD1306_128X64_NONAME_HW_I2C display(/*reset*/ PB5, /*clock*/ PB6, /*data*/ PB7);

For U8g2 (using full buffer):

    // No need to specify SCL and SDA, the default values
    // are already defined in the board definition.
    U8G2_SSD1306_128X64_NONAME_F_HW_I2C display(U8G2_R0, /*reset*/ PB5);

    // This is in fact identical to the above.
    U8G2_SSD1306_128X64_NONAME_F_HW_I2C display(U8G2_R0, /*reset*/ PB5, /*clock*/ SCL, /*data*/ SDA);

    // Same as above but explicitly specifies the GPIO ports to use for SCL and SDA.
    U8G2_SSD1306_128X64_NONAME_F_HW_I2C display(U8G2_R0, /*reset*/ PB5, /*clock*/ PB6, /*data*/ PB7);

Have you tried the constructors described in above U8g2/U8x8 constructors post? These constructors should all work (tested on F103).

I have no access to my F103 the coming week but I will try and post the result. SW I2C worked but HW would be better, obviously.

Hello,
I have bought 2 BSFrance L151 board to use with Lora, but can’t manage to retrieve the battery voltage on pin PA1. I saw some of you have this board, did you manage to retrieve it?
Thanks for the help,

What do you mean with “can’t manage to retrieve the battery voltage”, does it only return 0?

I tried int value = analogRead(PA1); which should work but it only returns 0.
(Is this a BSFrance-stm32 core issue?)

While searching for a solution I noticed the following:

  • STM32L151 ADC’s are 12-bit but the BSFrance-stm32 core appears to use only 10-bit resolution.
  • On a different Arduino Core (‘Maple’, not for LoRaM3-D) a port must explicitly be set for analog input with pinMode(pin, INPUT_ANALOG) but this does not work with the BSFrance-stm32 core.

FYI:
PA1 is connected via a voltage divider: a 100k resistor to Battery Plus (BAT+) and a 100k resistor to ground. So the voltage on PA1 is only 50% of the battery voltage.

With no battery connected I measure 4.1V on BAT+ (and 2V on PA1).

LoRaM3-D%20L151%20custom%20wire%20DIO1%20PB0%20690x397

LoRaM3-D L151. Added a wire from DIO1 to PB0 so that DIO1 is permanently wired.
(Only DIO0 is wired on the board but LMIC requires both DIO0 and DIO1.)
On the bottom side to keep the display side free from wires.

3 Likes

Can’t edit above post anymore so I do it here:
Forget the remark ‘aka stm32duino’ because it is incorrect and confusing.

Arduino cores for STM32 (and naming confusion)

Forum

There is a special forum for Arduino and STM32: Arduino for STM32
“Everything relating to using STM32 boards with the Arduino IDE”.
This forum also hosts dedicated sections for specific Arduino cores.
See: http://www.stm32duino.com/

Arduino and cores

Arduino is a popular open source hardware and software ecosystem for developing microcontroller applications. It was originally developed for educational purposes.
The Arduino ecosystem consists of a runtime with standard API’s for running applications, an integrated development environment called the Arduino IDE that includes compilers (C/C++), tools for uploading and libraries.
The source code of an Arduino application is called a sketch. The sketch, software libraries and the Arduino runtime are all compiled into a single binary file that is then uploaded to the microcontroller board.
The Arduino core in principle is the Arduino framework runtime code that is required to run an Arduino application. Originally Arduino only supported 8-bit AVR microcontrollers but when it was ported to other microcontroller platforms like ARM Cortex M (SAMD21 and STM32), ESP8266 and ESP32, that also required different compilers and tools. Therefore the term Arduino core now not only refers to the runtime, but also to the compilers, tools, libraries, board definitions etc., that are required for a specific microcontroller (family).
Cores can be provided by microcontroller manufacturers, by board manufacturers, by individuals or by a community. Cores are installed via the Arduino IDE Boards Manager (when supported) or can be installed from files from the core’s Github repository.

Arduino cores for STM32

There are several Arduino cores available for the STM32 family of microcontrollers. The most relevant ones are described below. Compatibility and supported features of these cores can be different so they are not fully compatible. Ech core supports a limited set of boards. Some boards (e.g. bluepill) are supported by multiple cores while others (e.g. LoRaM3-D) are only supported by a single core.

Arduino STM32

Roger Clark’s popular Arduino STM32 core is a derivative of libmaple (GitHub - leaflabs/libmaple: [INACTIVE] C and C++ library for STM32 ARM Cortex-M3 development boards.) which was first developed by LeafLabs for their Maple and Maple mini boards. LibMaple and hence Arduino STM32 only supports the STM32F103 series of microcontrollers. This core directly accesses the hardware registers and is therefore difficult to port to other microcontrollers from the STM32 family. This is one of the older and more mature cores.
This core can be installed either using the files from github or via a Boards Manager package.
See: https://github.com/rogerclarkmelbourne/Arduino_STM32

In the Arduino Boards Manager this core is listed as “STM32F1xx/GD32F1xx boards by stm32duino”.
In the Tools/Board dropdown its supported boards are listed under “STM32 Boards (STM32duino.com)”.

Bootloader:
Roger Clark also developed a special bootloader known as the STM32duino bootloader. It is available for different STM32 F103 based boards and supports automatic uploading from sketches via USB. GitHub - rogerclarkmelbourne/STM32duino-bootloader: Bootloader for STM32F103 boards, for use with the Arduino_STM32 repo and the Arduino IDE

Arduino Core STM32

STM have produced an Arduino Core, which now supports multiple microcontrollers from the STM32 family of products. The core is based on the STM HAL, which makes it easier to support and port to other members of the STM32 family. This core is relatively new but it is at least supported by ST-Microelectronics, the manufacturer of the STM32. For the STM32F103 series the USB DFU upload method is not supported.
This core can be installed either using the files from github or via a Boards Manager package.
See: https://github.com/stmduino/Arduino_Core_STM32
The term stm32duino is already used by Roger’s ‘Arduino STM32’ core and bootloader so using stm32duino as the Github user name and location for the repository of the completely different ‘Arduino Core STM32’ core is unsmart and utterly confusing (unless the other STM32 cores would also be hosted under the stm32duino Github account, but that probably isn’t going to happen).

In the Arduino Boards Manager this core is listed as “STM32 Cores by ST-Microelectronics”.
In the Tools/Board dropdown its supported boards are listed under “STM32 Boards (selected from submenu)”.

STM32GENERIC

‘A generic implementation of Arduino for STM32 boards’. This core (developed by Daniel Fekete) also uses the STM HAL, but the structure and architecture of the core differs from STM’s implementation.

There is no Boards Manager package for this core so it has to be manually installed using the files from github. See: https://github.com/danieleff/STM32GENERIC and https://danieleff.github.io/STM32GENERIC/

In the Tools/Board dropdown its supported boards are listed under “STM32GENERIC for STM32 boards”.

BSFrance-stm32

This core from BSFrance is specific for their LoRaM3-D boards. This core is also based on the STM HAL and it appears to be based on a fork of STM32GENERIC.

There is no Boards Manager package for this core (yet) so it has to be manually installed using the files from github. See: https://github.com/BSFrance/BSFrance-stm32

In the Tools/Board dropdown its supported boards (currently) are listed under “STM32(HALMX & LL)”.

PlatformIO support

I haven’t had a good look at Arduino + STM32 support in PlatformIO yet, but there is support for it.
PlatformIO shows ‘ST STM32’ as a supported platform with ‘framework-arduinoststm32’ as an available package, but it is not clear which of the above Arduino cores for STM32 are supported.
At least Roger’s ‘Arduino STM32’ core appears supported because I have an LMIC LoRa example working in PlatformIO with the ‘bluepill’ board using the USB DFU upload method. (The BSFrance-stm32 core is not currently supported in PlatformIO.)

3 Likes

Hi bluejedi and thanks for your answer.
I indeed try to do a simple:

vbat = analogRead(PA1);

which returned 0. Also tried with pinMode(PA1, INPUT_ANALOG) which led to a compilation error
And also tried to use adc_read, which was not recognized neither.
I measured half of my lipo voltage on the Vbat pin (1.9V), on both my boards so problem should be on the software / library side.

I looked at the ADC part of the library (BSFrance-stm32/stm32/cores/arduino/stm32/stm32_ADC.c at master · BSFrance/BSFrance-stm32 · GitHub), and tried to force resolution to 12bits, and to force ADC enable with

__HAL_RCC_ADC1_CLK_ENABLE();

But in the end, I still cannot read the value of it.
Any idea ?

No, waiting on response from BSFrance. I suspect it could be an issue in their core.

Ok. Keep in the loop when you get the solution :wink:
Thanks !

When you try exactly this:

int analogValue = analogRead(PA1);

Does this return 0 for analogValue, or was the 0 maybe the result from calculating the actual voltage?
(I had this problem somewhere during my testing.)

I have it working now, but I have tried and tested so many things that I do not remember what exactly fixed it.
I have first done some tests with a bluepill board because that allowed me to test with different cores: ‘Arduino STM32’, ‘Arduino Core STM32’ and STM32GENERIC.

On the bluepill I used PA1 for the measurements and added a 2x100k voltage divider, similar to the LoRaM3-D boards.
Arduino STM32 on bluepill worked. It uses the full 12-bit ADC resolution (max value: 4093).
Arduino Core STM32 on bluepill also worked but uses only 10 bits resolution (max value 1023), it’s readings were around 10% too low.
STM32GENERIC failed to compile without errors when I included #include <U8x8lib.h> so I didn’t bother to try it any further.

It now also works with BSFrance-stm32 and a LoRaM3-D F103 board. BSFrance-stm32 also uses only 10-bit ADC resolution.

With no battery connected and powered via USB (from computer) the multimeter measured a constant 2.007V on PA1, but analog read reported values fluctuating between 507 and 600+ (around 1.64 to 1.95V).
When battery connected (LiPo) to the battery connector and no USB connected, the multimeter measured a constant 1.864V on Pa1 and analog read is more stable, reporting values between 539 and 542 (1.74 to 1.75V).

#define ANALOG_MAX_VALUE 1023    // 1023 for 10-bit resolution, 4093 for 12-bit resolution
int analogValue = analogRead(PA1);
float voltage = analogValue * (3.3 / ANALOG_MAX_VALUE);

@bluejedi
OK, it is a bit late as the section moved forward to other topics, but I can confirm that HW I2C works as you describe on my F103.

1 Like

Hi
New challenge that I am facing today: Get a Waveshare e-Paper (1.54") running on the F103.
Yes, I know there is an OLED so what do I need a ePaper for … :wink:
And yes, could even be off-topic because it has not specifically to do with the radio part.

Thing is: With the Radio-module sitting on SPI, I am not sure if it is me, the library … why it won’t work.
And I always struggle with SPI, I2C seems to be easier to handle. Less wires maybe.

The soonuse-library https://github.com/soonuse/epd-library-arduino looked promising, simple and straight forward, so I gave it a try. Starting with the Pin description:
3.3V --> 3V3
GND --> GND
DIN --> D11
CLK --> D13
CS --> D10
DC --> D9
RST --> D8
BUSY --> D7

… it is easy to change some in the epdif.h.
like that:
#define RST_PIN PA8
#define DC_PIN PA0
#define CS_PIN PB14
#define BUSY_PIN PB9

These should be free to choose except DIN (MOSI) and CLK (SCLK)
I am not sure if I can share it with the SPI radio pins (PA7, PA5) or not.
Code stops at epd.Init() and I have no real clue where to look next.
If I need to use SPI2 (PB15, PB13) I have no idea how to do that.

Anybody experience with the epapers?

1 Like

OK, as edit is no longer possible, I will do a reply to my own question…

  • SOLVED -

I moved over to the library: https://github.com/ZinggJM/GxEPD
I had a bit trouble finding the parts and Pins and all, but it runs sharing SPI between the LoRa-Radio and the ePaper.
As there is only a suggested Pinout for STM32F103s but not the BSFrance-Board, I chose the following:

#include <GxEPD.h>
#include <GxGDEW0154Z04/GxGDEW0154Z04.cpp>  // The waveshare 1.54" black/white/red 200x200
#include <GxIO/GxIO_SPI/GxIO_SPI.cpp>
#include <GxIO/GxIO.cpp>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306_STM32.h>

GxIO_Class io(SPI, /*CS=*/ PA4, /*DC=*/ PB12, /*RST=*/ PB1);
GxEPD_Class display(io, /*RST=*/ PB1, /*BUSY=*/ PA8);
//CLK=PA5; DIN=PA7

No changes are necessary in the libraries, just in the code to use it.

Btw, regarding I2C:
Sharing the Pins for SDA: PB7 and SCL: PB6 with some other I2C devices also works fine (as should). However I noticed one case (a MOD-1023 from embedded adventures) where u8g2 seemingly interfered sometimes with the data transmission (I have no clue why and how).
Interestingly, the problem went away when using the Adafruit GFX library which I now also use for the OLED (and which is used on the ePaper by GxEPD.) Having two instances run is no problem. Though I like u8g2 over Adafruit’s Lib for it’s fonts I was not able to resolve the problem with the scrambled data.

Maybe this might help somebody in the future.

3 Likes

@GrumpyOldPizza

Contunued from here: Murata CMWX1ZZABZ-xxx LoRaWAN Module Breakout Board - #17 by GrumpyOldPizza

With all respect, what docs? :wink:
The code doesn’t contain any (and the LoRaWAN library code is rather cryptic).
Adding some documentation to the code and adding a description of the library will increase it’s usability for others tenfold.

I tried the included basic examples TTN_OTAA.ino and TTN_ABP.ino using #define REGION_EU868 (on a B-L072Z-LRWAN1 board).
Unfortunately I directly ran into several issues:

  • TTN_ABP.ino
    The examples use LoRaWAN keys/id’s in string format.
    The only (byte array) string format that TTN Console uses is msb-first format.
    (The TTN Console supports both msb-first and lsb-first formats only for the array initializer notation with brackets.)
    Unfortunately the TTN_ABP example expects the devAddr string variable to be in lsb-first format which is not consistent with the format that TTN Console provides and neither is it documented that devAddr requires lsb-format instead of msb-format. nwkSKey and appSKey use msb-first format, like presented on the TTN Console, but again information about the required format is missing.

  • TTN_OTAA.ino
    Different from TTN_ABP.ino, TTN_OTAA.ino expects all LoRaWAN keys/id’s in msb-first format.
    That is at least the only way where I can get a JOIN ACCEPT on a JOIN request.
    I tried devEui, appEui and appKey in different msb-first / lsb-first combinations but only when all were msb-first did I actually see JOIN ACCEPT’s on the gateway and application consoles.
    But then it stops. The JOIN ACCEPT is not followed up by an upstream message from the node. I see no data arriving.
    What can this be? Why doesn’t the node send any data messages?

  • Both the OTAA and ABP examples start communication at SF12 instead of the usual SF7.
    The examples do not specify a spreading factor so SF12 appears to be the default.
    I think the default should be SF7.
    Where can the spreading factor be specified?

1 Like