hello everyone,
I’m currently working on a similar project. We have a lot of old sewing machines at home. However, their motors are too weak to sew through thick material such as denim.
I’m now posting my experiences and questions in this thread. I hope that’s okay.
The first thing I bought was this BLDC motor together with a suitable motor driver:
The whole thing works pretty well and is a pretty simple solution.
Next I want to try out SimpleFoc for the motor control. I have now bought the DRV8302 as a driver board. The Hall sensor control works and I can already control the motor with the Voltage Torque Control. The next step I wanted to try was the DC Torque Control. But I’m having trouble parameterizing the PID-Q controller. The controller is extremely unstable. Does anyone have a tip for this?
#include <Arduino.h>
#include <SimpleFOC.h>
// DRV8302 pins connections
// I use the NUCLEO_G071RB board
#define INH_A PA8
#define INH_B PB3
#define INH_C PA10
#define INL_A PA7
#define INL_B PB14
#define INL_C PB15
#define EN_GATE PC4
#define M_PWM PC5
#define M_OC PD9
#define OC_ADJ PD8
#define OC_GAIN PB5
#define IOUTA A0
#define IOUTB A1
#define IOUTC A2
#define HALL_A PB0
#define HALL_B PC7
#define HALL_C PA9
HallSensor hallSensor = HallSensor(HALL_A, HALL_B, HALL_C, 4);
BLDCDriver6PWM driver = BLDCDriver6PWM(INH_A, INL_A, INH_B, INL_B, INH_C, INL_C, EN_GATE);
// DRV8302 board has 0.005Ohm shunt resistors and the gain of 12.22 V/V
LowsideCurrentSense currentSense = LowsideCurrentSense(0.005f, 12.22f, IOUTA, IOUTB, IOUTC);
BLDCMotor motor = BLDCMotor(4, 0.93f, 160);
Commander commander = Commander(Serial, '\n', true);
void onMotor(char* cmd){ commander.motor(&motor, cmd); }
// Interrupt routine initialization
void handleHallA() { hallSensor.handleA(); }
void handleHallB() { hallSensor.handleB(); }
void handleHallC() { hallSensor.handleC(); }
uint32_t time_ms = 0u;
void setup() {
hallSensor.pullup = Pullup::USE_INTERN;
hallSensor.init();
hallSensor.enableInterrupts(handleHallA, handleHallB, handleHallC);
// DRV8302 specific code
// M_OC - enable overcurrent protection
pinMode(M_OC,OUTPUT);
digitalWrite(M_OC,LOW);
// M_PWM - enable 6pwm mode
pinMode(M_PWM,OUTPUT);
digitalWrite(M_PWM,LOW);
// OD_ADJ - set the maximum overcurrent limit possible
// Better option would be to use voltage divisor to set exact value
pinMode(OC_ADJ,OUTPUT);
digitalWrite(OC_ADJ,HIGH);
pinMode(OC_GAIN,OUTPUT);
digitalWrite(OC_GAIN,LOW);
driver.voltage_power_supply = 24;
driver.pwm_frequency = 15'000;
driver.init();
Serial.begin(115200);
commander.add('M', onMotor, "motor");
motor.linkSensor(&hallSensor);
motor.linkDriver(&driver);
motor.voltage_sensor_align = 2;
motor.foc_modulation = FOCModulationType::SpaceVectorPWM;
motor.torque_controller = TorqueControlType::voltage;
motor.controller = MotionControlType::torque;
motor.current_limit = 4;
// current q loop PID
motor.PID_current_q.P = 1.5;
motor.PID_current_q.I = 20;
motor.LPF_current_q.Tf = 0.005;
motor.init();
currentSense.linkDriver(&driver);
currentSense.init();
currentSense.gain_a *= -1;
currentSense.gain_b *= -1;
currentSense.gain_c *= -1;
motor.linkCurrentSense(¤tSense);
motor.initFOC();
_delay(1000);
}
void loop() {
commander.run();
motor.loopFOC();
motor.move(0.5);
//motor.monitor();
//Serial.print(hallSensor.getAngle());
//Serial.print("\t");
//Serial.println(hallSensor.getVelocity());
/*
if (millis() - time_ms > 50){
PhaseCurrent_s current = currentSense.getPhaseCurrents();
Serial.print(current.a);
Serial.print("\t");
Serial.print(current.b);
Serial.print("\t");
Serial.print(current.c);
Serial.println("");
time_ms = millis();
}
*/
}
I also thought about the pedal. I want to realize the pedal using a load cell.
I think controlling the pedal using air pressure is a pretty cool idea. The system must not have any leaks. Otherwise you will have a problem with long seams.
Best regards
Nico