亿迅智能制造网
工业4.0先进制造技术信息网站!
首页 | 制造技术 | 制造设备 | 工业物联网 | 工业材料 | 设备保养维修 | 工业编程 |
home  MfgRobots >> 亿迅智能制造网 >  >> Manufacturing Technology >> 制造工艺

Arduino Mecanum Wheels 机器人

在本教程中,我们将学习如何构建一个能够向任何方向移动的 Arduino Mecanum Wheels 机器人。机器人这种独特的机动性是通过使用一种特殊类型的轮子实现的,称为麦克纳姆轮子。

您可以观看以下视频或阅读下面的书面教程。

概览

实际上,我设计并 3D 打印了这些轮子,因为它们的价格可能有点贵。他们工作得很好,我必须说驾驶这个机器人平台非常有趣。我们可以使用 NRF24L01 无线电收发器模块对机器人进行无线控制,或者就我而言,我使用的是我在之前的视频中制作的 DIY RC 发射器。

我还可以通过蓝牙通信使用智能手机进行控制。我制作了一个自定义的 Android 应用程序,通过它我们可以控制 Mecanum 轮机器人向任何方向移动。此外,使用应用程序中的滑块,我们可以控制移动的速度。

这个机器人平台的大脑是一个 Arduino Mega 板,可以单独控制每个轮子。每个轮子都连接在 NEMA 17 步进电机上,并且知道步进电机可以精确控制这一事实,我在应用程序中添加了一个更酷的功能,通过它我们可以对机器人进行编程以自动移动。使用保存按钮,我们可以保存每个位置或步骤,然后机器人可以自动运行并重复这些步骤。使用同一个按钮,我们可以暂停自动操作以及重置或删除所有步骤,以便我们可以存储新的步骤。

Mecanum Wheels 机器人 3D 模型

首先,我使用 3D 建模软件设计了这个 Mecanum Wheels 机器人。这个机器人的基础平台是一个简单的盒子,我将用 8mm 刻度 MDF 板制成。

四个步进电机连接到这个平台,麦克纳姆轮连接到电机的轴上。

您可以找到并下载此 3D 模型,也可以在 Thangs 上的浏览​​器中进行探索。

从 Thangs 下载装配 3D 模型。

用于 3D 打印的 STL 文件:

麦克纳姆轮的工作原理

麦克纳姆轮是在其圆周上附有滚子的轮子。这些滚轮与车轮的旋转轴成对角线或 45 度角放置。这使得车轮在向前或向后移动时沿对角线方向施加力。

因此,通过以某种方式旋转轮子,我们利用这些对角力,从而机器人可以向任何方向移动。

在这里我们还应该注意,我们需要两种类型的麦克纳姆轮,通常称为左旋和右旋麦克纳姆轮。它们之间的区别在于滚轮的方向,它们必须安装在机器人的特定位置。每个车轮的上辊的旋转轴应指向机器人的中心。

这是一个快速演示如何根据车轮旋转方向机器人移动。

如果所有四个轮子都向前移动,则机器人的最终移动将向前移动,反之亦然,如果所有轮子都向后移动,机器人将向后移动。为了向右移动,右轮需要在机器人内部旋转,而左轮需要在机器人外部旋转。由于对角放置的滚轮产生的力将使机器人向右移动。向左移动时会发生相同但相反的情况。有了这些轮子,我们还可以通过只转动两个轮子来实现对角线方向的运动。

制造 Mecanum Wheels 机器人

不过,现在让我向您展示我是如何构建这个机器人平台的。正如我所提到的,为了制作平台的底座,我使用了 8 毫米刻度 MDF 板。使用台锯,我首先根据 3D 模型尺寸切割所有部件。

接下来,使用 3 毫米钻头和 25 毫米 Forstner 钻头,我在侧板上制作了用于连接步进电机的开口。准备好零件后,我继续组装它们。我用了木胶和一些螺丝来固定它们。这里最重要的是要精确制作电机的开口,以便以后所有的轮子都能与表面均匀接触。

当然,你也可以 3D 打印这个基础平台,而不是用 MDF 制作,所以我会在网站文章中包含它的 3D 文件。最后,我喷涂了底座,并用白色覆盖了它。

接下来是麦克纳姆轮。正如我之前所说,购买这些轮子可能有点贵,所以我决定自己设计和 3D 打印这些轮子。车轮由外侧和内侧两部分制成,并用一些 M4 螺栓和螺母固定在一起。它们每个有 10 个滚轮,以及一个专门设计用于安装 NEMA 17 步进电机的联轴器。

我使用我的 Creality CR-10 3D 打印机 3D 打印了 Mecanum 车轮的所有部件。

这是这台 3D 打印机的链接,以备不时之需。

所以,一旦我准备好 3D 打印部件,我就继续为滚轮制作轴。为此,我使用了 3 毫米刻度钢丝。轴的长度需要在 40 毫米左右,所以我使用旋转工具将线切割到那个长度。

我开始通过使用四个 M4 螺栓和螺母固定两侧和联轴器来组装麦克纳姆轮。螺栓长度需为45mm。

安装滚轮时,首先需要将轴稍微插入内侧圆周上的孔。

然后我们可以插入一个小M3垫圈,插入滚轮并将轴一直推到车轮外侧的槽中。我使用了一个垫圈,因为我没有足够的空间在另一侧插入第二个垫圈。

我对所有 10 个滚筒重复了这个过程。组装这些轮子实际上很容易也很有趣。这里重要的是滚轮需要能够自由移动。

最后,我在每个内孔中使用了几滴 AC 胶水,以确保轴不会松动。

好的,一旦轮子准备好,我们就可以继续组装整个机器人了。首先,我们需要将步进电机连接到基础平台。为了将它们固定到位,我使用了长度为 12 毫米的 M3 螺栓。

接下来,我们需要将轮子连接到电机的轴上。我制作的联轴器有一个用于插入 M3 螺母的槽,M3 螺栓可以穿过该槽,这样我们就可以将车轮固定在轴上。

接下来,为了将顶盖固定到底座上,我在底座的两个角上安装了螺纹杆。我在盖子的相同位置打了孔,因此我能够轻松地将盖子插入并固定到底座上。

在底座的背面,我做了一个 20mm 的孔用于稍后连接电源开关,以及一个 5mm 的孔用于连接 LED。

电路图

现在我们可以继续使用电子设备了。这是这个项目的完整电路图。

因此,我们将使用四个 DRV8825 步进驱动器来控制四个 NEMA 17 步进电机,或者我们也可以使用 A4988 步进驱动器。为了给步进器和整个机器人供电,我们将使用 12V 电源,在我的情况下,我将使用提供 12V 左右的 3S Li-Po 电池。对于无线电通信,我们使用 NRF24L01 模块,对于蓝牙通信,我们使用 HC-05 蓝牙模块。我还包括一个简单的分压器,用于监控电池电压和一个 LED 连接,用于指示电池电压何时降至 11V 以下。

我还包括一个专用的 5V 稳压器,可以提供大约 3A 的电流。这是可选的,但我计划在未来的视频中将此项目与我的 Arduino 机器人手臂项目结合起来,为此我需要 5V 来驱动其伺服电机。

您可以通过以下链接获取本项目所需的组件:

  • 步进电机 – NEMA 17………………
  • DRV8825步进驱动器……………………
  • NRF24L01收发模块……....
  • HC-05 蓝牙模块……………….……
  • 锂聚合物电池……………………………….……
  • Arduino Mega Board…………………….……

PCB设计

尽管如此,为了保持电子元件井井有条并摆脱布线混乱,我使用 EasyEDA 免费在线电路设计软件设计了一个定制 PCB。该 PCB 实际上将充当 Arduino MEGA 屏蔽,因为我们将能够直接将其连接到 Arduino Mega 板的顶部。我使用顶层和底层来运行连接。对于我没有使用的那些 Arduno 引脚,我包括了引脚接头连接,以便我们将来想将它们用于某些事情时可以使用它们。我还包括了 12V、5V 和 GND 连接引脚,以及用于选择驱动器步进分辨率的引脚。

这是此 PCB 设计的项目文件的链接。所以一旦我完成了设计,我就生成了制造 PCB 所需的 Gerber 文件。

格柏文件:

然后我从JLCPCB订购了PCB,这也是这个视频的赞助商。

在这里,我们可以简单地拖放 Gerber 文件,上传后,我们可以在 Gerber 查看器中查看我们的 PCB。如果一切正常,那么我们可以继续选择我们想要的 PCB 属性。这次我选择 PCB 颜色为蓝色,以便与 Arduino 板颜色相匹配。就是这样,现在我们可以简单地以合理的价格订购我们的 PCB。请注意,如果这是您从 JLCPCB 订购的第一个订单,您只需 2 美元即可获得多达 10 个 PCB。

几天后,多氯联苯已经到货了。 PCB的质量很好,一切都与设计中的完全一样。

组装PCB

好的,现在我们可以继续组装 PCB。我首先焊接较小的组件,即电阻器和电容器。然后我将公针头插入并焊接到 PCB 上,用于将其连接到 Arduino 板。

接下来,我将所有母排针放置到位并焊接它们。至于用于选择步进分辨率的步进电机连接和引脚,我使用了公头排针。这样我们可以直接将电机连接到 PCB 并使用跳线来选择步进分辨率。然后我焊接了接线端子、微调器和电压调节器。

就是这样,PCB 现在已经准备好了,我们可以继续插入驱动器并将电机连接到它。首先,我放置了用于选择步进分辨率的跳线。我通过将驱动器的 MS3 引脚连接到 5V 来选择第 16 步分辨率。

然后在它们上面放置 DRV8825 驱动程序,以及连接 NRF24L01 模块和 HC-05 蓝牙模块。现在我们可以简单地将 PCB 连接到 Arduno 板上了。

接下来,我将电池连接到适当的接线端子并将它们放入底座平台中。

在这里,我将电源开关插入到位并将其连接到另一个接线端子。在电源开关的正上方,我还插入了电池指示灯 LED。

现在剩下的是将电机连接到 PCB。这里需要注意的是,当连接对置电机时,我们也应该将它们的连接器连接对置。稍后在对机器人进行编程时需要这样做,例如,前进命令将使两个电机沿相同方向移动,尽管它们实际上是翻转的,一个顺时针旋转,另一个逆时针旋转。

最后,我可以简单地将盖子插入顶部,这样我们就完成了这个 Mecanum Wheels 机器人项目。

Mecanum Wheels 机器人 Arduino 代码

这个视频剩下的就是看一下 Arduino 代码。实际上,有两个独立的 Arduino 代码。一个是用NRF24L01模块控制机器人,另一个是用智能手机控制机器人。

使用 NRF24L01 模块控制机器人的 Arduino 代码:

/*
   === Arduino Mecanum Wheels Robot ===
     Radio control with NRF24L01 
  by Dejan, www.HowToMechatronics.com
  Libraries:
  RF24, https://github.com/tmrh20/RF24/
  AccelStepper by Mike McCauley: http://www.airspayce.com/mikem/arduino/AccelStepper/index.html

*/

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

#include <AccelStepper.h>

RF24 radio(48, 49);   // nRF24L01 (CE, CSN)

const byte address[6] = "00001";
unsigned long lastReceiveTime = 0;
unsigned long currentTime = 0;

// Define the stepper motors and the pins the will use
AccelStepper LeftBackWheel(1, 42, 43);   // (Type:driver, STEP, DIR) - Stepper1
AccelStepper LeftFrontWheel(1, 40, 41);  // Stepper2
AccelStepper RightBackWheel(1, 44, 45);  // Stepper3
AccelStepper RightFrontWheel(1, 46, 47); // Stepper4

int wheelSpeed = 1500;

// Max size of this struct is 32 bytes - NRF24L01 buffer limit
struct Data_Package {
  byte j1PotX;
  byte j1PotY;
  byte j1Button;
  byte j2PotX;
  byte j2PotY;
  byte j2Button;
  byte pot1;
  byte pot2;
  byte tSwitch1;
  byte tSwitch2;
  byte button1;
  byte button2;
  byte button3;
  byte button4;
};
Data_Package data; //Create a variable with the above structure

void setup() {
  // Set initial seed values for the steppers
  LeftFrontWheel.setMaxSpeed(3000);
  LeftBackWheel.setMaxSpeed(3000);
  RightFrontWheel.setMaxSpeed(3000);
  RightBackWheel.setMaxSpeed(3000);

  radio.begin();
  radio.openReadingPipe(0, address);
  radio.setAutoAck(false);
  radio.setDataRate(RF24_250KBPS);
  radio.setPALevel(RF24_PA_LOW);
  radio.startListening(); //  Set the module as receiver

  Serial.begin(115200);
}

void loop() {
  // Check whether we keep receving data, or we have a connection between the two modules
  currentTime = millis();
  if ( currentTime - lastReceiveTime > 1000 ) { // If current time is more then 1 second since we have recived the last data, that means we have lost connection
    resetData(); // If connection is lost, reset the data. It prevents unwanted behavior, for example if a drone jas a throttle up, if we lose connection it can keep flying away if we dont reset the function
  }
  // Check whether there is data to be received
  if (radio.available()) {
    radio.read(&data, sizeof(Data_Package)); // Read the whole data and store it into the 'data' structure
    lastReceiveTime = millis(); // At this moment we have received the data
  }
  // Set speed - left potentiometer
  wheelSpeed = map(data.pot1, 0, 255, 100, 3000);
  
  if (data.j1PotX > 150) {
    moveSidewaysLeft();
  }
  else if (data.j1PotX < 100) {
    moveSidewaysRight();
  }
  else if (data.j1PotY > 160) {
    moveForward();
  }
  else if (data.j1PotY < 100) {
    moveBackward();
  }
  else if (data.j2PotX < 100 & data.j2PotY > 160) {
    moveRightForward();
  }
  else if (data.j2PotX > 160 & data.j2PotY > 160) {
    moveLeftForward();
  }
  else if (data.j2PotX < 100 & data.j2PotY < 100) {
    moveRightBackward();
  }
  else if (data.j2PotX > 160 & data.j2PotY < 100) {
    moveLeftBackward();
  }
  else if (data.j2PotX < 100) {
    rotateRight();
  }
  else if (data.j2PotX > 150) {
    rotateLeft();
  }
  else {
    stopMoving();
  }
  // Execute the steps
  LeftFrontWheel.runSpeed();
  LeftBackWheel.runSpeed();
  RightFrontWheel.runSpeed();
  RightBackWheel.runSpeed();
  
  // Monitor the battery voltage
  int sensorValue = analogRead(A0);
  float voltage = sensorValue * (5.0 / 1023.00) * 3; // Convert the reading values from 5v to suitable 12V i
  // If voltage is below 11V turn on the LED
  if (voltage < 11) {
    digitalWrite(led, HIGH);
  }
  else {
    digitalWrite(led, LOW);
  }
}

void moveForward() {
  LeftFrontWheel.setSpeed(wheelSpeed);
  LeftBackWheel.setSpeed(wheelSpeed);
  RightFrontWheel.setSpeed(wheelSpeed);
  RightBackWheel.setSpeed(wheelSpeed);
}
void moveBackward() {
  LeftFrontWheel.setSpeed(-wheelSpeed);
  LeftBackWheel.setSpeed(-wheelSpeed);
  RightFrontWheel.setSpeed(-wheelSpeed);
  RightBackWheel.setSpeed(-wheelSpeed);
}
void moveSidewaysRight() {
  LeftFrontWheel.setSpeed(wheelSpeed);
  LeftBackWheel.setSpeed(-wheelSpeed);
  RightFrontWheel.setSpeed(-wheelSpeed);
  RightBackWheel.setSpeed(wheelSpeed);
}
void moveSidewaysLeft() {
  LeftFrontWheel.setSpeed(-wheelSpeed);
  LeftBackWheel.setSpeed(wheelSpeed);
  RightFrontWheel.setSpeed(wheelSpeed);
  RightBackWheel.setSpeed(-wheelSpeed);
}
void rotateLeft() {
  LeftFrontWheel.setSpeed(-wheelSpeed);
  LeftBackWheel.setSpeed(-wheelSpeed);
  RightFrontWheel.setSpeed(wheelSpeed);
  RightBackWheel.setSpeed(wheelSpeed);
}
void rotateRight() {
  LeftFrontWheel.setSpeed(wheelSpeed);
  LeftBackWheel.setSpeed(wheelSpeed);
  RightFrontWheel.setSpeed(-wheelSpeed);
  RightBackWheel.setSpeed(-wheelSpeed);
}
void moveRightForward() {
  LeftFrontWheel.setSpeed(wheelSpeed);
  LeftBackWheel.setSpeed(0);
  RightFrontWheel.setSpeed(0);
  RightBackWheel.setSpeed(wheelSpeed);
}
void moveRightBackward() {
  LeftFrontWheel.setSpeed(0);
  LeftBackWheel.setSpeed(-wheelSpeed);
  RightFrontWheel.setSpeed(-wheelSpeed);
  RightBackWheel.setSpeed(0);
}
void moveLeftForward() {
  LeftFrontWheel.setSpeed(0);
  LeftBackWheel.setSpeed(wheelSpeed);
  RightFrontWheel.setSpeed(wheelSpeed);
  RightBackWheel.setSpeed(0);
}
void moveLeftBackward() {
  LeftFrontWheel.setSpeed(-wheelSpeed);
  LeftBackWheel.setSpeed(0);
  RightFrontWheel.setSpeed(0);
  RightBackWheel.setSpeed(-wheelSpeed);
}
void stopMoving() {
  LeftFrontWheel.setSpeed(0);
  LeftBackWheel.setSpeed(0);
  RightFrontWheel.setSpeed(0);
  RightBackWheel.setSpeed(0);
}


void resetData() {
  // Reset the values when there is no radio connection - Set initial default values
  data.j1PotX = 127;
  data.j1PotY = 127;
  data.j2PotX = 127;
  data.j2PotY = 127;
  data.j1Button = 1;
  data.j2Button = 1;
  data.pot1 = 1;
  data.pot2 = 1;
  data.tSwitch1 = 1;
  data.tSwitch2 = 1;
  data.button1 = 1;
  data.button2 = 1;
  data.button3 = 1;
  data.button4 = 1;
}Code language: Arduino (arduino)

说明: 因此,这里我们使用 RF24 库进行无线电通信,并使用 AccelStepper 库来控制步进电机。首先我们需要定义所有这些引脚所连接的引脚,定义下面程序所需的一些变量,并在设置部分设置步进器的最大速度并开始无线电通信。

在循环部分,我们首先读取来自 RC 发射器的数据。 RC 发射器代码以及此通信如何工作的更多详细信息可以在我的特定教程中找到。

因此根据接收到的数据,例如,如果左摇杆向前移动,其值将大于 160,在这种情况下将调用 moveForward() 自定义函数。如果我们看一下这个函数,我们可以看到它所做的只是将电机的速度设置为正值。对于向后移动,速度设置为负值。因此,为了在所有其他方向上移动,我们只需要按照开始时的说明适当地设置轮子的旋转即可。

为了执行这些命令,在循环部分我们需要为所有步进器调用 runSpeed() 函数。在loop部分我们还读取了来自电池的分压器的模拟输入,根据这个值我们可以知道电池电压什么时候会下降到11V以下,所以我们可以打开指示LED。

使用智能手机控制机器人的 Arduino 代码:

/*
   === Arduino Mecanum Wheels Robot ===
     Smartphone control via Bluetooth 
  by Dejan, www.HowToMechatronics.com
  Libraries:
  RF24, https://github.com/tmrh20/RF24/
  AccelStepper by Mike McCauley: http://www.airspayce.com/mikem/arduino/AccelStepper/index.html

*/

#include <SoftwareSerial.h>
#include <AccelStepper.h>

SoftwareSerial Bluetooth(A8, 38); // Arduino(RX, TX) - HC-05 Bluetooth (TX, RX)

// Define the stepper motors and the pins the will use
AccelStepper LeftBackWheel(1, 42, 43);   // (Type:driver, STEP, DIR) - Stepper1
AccelStepper LeftFrontWheel(1, 40, 41);  // Stepper2
AccelStepper RightBackWheel(1, 44, 45);  // Stepper3
AccelStepper RightFrontWheel(1, 46, 47); // Stepper4

#define led 14

int wheelSpeed = 1500;

int dataIn, m;

int lbw[50], lfw[50], rbw[50], rfw[50]; // for storing positions/steps
int index = 0;

void setup() {
  // Set initial seed values for the steppers
  LeftFrontWheel.setMaxSpeed(3000);
  LeftBackWheel.setMaxSpeed(3000);
  RightFrontWheel.setMaxSpeed(3000);
  RightBackWheel.setMaxSpeed(3000);

  Serial.begin(38400);
  Bluetooth.begin(38400); // Default baud rate of the Bluetooth module
  Bluetooth.setTimeout(1);
  delay(20);

  pinMode(led, OUTPUT);

}

void loop() {
  // Check for incoming data

  if (Bluetooth.available() > 0) {
    dataIn = Bluetooth.read();  // Read the data

    if (dataIn == 0) {
      m = 0;
    }
    if (dataIn == 1) {
      m = 1;
    }
    if (dataIn == 2) {
      m = 2;
    }
    if (dataIn == 3) {
      m = 3;
    }
    if (dataIn == 4) {
      m = 4;
    }
    if (dataIn == 5) {
      m = 5;
    }
    if (dataIn == 6) {
      m = 6;
    }
    if (dataIn == 7) {
      m = 7;
    }
    if (dataIn == 8) {
      m = 8;

    }
    if (dataIn == 9) {
      m = 9;
    }
    if (dataIn == 10) {
      m = 10;
    }
    if (dataIn == 11) {
      m = 11;
    }

    if (dataIn == 12) {
      m = 12;
    }
    if (dataIn == 14) {
      m = 14;
    }
    // Set speed
    if (dataIn >= 16) {
      wheelSpeed = dataIn * 10;
      Serial.println(wheelSpeed);
    }
  }
  if (m == 4) {
    moveSidewaysLeft();
  }
  if (m == 5) {
    moveSidewaysRight();
  }
  if (m == 2) {
    moveForward();
  }
  if (m == 7) {
    moveBackward();
  }
  if (m == 3) {
    moveRightForward();
  }
  if (m == 1) {
    moveLeftForward();
  }
  if (m == 8) {
    moveRightBackward();
  }
  if (m == 6) {
    moveLeftBackward();
  }
  if (m == 9) {
    rotateLeft();
  }
  if (m == 10) {
    rotateRight();
  }

  if (m == 0) {
    stopMoving();
  }
  //Serial.println(dataIn);
  // If button "SAVE" is pressed
  if (m == 12) {
    if (index == 0) {
      LeftBackWheel.setCurrentPosition(0);
      LeftFrontWheel.setCurrentPosition(0);
      RightBackWheel.setCurrentPosition(0);
      RightFrontWheel.setCurrentPosition(0);
    }
    lbw[index] = LeftBackWheel.currentPosition();  // save position into the array
    lfw[index] = LeftFrontWheel.currentPosition();
    rbw[index] = RightBackWheel.currentPosition();
    rfw[index] = RightFrontWheel.currentPosition();
    index++;                        // Increase the array index
    m = 0;
  }

  if (m == 14) {
    runSteps();
    if (dataIn != 14) {
      stopMoving();
      memset(lbw, 0, sizeof(lbw)); // Clear the array data to 0
      memset(lfw, 0, sizeof(lfw));
      memset(rbw, 0, sizeof(rbw));
      memset(rfw, 0, sizeof(rfw));
      index = 0;  // Index to 0
    }
  }

  LeftFrontWheel.runSpeed();
  LeftBackWheel.runSpeed();
  RightFrontWheel.runSpeed();
  RightBackWheel.runSpeed();

  // Monitor the battery voltage
  int sensorValue = analogRead(A0);
  float voltage = sensorValue * (5.0 / 1023.00) * 3; // Convert the reading values from 5v to suitable 12V i
  //Serial.println(voltage);
  // If voltage is below 11V turn on the LED
  if (voltage < 11) {
    digitalWrite(led, HIGH);
  }
  else {
    digitalWrite(led, LOW);
  }

}

void runSteps() {
  for (int i = index - 1; i >= 0; i--) { // Run through all steps(index)
    LeftFrontWheel.moveTo(lfw[i]);
    LeftFrontWheel.setSpeed(wheelSpeed);
    LeftBackWheel.moveTo(lbw[i]);
    LeftBackWheel.setSpeed(wheelSpeed);
    RightFrontWheel.moveTo(rfw[i]);
    RightFrontWheel.setSpeed(wheelSpeed);
    RightBackWheel.moveTo(rbw[i]);
    RightBackWheel.setSpeed(wheelSpeed);

    while (LeftBackWheel.currentPosition() != lbw[i] & LeftFrontWheel.currentPosition() != lfw[i] & RightFrontWheel.currentPosition() != rfw[i] & RightBackWheel.currentPosition() != rbw[i]) {
      LeftFrontWheel.runSpeedToPosition();
      LeftBackWheel.runSpeedToPosition();
      RightFrontWheel.runSpeedToPosition();
      RightBackWheel.runSpeedToPosition();

      if (Bluetooth.available() > 0) {      // Check for incomding data
        dataIn = Bluetooth.read();
        if ( dataIn == 15) {           // If button "PAUSE" is pressed
          while (dataIn != 14) {         // Wait until "RUN" is pressed again
            if (Bluetooth.available() > 0) {
              dataIn = Bluetooth.read();
              if ( dataIn == 13) {
                stopMoving();
                break;
              }
            }
          }
        }
        if (dataIn >= 16) {
          wheelSpeed = dataIn * 10;
          dataIn = 14;
        }
        if ( dataIn == 13) {
          break;
        }
      }
    }
  }
  // Go back through steps
  for (int i = 1; i <= index - 1; i++) { // Run through all steps(index)

    LeftFrontWheel.moveTo(lfw[i]);
    LeftFrontWheel.setSpeed(wheelSpeed);
    LeftBackWheel.moveTo(lbw[i]);
    LeftBackWheel.setSpeed(wheelSpeed);
    RightFrontWheel.moveTo(rfw[i]);
    RightFrontWheel.setSpeed(wheelSpeed);
    RightBackWheel.moveTo(rbw[i]);
    RightBackWheel.setSpeed(wheelSpeed);

    while (LeftBackWheel.currentPosition() != lbw[i]& LeftFrontWheel.currentPosition() != lfw[i] & RightFrontWheel.currentPosition() != rfw[i] & RightBackWheel.currentPosition() != rbw[i]) {

      LeftFrontWheel.runSpeedToPosition();
      LeftBackWheel.runSpeedToPosition();
      RightFrontWheel.runSpeedToPosition();
      RightBackWheel.runSpeedToPosition();
      //Serial.print("  current: ");
      //Serial.println(LeftBackWheel.currentPosition());

      if (Bluetooth.available() > 0) {      // Check for incomding data
        dataIn = Bluetooth.read();
        if ( dataIn == 15) {           // If button "PAUSE" is pressed
          while (dataIn != 14) {         // Wait until "RUN" is pressed again
            if (Bluetooth.available() > 0) {
              dataIn = Bluetooth.read();
              if ( dataIn == 13) {
                stopMoving();
                break;
              }
            }
          }
        }
        if (dataIn >= 16) {
          wheelSpeed = dataIn * 10;
          dataIn = 14;
        }
        if ( dataIn == 13) {
          //Serial.println("DEKI");
          break;
        }
      }
    }
  }
}

void moveForward() {
  LeftFrontWheel.setSpeed(wheelSpeed);
  LeftBackWheel.setSpeed(wheelSpeed);
  RightFrontWheel.setSpeed(wheelSpeed);
  RightBackWheel.setSpeed(wheelSpeed);
}
void moveBackward() {
  LeftFrontWheel.setSpeed(-wheelSpeed);
  LeftBackWheel.setSpeed(-wheelSpeed);
  RightFrontWheel.setSpeed(-wheelSpeed);
  RightBackWheel.setSpeed(-wheelSpeed);
}
void moveSidewaysRight() {
  LeftFrontWheel.setSpeed(wheelSpeed);
  LeftBackWheel.setSpeed(-wheelSpeed);
  RightFrontWheel.setSpeed(-wheelSpeed);
  RightBackWheel.setSpeed(wheelSpeed);
}
void moveSidewaysLeft() {
  LeftFrontWheel.setSpeed(-wheelSpeed);
  LeftBackWheel.setSpeed(wheelSpeed);
  RightFrontWheel.setSpeed(wheelSpeed);
  RightBackWheel.setSpeed(-wheelSpeed);
}
void rotateLeft() {
  LeftFrontWheel.setSpeed(-wheelSpeed);
  LeftBackWheel.setSpeed(-wheelSpeed);
  RightFrontWheel.setSpeed(wheelSpeed);
  RightBackWheel.setSpeed(wheelSpeed);
}
void rotateRight() {
  LeftFrontWheel.setSpeed(wheelSpeed);
  LeftBackWheel.setSpeed(wheelSpeed);
  RightFrontWheel.setSpeed(-wheelSpeed);
  RightBackWheel.setSpeed(-wheelSpeed);
}
void moveRightForward() {
  LeftFrontWheel.setSpeed(wheelSpeed);
  LeftBackWheel.setSpeed(0);
  RightFrontWheel.setSpeed(0);
  RightBackWheel.setSpeed(wheelSpeed);
}
void moveRightBackward() {
  LeftFrontWheel.setSpeed(0);
  LeftBackWheel.setSpeed(-wheelSpeed);
  RightFrontWheel.setSpeed(-wheelSpeed);
  RightBackWheel.setSpeed(0);
}
void moveLeftForward() {
  LeftFrontWheel.setSpeed(0);
  LeftBackWheel.setSpeed(wheelSpeed);
  RightFrontWheel.setSpeed(wheelSpeed);
  RightBackWheel.setSpeed(0);
}
void moveLeftBackward() {
  LeftFrontWheel.setSpeed(-wheelSpeed);
  LeftBackWheel.setSpeed(0);
  RightFrontWheel.setSpeed(0);
  RightBackWheel.setSpeed(-wheelSpeed);
}
void stopMoving() {
  LeftFrontWheel.setSpeed(0);
  LeftBackWheel.setSpeed(0);
  RightFrontWheel.setSpeed(0);
  RightBackWheel.setSpeed(0);
}Code language: Arduino (arduino)

说明: 使用 Android 应用程序控制机器人的其他代码非常相似并且工作方式相同。这里我们需要定义蓝牙模块而不是无线电模块,并在设置部分初始化它的通信。再说一遍,首先我们从智能手机或 Android 应用程序读取传入的数据,并据此告诉机器人向哪个方向移动。

如果我们看一下 Android 应用程序,我们会发现它只是在按下按钮时通过蓝牙发送从 0 到 15 的数字。

该应用程序是使用 MIT App Inventor 在线应用程序制作的,您可以在我的特定教程中找到有关它的更多详细信息。

在这里你可以下载这个应用程序以及可编辑的项目文件:

为了使用此应用程序对自动机器人运动进行编程,当我们按下“保存”按钮时,我们只需将步进电机的当前位置存储到数组中。然后当我们按下“RUN”按钮时,我们调用 runSteps() 自定义函数,该函数使用一些 for 和 while 循环执行或运行所有存储的步骤。

我希望你喜欢这个教程并学到了一些新东西。随时在下面的评论部分提出任何问题,并查看我的 Arduino 项目收藏。


制造工艺

  1. 通过蓝牙控制的树莓派机器人
  2. 带伺服电机的机器人避障
  3. 线跟随机器人
  4. 语音控制机器人
  5. Arduino 控制的钢琴机器人:PiBot
  6. Littlearm 2C:构建 3D 打印的 Arduino 机械臂
  7. 自主家庭助理机器人
  8. 使用 Android 应用程序控制 Arduino 机械臂
  9. 超酷室内导航机器人
  10. WiDC:Wi-Fi 控制的 FPV 机器人
  11. 智能会说话的人形机器人,仅使用 Arduino!
  12. 带有 Arduino 和 Python 的人工智能助手机器人