Link

自定义传感器实现

GenericSensorSimpleFOClibrary 中一个全新的类,它简化了新传感器的实现。用这个类,你可以添加一个自定义传感器到代码中并将其与arduino文件中的电机连接。

步骤一 读取传感器函数实现

基本上,你只需在 arduino 代码中实现以下这个函数,它能读取传感器,返回0到2PI之间,以rad为单位的角度值:

float readMySensorCallback(){
 // 读取传感器
 // 返回0到2PI之间,以rad为单位的角度值
 return ...;
}

此外,你可以选择执行初始化传感器函数

void initMySensorCallback(){
  // 初始化
}

步骤二 初始化类 GenericSensor

要初始化传感器类,需要为它提供读取传感器函数的指针,以及初始化传感器函数的指针(这是可选的)。

// GenericSensor class 建构
//  - 读取传感器角度函数指针 readCallback 
//  - 初始化传感器函数指针 initCallback (可选的)
GenericSensor sensor = GenericSensor(readMySensorCallback, initMySensorCallback);

步骤三 实时使用传感器

library库中有两个方式可以实现传感器的使用:

  • 作为FOC算法的电机位置传感器
  • 作为独立的位置传感器

独立传感器

你可以把你的传感器作为独立传感器使用。为了获取给定时间内传感器的角度和速度,你可以使用以下通用方法:

class GenericSensor{
 public:
    // 获取轴速度
    float getVelocity();
	  // 获取轴角度
    float getAngle();
}

以下是便捷的例程:

#include <SimpleFOC.h>

float readMySensorCallback(){
 // 读取传感器
 // 返回0到2PI之间,以rad为单位的角度值
 return ...;
}

void initMySensorCallback(){
  // 初始化
}

// 创建传感器
GenericSensor sensor = GenericSensor(readMySensorCallback, initMySensorCallback);

void setup() {
  // 监控端口
  Serial.begin(115200);

  // 初始化传感器
  sensor.init();

  Serial.println("My sensor ready");
  _delay(1000);
}

void loop() {
  // 注意 - 尽可能高频的调用
  // 更新传感器值
  sensor.update();
  // 显示角度和角速度到终端
  Serial.print(sensor.getAngle());
  Serial.print("\t");
  Serial.println(sensor.getVelocity());
}

FOC算法的位置传感器

要在library库中实现foc算法传感器的使用,初始化了sensor.init()后,只需要执行以下命令将它连接到BLDC无刷电机:

motor.linkSensor(&sensor);

一般来说,你的代码会跟如下代码类似:

#include <SimpleFOC.h>

float readMySensorCallback(){
 // 读取传感器
 // 返回0到2PI之间,以rad为单位的角度值
 return ...;
}

void initMySensorCallback(){
  // 初始化
}

// 创建传感器
GenericSensor sensor = GenericSensor(readMySensorCallback, initMySensorCallback);

....
BLDCMotor motor = ....
...

void setup() {
   ....
  // 初始化传感器
  sensor.init();
  // 连接电机
  motor.linkSensor(&sensor);
  ...
  motor.initFOC();
  ...
}
void loop() {
  ....
}

创建新传感器支持的完整例程 - ESP32 编码器

以下是ESP32架构下基于硬件计数器的编码器的实现例程。 SimpleFOClibrary库默认不支持此编码器。

为了设置计数器和其他硬件参数,我用使用了库ESP32Encoder ,完整例程代码如下所示:

#include <SimpleFOC.h>
#include <ESP32Encoder.h>

// 创建类 ESP32Encoder 
ESP32Encoder encoder;
// 定义传感器 cpr (500x4)
int64_t cpr = 2000;
// 初始化传感器函数
void initMySensorCallback(){
  // 编码器用引脚25和26 (Arduino引脚2和3) 
  encoder.attachFullQuad(25, 26);
}
// 读取编码器函数
float readMySensorCallback(){
  // 返回值在 0 - 2PI 之间
  float a = ((float)(encoder.getCount()%cpr)*_2PI/((float)cpr));
  return a > 0 ? a : a + _2PI;
}
// 创建通用传感器
GenericSensor sensor = GenericSensor(readMySensorCallback, initMySensorCallback);

// BLDC无刷电机和驱动器实例
BLDCMotor motor = BLDCMotor(11);
BLDCDriver3PWM driver = BLDCDriver3PWM(16, 27, 5, 12); // (Arduino引脚5、6、10、8)


// 命令通信实例
Commander command = Commander(Serial);
void doMotor(char* cmd){ command.motor(&motor, cmd); }

void setup() {

  // 初始化传感器
  sensor.init();
  // 连接电机到传感器
  motor.linkSensor(&sensor);

  // 配置驱动器
  // 电源输入电压[V]
  driver.voltage_power_supply = 12;
  driver.init();
  // 连接驱动器
  motor.linkDriver(&driver);

  // 设置要用到的控制环类型
  motor.controller = MotionControlType::torque;

  // 使用串口监控电机初始化
  // 监控端口
  Serial.begin(115200);
  // 如不需要,可注释掉
  motor.useMonitoring(Serial);

  // 初始化电机
  motor.init();
  // 校准编码器,启动FOC
  motor.initFOC();

  // 订阅电机到commander命令
  command.add('M', doMotor, "motor");

  _delay(1000);
}


void loop() {
  // 迭代设置FOC相电压
  motor.loopFOC();

  // 迭代函数设置外部环目标
  motor.move();

  // 用户通信
  command.run();
}