了解如何使用您的 Arduino 控制乐高电机和伺服系统,并构建您自己的 Android 应用程序来远程控制您的模型。
背景
您是否拥有带有电动机和伺服电机的超棒Lego Power Functions 模型之一?在本文中,我将向您展示如何使用 Arduino 和最少的电子元件来控制乐高模型。我将详细解释电路和编程,以便于初学者理解。
我们还将学习如何使用MIT 应用程序发明者来编写我们自己的远程控制 Android 应用程序。很快,您将在您的后院拥有自己的乐高火星探测器!
这是我的第一个 Arduino 项目,我儿子有一个漂亮的 Lego Technic 汽车模型(9398 4X4 Crawler ),带有乐高动力功能:一个用于转向的乐高伺服电机和两个用于驾驶的乐高 L 电机。同时他也允许我在这个项目中使用这辆车。
了解电源功能接线
首先,购买一些乐高电源功能延长线。接下来,将它们切断。我们将制作一些“分线”电缆,一端有乐高积木,另一端有别针。将引脚焊接在上面或类似的地方。以下是接线说明:
GND 代表接地,它是电池组(阳极)的负极端子 (-)。C1和C2可以切换极性,使电机和舵机切换方向。对于乐高伺服连接器,你需要将针脚焊接到所有四根电缆上。您可以使用浅灰色插头。对于连接电池盒和面包板的电源线,我们只需要 +9 Volt 和 GND 但您必须使用深灰色插头:
对于电机电缆,我们只需连接 C1 和 C2,您可以使用浅灰色插头。
使用 L293D 芯片控制乐高电机
我们需要直流电机的变速控制和乐高伺服的位置控制。这是通过脉冲宽度调制 (PWM)实现的。Arduino的编程语言使PWM易于使用;只需调用analogWrite(pin, dutyCycle) ,其中 dutyCycle 是一个从 0 到 255 的值。PWM 引脚在您的 arduino 上标有 ~。
Arduino 输出引脚为 5 伏特和最大值。30 毫安,而乐高电机需要 9 伏且每个拉力超过 100 毫安。我们需要某种介于两者之间的“开关设备”。我们还希望能够在两个方向上运行直流电机。这些功能由所谓的H 桥解决。我们将使用L293D ,它在一个集成芯片上包含两个 H 桥,这意味着我们可以将乐高电机 (M) 并联连接到芯片的一侧,将乐高伺服 (S) 连接到芯片的另一侧。(如果您想独立控制两个电机,则需要第二个 L293D)。乐高伺服还需要连接到 GND 和乐高 +9 伏。
该芯片使 Lego +9 Volt 和 Arduino +5 Volt 完全分离。切勿将它们连接在一起,否则会损坏某些东西!但是您同时须将所有接地线连接在一起并与 L293D 接地引脚连接。
在我们的 Arduino 中,我们将使用引脚 9 来控制电机速度,使用引脚 2 和 5 来控制旋转方向。乐高伺服像电机一样被控制:我们连接引脚 3 用于位置,引脚 6 和 8 用于方向(左或右)。
在我们程序的顶部,我们将使用的 Arduino 引脚定义为常量。此外,我们定义了一些用于控制电机的变量:
// Motor control digital output pins defined as global constants
const int controlPin1A = 2;
const int controlPin2A = 5;
const int ENablePin = 9;
// Servo control digital output pins defined as global constants
const int controlPin3A = 6;
const int controlPin4A = 8;
const int servoENablePin = 3;
// Motor control global variables:
int motorSpeed = 0; // Motor speed 0..255
int motorDirection = 1; // Forward (1) or reverse (0)
// Servo control global variables:
int steering = 0; // Servo position 0..255
int steeringDirection = 0; // Left (0) and Right (1)
在设置中,我们使用pinmode()命令将这些引脚定义为输出,然后使用digitalWrite ()将它们设置为 0 伏。
void setup()
{
//other stuff....
// Declare digital output pins:
pinMode(controlPin1A, OUTPUT); // 1A
pinMode(controlPin2A, OUTPUT); // 2A
pinMode(ENablePin, OUTPUT); // EN1,2
pinMode(controlPin3A, OUTPUT); // 3A
pinMode(controlPin4A, OUTPUT); // 4A
pinMode(servoENablePin, OUTPUT); // EN3,4
digitalWrite(ENablePin, LOW); // motor off
digitalWrite(servoENablePin, LOW); // steering centered
}
现在我们需要了解 L293D 芯片是如何控制电机的旋转方向的。我们必须提供以下信号(高 == 5 伏;低 == 0 伏):
EN1,2 1A 2A
高 高 低 电机左转(前进;motorDirection == 1)
高 低 高 电机右转(反向;motorDirection == 0)
EN3,4 3A 4A
高 高 低 舵机左转(steeringDirection == 0)
高 低 高 舵机右转(steeringDirection == 1)
接下来我们准备编写一个子程序来读取方向和速度/位置的全局变量并控制电机和伺服:
void SetMotorControl()
{
if (motorDirection == 1) //Forward
{
digitalWrite(controlPin1A, HIGH);
digitalWrite(controlPin2A, LOW);
}
else //Reverse
{
digitalWrite(controlPin1A, LOW);
digitalWrite(controlPin2A, HIGH);
}
analogWrite(ENablePin, motorSpeed); //Speed
if (steeringDirection == 0) //Left
{
digitalWrite(controlPin3A, HIGH);
digitalWrite(controlPin4A, LOW);
}
else //Right
{
digitalWrite(controlPin3A, LOW);
digitalWrite(controlPin4A, HIGH);
}
analogWrite(servoENablePin, steering); //Servo position
}
带有操纵杆的简单 RC Android 应用程序
接下来,让我们构建一个简单的 Android 应用程序来控制模型。
我们将使用 MIT app inventor 2。MIT App Inventor 是一个创新的初学者对编程和应用程序创建的介绍。Google 的 Mark Friedman 和麻省理工学院教授 Hal Abelson 共同领导了 App Inventor 的开发。它作为一项网络服务运行,由麻省理工学院移动学习中心的工作人员管理。
在您的 Android 手机上,前往 Google Play 并安装MIT AI2 Companion 应用程序。在您的计算机上,在 Firefox 或 Chrome 浏览器中打开我的RC 应用程序的链接。您必须使用您的 gmail 地址登录并创建一个帐户才能查看源代码。如果您在手机上打开配套应用程序,您可以在浏览器中查看源代码,对其进行更改并立即在手机上进行测试。
在浏览器中,您现在将看到应用程序的设计器视图:
在底部,我们看到带有蓝色操纵杆球的橙色垫。现在切换到 Blocks-view 来查看程序。该程序的核心是一个 when 块,它跟踪您的手指触摸和拖动蓝色操纵杆球的动作:
您的手指位置将会在两个变量currentX和currentY中进行跟踪,并用于计算两个变量转向和速度的值(范围:-100..0..+100)。首先,程序会先检查您的手指是否在垫外,并将值限制为 +/- 100。如果手指在垫内,程序会计算转向和速度的值。接下来,程序生成以下形式的命令字符串:
“遥控,转向,速度,\n”
该命令以用于远程控制的“RC”开头,后跟逗号。然后我们发送转向和速度的值。命令末尾的换行符 (‘\n’) 是向 Arduino 发出命令完成的信号。该命令字符串通过蓝牙发送到 Arduino。供您参考,该字符串也显示在屏幕上。
将蓝牙命令读入 Arduino
为了读取蓝牙命令字符串,我们需要连接一个 HC-05 蓝牙模块:
我的这块板子有 6 个引脚。但我们实际上只需要 4 个引脚。VCC 是(正)电源电压,GND 是地。该模块可承受 6 伏电源电压,这意味着我们可以将其连接到 arduino 5 伏电源引脚。TXD 和 RXD 是串行信号。我们必须越线并将 TXD 连接到 arduino RXD(引脚 0),反之亦然。
注意: LEVEL:3.3V,这意味着 RXD不能直接连接到 5V arduino TXD(引脚 1)。我们必须构建一个带有三个 1 kOhm 电阻的分压器,以产生 5V 的 2/3 的输出电压。另一方面,3.3V 的 TXD 信号可以直接连接到 Arduino RXD。Arduino 会将 3.3V识别为高。
由于引脚 0 和 1 与 Arduino 的 USB 端口共享,因此在通过 USB 将程序上传到开发板时,您必须断开引脚 0 和 1 的 RXD 和 TXD 信号。如果您不断开电缆,上传将无法进行。
接下来,您必须将 HC-05 模块与您的 Android 设备配对。打开蓝牙;启动应用程序;按“蓝牙连接”;让您的手机可见并寻找名为 HC-05 或类似设备的设备。选择设备。您将被要求输入代码。按“1234”。当您返回操纵杆屏幕时,它应该以绿色显示“已连接”。
现在,让我们看一下代码:
// Serial buffer size: calculate based on max input size expected for one command
#define INPUT_SIZE 30
void loop()
{
// Get next command from serial bluetooth (add 1 byte for final 0)
char input[INPUT_SIZE + 1]; // array of type char (C-string)
//read Serial until new line or buffer full or time out
byte size = Serial.readBytesUntil('\n', input, INPUT_SIZE);
// Add the final 0 to end the C-string
input[size] = 0;
// Split string which is of the form: "RC,steering,speed,\n\0"
char* command = strtok(input, ","); // command (RC)
// RCsteering in Range: -100 (left).. 0 .. 100 (right)
char* RCsteering = strtok(NULL, ",");
// RCspeed in Range: -100 (full speed reverse).. 0 .. 100 (full speed forward)
char* RCspeed = strtok(NULL, ",");
int iRCsteering = atoi(RCsteering); // convert string into integer
int iRCspeed = atoi(RCspeed); // convert string into integer
//rest of program
}
Android 应用程序发送的字符串被读入一个特殊的字符串结构:一个带有 null-termination 的 C 字符串。(0 字符告诉程序它已经到了字符串的末尾)。这是通过使用函数 Serial.readBytesUntil(‘\n’, input, 。..)来完成的,该函数从串行接口(蓝牙)读取,直到获得换行符(‘\n’)。这样,我们会一直读取字节,直到在input中有完整的命令:
“遥控,转向,速度,\n\0”。
处理输入的一种非常有效的方法是字符串标记函数,它使用逗号作为分隔符将字符串分成几部分。第一次调用 strtok() 返回“RC”。然后通过将 NULL 传递给 strtok() 来读取命令的后续部分。返回值存储在RCsteering和RCspeed中。这些变量实际上是指向input中位置的指针。atoi()函数最终将它们转换为整数。现在,我们有:
iRC 转向 == -100(左)。. 0 。. +100(右)
iRCspeed == -100(后退)。. 0 。. +100(前进)
现在差不多完成了。在将它们传递给我们的例程 SetMotorControl() 之前,我们必须将这些值乘以 2.55(请记住,电机速度在 0..255 范围内)。你现在可以在 CODE 部分研究程序的其余部分,构建电路并测试您的遥控乐高模型。
未来?
既然您有一个 Arduino 控制您的乐高模型,您可能希望将该模型用作机器人平台:
添加一些超声波 ping 传感器,编写您自己的避障逻辑并制作您自己的自动驾驶机器人火星探测器。
或者给遥控器增加更多指令,给模型增加更多功能。
评论
查看更多