SimpleFOC-PowerShield

Hey Guys,
Yes I am excited about this baord! It has been completely inspired by the infineons board.
https://community.simplefoc.com/t/infineon-bldc-shields-impressions/417

It is designed to support the middle range BLDC motors up to 500W. I am still a bit in the testing phase, namely to determine which kind of current sensing we will be able to use with it and what is the actual current it will be able to withstand. :smiley:

Features for now

  • Plug & play: In combination with Arduino SimpleFOClibrary - github
  • Low-cost: Current price of fabrication is less then 20€
  • High-side current sensing: - not yet supported by SimpleFOClibrary
  • Max power >500W: max current 30A, power-supply 24V
  • Arduino headers: Arduino UNO, Arduino MEGA, STM32 Nucleo boards, Aruidno DUE…
  • Small size: 55mm x 55mm
  • Open Source: Fully available fabrication files

Future features

  • Stackable: running 2 motors in the same time
  • Encoder/Hall sensors interface: Integrated 3.3kΩ pullups (configurable)
  • I2C interface: Integrated 4.7kΩ pullups (configurable)
  • Configurable pinout: Hardware configuration - soldering connections

How to use it

This board has enable pins for each of the phases for now and it has completely static pinout.

name description pin
IN1 pwm 1 9
IN2 pwm 2 6
IN3 pwm 3 5
INH1 enable 1 8
INH2 enable 2 7
INH3 enable 3 4

The simplefoc library v2.0.x does not support the BLDC drivers with 3 enable pins.

simplefoc library v2.1

But if you download the dev version which will be released very soon it does so you can just do:

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

// BLDC motor & driver instance
// BLDCMotor motor = BLDCMotor(pole pair number);
BLDCMotor motor = BLDCMotor(11);
// BLDCDriver3PWM driver = BLDCDriver3PWM(pwmA, pwmB, pwmC, Enable(optional));
BLDCDriver3PWM driver = BLDCDriver3PWM(9, 5, 6, 8, 7, 4);

//target variable
float target_velocity = 0;

// instantiate the commander
Commander command = Commander(Serial);
void doTarget(char* cmd) { command.variable(&target_velocity, cmd); }
void doLimit(char* cmd) { command.variable(&driver.voltage_limit, cmd); motor.voltage_limit=driver.voltage_limit/2;}

void setup() {

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

  // limiting motor movements
  motor.voltage_limit = 0.5;   // [V]
  motor.velocity_limit = 5; // [rad/s] cca 50rpm
 
  // open loop control config
  motor.controller = MotionControlType::velocity_openloop;

  // init motor hardware
  motor.init();

  // add target command T
  command.add('T', doTarget, "target velocity");
  command.add('L', doLimit, "voltage limit");

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

void loop() {

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

  // user communication
  command.run();
}

Thie example uses some of the new features of the simplefoc v2.1, for example Commander interface.
In this example you can set/get target velocity with commad T. For example to get target velocity just send T and to set for example 2.5 rad/s send T2.5.
The same can be done for the voltage limit, with command L.

simplefoc library v2.0.x

For the version of the library v2.0.x you can enable additional pins by hand, here is an example:

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

// BLDC motor & driver instance
// BLDCMotor motor = BLDCMotor(pole pair number);
BLDCMotor motor = BLDCMotor(11);
// BLDCDriver3PWM driver = BLDCDriver3PWM(pwmA, pwmB, pwmC, Enable(optional));
BLDCDriver3PWM driver = BLDCDriver3PWM(9, 5, 6);

void setup() {

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

  // enbale pins set to high
  pinMode(8,OUTPUT); // inh1
  pinMode(7,OUTPUT); // inh2
  pinMode(4,OUTPUT); // inh3
  digitalWrite(7,HIGH);
  digitalWrite(4,HIGH);
  digitalWrite(8,HIGH);

  // limiting motor movements
  motor.voltage_limit = 1;   // [V]
  motor.velocity_limit = 5; // [rad/s]

  // open loop control config
  motor.controller = ControlType::velocity_openloop;

  // init motor hardware
  motor.init();

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

float target_velocity = 0; // [rad/s]

void loop() {
  // open loop velocity movement
  // using motor.voltage_limit and motor.velocity_limit
  motor.move(target_velocity);

  // receive the used commands from serial
  serialReceiveUserCommand();
}

// utility function enabling serial communication with the user to set the target values
// this function can be implemented in serialEvent function as well
void serialReceiveUserCommand() {

  // a string to hold incoming data
  static String received_chars;

  while (Serial.available()) {
    // get the new byte:
    char inChar = (char)Serial.read();
    // add it to the string buffer:
    received_chars += inChar;
    // end of user input
    if (inChar == '\n') {

      // change the motor target
      target_velocity = received_chars.toFloat();
      Serial.print("Target velocity ");
      Serial.println(target_velocity);

      // reset the command buffer
      received_chars = "";
    }
  }
}
1 Like