Small problems going from Arduino Uno/Nano to Bluepill

Hey guys, so with nothing to do while waiting for my Nucleo boards to come in, I decided to give a second chance to my bluepills which I thought were fakes. Turns out they’re real! I just had wrong configurations when flashing to get them to connect properly. After a bunch of troubleshooting, the board seems to be working great mostly.

I went through testing the functionality from the beginning with no issues, until now I’m at basically full FOC doing position testing. I’ve managed to get it working, but there’s two issues I came across and wanted to see if there was any ideas on how to help or improve things. My concerns are that the same code (minus the pin numbers) are almost exactly the same as I had working on my Arduino Uno / Nano.

The first issue was on compilation size. The same code compiles and uploads to my Arduino Uno / Nano without any issues. However on the STM32F103C8T6 using platformio, when compiling a barebones full FOC program, it gives me the error “region `FLASH’ overflowed by 5104 bytes”. The Nano / Uno should have 32KB flash memory, while the STM32F103C8T6 should have 64KB flash memory given. Is the compiled size expected to be this much larger or is there something I’m doing wrong?
I know there’s an extra 64KB hidden flash that is untested, so I was able to get it working by compiling using the bluepill_f103c8_128k board ini configuration, however that won’t upload from PlatformIO, instead I had to flash it using the STLink utility and it still works fine, so I’m able to keep testing.

The second, and more concerning issue is while it’s actually running I’m getting a strange noise which I’ll try to describe. When the motor is completely at rest, where position sensor is exact, there’s no noise. When the motor is trying to spin quickly to reach a new position there’s a high pitch whine that is normal, and I’ve heard the entire time. However when it reaches the position, but not exact (there’s some noise on my magnetic sensor) and it’s trying to do very small compensations, there’s a sort of high pitch scratchy noise. It’s not as high pitch as the motor running, and it’s not very loud, but it’s still very noticeable when you’re near and was not there with the same settings on my arduino boards at all.

I’ve searched through the community posts and have tried changing the PWM frequency from 15000 to 50000 and it doesn’t seem to make a difference. My motor settings code are as below if it may help.

driver.voltage_power_supply = 12;
//driver.pwm_frequency = 15000; //tried between 15000 and 500000
driver.init();
motor.linkDriver(&driver);

current_sense.init();
motor.linkCurrentSense(&current_sense);

motor.foc_modulation = FOCModulationType::SpaceVectorPWM;
motor.controller = MotionControlType::angle;

motor.phase_resistance = 0.0946; // [Ohm]
motor.current_limit = 10;   // [Amps]
motor.PID_velocity.P = 0.5f;
motor.PID_velocity.I = 10;
motor.PID_velocity.D = 0;
motor.LPF_velocity.Tf = 0.01f;
motor.LPF_angle.Tf = 0.01;
motor.P_angle.P = 20;
motor.velocity_limit = 100;

It still runs fine, no apparent overheating, and the motion is actually smoother than my arduinos, but it still seems strange to experience this noise that wasn’t there before.

If anyone has any suggestions on these two issues, it would be much appreciated.

Hi Ivan_Lee!

In brief, unfortunately, yes. It’s one of the differences between 32bit and 8bit MCUs - instruction sizes also increase, which means program sizes increase.

Normally 64k flash should be enough though… do you have a lot of other libraries, debug-code or similar in there that could be increasing your compiled program size?

Are you compiling with the option lib_archive = false in your platformio.ini? If not, that could be one explanation for the noise…

Hi @runger, thanks for the response!

That makes sense about the instruction size increase… even on the arduino it was generally around 90% full. But my code is pretty simple, the only real deviation from the examples is moving the init codes to a separate function so it doesn’t start up immediately and instead triggered by a command. and another command to software reset the board. But even removing these deviations it still is compiling too large. Could it be my build flags? I had to add those to get my bluepill’s usb to be usable

#include <SimpleFOC.h>

MagneticSensorI2C sensor = MagneticSensorI2C(AS5600_I2C);
BLDCMotor motor = BLDCMotor(7);
BLDCDriver3PWM driver = BLDCDriver3PWM(PA7, PB0, PB1, PA10, PA9, PA8);
LowsideCurrentSense current_sense = LowsideCurrentSense(0.01, 50.0, PA2,PA1, PA0);

float target_angle = 0;
bool initialized = false;
bool runInit = false;

Commander command = Commander(Serial);

void doTarget(char* cmd) { command.scalar(&target_angle, cmd); }
void doCurrent(char* cmd) { command.scalar(&motor.current_limit, cmd); }

void initialize(){
  Serial.println("Begin initialization...");
  sensor.init();
  motor.linkSensor(&sensor);

  driver.voltage_power_supply = 12;
  //driver.pwm_frequency = 15000;
  driver.init();
  motor.linkDriver(&driver);

  current_sense.init();
  motor.linkCurrentSense(&current_sense);

  motor.foc_modulation = FOCModulationType::SpaceVectorPWM;
  motor.controller = MotionControlType::angle;
  motor.phase_resistance = 0.0946; // [Ohm]
  motor.current_limit = 10;   // [Amps] - if phase resistance defined

  motor.PID_velocity.P = 0.5f;
  motor.PID_velocity.I = 10;
  motor.PID_velocity.D = 0;

  motor.LPF_velocity.Tf = 0.01f;
  motor.LPF_angle.Tf = 0.01;
  motor.P_angle.P = 20;
  motor.velocity_limit = 100;

  motor.useMonitoring(Serial);
  motor.init();

  motor.initFOC();
  motor.monitor_downsample = 1000; // initially disable the real-time monitor
  initialized = true;
  runInit = false;

  Serial.println("Motor ready!");
  _delay(1000);
}

void doInit(char* cmd) { runInit = true; }
void doReset(char* cmd) { NVIC_SystemReset(); }

void setup() {
  Serial.begin(500000);

  Serial.println("Starting!");

  command.add('T', doTarget, "target position");
  command.add('C', doCurrent, "current limit");
  command.add('Z', doInit, "initialize");
  command.add('X', doReset, "reset");

  Serial.println("Waiting for initialization");

}

void loop() {
  if(initialized){
    motor.loopFOC();
    motor.move(target_angle);
    motor.monitor();
  }else{
    if(runInit){
      initialize();
    }else{
      Serial.println("Waiting for initialization");
      _delay(1000);
    }
  }
  command.run();
}

And here is my platformio.ini

[env:bluepill_f103c8]
platform = ststm32
board = bluepill_f103c8
framework = arduino
upload_protocol = stlink
;upload_port = COM9
build_flags =
   -D PIO_FRAMEWORK_ARDUINO_ENABLE_CDC
   -D USBCON
   -D USBD_VID=0X0483
   -D USBD_PID=0x0004
   -D USB_MANUFACTURER="Unknown"
   -D USB_PRODUCT="\"BLUEPILL_F103C8\""
   -D HAL_PCD_MODULE_ENABLED
lib_deps = askuric/Simple FOC@^2.2.1
lib_archive = false
monitor_speed = 500000

Hi,

This all looks very ok. I think the USB code is significant in size, but of course you need it if you want to use the USB serial port…

I’m just looking at some code I’m compiling here, for STM32G4 and also with USB, and this is what I get:

Flash: [=         ]  11.4% (used 59800 bytes from 524288 bytes)

so it does look like it uses around that much…

Ah okay, well at least I know it’s not an unusual size. Thanks for checking that out. I’ll just have to keep that in mind going forward.