Encoder library for Blue Pill

Hi everyone,

Recently I brought a Blue Pill clones and I installed STM core for Arduino
I want to test the board to see whether it can be a good replacement for Due, and I find that STM32 compatible library is very limited.

My project needed to use rotary encoder, I tried the one discussed in this thread

https://forum.arduino.cc/index.php?topic=553990.0

When I tried to test the included example, the following error appears :

Compiling sketch...
"C:\Users\Home User\AppData\Local\Arduino15\packages\STM32\tools\arm-none-eabi-gcc\6-2017-q2-update/bin/arm-none-eabi-g++" -mcpu=cortex-m3 -mthumb "@C:\Users\HOMEUS~1\AppData\Local\Temp\arduino_build_789738/sketch/build_opt.h" -c -Os -std=gnu++14 -ffunction-sections -fdata-sections -nostdlib -fno-threadsafe-statics --param max-inline-insns-single=500 -fno-rtti -fno-exceptions -MMD "-IJ:\Arduino_Project\STM32\STM32RotaryEncoderInterruptsSerial" "-IC:\Users\Home User\AppData\Local\Arduino15\packages\STM32\hardware\stm32\1.4.0\cores\arduino/avr" "-IC:\Users\Home User\AppData\Local\Arduino15\packages\STM32\hardware\stm32\1.4.0\cores\arduino/stm32" "-IC:\Users\Home User\AppData\Local\Arduino15\packages\STM32\hardware\stm32\1.4.0\cores\arduino/stm32/LL" "-IC:\Users\Home User\AppData\Local\Arduino15\packages\STM32\hardware\stm32\1.4.0\system/Drivers/STM32F1xx_HAL_Driver/Inc/" "-IC:\Users\Home User\AppData\Local\Arduino15\packages\STM32\hardware\stm32\1.4.0\system/Drivers/STM32F1xx_HAL_Driver/Src/" "-IC:\Users\Home User\AppData\Local\Arduino15\packages\STM32\hardware\stm32\1.4.0\system/STM32F1xx/" "-IC:\Users\Home User\AppData\Local\Arduino15\packages\STM32\hardware\stm32\1.4.0\variants\BLUEPILL_F103C8/usb" "-IC:\Users\Home User\AppData\Local\Arduino15\packages\STM32\hardware\stm32\1.4.0\system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc" "-IC:\Users\Home User\AppData\Local\Arduino15\packages\STM32\hardware\stm32\1.4.0\system/Middlewares/ST/STM32_USB_Device_Library/Core/Src" -DSTM32F1xx -DARDUINO=10802 -DARDUINO_BLUEPILL_F103C8 -DARDUINO_ARCH_STM32 -DBOARD_NAME="BLUEPILL_F103C8" -DSTM32F103xB -DHAL_UART_MODULE_ENABLED "-IC:\Users\Home User\AppData\Local\Arduino15\packages\STM32\tools\CMSIS\5.3.0/CMSIS/Core/Include/" "-IC:\Users\Home User\AppData\Local\Arduino15\packages\STM32\hardware\stm32\1.4.0\system/Drivers/CMSIS/Device/ST/STM32F1xx/Include/" "-IC:\Users\Home User\AppData\Local\Arduino15\packages\STM32\hardware\stm32\1.4.0\system/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/" "-IC:\Users\Home User\AppData\Local\Arduino15\packages\STM32\hardware\stm32\1.4.0\cores\arduino" "-IC:\Users\Home User\AppData\Local\Arduino15\packages\STM32\hardware\stm32\1.4.0\variants\BLUEPILL_F103C8" "-IJ:\Arduino_Project\libraries\RotaryEncoder-master\src" "C:\Users\HOMEUS~1\AppData\Local\Temp\arduino_build_789738\sketch\STM32RotaryEncoderInterruptsSerial.ino.cpp" -o "C:\Users\HOMEUS~1\AppData\Local\Temp\arduino_build_789738\sketch\STM32RotaryEncoderInterruptsSerial.ino.cpp.o"
In file included from J:\Arduino_Project\STM32\STM32RotaryEncoderInterruptsSerial\STM32RotaryEncoderInterruptsSerial.ino:39:0:

J:\Arduino_Project\libraries\RotaryEncoder-master\src/RotaryEncoder.h:95:21: warning: inline function 'int16_t RotaryEncoder::getPosition()' used but never defined

inline int16_t getPosition(void);

^~~~~~~~~~~

Compiling libraries...
Compiling library "RotaryEncoder-master"
Using previously compiled file: C:\Users\HOMEUS~1\AppData\Local\Temp\arduino_build_789738\libraries\RotaryEncoder-master\RotaryEncoder.cpp.o
Using previously compiled file: C:\Users\HOMEUS~1\AppData\Local\Temp\arduino_build_789738\libraries\RotaryEncoder-master\RotaryEncoderAdvanced.cpp.o
Compiling core...
Using previously compiled file: C:\Users\HOMEUS~1\AppData\Local\Temp\arduino_build_789738\core\PeripheralPins.c.o
Using previously compiled file: C:\Users\HOMEUS~1\AppData\Local\Temp\arduino_build_789738\core\variant.cpp.o
Using precompiled core
Linking everything together...
"C:\Users\Home User\AppData\Local\Arduino15\packages\STM32\tools\arm-none-eabi-gcc\6-2017-q2-update/bin/arm-none-eabi-gcc" -mcpu=cortex-m3 -mthumb -Os --specs=nano.specs -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--entry=Reset_Handler -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align "-TC:\Users\Home User\AppData\Local\Arduino15\packages\STM32\hardware\stm32\1.4.0\variants\BLUEPILL_F103C8/ldscript_cb.ld" "-Wl,-Map,C:\Users\HOMEUS~1\AppData\Local\Temp\arduino_build_789738/STM32RotaryEncoderInterruptsSerial.ino.map" "-LC:\Users\Home User\AppData\Local\Arduino15\packages\STM32\tools\CMSIS\5.3.0/CMSIS/Lib/GCC/" -larm_cortexM3l_math -o "C:\Users\HOMEUS~1\AppData\Local\Temp\arduino_build_789738/STM32RotaryEncoderInterruptsSerial.ino.elf" "-LC:\Users\HOMEUS~1\AppData\Local\Temp\arduino_build_789738" -Wl,--start-group "C:\Users\HOMEUS~1\AppData\Local\Temp\arduino_build_789738\sketch\STM32RotaryEncoderInterruptsSerial.ino.cpp.o" "C:\Users\HOMEUS~1\AppData\Local\Temp\arduino_build_789738\libraries\RotaryEncoder-master\RotaryEncoder.cpp.o" "C:\Users\HOMEUS~1\AppData\Local\Temp\arduino_build_789738\libraries\RotaryEncoder-master\RotaryEncoderAdvanced.cpp.o" "C:\Users\HOMEUS~1\AppData\Local\Temp\arduino_build_789738\core\PeripheralPins.c.o" "C:\Users\HOMEUS~1\AppData\Local\Temp\arduino_build_789738\core\variant.cpp.o" -Wl,--whole-archive "C:\Users\HOMEUS~1\AppData\Local\Temp\arduino_cache_517726\core\core_STM32_stm32_GenF103_pnum_BLUEPILL_F103C8,flash_CB,upload_method_serialMethod,xserial_generic,opt_osstd,rtlib_nano_f4ae01b8b35b7a4b9d4ec525cfd5836d.a" -Wl,--no-whole-archive -lc -Wl,--end-group -lm -lgcc -lstdc++
C:\Users\HOMEUS~1\AppData\Local\Temp\arduino_build_789738\sketch\STM32RotaryEncoderInterruptsSerial.ino.cpp.o: In function `loop':

STM32RotaryEncoderInterruptsSerial.ino.cpp:(.text.loop+0x4): undefined reference to `RotaryEncoder::getPosition()'

STM32RotaryEncoderInterruptsSerial.ino.cpp:(.text.loop+0x14): undefined reference to `RotaryEncoder::getPosition()'

collect2.exe: error: ld returned 1 exit status

Using library RotaryEncoder-master at version 1.4.0 in folder: J:\Arduino_Project\libraries\RotaryEncoder-master
exit status 1
Error compiling for board Generic STM32F103 series.

I don't know why this error occurs because in the corresponding library file rotaryEncoder.cpp , there is an entry exist :

/**************************************************************************/
/*
setPosition()

Manualy sets encoder position
*/
/**************************************************************************/
void RotaryEncoder::setPosition(int16_t position)
{
_counter = position;
}

does anyone use this encoder library successfully ?

Note that the bug is about getPosition, not setPosition.

The same bug occurs for AVR boards, so it's not necessary to install the STM32 package if anyone wants to reproduce this.

Here's a minimal sketch that will cause the error:

#include <RotaryEncoder.h>
RotaryEncoder encoder(2, 3, 4);
void setup() {
  encoder.getPosition();
}
void loop() {}

There is a previous bug report for this error:

I was able to fix the error by changing line 95 of RotaryEncoder.h from:

    inline int16_t  getPosition(void);

to:

    int16_t  getPosition(void);

I don't understand why the inline specifier causes this error. I've never used inline. I always figure I'll just let the compiler do as it sees fit with my functions. I did a little bit of searching but everything I turned up was about people using the inline specifier on the definition in the .cpp file instead of on the declaration in the .h file, and that's not the problem here.

Thank you very much pert :slight_smile:

I will try it.

The bug in the library has now been fixed, and the author also took the approach of removing the inline specifier.

I'm still curious about why this was necessary.

I'm still curious about why this was necessary.

Because the source had a bug which was evident from the compiler error message. There was no matching source for the header declaration of:

inline int16_t getPosition()

I think you could have fixed it by adding the inline modifier to the .cpp or, as you did, removing it from the header declaration. Either method should yield the same result since I doubt the compiler needed the hint to inline a simple, single return statement as the entire function body.

I’d test it but at the moment, I’ve only got access via a tablet.

Ah, I see I just made post 311, also the octal opcode for the 8080 return instruction. The (now useless) stuff the brain retains. Now, if I could only remember where I left my car keys...

Thanks for the reply. I get the same error if I add inline specifier to the function definition.

The only way I can make it work inline is to move the definition to the .h file. If I understand this correctly, that will cause it to be inline even without the inline specifier:
https://en.cppreference.com/w/cpp/language/inline

A function defined entirely inside a class/struct/union definition, whether it's a member function or a non-member friend function, is implicitly an inline function.