STM32 blue pill fakes

STM32F103C8T6 (that really was a CS32F103C8T6)

I'm always looking for cheap but powerful microcontroller boards as an alternative to the usual Arduino boards. The blue pills looked promising. However, after a weekend of testing, I do not recommend to buy these boards! There are too many problems with clones of varying quality. If you want to try boards with STM chips, try the WeAct BlackPill with the more powerful F4 chip, which is of much better quality.

The chip is marked as STM32 but has wrong chip idcode

Specs: 32 bit ARM Cortex-M3; 72MHz work frequency, 64K flash memory, 20K SRAM, 2.0-3.6V power.

I got these boards for around $2, which is very cheap given the performance. There are several methods to program them. It seemed to me that the easiest way was to buy a ST-LINK V2 USB-adapter. You don't program them via USB bootloader. Think of it like a Pro Mini but you only need 4 cables. It is possible to flash a bootloader but this process seems not straight-forward. Spoiler alert: nothing seems to be straight-forward with these boards.

ST-LINK V2 STM32 blue pill

SWDIO (2)-------------SWIO (orange)

SWCLK (6)-------------SWCLK (brown)

3.3V (8)----------------3V3 (red)

GND (4)----------------GND (black)


You have to download and install the USB-driver (Win10) before plugging in the adaptor for the first time. After having installed the USB-driver, you can plug in the ST-LINK V2 adaptor. You should find it in the device manager under Universal Serial Bus devices: STM32 STLink.

Next, you have to install the correct Core in PlatformIO. There is an official Arduino core from ST called STM32duino that I decided to try:

In PlatformIO, this core is called ST STM32. Launch PlatformIO, go to PlatformIO home and click on Platforms. Search and install ST STM32.

Now, start a new project and search board STM32F103C8 (20k RAM. 64k Flash) (Generic).

Everything seemed to work fine until the upload failed:

xPack OpenOCD, x86_64 Open On-Chip Debugger 0.10.0+dev-00378-ge5be992df (2020-06-26-09:29)Licensed under GNU GPL v2For bug reports, read http://openocd.org/doc/doxygen/bugs.htmldebug_level: 1
hla_swdWarn : UNEXPECTED idcode: 0x2ba01477Error: expected 1 of 1: 0x1ba01477in procedure 'program'** OpenOCD init failed **shutdown command invoked
*** [upload] Error 1

I googled this error with the following result:

Your BluePill board contains a CS32F103C8T6 chip, a Chinese clone instead of a real STM32F103C8T6.

In order to upload the code, add the below line to platformio.ini:

upload_flags = -c set CPUTAPID 0x2ba01477

And really, this did the trick.

0x2ba01477hla_swdtarget halted due to debug-request, current mode: Thread xPSR: 0x01000000 pc: 0x080007dc msp: 0x20005000** Programming Started **** Programming Finished **** Verify Started **** Verified OK **** Resetting Target **shutdown command invoked

I was able to flash a basic blink program to the chip successfully. Which explains at least why these boards were so incredibly cheap... they are clones.. Here some links discussing the different clones out there:

https://github.com/keirf/Greaseweazle/wiki/STM32-Fakes

https://hackaday.com/2020/10/22/stm32-clones-the-good-the-bad-and-the-ugly/

https://www.youtube.com/watch?v=VE8-DCMXzo8

https://www.blaatschaap.be/32f103-comparison-part-1/ (4 parts, in detail)

On my boards, the chips are marked STM32 so they are obviously fake. I would prefer to buy genuine STM32 boards instead of counterfeits. Anyway, now that I have bought these boards, lets test them.

Here a copy of the platformio.ini file:

[env:genericSTM32F103C8]

platform = ststm32

board = genericSTM32F103C8

framework = arduino

upload_protocol = stlink

upload_flags = -c set CPUTAPID 0x2ba01477

And my blink test program (the on-board LED is connected to PC13):

#include <Arduino.h>

void setup() {

// put your setup code here, to run once:

pinMode(PC13, OUTPUT);

}


void loop() {

// put your main code here, to run repeatedly:

digitalWrite(PC13, HIGH); // turn the LED off (HIGH is the voltage level)

delay(1000); // wait for a second

digitalWrite(PC13, LOW); // turn the LED on by making the voltage LOW

delay(1000); // wait for a second

}

The program starts executing immediately. No need to to touch the jumpers or the reset-button.

USB serial

I can accept to program the boards via ST-Link. However, USB serial has to work or these boards are of little use to me. There seem to be lots of problems with the USB interface on blue pills though:

https://stm32duinoforum.com/forum/wiki_subdomain/index_title_Blue_Pill.html

R10 needs to be 1.5k. Many boards ship with wrong resistor values. I measured R10 on my board and surprisingly it was correct. In order to get a USB interface, the platformio.ini file has to be adapted. There are some discussions online:

https://community.platformio.org/t/difficulty-with-getting-usb-serial-usb-cdc-working/7501/6

I tried this for platformio.ini:

[env:genericSTM32F103C8]

platform = ststm32

board = genericSTM32F103C8

framework = arduino

upload_protocol = stlink

upload_flags = -c set CPUTAPID 0x2ba01477

build_flags =

-D PIO_FRAMEWORK_ARDUINO_ENABLE_CDC

-D USBCON

-D USBD_VID=0x0483

-D USBD_PID=0x5740

-D USB_MANUFACTURER="Unknown"

-D USB_PRODUCT="\"BLUEPILL_F103C8\""

-D HAL_PCD_MODULE_ENABLED

And here is my hello world code:

#include <Arduino.h>


void setup() {

// put your setup code here, to run once:

pinMode(PC13, OUTPUT);

SerialUSB.begin();

}


void loop() {

// put your main code here, to run repeatedly:

digitalWrite(PC13, HIGH); // turn the LED off (HIGH is the voltage level)

delay(10000); // wait for a second

digitalWrite(PC13, LOW); // turn the LED on by making the voltage LOW

delay(1000); // wait for a second

SerialUSB.println("Hello world");

}

Probably a good idea to disconnect the board from ST-Link before plugging in the USB cable. The code worked without problems.

Test with Adafruit MCP9808 Precision I2C Temperature Sensor

Next, I connected a I2C sensor and uploaded a slightly modified version of the Adafruit test program (mcp9808test.ino):

STM32 MCP9808

GND------------GND (black)

3.3V------------Vdd (red)

B6 (SCL1)-------SCL (white)

B7 (SDA1)-------SDA (yellow)

Serial USB Terminal (Kai Morich)

Android phone with USB On-The-Go (OTG) cable

[Use USB CDC driver in app settings for STM32]

#include <Arduino.h>

/**************************************************************************/

/*!

This is a demo for the Adafruit MCP9808 breakout

----> http://www.adafruit.com/products/1782

Adafruit invests time and resources providing this open source code,

please support Adafruit and open-source hardware by purchasing

products from Adafruit!

*/

/**************************************************************************/

//*********** THIS DEMO WAS MODIFIED TO RUN ON A STM32F103C8 **************


#include <Wire.h>

#include "Adafruit_MCP9808.h"


// Create the MCP9808 temperature sensor object

Adafruit_MCP9808 tempsensor = Adafruit_MCP9808();


void setup() {

pinMode(PC13, OUTPUT);

SerialUSB.begin();

if (!tempsensor.begin(0x18)) {

Serial.println("Couldn't find MCP9808! Check your connections and verify the address is correct.");

while (1);

}

Serial.println("Found MCP9808!");


tempsensor.setResolution(3); // sets the resolution mode of reading

}


void loop() {

digitalWrite(PC13, HIGH); // turn the LED off (HIGH is the voltage level)

SerialUSB.println("wake up MCP9808.... "); // wake up MCP9808 - power consumption ~200 mikro Ampere

tempsensor.wake(); // wake up, ready to read!


// Read and print out the temperature, also shows the resolution mode used for reading.

SerialUSB.print("Resolution in mode: ");

SerialUSB.println (tempsensor.getResolution());

float c = tempsensor.readTempC();

float f = tempsensor.readTempF();

SerialUSB.print("Temp: ");

SerialUSB.print(c, 4); Serial.print("*C\t and ");

SerialUSB.print(f, 4); Serial.println("*F.");

delay(2000);

SerialUSB.println("Shutdown MCP9808.... ");

tempsensor.shutdown_wake(1); // shutdown MSP9808 - power consumption ~0.1 mikro Ampere, stops temperature sampling

SerialUSB.println("");

digitalWrite(PC13, LOW); // turn the LED on by making the voltage LOW

delay(1000);

delay(200);

}

From the web I get the impression that there are lots of blue pill clones for sale and it is difficult to get your hands on a board with genuine ST chip. Programming them is also not straight forward. Andreas Spiess has made a good video about the different boards and how to program them. He doesn't recommend buying blue pills. He recommends black pills with the more powerful F4 chip.

https://youtu.be/337rDuCGeYs

I am not sure if I want to spend more time trying to use these boards as there are so many problems. I might rather order some black pills and try them instead. For small projects where a USB serial interface is needed, I recommend the Wemos D1 mini or the Seeeduino Xiao. They cost a little more but are much easier to program and work without problems.


Relevant links

https://stm32duinoforum.com/forum/wordpress/wp-content/uploads/2016/07/The-Generic-STM32F103-Pinout-Diagram.pdf

https://docs.platformio.org/en/latest/platforms/ststm32.html

https://github.com/stm32duino/wiki/wiki/Getting-Started

https://www.st.com/en/development-tools/stsw-link009.html

https://youtu.be/vzDsSdtKQXA

https://www.e-tinkers.com/2020/01/getting-started-with-stm32-and-things-you-need-to-be-aware-of/

http://amitesh-singh.github.io/stm32/2017/05/27/Overcoming-wrong-pullup-in-blue-pill.html

https://stm32duinoforum.com/forum/index_php.html

https://medium.com/coinmonks/stm32-blue-pill-usb-bootloader-how-i-fixed-the-usb-storage-serial-dfu-and-webusb-interfaces-36d7fe245b5c



Technical information

I2C pins and usage:

While the test of the MCP9809 worked without problems, I couldn't get the MAX30100 sensor to work properly. The i2c scanner for STM32 (Arduino IDE example) detects the sensor, the test code manages to get the sensor started but then only reads zeros from the sensor. At the same time, communication was lost to a SSD1306 OLED display after short time. The i2c seems not to function reliably. I tried with an identical board but encountered the same issue. I also tried all different i2c ports without luck, see details below:


/* Example pinmap for Bluepill I2Cs (by Testato)


I2C-1 standard pins: PB7(sda) PB6(scl)

Use it by "Wire" without pin declaration

Wire.begin();


I2C-1 alternative pins: PB9(sda) PB8(scl)

Remap the first I2C before call begin()

Wire.setSDA(PB9);

Wire.setSCL(PB8);

Wire.begin();


I2C-2: PB11(sda) PB10(scl)

Remap the second I2C before call begin()

Wire.setSDA(PB11);

Wire.setSCL(PB10);

Wire.begin();


If you want to use the two I2Cs simultaneously, create a new instance for the second I2C

TwoWire Wire2(PB11,PB10);

Wire2.begin();

*/



© 2021 notthemarsian