> For the complete documentation index, see [llms.txt](https://voltbro.gitbook.io/vbcores/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://voltbro.gitbook.io/vbcores/primery/primery-arduino/rabota-s-beskollektornymi-dvigatelyami/simple-foc.-upravlenie-momentom.md).

# Simple FOC. Управление моментом

Написанный ниже пример написан с использованием библиотеки [SimpleFoc](https://docs.simplefoc.com/). Оригинал вы найдете [здесь](https://docs.simplefoc.com/foc_current_torque_mode). В качестве torque\_controller укажите foc\_current.

{% file src="/files/OfssERQCluBqcK1vU09p" %}

Токовое управление FOC является единственным истинным подходом к управлению моментом. Он управляет двумя компонентами вектора тока q и d. Предполагается, что крутящий момент пропорционален компоненте тока q, а компонента тока d управляется так, чтобы оставаться равной 0.

Познакомиться с теорией векторного управления электродвигателем и подробнее почитать  о компонентах q и d мы предлагаем в статье на [хабре](https://habr.com/ru/companies/npf_vektor/articles/367653/).&#x20;

При управлении моментом, здесь в качестве управляющего воздействия подается максимальный потребляемый ток, когда двигатель прикладывает максимальный крутящий момент либо потому, что ему не дают двигаться полностью, либо потому, что он не может больше разгоняться с учетом нагрузки, которую он испытывает.

Не забудьте в функции setup() добавить ограничения для тока, напряжения и скорости.

```arduino
#include <VBCoreG4_arduino_system.h>
#include <SimpleFOC.h>
#define EN_GATE PB3 // PB3 - включает/отключает драйвер

SPIClass SPI_3(PC12, PC11, PC10);

// MagneticSensorSPI(int cs, float _cpr, int _angle_register)
//  cs              - SPI chip select pin 
//  bit_resolution - magnetic sensor resolution
//  angle_register  - (optional) angle read register - default 0x3FFF
MagneticSensorSPI sensor = MagneticSensorSPI(PA15, 14, 0x3FFF);

float sensitivity = 45.0; // mV/A 

// InlineCurrentSensor constructor
//  - mVpA  - mV per Amp ratio
//  - phA   - A phase adc pin
//  - phB   - B phase adc pin
//  - phC   - C phase adc pin (optional)
//                                                          phA  phB  phC
InlineCurrentSense current_sense = InlineCurrentSense(45.0, PC1, PC2, PC3); 

BLDCMotor motor = BLDCMotor(11); //11 -пар полюсов

//  BLDCDriver3PWM( int phA, int phB, int phC)
//  - phA, phB, phC - A,B,C phase pwm pins
BLDCDriver3PWM driver = BLDCDriver3PWM(PA10, PA9, PA8);



Commander command = Commander(Serial);
void doTarget(char* cmd) { command.scalar(&motor.target, cmd);}
//Serial.println(digitalRead(PB5)); }
void setup() {

Serial.begin(115200);
 motor.useMonitoring(Serial);

  pinMode(PB5, INPUT);
  pinMode(EN_GATE, OUTPUT);
  

  pinMode(PB15, OUTPUT);
  pinMode(PB14, OUTPUT);
  pinMode(PB13, OUTPUT);
  digitalWrite(PB15, HIGH);
  digitalWrite(PB14, HIGH);
  digitalWrite(PB13, HIGH);
  
  digitalWrite(EN_GATE, HIGH);
  delay(10);
  // driver config
  driver.voltage_power_supply = 12;
  driver.init();
  driver.enable();

  
  // set torque mode:
  motor.torque_controller = TorqueControlType::foc_current; 
  // set motion control loop to be used
  motor.controller = MotionControlType::torque;


  // initialise magnetic sensor hardware
  sensor.init(&SPI_3);
  // link the motor to the encoder
  motor.linkSensor(&sensor);
  // link the motor to the driver
  motor.linkDriver(&driver);
  current_sense.init();
  current_sense.linkDriver(&driver);
  // link the current sense to the motor
  motor.linkCurrentSense(&current_sense);

  motor.current_limit = 1.94;
  motor.voltage_limit = 15;
  motor.velocity_limit - 5.5; // rad/sec
  // initialize motor
  motor.init();
  // align encoder and start FOC
  motor.initFOC();


 // add target command T
  command.add('T', doTarget, "target current");

  Serial.println(F("Motor ready."));
  _delay(1000);
}

int t;
void loop() {
  // main FOC algorithm function
  motor.loopFOC();

  // Motion control function
  motor.move();

  // user communication
  command.run();
}
```

Загрузите программу и убедитесь, что все работает. Далее попробуйте поменять torque\_controller - вместо foc\_current, поставьте voltage.&#x20;

Управление моментом по напряжению - это наиболее простой тип управления моментом, который позволяет абстрагироваться от BLDC-двигателя и управлять им как двигателем постоянного тока. Он основан на принципе прямой пропорциональности тока напряжению (динамикой тока пренебрегается) и поэтому не нуждается в аппаратных средствах измерения тока. Данный подход к управлению моментом может быть использован на любой плате BLDC-драйвера, независимо от того, есть ли в ней датчик тока или нет. Подробнее ознакомиться с теорией можно на [сайте SimpleFoc](https://docs.simplefoc.com/torque_control).

А теперь поставьте torque\_controller - dc\_current.&#x20;

Режим управления постоянным током позволяет управлять током BLDC-двигателя, как если бы это был двигатель постоянного тока. Датчик тока используется для получения общей величины тока, потребляемого двигателем, и его направления, при этом предполагается, что вращающий момент пропорционален общему току. Преимущество такого подхода заключается в том, что можно очень точно управлять истинным током, задаваемым BLDC-двигателем, и он немного быстрее и стабильнее выполняется для менее производительных микроконтроллеров.
