This category is intended for any type of discussion about the hardware support of the SimpleFOClibrary
- Support problems and issues
- Suggestions
- Advises
- …
This category is intended for any type of discussion about the hardware support of the SimpleFOClibrary
1#:“Maple and maple mini” use “simplefoc” Library:(please note that this is only my actual use test, not necessarily necessary)
1-01:“Maple and maple mini” uses bootloader of “stm32duino”-
→ GitHub - rogerclarkmelbourne/Arduino_STM32: Arduino STM32. Hardware files to support STM32 boards, on Arduino IDE 1.8.x including LeafLabs Maple and other generic STM32F103 boards
1-02: Ports for sensors and motors:
// External Encoder AS5048A—>Use Maple REV3 SPI1
#define ENC_SPI_SCK 13 //
#define ENC_SPI_MISO 12 //
#define ENC_SPI_MOSI 11 //
#define ENC_CS 10 //Fast Pin Switching REG_PORT_OUTSET0
// MagneticSensor(int cs, float _cpr, int _angle_register)
// cs - SPI chip select pin
// _cpr - counts per revolution
// _angle_register - (optional) angle read register - default 0x3FFF
MagneticSensor AS5x4x = MagneticSensor(ENC_CS, 16384, 0x3FFF);
//moto 12N14P size:4108 KV=66
const int MOTO_PhA_pin = 9; // motor A,B,C phase pwm pins
const int MOTO_PhB_pin = 5; //
const int MOTO_PhC_pin = 14; //
const int MOTO_EN_pin = 8; // moto enable pin
const int num_pole_pair = 14;// pole pair number
void setPwmFrequency(int pin) {
if (pin >= BOARD_NR_GPIO_PINS) {
//Serial.begin(115200);
//_delay(100);
Serial.println("DEBUG: Set high frequency PWM.PIN Was wrong!!");
}
pinMode(pin, PWM);
uint16_t ducty_Num_Max = 72000000/36000;
timer_dev *dev = PIN_MAP[pin].timer_device;
uint8_t cc_channel = PIN_MAP[pin].timer_channel;
timer_pause(dev);
ASSERT(dev && cc_channel);
(dev->regs).bas->ARR = ducty_Num_Max;
timer_resume(dev);
timer_generate_update(dev);
}
void _delay(unsigned long ms){
long t = _micros();
while((_micros() - t)/1000 < ms){};
}
// function buffering _micros()
// arduino function doesn’t work well with interrupts
unsigned long _micros(){
// return the value based on the prescaler
//if((TCCR0B & 0b00000111) == 0x01) return (micros()/32);
//else
return (micros());
}
void BLDCMotor::setPwm(int pinPwm, float U) {
// max value
float U_max = voltage_power_supply;
uint16_t Max_ducty = 72000000/36000; //72M主频除以PWM的频率,即为占空比位宽约为11位.
// sets the voltage [0,12V(U_max)] to pwm [0,Max_ducty]
// - U_max you can set in header file - default 12V
int U_pwm = Max_ducty * U / U_max;
// limit the values between 0 and Max_ducty
U_pwm = (U_pwm < 0) ? 0 : (U_pwm >= Max_ducty) ? Max_ducty : U_pwm;
U_pwm = U_pwm +0.5; //取整
timer_dev *dev = PIN_MAP[pinPwm].timer_device;
uint8_t cc_channel = PIN_MAP[pinPwm].timer_channel;
ASSERT(dev && cc_channel);
// CCR1的预加载寄存器使能,每次更新事件发生后才更新占空比
__IO uint32 *ccr = &(dev->regs).gen->CCR1 + ( cc_channel - 1);
*ccr = U_pwm;
*bb_perip(&(dev->regs).bas->CR1, TIMER_CR1_CEN_BIT) = 1;
}
1-04:AS5048A and SPI
Magneticsensor works very well in SPI1 (default state) of maple and maple Mini.
In order to show the necessary speed advantage, I will still MagneticSensor.cpp The function “magicsensor:: init()” in has been modified:
// 1MHz clock (AMS should be able to accept up to 10MHz)
settings = SPISettings(1000000, MSBFIRST, SPI_MODE1);
—>Change to
settings = SPISettings(4500000, MSBFIRST, SPI_MODE1);
1-05:I can’t upload photos and videos for you at this time. First, paste the complete code of my test (use map Rev3)
THE CODE:
#include <SimpleFOC.h>
// External Encoder AS5048A—>Use Maple REV3 SPI1
#define ENC_SPI_SCK 13 //
#define ENC_SPI_MISO 12 //
#define ENC_SPI_MOSI 11 //
#define ENC_CS 10 //Fast Pin Switching REG_PORT_OUTSET0
// MagneticSensor(int cs, float _cpr, int _angle_register)
// cs - SPI chip select pin
// _cpr - counts per revolution
// _angle_register - (optional) angle read register - default 0x3FFF
MagneticSensor AS5x4x = MagneticSensor(ENC_CS, 16384, 0x3FFF);
//moto 12N14P size:4108 KV=66
const int MOTO_PhA_pin = 9; // motor A,B,C phase pwm pins
const int MOTO_PhB_pin = 5; //
const int MOTO_PhC_pin = 14; //
const int MOTO_EN_pin = 8; // moto enable pin
const int num_pole_pair = 14;// pole pair number
// BLDCMotor( int phA, int phB, int phC, int pp, int en)
BLDCMotor motor = BLDCMotor(MOTO_PhA_pin , MOTO_PhB_pin , MOTO_PhC_pin ,num_pole_pair , MOTO_EN_pin);
//gets the target value from the user,when Test Moto velocity.
// velocity set point variable
#define BOARD_LED_PIN 13
#define BOARD_BUTTON_PIN 38
float target_velocity = 0;
unsigned long t = 0;
long timestamp = _micros();
void setup() {
pinMode(BOARD_LED_PIN,OUTPUT);
pinMode(BOARD_BUTTON_PIN, INPUT);
// debugging port:maple’s DFU/Serial port
Serial.begin(115200);
// while (!Serial);
_delay(100);
Serial.println(“serial ready.”);
digitalWrite(BOARD_LED_PIN, HIGH);
_delay(1000);
digitalWrite(BOARD_LED_PIN, LOW);
// initialise magnetic sensor hardware
AS5x4x.init();
// power supply voltage
// default 12V
motor.voltage_power_supply = 12;
// choose FOC algorithm to be used:
// FOCModulationType::SinePWM (default)
// FOCModulationType::SpaceVectorPWM
motor.foc_modulation = FOCModulationType::SpaceVectorPWM;
// set control loop type to be used
// ControlType::voltage
// ControlType::velocity
// ControlType::angle
motor.controller = ControlType::velocity;
// contoller configuration based on the controll type
// velocity PI controller parameters
// default P=0.5 I = 10
motor.PI_velocity.P = 0.2;
motor.PI_velocity.I = 20;
// default voltage_power_supply/2
motor.PI_velocity.voltage_limit = 6;
// jerk control using voltage voltage ramp
// default value is 300 volts per sec ~ 0.3V per millisecond
motor.PI_velocity.voltage_ramp = 1000;
// velocity low pass filtering
// default 5ms - try different values to see what is the best.
// the lower the less filtered
motor.LPF_velocity.Tf = 0.01;
// use debugging with serial for motor init
// comment out if not needed
motor.useDebugging(Serial);
// link the motor to the sensor
motor.linkSensor(&AS5x4x);
// initialize motor
motor.init();
// align sensor and start FOC
motor.initFOC();
Serial.println(“Motor ready.”);
Serial.println(“Set the target velocity using Serial windows”);
_delay(1000);
}
unsigned long Now;
unsigned long delta;
long loop_count = 0;
void loop() {
// iterative state calculation calculating angle
// and setting FOC phase voltage
// the faster you run this function the better
// in arduino loop it should have ~1kHz
// the best would be to be in ~10kHz range
static String inputString;
Now = _micros();
motor.loopFOC();
delta = _micros() - Now;
if (loop_count++ > 1000) {
Serial.print(“LoopFOC Time (us) :”);
Serial.println(delta);
loop_count=0;
}
// iterative function setting the outter loop target
// velocity, position or voltage
// this function can be run at much lower frequency than loopFOC function
// it can go as low as ~50Hz
motor.move(target_velocity);
// function intended to be used with serial plotter to monitor motor variables
// significantly slowing the execution down!!!
// motor.monitor();
if (Serial.available()) {
// get the new byte:
char inChar = (char)Serial.read();
// add it to the inputString:
inputString += inChar;
// if the incoming character is a newline
// end of input
if (inChar == ‘\n’) {
target_velocity = inputString.toFloat();
Serial.print("target_velocity: ");
Serial.println(target_velocity);
inputString = “”;
}
}
if (abs(target_velocity) > 5.0) digitalWrite(BOARD_LED_PIN, HIGH);
if (abs(target_velocity) <= 5.0) digitalWrite(BOARD_LED_PIN, LOW);
if(digitalRead(BOARD_BUTTON_PIN)==HIGH) {
Serial.print("Average loop time is (microseconds): ");
Serial.println((_micros() - timestamp)/t);
t = 0;
timestamp = _micros();
//Serial.print("Target velocity: ");
//Serial.println(target_velocity);
}
}