B_G431B_ESC1 Current Control Implementation

Hi All,

I’m new to this project, and have been really happy with it so far, thanks for all your hard work.

I’m using B_G431B_ESC1 to control an rctimer GBM5010 Gimbal motor, with an AS5048b encoder using i2c communication. Up until now I’ve only used voltage control, with closed loop position and velocity control. I’m now trying to implement current control.

PROBLEM: I’ve spent about two days trying to get current readings from this controller. I’ve been trying inline, and lowside. I’ve run the example code (with minor changes for it to compile) and all I get is seemingly random noisy values that don’t make sense to me. See the image below for an example from the arduino serial plotter. This is the output from the monitor: motor.monitor_variables = _MON_CURR_D | _MON_CURR_Q;

This is the serial output at calibration:
MOT: Monitor enabled!
MOT: Init
MOT: Enable driver.
MOT: Align sensor.
MOT: sensor_direction==CW
MOT: PP check: OK!
MOT: Zero elec. angle: 1.40
MOT: Align current sense.
MOT: Success: 1
MOT: Ready.

All while running the following code. Noisy output doesn’t change when I send a voltage to the motor to make it turn, sometimes sending a command or holding the motor seems to have some effect on the readings, but nothing that makes sense to me. I figure D and Q current should be at zero when the motor is set to zero torque. Q should fluctuate when I turn the motor by hand, and D should then also fluctuate to correct it in order to maintain zero current. Is this right?

#include <SimpleFOC.h>

//Motor Definition
BLDCMotor motor = BLDCMotor(7);
BLDCDriver6PWM driver = BLDCDriver6PWM(A_PHASE_UH, A_PHASE_UL, A_PHASE_VH, A_PHASE_VL, A_PHASE_WH, A_PHASE_WL);
LowsideCurrentSense currentSense = LowsideCurrentSense(0.003, -64.0/7.0, A_OP1_OUT, A_OP2_OUT, A_OP3_OUT);
//InlineCurrentSense currentSense = InlineCurrentSense(0.003, -64.0/7.0, A_OP1_OUT, A_OP2_OUT, A_OP3_OUT);

//Commander Definition
Commander commander = Commander(Serial, '\n', false);
void onMotor(char* cmd){commander.motor(&motor, cmd);}

// MagneticSensorI2C(uint8_t _chip_address, float _cpr, uint8_t _angle_register_msb)
//  chip_address         - I2C chip address
//  bit_resolution       - resolution of the sensor
//  angle_register_msb   - angle read register msb
//  bits_used_msb        - number of used bits in msb register
MagneticSensorI2C sensor = MagneticSensorI2C(0x40, 14, 0xFE, 8);
//MagneticSensorI2C sensor = MagneticSensorI2C(AS5048_I2C);


//Setup Code
void setup() {
  Serial.begin(115200);
  delay(1000);

  //Commander Setup
  commander.add('M',onMotor,"my motor");

  //init i2c position sensor (as5048b)
  sensor.init();
  Wire.setClock(400000); //set i2c clock speed to 400khz)
 
  //link motor to sensor
  motor.linkSensor(&sensor);

  driver.voltage_power_supply = 25.2;
  driver.init();
  // link the motor and the driver
  motor.linkDriver(&driver);

  // limiting motor movements
  motor.voltage_limit = 10;   // [V]
  motor.velocity_limit = 40; // [rad/s] 
  motor.voltage_sensor_align = 10;  //limits motor voltage during calibration of motor

  // current sense init hardware
  currentSense.skip_align = true; //skip current sensing since code is breaking here
  currentSense.init();
  motor.linkCurrentSense(&currentSense);


  //PID Settings
  motor.PID_velocity.P = 0.25;
  motor.PID_velocity.I = 20;
  motor.PID_velocity.D = 0;
  motor.LPF_velocity.Tf = 0.01; 
  
  motor.P_angle.P = 20;
  motor.P_angle.D = 1;
  motor.PID_velocity.output_ramp = 1000;
  motor.LPF_angle.Tf = 0.001;

  //control type
  motor.torque_controller = TorqueControlType::voltage;
  motor.controller = MotionControlType::torque;

  //use monitoring
  motor.useMonitoring(Serial);
  motor.monitor_variables = _MON_CURR_D | _MON_CURR_Q;
  motor.monitor_downsample = 100; //monitor every 100 calls

  // init motor hardware
  motor.init();
  motor.initFOC();

  //target value
  motor.target = 0;

}


void loop() {

  commander.run();
  
  motor.loopFOC();
  
  motor.move(); 
  
  motor.monitor();
}

I’m using the main library installed through arduino IDE, and the STM32 2.1.0. Am I supposed to use a dev branch? I tried to follow all the forums I could find regarding this board and current control, but I could easily be missing something major.

But this device does not have inline current-sense circuitry ! How will that ever work ???
It should have low-side current sensing hardware.
Most boards you can buy support this, but simplefoc doesn’t like it, because it creates a hardware-dependency. I believe there is a solution for this board, you should ask on this forum.

Thanks for your response. First of all the code I’ve posted is using Low side current sensing. But also according to the docs this board does have in line current sensing (see screenshot below). Also when going through old revisions of the code it appears it was only recently updated to support low side.
image

I haven’t had success with either, both give me similar random noisy graphs of current. Any ideas on why I might be doing wrong are greatly appreciated.

Cheers.

What do I need if I want my microcontroller to sense current ?

  • current-sensing hardware
  • a microcontroller + software.
    What you have is al list of microcontrollers/single-board computers for which software exists. But you don’t have the hardware.
    And “initial” means " “we’re working on it”.

I’m a newbie in the field, so please be lenient :slight_smile:

@Jan_Donker, on this SimpleFOC page, it really looks like the B_G431B_ESC1 can perform current sensing:

I agree with quentin. Jan, I understand that some of the controllers / drivers / combinations have different hardware and some don’t have current sensing hardware, but the B-G431B-ESC1 does, and people have it working with current sensing. See these threads:

B-G431B-ESC1: Beginner guide + I2C guide

B-G431B-ESC1 Current Control

I’m looking for a response from someone who has used the B-G431B_ESC1 board (someone from the other threads?) and can hopefully point out something obvious that I’m doing wrong with my setup. Any help is appreciated!

Cheers

Most commercial boards have low-side current sensing, but not inline sensing. That’s why all homemade “SimpleFOC compatible” boards have inline current sensing or no sensing at all. The G431-ESC board has low-side hardware, but support for it seems “under construction”. It just doesn’t fit the Arduino concept, where you are not supposed to talk to hardware directly.

Hey Folks,

I’ve realized my mistake. I just downloaded the dev branch and am getting sensible readings now in both inline and low side. My bad! Seems to be working now.

I’m looking forward to diving deeper into current control now.

Cheers!