基于Arduino的乐高电源控制系统

控制/MCU

1852人已加入

描述

  了解如何使用您的 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 传感器,编写您自己的避障逻辑并制作您自己的自动驾驶机器人火星探测器。

  或者给遥控器增加更多指令,给模型增加更多功能。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分