PWM signal is inconsistent for STMF446RE - Help needed

Post here first, or if you can't find a relevant section!
Post Reply
Neuro
Posts: 3
Joined: Thu Mar 11, 2021 5:17 am

PWM signal is inconsistent for STMF446RE - Help needed

Post by Neuro »

Hi All,

I'm developing a project that aims to control 3 Gimbal BLDC motors. So the MCU I selected is the STM32F446RE (Nucleo-64).

The Driver is basically a L6234 using the simpleFOCShield. This is from a community that creates and maintains an arduino library that runs BLDC motors, based on a claim that FOC makes BLDC more effiecient.
More info here -> https://www.simplefoc.com

The driver takes 3 pwm signals and 1pwm enable(optional enable).

The closed loop programming is completed using a Magnetic angle sensor, AS5048a. The data from the sensors is collected via SPI.

So, STM32F446RE has an arduino uno stack system, so it is compartiable with the shield.

Testing I have done,
Motors and drivers are fine, as I used an Arduino uno to test the other hardware and the motors runs as commanded, in both open loop/closed loop operations. So the only difference from the working setup I have is the STM32F446RE <- this is the only difference.

However, I face a few problems with the STM32. I currently have 2 boards, and both gave me different behaviours.

Board 1)
Can run the motors, however the SPI DOES NOT work.

Board 2)
The motors will not move. However, the SPI can work well. I can hook up 3 sensors and get accurate readings from them.

The codes that run the 2 STM32F446RE and Arduino Uno are the same, so the Uno proves that the codes is not in error. (using the same pins etc)

I understand the difference bwt the PWM signals of the Uno and the STM32 is the voltage and frequency. As I just started using the STM32 (just for a few days actually) I'm suspecting the the pwm signal is causing the problem. I tried using different PWM outputs from the STM32 board that cannot run the motors (i.e. board 2)and I sometimes get it to vibrate between two points instead of a continuous motion.

I do noticed that in order to get better SPI data, I actually have to make some changes to the SPI setting for the working SPI board. This was due to the frequency mostly.

Any help or any guidance in solving this problem (PWM) is much appreciated.
ag123
Posts: 1655
Joined: Thu Dec 19, 2019 5:30 am
Answers: 24

Re: PWM signal is inconsistent for STMF446RE

Post by ag123 »

welcome and if stm32duino is new to you
don't forget to read these first
https://github.com/stm32duino/wiki/wiki
viewtopic.php?f=2&t=3
viewtopic.php?f=2&t=301

there are some significant differences between the original uno vs stm32 based boards.
for one thing many of the peripherals on stm32 (and stm32duino core) are driven directly by hardware e.g. SPI
hence you'd need to make sure that you are connecting the appropriate SPI hardware pins
e.g. for SPI1 it is normally

Code: Select all

 #define SS		PA4
 #define CLK		PA5
 #define MISO		PA6
 #define MOSI		PA7
it is feasible to use the SS pin as a CS pin in master mode e.g.

Code: Select all

pinMode(PA4,OUTPUT);
and you can use digitalWrite() to control that pin

in addition do share codes for more clarity on specific topics
for PWM more commonly it is the HardwareTimers, those use specific pins as well
stm32 has elaborate hardware timers
do review the datasheet and reference manuals on ST's web for your specific mcu
e.g.
https://www.st.com/resource/en/referenc ... ronics.pdf
Last edited by ag123 on Thu Mar 11, 2021 5:59 am, edited 1 time in total.
leonardo
Posts: 18
Joined: Sat Mar 06, 2021 2:37 pm

Re: PWM signal is inconsistent for STMF446RE - Help needed

Post by leonardo »

The software (simple FOC) and the development board (Nucleo F446RE) are fully compatible. Because I tried the same operation a few days ago, but the driver I used is DRV8302 15A

I think this is a pure hardware problem, please check whether your wiring and hardware are normal. It is recommended to attach your wiring photos and source code

In the Gimbal system, I think you only need to convert the attitude calculation into a torque command, and then send it to a simple FOC controlled motor to complete the closed-loop control of the IMU.
Neuro
Posts: 3
Joined: Thu Mar 11, 2021 5:17 am

Re: PWM signal is inconsistent for STMF446RE - Help needed

Post by Neuro »

Hi leonardo,

As can be seen from the image, I'm quite sure that it's not a wiring issue. (Basically lifting up the same shield and attach it to another) It's the same shield and wiring when used with the arduino uno.

The source code can be found in the previous reply.

We are not using a drone for our application. Interesting to know thou. :)

Regards

Image
Image
Last edited by Neuro on Thu Mar 11, 2021 6:39 am, edited 1 time in total.
Neuro
Posts: 3
Joined: Thu Mar 11, 2021 5:17 am

Re: PWM signal is inconsistent for STMF446RE

Post by Neuro »

ag123 wrote: Thu Mar 11, 2021 5:50 am
there are some significant differences between the original uno vs stm32 based boards.
for one thing many of the peripherals on stm32 (and stm32duino core) are driven directly by hardware e.g. SPI
hence you'd need to make sure that you are connecting the appropriate SPI hardware pins
e.g. for SPI1 it is normally

Code: Select all

 #define SS		PA4
 #define CLK		PA5
 #define MISO		PA6
 #define MOSI		PA7
** retype cos somehow the forum deleted the pervious reply **

Hi ag123,

Thanks for sharing.

I am using the same pins you mentioned.

For the open loop motion control

Code: Select all

// Open loop motor control example
#include <SimpleFOC.h>

BLDCMotor motor = BLDCMotor(7); 
BLDCDriver3PWM driver = BLDCDriver3PWM(9, 5, 6, 8);
//BLDCDriver3PWM driver = BLDCDriver3PWM(PA8, PA9, PA10, PA11);

//target variable
float target_velocity = 2; // rad/s

// instantiate the commander
Commander command = Commander(Serial);
void doTarget(char* cmd) { command.scalar(&target_velocity, cmd); }

void setup() {

  // driver config
  // power supply voltage [V]
  driver.voltage_power_supply = 12;
  driver.init();
  // link the motor and the driver
  motor.linkDriver(&driver);

  // limiting motor current (provided resistance)
  //motor.current_limit = 0.5;   // [Amps]
  motor.current_limit = 1.0;   // [Amps]
 
  // open loop control config
  motor.controller = MotionControlType::velocity_openloop;

  // init motor hardware
  motor.init();

  // add target command T
  command.add('T', doTarget, "target velocity");

  Serial.begin(115200);
  Serial.println("Motor ready! Mass Storage2");
  Serial.println("Set target velocity [rad/s]");
  _delay(1000);
}

void loop() {

  // open loop velocity movement
  // using motor.current_limit and motor.velocity_limit
  motor.move(target_velocity);

  // user communication
  command.run();
}

Code: Select all

#include <SPI.h>

//simplefoc
#include <SimpleFOC.h>

MagneticSensorSPI sensor1 = MagneticSensorSPI(10, 14, 0x3FFF);
//SPIClass SPI_1(PA7, PA6, PA5);//mosi miso, sclk

void setup() {
  // put your setup code here, to run once:
  SPI.begin();
  //simplefoc sensor init
  sensor1.spi_mode = SPI_MODE1; // spi mode - OPTIONAL
  sensor1.clock_speed = 500000; // spi clock frequency - OPTIONAL
  //sensor1.init(&SPI_1);
  sensor1.init();
  delay(10);
 
  //serial setup
  Serial.begin(115200);
  delay(1000);
}

void loop() {
  // put your main code here, to run repeatedly:
  //sensor1.spi_mode = SPI_MODE0; // spi mode - OPTIONAL
  //sensor1.clock_speed = 500000; // spi clock frequency - OPTIONAL
  //sensor1.init();
  //sensor1.init(&SPI_1);
  sensor1.init();

  Serial.println(sensor1.getAngle());
  //Serial.print("\t");
  delay(10);
}

ag123
Posts: 1655
Joined: Thu Dec 19, 2019 5:30 am
Answers: 24

Re: PWM signal is inconsistent for STMF446RE - Help needed

Post by ag123 »

apparently the interface to SPI is 'within' the library, what i'd normally try is to use Serial.print() as a primitive 'debug'
interface. e.g. to examine specific parts in the codes where it interface the sensors / peripheral.
things like where it sends the commands and print the response. if the response is as expected SPI should be working ok.
this would likely mean digging into the library codes and inserting those statements
other 'professional' ways could perhaps be use debug - you could literally step the codes or even use aids like scope / logic analyzers etc

PWM is different between between '*duinos*', some could literally 'bit bang' it. while for stm32 one common way is to use hardware timers
found a thread from a google search
viewtopic.php?t=496
for the hardware timers again there are specific pins, and it would also be necessary to enable afio on the output pins and select hardware timer as the output. controlling PWM for 'single pulse' and varying duty cycle between pulses could have challenges beyond just using the timers.
it may involve interrupt handling, e.g. callbacks, or specific settings changing the duty cycle on the fly (e.g. the output compare register, for a particular channel)
https://github.com/stm32duino/wiki/wiki ... er-library
it would help to review the manuals on the hardware timer while attempting to use the api

'bit banging' motor control waveforms is feasible, but as expected it is 'slow', but u'd only need it to be 'fast' enough. i've once tried an implementation, where the hardware timer simply callback my isr at a fixed interval. And I bit bang my motor waveforms using digitalWrite(). this could be simplier if the control waveforms are complicated.

with stm32 hardware timers, if the duty cycle doesn't need to vary at the edge of each cycle, e.g.. a train of same duty cycle pulses. that output compare register may be a convenient way to do so and it'd be 'fast'. the pulse train is completely generated by the timer. u'd only need to change the duty cycle (e.g. output compare register) as and when needed.

i'd think it is also possible to have the hw timer callback in an interrupt every cycle, and you can change the duty cycle (output compare register) of each channel on the fly during that isr call. the only trouble is interrupts has non-trival overheads and is thus 'slow'. but timing and duty cycle precision is assured by the hw timer
ag123
Posts: 1655
Joined: Thu Dec 19, 2019 5:30 am
Answers: 24

Re: PWM signal is inconsistent for STMF446RE - Help needed

Post by ag123 »

in the HardwareTimer api, duty cycle is set using

Code: Select all

pTimer->setCaptureCompare(channel, dutycycle, PERCENT_COMPARE_FORMAT);
'breathing led' example
viewtopic.php?p=6334#p6334

there may be another reason for apparent 'inconsistent' pwm, if pwm is implemented using loops and codes to create delays, stm32f4xx has that 'ART accelerator' which is the on chip cache, that in the most optimistic scenario can reduce flash memory access from say like 8-10 wait states to say 0 wait states, if the codes are cached. the speedup is 'enormous', but it'd create problems for apps needing 'fixed' timing. the solution is to use things like hardware timers where the timing is assured
Post Reply

Return to “General discussion”