之前我们学习了如何控制称为RC伺服电机的设备。我们了解到,伺服电机是指一个包含电机和传感器的设备,这样我们就可以控制设备的旋转位置。我们从RC伺服电机开始学习,因为它们易于理解,但这些设备并不特别精确,动作也不特别平滑。如果你想构建更精确且动作更平滑的机器人,你需要学习如何进行自己的运动控制。这就是我们将在本单元中学习的内容。
每个电机都有一个常数,称为电机常数(Kv),它将电压与速度、电流与扭矩联系起来。计算公式如下:

其中 ω为无负载时的电机转速,V为电压。
电机常数是电机结构的属性,通常可以在电机的数据表中找到,也可以通过测试电机来找出其常数。我们现在就来做这个测试,因为它可以帮助我们了解许多关于电机工作原理的其他知识。
在Arduino模拟器如TinkerCAD中建立以下电路,L293D是一个H桥电机驱动芯片,直流电机自带编码器。

接线方式如下:
L293D

Enable 1&2接Arduino pin 10
Input 1接Arduino pin 8
Input 2接Arduino pin 9
Output 1接电机正极(motor positive)
Output 2接电机负极(motor negetive)
Power 1接外部电源正极
Power2接Arduion 5V
编码器Encoder

Encoder -接Arduino Gound
Encoder +接Arduino 5V
Encoder A接Aruino Pin 2
Encoder B接Aruino Pin 3
Arduino代码如下(采用Encoder.h库):
#include <Encoder.h> // Include Encoder library
// Define motor control pins
int IN1 = 8;
int IN2 = 9;
int ENABLE1 = 10; // PWM for speed
// Define encoder pins and create Encoder object
Encoder myEncoder(2, 3); // Channel A = pin 2, Channel B = pin 3
long encoderPos = 0; // Variable to store the current encoder position
void setup() {
// Set motor control pins as outputs
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(ENABLE1, OUTPUT);
// Initialize serial communication for debugging
Serial.begin(9600);
}
void loop() {
// Run motor forward at full speed for 2 seconds
digitalWrite(IN1, HIGH); // Set direction forward
digitalWrite(IN2, LOW);
analogWrite(ENABLE1, 255); // Set speed to full (255)
delay(2000); // Run for 2 seconds
// Stop the motor
analogWrite(ENABLE1, 0); // Stop motor by setting speed to 0
delay(1000); // Pause
// Read and print the encoder position
encoderPos = myEncoder.read();
Serial.print("Encoder Position: ");
Serial.println(encoderPos);
}
首先来估计编码器每圈的计数(CPR:cunter per revolution),将上面代码的PWM值改小,然后将运行时间加长以方面估计。

看着电机转了大概3 1/4圈,cpr为 2551/3.25 ≈ 785
接着让电机运行2s, 编码器读数为6545, 一分钟即为6545*30=196,350
由此可以计算出电机转速为 cpm/cpr ≈ 250rpm

实际软件显示的电机转速为258rpm
查看电压为6V

可以计算出电机常数为Kv = 258/6 = 43 rpm/V
理论上,电机常数应该是恒定的,这意味着如果我们给电机提供4伏电压,我们可以将其乘以43 rpm/V,电机应该以大约172 rpm的速度旋转。但实际上,这并不完全准确,因为它没有考虑电机内部摩擦的影响。接下来我们将进行一个测试,找出不同电压下的电机常数值。