Adafruit QT PY or Seeed Xiao boards and simplefoc

I just saw these “qt py” boards from adafruit, they are so low profile and they seem to be either samd21, esp32 or rp2040 based.

I was wondering if some of you have had a chance to test the simplefoc on these tiny mcus?

I’ve tested on the SAMD21 version, but I was only running the code and testing communications, not really running a motor…

They’re a bit low on pin-count, but otherwise no reason they can’t run. Seeed Studio sells the same boards as "Seeed Xiao"s

Nice!
yeah, the pin count is really low. But they might allow for encoder based closed voltage closed loop control. Even maybe with current sensing.

I was wondering if this could be a good format for SimpleFOCmini.

I’m using the waveshare rp2040-zero which has almost the same footprint. (~4€)
I never missed current sensing for gimbal motors.

It builds a nice little package with the simpleFOC-mini.

1 Like

Nice!

Is there some kind of standard dimension/pinout for these boards?
It seems that they are more or less 18mm wide.

The waveshare version has a few more pins (23) which makes it 18x23.5mm.
Unfortunately you can’t use these pins on a breadboard test-setup.

At least Seeed and Adafruit have agreed on the “standard” :smiley:

@o_lampe is that your extruder?

Yes, it’s part of it. The whole setup looks like this:

2 Likes

What printer is it for? Did you open-source the designs? I’d be interested in trying it out sometime…

What are the advantages of using a BLDC in an extruder?

That’s a good question! For me, probably only that I have lots of BLDCs and drivers for them…

Perhaps the motor can be more quiet and have more torque when driven with FOC. But that would work with a stepper motor also. But for the stepper the demands on MCU and sensor are much higher for FOC, due to high pole count. So maybe, under the assumption you want closed loop FOC control of your stepper, then doing it with a BLDC is slightly cheaper than doing it with the stepper.

But I guess compared to the very cheap and well-tested solutions with stepper motors it’s not a reasonable proposition for users that just want to 3D-print stuff.

I believe another draw is that BLDC are usually much lighter than the pancake steppers, too.

1 Like

I’m not sure if I should hijack this thread?
In short: it is a DIY delta printer with direct drive extruder. The reason I started using BLDC motors was the fact, that I couldn’t find hollow shaft steppers in the right size.
I needed the hollow shaft, because I wanted to try a new screw extruder drive called VDE100 which requires a hollow shaft. (short video with NEMA8)
While waiting for an optical encoder I ran the BLDC on a “sherpa mini” extruder, because it would also work with magnetic sensors. That’s the picture I posted.
It turned out, that the motor has more torque than the usual NEMA14 pancake it is supposed to replace.

2 Likes

Hello!
Has anyone tested the Seeed Studio Xiao board?

I’ve just bought two of them to test after seeing this thread. Unfortunately not working for me with

I’ve tried pin combinations
0,1,2,3
1,2,3,6
10,9,8,7
7,2,3,6

Here is the pinout of QT PY SAMD21:

On my QT PY based on SAMD21 I was able to get the PWM right away on pins 2,3,4 (A2, A3, SDA)

// BLDC driver standalone example
#include <SimpleFOC.h>


// BLDC driver instance
BLDCDriver3PWM driver = BLDCDriver3PWM(2, 3, 4);

void setup() {
  
  // pwm frequency to be used [Hz]
  // for atmega328 fixed to 32kHz
  // esp32/stm32/teensy configurable
  driver.pwm_frequency = 50000;
  // power supply voltage [V]
  driver.voltage_power_supply = 12;
  // Max DC voltage allowed - default voltage_power_supply
  driver.voltage_limit = 12;

  // driver init
  driver.init();

  // enable driver
  driver.enable();

  _delay(1000);
}

void loop() {
    // setting pwm
    // phase A: 3V
    // phase B: 6V
    // phase C: 5V
    driver.setPwm(3,6,5);
}

The first two of your combinations should not work as the pins 0 and 1 are not associated to a PWM timer. But the other two should work, at least if your board is SAMD21 based. :smiley:

Hi @Antun_Skuric,

I am also able to get pwm outputs and the motor seems to be ‘moved’, but unfortunately just
oscillates in place, like when you have two phase connected and one missing.
But I’ve confirmed that all three phases are connected and swapping to other esp32 / arduino uno works fine.

Were you able to get the motor to spin?

Cheers,

Could I ask you to add debugging to your code:

void setup() {
  Serial.begin(115200);
  SimpleFOCDebug::enable(Serial);
  delay(5000); // wait 5s for serial connection

  ...
}

And add the build-flag -DSIMPLEFOC_SAMD_DEBUG

If using PlatformIO, then you can put the build-flag in the build_flags section of the platformio.ini

If using ArduinoIDE, you can add the flag in your global platform.txt file. So if your Arduino IDE installation is at “C:\Program Files (x86)\Arduino” then the location of the global platform.txt is “C:\Program Files (x86)\Arduino\hardware\platform.txt”

Once you do this, if you run the code and monitor the serial port, it will print information about the timers it wants to use… then we will see what is wrong with your pins.

Could you also share the code you’re running? Maybe its not the pins but another problem.

As Antun has written, some of the pin combinations you tried should actually work.

I can confirm that in on pins 2,3 and 4 my motor tuns:

Here is the example code that I’ve used.

// 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(2, 3, 4, 5);

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

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

void setup() {
  // driver config
  // power supply voltage [V]
  driver.voltage_power_supply = 12;
  // limit the maximal dc voltage the driver can set
  // as a protection measure for the low-resistance motors
  // this value is fixed on startup
  driver.voltage_limit = 6;
  driver.init();
  // link the motor and the driver
  motor.linkDriver(&driver);

  // limiting motor movements
  // limit the voltage to be set to the motor
  // start very low for high resistance motors
  // current = voltage / resistance, so try to be well under 1Amp
  motor.voltage_limit = 3;   // [V]
 
  // open loop control config
  motor.controller = MotionControlType::velocity_openloop;

  // init motor hardware
  motor.init();

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

  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
  // to turn the motor "backwards", just set a negative target_velocity
  motor.move(target_velocity);

  // user communication
  command.run();
}

Hi @runger and @Antun_Skuric ,

Thanks!

Just saw this, unfortunately haven’t been checking the forum in 2 days.

I’ll do more tests tomorrow :slight_smile:

Cheers,