TMC6300 on Arduino Uno + a GM3506

Hi There
I’m tryin to make a setup, where I controll a GM3506 BLDC motor with the TMC 6300 motor
The code can be compiled, but the motor just makes a weird noice, move back and forth very quick and does not really do anything. I think it is maybe something to to with my motor driver, but I’m not sure. Can anyone PLEASE help me?

I have connected the pins on the tmc6300 to the Arduino pins

const int phU_h = 5;
const int phU_l = 6;
const int phV_h = 9;
const int phV_l = 10;
const int phW_h = 3;
const int phW_l = 11;

Also there is connected 5V to VIO and GND GND

This is what the serial print says
MOT: Monitor enabled!
MOT: Init
MOT: Enable driver.
MOT: Align sensor.
MOT: sensor_direction==CW
MOT: PP check: fail - estimated pp: 14.06
MOT: Zero elec. angle: 2.23
MOT: No current sense.
MOT: Ready.
Motor commands sketch | Initial motion control > torque/voltage : target 2V.
1.0000	1.0000	-0.0329	0.7191
1.0000	1.0000	-0.2727	0.7121
1.0000	1.0000	0.2640	0.7191
1.0000	1.0000	0.3684	0.7191
1.0000	1.0000	-0.0946	0.7121
1.0000	1.0000	-0.3737	0.7121
1.0000	1.0000	-0.2988	0.7121
1.0000	1.0000	-0.2178	0.7121
1.0000	1.0000	-0.2556	0.7121

Here is my code:

#include <SimpleFOC.h>

const int phU_h = 5;
const int phU_l = 6;
const int phV_h = 9;
const int phV_l = 10;
const int phW_h = 3;
const int phW_l = 11;

const int encoder_J = A3;

// instantiate motor
//  BLDCMotor( pole_pairs , ( phase_resistance, KV_rating  optional) )
BLDCMotor motor = BLDCMotor(11);

// instantiate driver

//  BLDCDriver6PWM( int phA_h, int phA_l, int phB_h, int phB_l, int phC_h, int phC_l, int en)
//  - phA_h, phA_l - A phase pwm pin high/low pair
//  - phB_h, phB_l - B phase pwm pin high/low pair
//  - phB_h, phC_l - C phase pwm pin high/low pair
//  - enable pin    - (optional input)
BLDCDriver6PWM driver = BLDCDriver6PWM(phU_h,phU_l, phV_h,phV_l, phW_h,phW_l);



// instantiate sensor
// MagneticSensorPWM(uint8_t _pinPWM, int _min_raw_count, int _max_raw_count)
// - _pinPWM:         the pin that is reading the pwm from magnetic sensor
// - _min_raw_count:  the minimal length of the pulse (in microseconds)
// - _max_raw_count:  the maximal length of the pulse (in microseconds)
MagneticSensorPWM sensor = MagneticSensorPWM(encoder_J, 4, 904);


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

void setup() {

  pinMode(encoder_J, INPUT);
  pinMode(phU_h, OUTPUT);
  pinMode(phU_l, OUTPUT);
  pinMode(phV_h, OUTPUT);
  pinMode(phV_l, OUTPUT);
  pinMode(phW_h, OUTPUT);
  pinMode(phW_l, OUTPUT);


  // init sensor
  // initialize magnetic sensor hardware
  sensor.init();


  // link the motor to the sensor
  motor.linkSensor(&sensor);

  // init driver
  // pwm frequency to be used [Hz]
  driver.pwm_frequency = 20000;



  // power supply voltage [V]
  driver.voltage_power_supply = 10;
  // Max DC voltage allowed - default voltage_power_supply
  driver.voltage_limit = 10;

    // daad_zone [0,1] - default 0.02 - 2%
  driver.dead_zone = 0.05;

  // driver init
  driver.init();

  // enable driver
  driver.enable();

  // link the motor to the driver
  motor.linkDriver(&driver);

  // aligning voltage [V]
  motor.voltage_sensor_align = 3; // default 3V

  // enable monitoring
  // use monitoring with the BLDCMotor
  Serial.begin(9600);
  // monitoring port
  motor.useMonitoring(Serial);




  // configure motor
   // set control loop type to be used
  motor.controller = MotionControlType::torque;


  // contoller configuration based on the control type
  motor.PID_velocity.P = 0.2;
  motor.PID_velocity.I = 20;
  motor.PID_velocity.D = 0;
  // default voltage_power_supply
  motor.voltage_limit = 10;

  // velocity low pass filtering time constant
  motor.LPF_velocity.Tf = 0.01;

  // angle loop controller
  motor.P_angle.P = 20;
  // angle loop velocity limit
  motor.velocity_limit = 50;




  // initialize motor
  motor.init();

  // align encoder and start FOC
  motor.initFOC();


   // set the inital target value
  motor.target = 1;

  // define the motor id
  command.add('A', onMotor, "motor");

  // Run user commands to configure and the motor (find the full command list in docs.simplefoc.com)
  Serial.println(F("Motor commands sketch | Initial motion control > torque/voltage : target 2V."));

  _delay(1000);



}

void loop() {

  // FOC execution
  // FOC algorithm function
  motor.loopFOC();

  // motion control loop
  // velocity control loop function
  // setting the target velocity or 2rad/s
  motor.move();

  // monitor variables
  // monitoring function outputting motor variables to the serial terminal
  motor.monitor();

    // read user commands
  command.run();

}

@JesperSondergaard

Welcome to the community.

Before you run closed loop and sensor, please make sure your motor runs in the simplest open velocity loop. Else debugging will be exceedingly complex.

Once you get the setup to run open velocity we can help further.

Good pictures/videos of the setup will be very helpful.

Cheers,
Valentine

Hi Valentine
Thank you for your message.

So, I tried to implement this code, but still the motor does not move, now its just locked into its position… Should it be able to move around?

#include <SimpleFOC.h>

const int phU_h = 5;
const int phU_l = 6;
const int phV_h = 9;
const int phV_l = 10;
const int phW_h = 3;
const int phW_l = 11;

// BLDCDriver6PWM( int phA_h, int phA_l, int phB_h, int phB_l, int phC_h, int phC_l, int en)
// - phA_h, phA_l - A phase pwm pin high/low pair
// - phB_h, phB_l - B phase pwm pin high/low pair
// - phB_h, phC_l - C phase pwm pin high/low pair
// - enable pin - (optional input)
BLDCDriver6PWM driver = BLDCDriver6PWM(phU_h,phU_l, phV_h,phV_l, phW_h,phW_l);

void setup() {

pinMode(phU_h, OUTPUT);
pinMode(phU_l, OUTPUT);
pinMode(phV_h, OUTPUT);
pinMode(phV_l, OUTPUT);
pinMode(phW_h, OUTPUT);
pinMode(phW_l, OUTPUT);

// pwm frequency to be used [Hz]
driver.pwm_frequency = 20000;
// power supply voltage [V]
driver.voltage_power_supply = 10;
// Max DC voltage allowed - default voltage_power_supply
driver.voltage_limit = 10;
// daad_zone [0,1] - default 0.02 - 2%
driver.dead_zone = 0.05;

// 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);
}

I finnally got a breakthrough!!! :slight_smile:

I Implemented the code from the openloop and now it spins like a baby!!!
I found the code at: Getting started | Arduino-FOC

Step 2. Testing the driver + motor combination - open-loop

And put in my names/values in the code

Also I can control the speed from the command line :slight_smile:
image

This code works :slight_smile:

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

const int phU_h = 5;
const int phU_l = 6;
const int phV_h = 9;
const int phV_l = 10;
const int phW_h = 3;
const int phW_l = 11;

// BLDC motor & driver instance
// BLDCMotor motor = BLDCMotor(pole pair number, phase resistance (optional) );
BLDCMotor motor = BLDCMotor(11);

BLDCDriver6PWM driver = BLDCDriver6PWM(phU_h,phU_l, phV_h,phV_l, phW_h,phW_l);

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

void setup() {

pinMode(phU_h, OUTPUT);
pinMode(phU_l, OUTPUT);
pinMode(phV_h, OUTPUT);
pinMode(phV_l, OUTPUT);
pinMode(phW_h, OUTPUT);
pinMode(phW_l, OUTPUT);

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

// limiting motor movements
// motor.phase_resistance = 3.52 // [Ohm]
// motor.current_limit = 2; // [Amps] - if phase resistance defined
motor.voltage_limit = 3; // [V] - if phase resistance not defined
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”);

Serial.begin(9600);
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();

// user communication
command.run();
}

That’s the problem, good you figured it out yourself!

Cheers,
Valentine

That’s great, @JesperSondergaard , open loop is working, so this means motor and PWM are working, you have the right pins, etc…

Closed loop is not working - one likely reason is the PWM sensor. While some people have made them work, it is difficult, they are quite low resolution and very slow, limiting your loop speed severely.
I would recommend trying a different sensor, especially if it is your first project with SimpleFOC, using the PWM sensor could just be an exercise in frustration.

Hi @runger
Thank you for your reply
So, would it be better to use the spi interface on the AS5048A?

Much better!

PWM operates at 1kHz - so your loop speed will be limited to this low speed. The SPI interface can operate at 10MHz clock speed, and return values within a few microseconds. That will enable a much faster loop speed, which is better for control.

@Awesome, thank you, Ill will try it out tomorrow and let you all know :slight_smile: This is such a great community, thank you so much for the help. It is good to have this opportunity, when I am writing my thesis :slight_smile:

1 Like