INA240三相无刷电机电流采样实例(arduino)

目录

前言&&准备材料

arduino程序

参考链接:


前言&&准备材料

我这里用的控制器是esp32,它的adc采集器分辨率是12位,工作电压是3.3V。因此我们读取到的模拟数值0~4096就是对应的0~3.3V。

这里我的ina240型号是I240A2。也就是说ina240的增益是50V/V。

我的驱动器型号是simplefoc v0.2。采用内置电流采样,具体电流采样电路如下图:

 双向

arduino程序

/**
   使用电压控制回路的扭矩控制示例。
   大多数低端无刷电机驱动器没有电流测量功能,因此SimpleFOC为您提供了一种通过设置电机电压而不是电流来控制电机扭矩的方法。
   这使无刷直流电机有效地成为直流电机,您可以以相同的方式使用它。
*/
// IN1     pwm1    9  27
// IN2     pwm2    6  26
// IN3     pwm3    5  25
// INH1   enable1  8  12
// INH2   enable2  7  13
// INH3   enable3  4  14
//in-line current sense - phase 1/A 35
//in-line current sense - phase 1/C 34
 
#include <SimpleFOC.h>
 
class LowPassFilte {
  public:
    LowPassFilte(float Tf);//低通滤波器时间常量
    ~LowPassFilte() = default;
    float operator() (float x);
    float Tf; //!< 低通滤波器时间常量
  protected:
    unsigned long timestamp_prev;  //!< 上次执行时间戳
    float y_prev; //!< 经过上次执行后过滤到的值
};
 
LowPassFilte::LowPassFilte(float time_constant)
  : Tf(time_constant)
  , y_prev(0.0f)
{
  timestamp_prev = micros();
}
 
float LowPassFilte::operator() (float x)
{
  unsigned long timestamp = micros();
  float dt = (timestamp - timestamp_prev) * 1e-6f;
 
  if (dt < 0.0f || dt > 0.5f)
    dt = 1e-3f;
 
  float alpha = Tf / (Tf + dt);
  float y = alpha * y_prev + (1.0f - alpha) * x;
 
  y_prev = y;
  timestamp_prev = timestamp;
  return y;
}
 
LowPassFilte LF_a(0.01);//原始数据滤波器
LowPassFilte LF_b(0.01);//A相电流滤波器
LowPassFilte LF_c(0.01);//C相电流滤波器
 
 
//AS5600编码器支持spi,iic和模拟量三种数据传输方式,这里用iic(同时也是最常用的方式)
// magnetic sensor instance - I2C
MagneticSensorI2C sensor = MagneticSensorI2C(AS5600_I2C);
TwoWire I2Cone = TwoWire(0);
 
// BLDC motor & driver instance
BLDCMotor motor = BLDCMotor(11);
BLDCDriver3PWM driver = BLDCDriver3PWM(27, 26, 25, 12, 13, 14);


InlineCurrentSense Cs_motor(0.001, 50.0, 35, 36, 34);

// voltage set point variable
float target_voltage = 5.0;
// instantiate the commander
Commander command = Commander(Serial);
void doTarget(char* cmd) {
  command.scalar(&target_voltage, cmd);
}
 
void setup() {
  // initialise magnetic sensor hardware
  I2Cone.begin(18, 5, 400000);
  sensor.init(&I2Cone);
  // link the motor to the sensor
  motor.linkSensor(&sensor);
 
  // power supply voltage
  driver.voltage_power_supply = 12;
  driver.init();
  motor.linkDriver(&driver);
 
  // aligning voltage
  motor.voltage_sensor_align = 5;
  // choose FOC modulation (optional)
  motor.foc_modulation = FOCModulationType::SpaceVectorPWM;
  // set motion control loop to be used
  motor.controller = MotionControlType::torque;
 
  // use monitoring with serial
  Serial.begin(115200);
  // comment out if not needed
  motor.useMonitoring(Serial);
 
  // initialize motor
  motor.init();
  // align sensor and start FOC
  motor.initFOC();
 
  // add target command T
  command.add('T', doTarget, "target voltage");
 
  Serial.println(F("Motor ready."));
  Serial.println(F("Set the target voltage using serial terminal:"));
  _delay(1000);

  Cs_motor.init();
}
 
void loop() {
 
  // main FOC algorithm function
  // the faster you run this function the better
  // Arduino UNO loop  ~1kHz
  // Bluepill loop ~10kHz
  motor.loopFOC();
 
  // Motion control function
  // velocity, position or voltage (defined in motor.controller)
  // this function can be run at much lower frequency than loopFOC() function
  // You can also use motor.move() and set the motor.target in the code
  motor.move(target_voltage);


  // Cs_motor.getPhaseCurrents();
  Serial.print(LF_b((Cs_motor.getPhaseCurrents()).a));
  Serial.print(",");
  Serial.println(LF_c((Cs_motor.getPhaseCurrents()).c));
 
//  Serial.print(LF_a(analogRead(35)));
//  Serial.print(",");
//  Serial.print(LF_b((3.3 * ((float)analogRead(35) - 1930) / 4096.0) * 20.0));
//  Serial.print(",");
//  Serial.println(LF_c((-3.3 * ((float)analogRead(34) - 1930) / 4096.0) * 20.0));
 
  // user communication
  command.run();
}

串口打印效果:

用Baize_Foc的测试代码

/**
   使用电压控制回路的扭矩控制示例。
   大多数低端无刷电机驱动器没有电流测量功能,因此SimpleFOC为您提供了一种通过设置电机电压而不是电流来控制电机扭矩的方法。
   这使无刷直流电机有效地成为直流电机,您可以以相同的方式使用它。
*/
// IN1     pwm1    9  27
// IN2     pwm2    6  26
// IN3     pwm3    5  25
// INH1   enable1  8  12
// INH2   enable2  7  13
// INH3   enable3  4  14
//in-line current sense - phase 1/A 35
//in-line current sense - phase 1/C 34
 
#include <SimpleFOC.h>
 
class LowPassFilte {
  public:
    LowPassFilte(float Tf);//低通滤波器时间常量
    ~LowPassFilte() = default;
    float operator() (float x);
    float Tf; //!< 低通滤波器时间常量
  protected:
    unsigned long timestamp_prev;  //!< 上次执行时间戳
    float y_prev; //!< 经过上次执行后过滤到的值
};
 
LowPassFilte::LowPassFilte(float time_constant)
  : Tf(time_constant)
  , y_prev(0.0f)
{
  timestamp_prev = micros();
}
 
float LowPassFilte::operator() (float x)
{
  unsigned long timestamp = micros();
  float dt = (timestamp - timestamp_prev) * 1e-6f;
 
  if (dt < 0.0f || dt > 0.5f)
    dt = 1e-3f;
 
  float alpha = Tf / (Tf + dt);
  float y = alpha * y_prev + (1.0f - alpha) * x;
 
  y_prev = y;
  timestamp_prev = timestamp;
  return y;
}
 
LowPassFilte LF_a(0.01);//原始数据滤波器
LowPassFilte LF_b(0.01);//A相电流滤波器
LowPassFilte LF_c(0.01);//C相电流滤波器
 
 
//AS5600编码器支持spi,iic和模拟量三种数据传输方式,这里用iic(同时也是最常用的方式)
// magnetic sensor instance - I2C
MagneticSensorI2C sensor = MagneticSensorI2C(AS5600_I2C);
TwoWire I2Cone = TwoWire(0);
 
// BLDC motor & driver instance
BLDCMotor motor = BLDCMotor(11);
BLDCDriver3PWM driver = BLDCDriver3PWM(17, 18, 19, 21, 22, 23);
 
 
InlineCurrentSense Cs_motor(0.001, 50.0, 34, 35);
 
// voltage set point variable
float target_voltage = 5.0;
// instantiate the commander
Commander command = Commander(Serial);
void doTarget(char* cmd) {
  command.scalar(&target_voltage, cmd);
}
 
void setup() {
  // initialise magnetic sensor hardware
  I2Cone.begin(26, 25, 400000);
  sensor.init(&I2Cone);
  // link the motor to the sensor
  motor.linkSensor(&sensor);
 
  // power supply voltage
  driver.voltage_power_supply = 12;
  driver.init();
  motor.linkDriver(&driver);
 
  // aligning voltage
  motor.voltage_sensor_align = 5;
  // choose FOC modulation (optional)
  motor.foc_modulation = FOCModulationType::SpaceVectorPWM;
  // set motion control loop to be used
  motor.controller = MotionControlType::torque;
 
  // use monitoring with serial
  Serial.begin(115200);
  // comment out if not needed
  motor.useMonitoring(Serial);
 
  // initialize motor
  motor.init();
  // align sensor and start FOC
  motor.initFOC();
 
  // add target command T
  command.add('T', doTarget, "target voltage");
 
  Serial.println(F("Motor ready."));
  Serial.println(F("Set the target voltage using serial terminal:"));
  _delay(1000);
 
  Cs_motor.init();
}
 
void loop() {
 
  // main FOC algorithm function
  // the faster you run this function the better
  // Arduino UNO loop  ~1kHz
  // Bluepill loop ~10kHz
  motor.loopFOC();
 
  // Motion control function
  // velocity, position or voltage (defined in motor.controller)
  // this function can be run at much lower frequency than loopFOC() function
  // You can also use motor.move() and set the motor.target in the code
  motor.move(target_voltage);
 
 
  // Cs_motor.getPhaseCurrents();
//  Serial.print(LF_b((Cs_motor.getPhaseCurrents()).a));
//  Serial.print(",");
//  Serial.println(LF_c((Cs_motor.getPhaseCurrents()).c));
 
//  Serial.print(LF_a(analogRead(35)));
//  Serial.print(",");
  Serial.print(LF_b((3.3 * ((float)analogRead(35) - 1930) / 4096.0) * 20.0));
  Serial.print(",");
  Serial.println(LF_c((-3.3 * ((float)analogRead(34) - 1930) / 4096.0) * 20.0));
 
  // user communication
  command.run();
}

参考链接:

1.【INA240】产品参数介绍、INA240数据手册、中英文PDF资料下载-TI资料-电子发烧友

2. 

  • 7
    点赞
  • 48
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Allen953

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值