QVADRANS v1.0 (fka Lepton 3.0)

Hi!
I am sorry that I was not able to use English well.

Thanks for the wonderful board!
I was just lamenting that the B-G431-ESC1 couldn’t use SPI communication.

I ordered five and they arrived last week.
I confirmed that I can control LED_Blink and OpenLoop using the information in this thread!
I want to do is torque control. I tried to run the code that was working with B-G431-ESC1, but the motor vibrates when it should be stationary, making a strange noise and randomly rotating a little at a time.
Regarding current sensing, I set it as follows, referring to the Power Shield-D thread. (Because it is the same current sensor)

InlineCurrentSense current_sense = InlineCurrentSense(0.055, 1.0, A0, A1, A2);

Would you help me?
What should I be suspicious of first?

Thanks.

This is all the code.

Summary

#include <SimpleFOC.h>

BLDCMotor motor = BLDCMotor(7);
BLDCDriver6PWM driver = BLDCDriver6PWM(PA8, PB13, PA9, PB14, PA10, PB15);

InlineCurrentSense currentSense = InlineCurrentSense(0.055f, 1.0f, PA0, PA1, PA2);

Encoder encoder = Encoder(PA3, PA4, 1000, PA5);

void doA() { encoder.handleA(); }
void doB() { encoder.handleB(); }
void doIndex() { encoder.handleIndex(); }

Commander command = Commander(Serial);
void doTarget(char* cmd) { command.motion(&motor, cmd); }

void setup() {
Serial.setRx(PB7);
Serial.setTx(PB6);
Serial.begin(115200);
encoder.init();
encoder.enableInterrupts(doA, doB, doIndex);

motor.linkSensor(&encoder);

driver.voltage_power_supply = 12;
driver.init();
motor.linkDriver(&driver);

currentSense.linkDriver(&driver);
currentSense.init();
currentSense.skip_align = true;
motor.linkCurrentSense(&currentSense);

motor.voltage_sensor_align = 1;
motor.velocity_index_search = 3;
motor.voltage_limit = 7;
motor.velocity_limit = 1000;

motor.controller = MotionControlType::velocity;
motor.torque_controller = TorqueControlType::foc_current;

motor.PID_current_q.P = motor.PID_current_d.P = 0.1;
motor.PID_current_q.I = motor.PID_current_d.I = 10;

motor.PID_velocity.P = 0.5;
motor.PID_velocity.I = 1;
motor.PID_velocity.output_ramp = 1000;
motor.LPF_velocity.Tf = 0.01;

motor.P_angle.P = 20;
motor.useMonitoring(Serial);

motor.init();
motor.initFOC();
command.add(‘T’, doTarget, “target angle”);

Serial.println(F(“Motor ready.”));
Serial.println(F(“Set the target angle using serial terminal:”));
_delay(1000);
}

void loop() {
motor.move();
motor.loopFOC();
command.run();
}

Is it possible for you to bake some kind of solution to carry higher current that does not require thicker copper? Suppose you put a through hole in the right places, and solder thick copper wire between them?

We have considered flooding traces with solder, but the ground plane is in the middle of the board so that can’t work there unfortunately :(.

I (finally :() sent a board out to Pete for testing, still got one more if anyone wants it.

Absolutely, but that would make the board bigger. If you are not concerned with space I can look into a large cheap variant a-la Krakatoa, but with built-in MCU.

Cheers,
Valentine

1 Like

What about lower resistance mosfets? I’m curious why you chose two 11mOhm dual-channels in parallel for each phase rather than two single-channels which can be <2mOhm with the same total footprint area. For example these are 1.2mOhm, so I would think you could use twice the current with similar heating. Do dual-channels have some advantage I’m not aware of?

1 Like

I have no idea, I was in a hurry?

Cheers,
Valentine

2 Likes

I’m not generally fussed about space. I think it’s fair to say most of us generally are not, when we look at the other boards people are trying to prepare. For the big fan project I’ve got lots of space. The TW4 fan has taken a different direction but there is plenty of space in there.

I think the original simplefoc board is quite a bit larger still.

Mind you, I don’t need higher current either, personally. So none of it’s about me, but I think it’s fair to say a lot of people do want the extra current and if it’s that much power it’s a fairly big machine, not likely to be space constrained.

Variants can always be produced, I think the base design should not be space constrained, that makes things hard to experiment with and so on. I was going to break the pins out to 2.54 mm through holes on the edges probably at some point.

Sorry I’ve really had to put all this on the back burner, but I will be here to pay for boards and mail them out, that’s all I can really promise right now. I’m not great with the ecad stuff.

Hey guys I’m back!
Got everything setup with a ST-Link, we also added a 2.57mm pitch breakout shield for the Qvadrans (v1.0) not the new one I saw floating around in the comments.

I’m able to

  • Blink the blue LED
  • Readout Hall sensor position and velocity

I’m however unable to initialise the driver :smiling_face_with_tear:.
I tried adding the SimpleFOCDebug::enable but I get no verbose output on my Serial monitor.
Added this line but gave the same result.

build_flags = 
	-D SIMPLEFOC_STM32_DEBUG

Here’s my setup:

  • ST-Link V3 with SWD + UART for serial monitoring
  • Qvadrans supplied with 24V


Code:

  • platform.ini
; PlatformIO Project Configuration File
;
;   Build options: build flags, source filter
;   Upload options: custom upload port, speed and extra flags
;   Library options: dependencies, extra library storages
;   Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html

[platformio]
; change this if you want to compile for another board
; To distinguish in the code, use #ifdef <board macro> to enable board-specific code for each target, e.g. #ifdef ARDUINO_AVR_PROMICRO16 et cetera.
default_envs = genericSTM32G431CB

[common]
lib_archive = false
lib_deps_builtin =
	Arduino
    SPI
    Wire

lib_deps = askuric/Simple FOC@^2.3.4

[env:genericSTM32G431CB]
platform = ststm32@17.3.0
board = genericSTM32G431CB
framework = arduino
upload_protocol = stlink
debug_tool = stlink
; Enable serial monitor at 115200
monitor_speed = 115200
build_flags = 
	-D SIMPLEFOC_STM32_DEBUG
  • main.cpp
#include <Arduino.h>
#include <SimpleFOC.h>


#define DebugSerial Serial
#define LED_BUILTIN PC11

// Hall sensor instance
// HallSensor(int hallA, int hallB , int hallC , int pp)
//  - hallA, hallB, hallC    - HallSensor A, B and C pins
//  - pp                     - pole pairs
HallSensor sensor = HallSensor(PB10, PB11, PB12, 7);

// Define the BLDC motor driver, Qvadrans supports 6PWM mode
// BLDCDriver6PWM( int phA_h, int phA_l, int phB_h, int phB_l, int phC_h, int phC_l, int en)
// the pins PA8, PB13, PA9, PB14, PA10, PB15 are standard for STM32 chips
BLDCDriver6PWM driver = BLDCDriver6PWM(PA8, PB13, PA9, PB14, PA10, PB15);

// Define the BLDC motor

// Interrupt routine initialization
// channel A and B callbacks
void doA(){sensor.handleA();}
void doB(){sensor.handleB();}
void doC(){sensor.handleC();} 

bool LED_ON = HIGH;

void setup() {
  // Setup serial monitoring through UART
  DebugSerial.setTx(PB6); // using USART - connect to CN3 Tx connector on ST-Link 
  DebugSerial.setRx(PB7); // using USART - connect to CN3 Rx connector on ST-Link 
  DebugSerial.begin(115200);
  // enable SimpleFOC debugging mode to get more verbose outputs.
  SimpleFOCDebug::enable(&DebugSerial);

  // Initialize LED pin as an output.
  pinMode(LED_BUILTIN, OUTPUT);  // LED_BUILTIN 
  digitalWrite(LED_BUILTIN, HIGH);

  // set driver parameters
  driver.voltage_power_supply = 24;
  driver.voltage_limit = 12;
  driver.dead_zone = 0.05;

  SIMPLEFOC_DEBUG("Hello world!");
  delay(2000);
  // init driver
  SIMPLEFOC_DEBUG("Driver init ... ");
  if (driver.init())  {
    SIMPLEFOC_DEBUG("Driver init succesful!");
  }
  else{
    digitalWrite(LED_BUILTIN, LOW);
    SIMPLEFOC_DEBUG("Driver init failed!");
    return;
  }

  // enable the driver
  SIMPLEFOC_DEBUG("Enabling driver ...");
  driver.enable();
  _delay(1000);
}

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

The only output I get in my serial monitor:

 *  Executing task: platformio device monitor 

--- Terminal on /dev/cu.usbmodem1103 | 115200 8-N-1
--- Available filters and text transformations: colorize, debug, default, direct, hexlify, log2file, nocontrol, printable, send_on_enter, time
--- More details at https://bit.ly/pio-monitor-filters
--- Quit: Ctrl+C | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H
Driver init ... 
Driver init failed!

Could you guys help me figuring out how to get the verbose SimpleFOCDebugging active?
Is it because of the Tx Rx being used on the Serial monitor?

Smh seemed to be that the [common] tag in the platform.ini file is doing nothing. I moved the lib_deps and lib_archive tags into my environment and suddenly it started working!

Tried several variations because I saw that by tweaking the Spacedays Git repo it did work and gave me some verbose outputs!

I ended up with this platform.ini file.

; PlatformIO Project Configuration File
;
;   Build options: build flags, source filter
;   Upload options: custom upload port, speed and extra flags
;   Library options: dependencies, extra library storages
;   Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html

[platformio]
; change this if you want to compile for another board
; To distinguish in the code, use #ifdef <board macro> to enable board-specific code for each target, e.g. #ifdef ARDUINO_AVR_PROMICRO16 et cetera.
default_envs = genericSTM32G431CB

[env:genericSTM32G431CB]
; commented away version @17.3.0
platform = ststm32
board = genericSTM32G431CB
framework = arduino
upload_protocol = stlink

build_flags = 
    -D ARDUINO_GENERIC_G431CBUX
lib_deps = askuric/Simple FOC@^2.3.4
lib_archive = false
; Enable serial monitor at 115200
monitor_speed = 115200

This was my output now:

 *  Executing task: platformio device monitor 

--- Terminal on /dev/cu.usbmodem1103 | 115200 8-N-1
--- Available filters and text transformations: colorize, debug, default, direct, hexlify, log2file, nocontrol, printable, send_on_enter, time
--- More details at https://bit.ly/pio-monitor-filters
--- Quit: Ctrl+C | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H
Driver init ... 
TIM1-CH1 TIM1-CH1N TIM1-CH2 TIM1-CH2N TIM1-CH3 TIM1-CH3N score: 1
TIM1-CH1 TIM1-CH1N TIM1-CH2 TIM1-CH2N TIM1-CH3 TIM15-CH1N score: -6
TIM1-CH1 TIM1-CH1N TIM1-CH2 TIM1-CH2N TIM1-CH3 TIM15-CH2 score: -6
TIM1-CH1 TIM1-CH1N TIM1-CH2 TIM1-CH2N TIM2-CH4 TIM1-CH3N score: -6
TIM1-CH1 TIM1-CH1N TIM1-CH2 TIM1-CH2N TIM2-CH4 TIM15-CH1N score: -6
TIM1-CH1 TIM1-CH1N TIM1-CH2 TIM1-CH2N TIM2-CH4 TIM15-CH2 score: -6
TIM1-CH1 TIM1-CH1N TIM1-CH2 TIM15-CH1 TIM1-CH3 TIM1-CH3N score: -6
TIM1-CH1 TIM1-CH1N TIM1-CH2 TIM15-CH1 TIM1-CH3 TIM15-CH1N score: -6
TIM1-CH1 TIM1-CH1N TIM1-CH2 TIM15-CH1 TIM1-CH3 TIM15-CH2 score: -6
TIM1-CH1 TIM1-CH1N TIM1-CH2 TIM15-CH1 TIM2-CH4 TIM1-CH3N score: -6
TIM1-CH1 TIM1-CH1N TIM1-CH2 TIM15-CH1 TIM2-CH4 TIM15-CH1N score: -6
TIM1-CH1 TIM1-CH1N TIM1-CH2 TIM15-CH1 TIM2-CH4 TIM15-CH2 score: -6
TIM1-CH1 TIM1-CH1N TIM2-CH3 TIM1-CH2N TIM1-CH3 TIM1-CH3N score: -6
TIM1-CH1 TIM1-CH1N TIM2-CH3 TIM1-CH2N TIM1-CH3 TIM15-CH1N score: -6
TIM1-CH1 TIM1-CH1N TIM2-CH3 TIM1-CH2N TIM1-CH3 TIM15-CH2 score: -6
TIM1-CH1 TIM1-CH1N TIM2-CH3 TIM1-CH2N TIM2-CH4 TIM1-CH3N score: -6
TIM1-CH1 TIM1-CH1N TIM2-CH3 TIM1-CH2N TIM2-CH4 TIM15-CH1N score: -6
TIM1-CH1 TIM1-CH1N TIM2-CH3 TIM1-CH2N TIM2-CH4 TIM15-CH2 score: -6
TIM1-CH1 TIM1-CH1N TIM2-CH3 TIM15-CH1 TIM1-CH3 TIM1-CH3N score: -6
TIM1-CH1 TIM1-CH1N TIM2-CH3 TIM15-CH1 TIM1-CH3 TIM15-CH1N score: -6
TIM1-CH1 TIM1-CH1N TIM2-CH3 TIM15-CH1 TIM1-CH3 TIM15-CH2 score: -6
TIM1-CH1 TIM1-CH1N TIM2-CH3 TIM15-CH1 TIM2-CH4 TIM1-CH3N score: -6
TIM1-CH1 TIM1-CH1N TIM2-CH3 TIM15-CH1 TIM2-CH4 TIM15-CH1N score: -6
TIM1-CH1 TIM1-CH1N TIM2-CH3 TIM15-CH1 TIM2-CH4 TIM15-CH2 score: -6
STM32-DRV: best: TIM1-CH1 TIM1-CH1N TIM1-CH2 TIM1-CH2N TIM1-CH3 TIM1-CH3N score: 1
STM32-DRV: Syncronising timers! Timer no. 1
STM32-DRV: Restarting timer 1
Driver init succesful!
Enabling driver ...

Here’s my main.cpp file again:

#include <Arduino.h>
#include <SimpleFOC.h>


#define DebugSerial Serial
#define LED_BUILTIN PC11

// Hall sensor instance
// HallSensor(int hallA, int hallB , int hallC , int pp)
//  - hallA, hallB, hallC    - HallSensor A, B and C pins
//  - pp                     - pole pairs
HallSensor sensor = HallSensor(PB10, PB11, PB12, 7);

// Define the BLDC motor driver, Qvadrans supports 6PWM mode
// BLDCDriver6PWM( int phA_h, int phA_l, int phB_h, int phB_l, int phC_h, int phC_l, int en)
// the pins PA8, PB13, PA9, PB14, PA10, PB15 are standard for STM32 chips
BLDCDriver6PWM driver = BLDCDriver6PWM(PA8, PB13, PA9, PB14, PA10, PB15);

// Define the BLDC motor

// Interrupt routine initialization
// channel A and B callbacks
void doA(){sensor.handleA();}
void doB(){sensor.handleB();}
void doC(){sensor.handleC();} 

bool LED_ON = HIGH;

void setup() {
  // Setup serial monitoring through UART
  DebugSerial.setTx(PB6); // using USART - connect to CN3 Tx connector on ST-Link 
  DebugSerial.setRx(PB7); // using USART - connect to CN3 Rx connector on ST-Link 
  DebugSerial.begin(115200);
  // enable SimpleFOC debugging mode to get more verbose outputs.
  SimpleFOCDebug::enable(&DebugSerial);

  // Initialize LED pin as an output.
  pinMode(LED_BUILTIN, OUTPUT);  // LED_BUILTIN 
  digitalWrite(LED_BUILTIN, HIGH);

  // set driver parameters
  driver.voltage_power_supply = 24;
  driver.voltage_limit = 12;
  driver.dead_zone = 0.05;
  // pwm frequency to be used [Hz]
  driver.pwm_frequency = 25000;

  SIMPLEFOC_DEBUG("Hello world!");
  delay(2000);
  // init driver
  SIMPLEFOC_DEBUG("Driver init ... ");
  if (driver.init())  {
    SIMPLEFOC_DEBUG("Driver init succesful!");
  }
  else{
    digitalWrite(LED_BUILTIN, LOW);
    SIMPLEFOC_DEBUG("Driver init failed!");
    return;
  }

  // enable the driver
  SIMPLEFOC_DEBUG("Enabling driver ...");
  driver.enable();
  _delay(1000);
}

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

To get a shared set of environment settings, I think you need to replace [common] with [env]. That’s what’s been working for me, at least. Glad to hear you got it working!

Side note, I also have received Anthony’s board and (after many delays…) plan on testing it this week now that I have the rest of my workspace set up again. The V1.0 qvadrans boards still seem to be behaving well for my (very low performance) uses, too.

2 Likes

Hi @Valentine,

I was trying to look for the “improved” pcb design of the QVADRANS but I’m unable to find it, it looks like the project is gone from this link:

https://oshwlab.com/cost.co/20230516_lepton_pro_g431

Is it now the QVADRANS v1.1?

All Valentine’s designs are provided for the time being.

You’ll have to message him to see if he will send you the 1.1 board
Edit: Just noticed you ping him. That should get his attention.

2 Likes

@Zeno Please message me, thank you.

Cheers,
Valentine

@Valentine have you ever seen DRV8300D work before? I’m at the end of my rope trying to get it going on my Gooser design. The bootstrap capacitors won’t charge up except for a tiny blip during deadtime after high side switches off and before low side switches on. I’ve tried 470nF, 100nF, different battery voltages, and adding gate resistors, and nothing makes a difference. If it works on Qvadrans (or anything else) I’ll continue struggling with it, but otherwise I have no working example to refer to, and no more ideas to try.

EDIT: The answer is yes! Anthony has finally returned to the forum and replied to my PM from a few weeks ago, and his Qvadrans boards have DRV8300 and work in open loop. They also have the theoretically-unnecessary bootstrap diodes, so I’ll transplant some from a dead Lepton and see if that does it. But in any case, I now know that it should work the way I have it wired up.

I’m so sorry it took so long for me to reply, I would like to have helped more sooner. If anyone needs to contact me in the future it’s anthony . a. douglas at gmail dot com.

I’m very sad and frustrated that we’ve lost the latest version. Valentine, I understand your concern I think on some level, but can we have back just this design? I forget the modifications we made and am not very good at this stuff so it’s very hard for me to try to recreate the modifications, I think they were important changes to the grounding which I have only marginal understanding of.

I really think this board has potential to unite the community to some degree. It’s been working to some moderate degree.

I would like to modify the best known design to increase the pitch of the through holes, change the wiring so we can use the interesting current measurement method (bias one side of the op amps with the DAC and change the gain of the op amps on the fly to add bits of resolution to our current measurement method) and a few other things.

I can’t afford to risk importing an issue that’s already been solved by reverting to 1.0.

The simplefoc board was generally used by a lot of people for a lot of things including for profit and I was under the impression we were generally ok with that.

My project is pseudo for profit, it is funded but open source.

I am willing to pay for the next batch of boards, probably 10 this time, and mail them out to others who wish to have them, at my expense (some of the funding is explicitly to develop this board).

I need anti cogging for noise, it’s an air filter appliance and it has to be super super quiet. I can’t get amotor that’s low cogging in this size range etc. Either I use this board or I have to crawl back to the b-g431-esc1 board, whic is not good, it’s expensive, unreliable and the work that goes into it does not benefit the community for the long term nearly as well.

I believe the next version of the qvadrans will be superior on basically every count, current capacity, voltage, current measurement resolution, price, everything but size which is not a priority for most of us.

As I mentioned, I’m traveling, will be back after TG.

No worry nothing is lost, just reorgs. I’m not going away or anything.

Cheers,
Valentine

UPDATE: ok I’ve been able to use the board to make a quiet motor driver, but it’s become clear there is an issue with noise on the hall sensors. It may be coming from the ground plane or something, similar to the lepton.

the B-g431-esc1 board works ok, no problems on this count. Nearly the same program, all I changed was the pinouts to make it work on the b-g431 board.

So this seems to be an issue, which I was afraid of. Putting capacitors on the pins (3.9 nf) helped significantly but it’s not solved. I can’t use the board as is, I have had to run back to the b-g431 board until I can eventually figure this out and solve it.

How does the b-g431 board reduce noise and why can’t we just copy them?