PlatformIO Community

Trouble with LORA and PingPong demo


#1

Hello everyone!

Just wanted to say a big congrats to the devs for such an amazing piece of software. I have tried it out on multiple boards and multiple frameworks and it is amazing!

As I get to know the software better, I have been reading the docs and testing out new things. Most of the time I manage to get it working again but this time I’m hoping to get some answers and some insight (on how I should tackle this problem going forward)

Basically, I am using an STM32 Nucleo board with the LORA SX1272 shield. I am using mbed.

I have installed the SX1272Lib library
I have copied the PingPong example supplied here https://os.mbed.com/teams/Semtech/code/SX1276PingPong/

I have made a new project with the PingPong code (in main.cpp / main.h)

I have added to platformio.ini lib_deps = SX1272Lib

1st. When I compile, I get errors about the debug function being already defined (in 2 areas):
/home/tb_t/.platformio/packages/framework-mbed/platform/mbed_debug.h
And
.piolibdeps/SX1272Lib_ID2756/debug/debug.h:56:20: note: 'void debug(const char*, ...)' previously defined here

How do I get rid of this error? I looked into src_filter but don’ t quite understand if that’ s applicable here, especially since these are just 2 libraries I installed from within PIO (can’t they both cohabitate?)

And 2nd. If I remove the debug.h (from SX1272 library, so mbed’s version should be used) it will complain about not being able to find a radio.h… Which is in the SX1272 library. I don’ t quite understand this error

Please help
Any help would be greatly appreciated!


#2

You have a SX1272 shield but use the SX1276 ping pong project instead of https://os.mbed.com/teams/Semtech/code/SX1272PingPong/ , is that right? What exact Nucleo board are you compiling for?


#3

Yeah there is a clash with mbedOS 5.8.2 functions from mbed_debug.h as defined here with additional but identical debug functions defined in Semtech’s debug.h in the SX1272 lib. Unfortunetly the debug.h header defines the prototypes of the functions no matter what macros are set (here).

You can get the project to compile by doing the following things:

Use the platformio.ini file:

[env:nucleo_l152re]
platform = ststm32
board = nucleo_l152re
framework = mbed
lib_deps = 
	mbed-rtos
	SX1272Lib
lib_ignore = 
	mbed-LWIP
	mbed-mbedtls
build_flags =
	-D PIO_FRAMEWORK_MBED_RTOS_PRESENT
	-I .piolibdeps/SX1272Lib_ID2756/radio
	-I .piolibdeps/SX1272Lib_ID2756/registers
	-I .piolibdeps/SX1272Lib_ID2756/sx1272
	-I .piolibdeps/SX1272Lib_ID2756/typedefs
	-I .piolibdeps/SX1272Lib_ID2756/debug

Your board may differ, but the important parts are that it includes the SX1272 lib, then ignores LWIP and mbedtls which PIO somehow thinks have to be included (but results in compilation error), and finally defines for fixing this and including the directories of the library which also somehow don’t get automatically added to the include path. This assumes that the SX1272 is installed in your project folder under .piolibdeps and not some global repository.

Use the main.cpp and main.h from here.

Modify the debug.h file of your SX1272 lib to be an empty file.

Then you should see

Dependency Graph
[05/06/18 10:44:11] Processing nucleo_l152re (platform: ststm32; board: nucleo_l152re; framework: mbed)
|-- <mbed-rtos> (C:\Users\Maxi\.platformio\packages\framework-mbed\rtos)
|-- <SX1272Lib> (C:\Users\Maxi\Documents\stackoverflow_testing\.piolibdeps\SX1272Lib_ID2756)
[...]
arm-none-eabi-ar rc .pioenvs\nucleo_l152re\lib5d0\libSX1272Lib_ID2756.a .pioenvs\nucleo_l152re\lib5d0\SX1272Lib_ID2756\radio\radio.o .pioenvs\nucleo_l152re\lib5d0\SX1272Lib_ID2756\sx1272\sx1272-hal.o .pioenvs\nucleo_l152re\lib5d0\SX1272Lib_ID2756\sx1272\sx1272.o
arm-none-eabi-ranlib .pioenvs\nucleo_l152re\lib5d0\libSX1272Lib_ID2756.a
arm-none-eabi-g++ -o .pioenvs\nucleo_l152re\firmware.elf -mcpu=cortex-m3 -mthumb -Wl,--gc-sections -Wl,--wrap,main -Wl,--wrap,_malloc_r -Wl,--wrap,_free_r -Wl,--wrap,_realloc_r -Wl,--wrap,_memalign_r -Wl,--wrap,_calloc_r -Wl,--wrap,exit -Wl,--wrap,atexit -Wl,-n -Wl,-T".pioenvs\nucleo_l152re\STM32L152XE.ld.link_script.ld" @"C:\Users\Maxi\Documents\stackoverflow_testing\.pioenvs\nucleo_l152re\longcmd-293bab093b121e5cafa557dcae476abb" -LC:\Users\Maxi\.platformio\platforms\ststm32\ldscripts -L.pioenvs\nucleo_l152re -Wl,--start-group .pioenvs\nucleo_l152re\lib5d0\libSX1272Lib_ID2756.a -lstdc++ -lsupc++ -lm -lc -lgcc -lnosys -lc -lstdc++ -Wl,--end-group
arm-none-eabi-size -B -d .pioenvs\nucleo_l152re\firmware.elf
arm-none-eabi-objcopy -O binary .pioenvs\nucleo_l152re\firmware.elf .pioenvs\nucleo_l152re\firmware.bin
text	   data	    bss	    dec	    hex	filename
44476	   2568	   8636	  55680	   d980	.pioenvs\nucleo_l152re\firmware.elf
 [SUCCESS] Took 31.86 seconds 

Since modifying libraries files isn’t that great you could just drop a copy of the SX1272Lib in the lib/ folder, give it a custom name and include that in lib_deps with adapter include flags. Then it would we re-producable across all systems.


Getting started modifying PIO build process, specifically around hacking platform build scripts
#4

Wow! Thanks for the very detailed response!

And Yes I was using the SX1272 Ping Pong code.

Thanks a lot for going through and detailing the necessary changes.
Yes the SX1272 is a local library.

It seems odd to me that PIO includes libraries that are not needed? And then omits some that are?
Is there a known bug in this functionality? (Especially in regards to using 2 libraries that are provided by the PIO library manager)

I am currently away from my setup, I should be able to try out these changes in the next couple of days, and I will post back my results!


#5

I finally got back to my setup (longer than expected!)

I ended up modifying my platformio.ini to look like yours (adapted to my board, I am using a nucleo_f103rb)

I got it to compile and it doesn’t seem to work :frowning: nothing is being sent out to console for debugging…

I got the following warnings while compiling though:

/home/tb_t/.platformio/packages/framework-mbed/targets/TARGET_STM/TARGET_STM32F1/serial_device.c:43:15: warning: inline function ‘get_uart_index’ declared but never defined
inline int8_t get_uart_index(UARTName uart_name);

And

.piolibdeps/SX1272Lib_ID2756/sx1272/sx1272-hal.cpp:187:10: warning: #warning “Check the board’s SPI frequency” [-Wcpp]
#warning “Check the board’s SPI frequency”
^~~~~~~
.piolibdeps/SX1272Lib_ID2756/sx1272/sx1272-hal.cpp: In member function ‘virtual void SX1272MB2xAS::SpiInit()’:
.piolibdeps/SX1272Lib_ID2756/sx1272/sx1272-hal.cpp:181:14: warning: unused variable ‘frequencyToSet’ [-Wunused-variable]
uint32_t frequencyToSet = 8000000;
^~~~~~~~~~~~~~

Could that have an effect?

I couldn’t believe that this didn’t work, so I went to the online mbed compiler, imported the same project (modified the debug.h file), compiled it and it ran perfectly on the boards I’m testing (debug and all!)

So it’s obviously a problem on the PC end of things, either my setup or the PIO way of doing things

Would you have any tips? I don’t seem to have much luck with mbed and PIO :confused:


#6

Could you please go to your PIO home folder (Windows: C:\Users\<Username>\.platformio, Linux/Mac ~/.platformio), go to the path .platformio\packages\framework-mbed\platformio\variants\NUCLEO_F103RB, open the NUCLEO_F103RB.json, delete the line "-DNDEBUG",, clean, recompile and re-upload again?


#7

Thanks for the reply.
I seem to be learning quite a few things about PIO and mbed with this example.

I got rid of DNDEBUG, got it compiled, uploaded and now it outputs

SX1272 Ping Pong Demo Application

Board Type: SX1272MB2xAS <

         > LORA Mode < 

Starting Ping-Pong loop

And then stops, I’ll have a look through it again to see if I can find anything else that could be blocking it


#8

Hm, at least we’re getting closer step-by-step.

Seems like it dies inside mbed_die with a fatal error (does the LED blink periodically?) or hangs in the radio initialization routines, possible at a SPI transfer. If you have a PIO Plus (trial), try debugging it stepwise [or follow my tutorial]. Also use a firmware with the added flag -ggdb to your build_flags for debug symbols.

Double check if the used connection pins for the constructor (https://os.mbed.com/teams/Semtech/code/SX1272Lib/file/b988b60083a1/sx1272/sx1272-hal.h/ Line 70 and https://os.mbed.com/teams/Semtech/code/SX1272Lib/file/b988b60083a1/sx1272/sx1272-hal.cpp/ Line 92) are correct for your board (which should be here [careful, upside down] and here)

I had a RFM95 radio attached to my Nucleo-L152 and got until a “RX Timeout”.


#9

Yep slowly getting there!

I just debugged it and it seems to be hanging on line 168
in the

switch( State) {

Statement.

The State variable is LOWPOWER
So it gets stuck in the while loop, as the switch case is
case LOWPOWER: break;

So it seems it could be a radio initialisation routine

I will check the pinouts.

(Thanks for the link for your debugging tutorial!)
I am currently using a modified launch.json to launch gdb and pipe it into OpenOCD from within PIO (it works with the frameworks: Arduino and STM32CUBE, and also MBED (but it seems to be a bit hit and miss with MBED, jumping back on lines at times or Stopping a few lines from the BP - I haven’t found out why yet… )


#10

This is due to optimization. Try build_unflags = -Os to remove the default -Os flag and add -O0 in build_flags to disable optimization. It should stop jumping around (and run slower). If -Os is still in the compiler output, go to that JSON file again where you deleted -DNDEBUG and kill the switches.


#11

Thanks! That fixed it!

Got the debugging working as expected. Now to continue with the Lora module and see if I can find something :slight_smile:


#12

Got it working!

Had checked all the pinouts and everything seemed ok (and checked some of the code over).
Went to test it again and surprisingly it was working now…

So I worked backwards to see what it was and found it was the -O0 that had fixed it!

So for anybody else wondering about the final platformio.ini I used, it’s:

[env:nucleo_f103rb]
platform = ststm32
board = nucleo_f103rb
framework = mbed
upload_protocol = stlink
lib_deps = 
	mbed-rtos
	SX1272Lib
lib_ignore = 
	mbed-LWIP
	mbed-mbedtls
build_flags =
	-D PIO_FRAMEWORK_MBED_RTOS_PRESENT
	-I .piolibdeps/SX1272Lib_ID2756/radio
	-I .piolibdeps/SX1272Lib_ID2756/registers
	-I .piolibdeps/SX1272Lib_ID2756/sx1272
	-I .piolibdeps/SX1272Lib_ID2756/typedefs
	-I .piolibdeps/SX1272Lib_ID2756/debug
	-O0

Thanks again for your help! It lead me down the right path and I learnt from your responses. :grinning:

Now this is working, it has jogged my memory on past MCU projects that were really affected by optimisation flags.

Quick question(s!)
Does optimisation affect MCU code often? And if so, in any major sections (along with printing / debugging) or any areas to watch out for it specifically?


#13

Great to hear that it works!

The correctness of normal, well-written code, which is free of warnings and undefined behavior, should be immune to a change in optimization flags. That should only be critical if you’re writing timing-critical code which must beat some given execution time to function properly (like loading / pushing data from a peripheral fast enough). It shouldn’t be the case that the correct behavior of Semtech’s driver code is dependent on the optimization flags.

As a few closing words: The state variable volatile AppStates_t State = LOWPOWER; was correctly marked as volatile to prevent the compiler from optimizing this variable. This apparently didn’t work if that State variable is to be blamed for the problems or the problem is actually somewhere else. I suggest reading this for some general good info on interrupt-handling code.

Also, with this platformio.ini and without build_unflags = -Os(docs) you still have -Os, now together with -O0 in the compiler options. Apparently -O0 wins if it works now? Does it still win with -O1?

All over very weird problems. If you compile the same code with the same compile options in the mbed online compiler and with PIO, the results should be the same. I’d suggest executing pio settings set force_verbose Yes in the commandline and a clean recompilation. You can see every full compile command. Compare that what the mbed online compiler does (if you see the gcc/g++ commands, that is) and maybe you’ll notice some differences (in defined macros, optimizer flags, …). Or never touch it again and accept it as a miraculous thing.


#14

To provide some more info (in the sake of completing this answer)

I am building with -O0 which works (the -Os flag doesn’t seem to have an impact on the compilation at all when-O0 is used, nor -O1 or-O2 for that matter. Same output filesizes).

It does not work with -O1 and-O2 flags set.

For eg with the -O1 flag set (as it will build) and then connecting to the board by serial, the output will eventually lead to:

     SX1272 Ping Pong Demo Application 


 > Board Type: SX1272MB2xAS < 


             > LORA Mode < 

Starting Ping-Pong loop
> OnRxTimeout


++ MbedOS Fault Handler ++

FaultType: HardFault

Context:
R0   : 20001680
R1   : 00000033
R2   : 00000020
R3   : 3000C12A
...

I actually do not really use the mbed compiler (I use it very rarely to test quickly if something will compile - so I do not know my way around it very well nor if it can output the gcc/g++ commands) it is just not very intuitive and not very inviting / hard to use as an IDE IMHO.

I do not wish to touch this again :grin: (The MBed framework has me wanting more, I thought it would be better than it is (friendlier and more intuitive), especially as it’s backed by such a large company, been available for years and compared to what is available in other frameworks) I will continue to dabble in this, for learning and interest’s sake (but will probably use other frameworks to get projects done quickly)