• 正文
  • 相关推荐
  • 电子产业图谱
申请入驻 产业图谱

基于ESP8266的Wi-Fi控制机械臂

2022/10/14 作者:有灵魂的发烧友
352
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

使用ESP8266 WiFi模块远程控制您的机械臂,从一个简单的html界面开始!

机械臂套件变得越来越便宜。你可以在网上找到不同的模型,并尝试不同的方法来控制它们。

这个项目是我探索控制机械臂的不同方法的系列教程的一部分。

在我之前的实验中,我做过用任天堂Wii Nunchuk来控制一个6关节的机械手臂的项目。

这次我想用一个便宜的ESP8266 WiFi模块远程控制它。为此,我设计了一个html界面,我可以通过它向我的机器人发送命令,存储它们并在以后重复。

本文共有几种方法。如果你没有机械臂套件,你仍然可以使用它来学习Arduino编程,以及如何在自己的项目中将Arduino与ESP8266模块连接。你也可以当作用它来练习你的电子和机械技能。

第 1 步:工具和材料

 

本项目使用了以下工具和材料:

工具和材料:

  • 焊锡铁丝。为了将Nunchuk连接到Arduino上,我必须在Nunchuk的电线上焊接一些端子;
  • 收缩管。一些缩管片被用来更好地隔离导体;
  • 螺丝刀。该结构是用一些螺栓和螺母安装的;
  • 六轴机械台式机械臂
  • 12V电源(2A或以上);
  • ESP8266-01
  • 跳线(5线);
  • Arduino Mega

Sain智能6轴机械桌面臂已经配备了以下组件:

  • Arduino Mega 2560 R3
  • 控制板屏蔽
  • NRF24L01+无线收发模块
  • MPU6050三轴陀螺仪及三轴加速度计
  • 71 × m3 × 8螺钉
  • 47 × M3螺母
  • 2 * U支架
  • 5倍伺服支架
  • 4 x 9公斤伺服
  • 2 x 20公斤伺服
  • 6 x金属伺服托盘
  • 3 × U支架
  • 21x直角支架
  • 3 ×法兰轴承
  • 1 x机械手掌

你可以在网上找到其他的机械臂套件,甚至可以自己设计。例如使用3D打印

在下一步,我将向您展示如何组装手臂套件之前布线电路。如果您没有类似的套件,可以跳过部分步骤。同时也可以使用另一个机械臂套件,组装它,然后直接跳到电子和编程步骤。

第 2 步:装配机械臂

  • 第一个要组装的部件是机器人的底座。它由两个U形支架组成,用四个M3螺栓和螺母背对背连接,如图所示
  • 伺服电机安装垂直于底座,使用伺服支架。这个剖面使用四个M3螺栓和螺母连接到底座上,如图所示。伺服#1放在它的顶部,并使用四个M3螺栓和螺母连接。一个圆形的金属喇叭附在伺服轴上。
  • 另一个伺服支架安装垂直于前一个。它连接到伺服1号喇叭使用四个M3螺栓。伺服#2安装有四个M3螺栓和螺母,也使用圆形金属喇叭。一个U型支架,然后连接到喇叭使用四个螺栓。注意,在伺服轴的正侧使用了一个M3螺栓。它使结构稳定。一个轴承安装在这个螺栓上,并使用另一个M3螺母锁定在位置上。这样U型支架紧密地连接到伺服#2中心轴上。
  • 另一个U型支架使用4颗M3螺栓和螺母安装。在另一端,安装伺服#3,使用一个圆形金属喇叭和四个螺栓。伺服支架与伺服电机连接,用一些螺栓和螺母将L型型材与伺服支架连接。注意,另一个轴承是用对伺服轴,如前所述。
  • 还有一个U型支架使用一组M3螺栓和螺母连接到L型型材上。类似于前面的步骤,伺服#4是安装到U支架使用四个螺栓。另一个伺服支架与伺服连接。
  • 第五个伺服与伺服4号垂直连接,使用另一个伺服支架,安装使用四个M3螺栓和螺母。
  • 夹持器连接到伺服#5轴上。在它的顶部,伺服#6连接使用一些螺栓,螺母和一个金属喇叭。夹持器有一些齿轮,这将把伺服的旋转变成夹持器的线性运动。

第 3 步:连接电路

只需要结构组装好,你就可以准备连接电路了。我用的是机械臂套件自带的控制板。它使组件的连接更容易,因为它已经为伺服电机、电源等提供了特定的连接器。

不巧的是,这个控制板没有ESP8266的特定连接器。所以我必须用一些跳线把Wi-Fi模块连接到我的Arduino Mega上。

各组件的连接方法如下:

ESP8266:

  • Arduino Mega Pin 14(在屏蔽上)
  • Arduino Mega Pin 15(在屏蔽上)
  • ESP8266 Vcc => Ardino Mega Pin 3V3(在盾牌上)
  • ESP8266 Gnd => Arduino Mega Pin Gnd(在屏蔽上)
  • ESP8266 CH_PD => Arduino Mega Pin 3V3(在屏蔽上,在为24L01模块预留的连接器中)

你会注意到伺服控制屏蔽有两个标记为5V的引脚。虽然,其中一个实际上是3.3V引脚。用电压表测试一下。

伺服系统:

  • 控制屏蔽端子11 =>伺服#1
  • 控制屏蔽端子12 =>伺服#2
  • 控制屏蔽端子13 =>伺服#3
  • 控制屏蔽端子8 =>伺服#4
  • 控制屏蔽端子9 =>伺服#5
  • 控制屏蔽端子10 =>伺服#6

如果你不使用控制屏蔽,你应该使用以下引脚配置:

  • Arduino Pin 11 =>伺服#1 (Sgn)
  • Arduino Pin 12 =>伺服#2 (Sgn)
  • Arduino Pin 13 => 3伺服(Sgn)
  • Arduino Pin 8 =>伺服#4 (Sgn)
  • Arduino Pin 9 =>伺服#5 (Sgn)
  • Arduino Pin 10 =>伺服#6 (Sgn)
  • Arduino Gnd => Servos Gnd
  • 6V电源=>伺服Vcc

你还需要连接一个外部12V电源。我建议一个输出大于2A的。伺服系统消耗大量的电力,如果电力供应不够充足,伺服系统就会振动,变得非常热。

在上传Arduino代码(在后面的步骤中显示)之前,不要连接电源。防护罩上有个电源按钮。保持关闭状态。

在Arduino上插入USB线,然后进行下一步。

警告:你会注意到我已经将我的ESP8266 RX/TX引脚直接连接到Arduino TX/RX引脚。这对我很有效,但我不建议你也这么做。ESP8266工作在3.3V, Arduino引脚运行在5V。有人说它可能会烧毁你的ESP8266模块(尽管我已经测试了几次,没有问题)。如果你想将5V转换为3.3V,你可能会使用电压分压器或电压电平转换器。

第 4 步:设置Arduino IDE

现在硬件已经准备好了,是时候处理Arduino代码了。

1. 下载并安装Arduino IDE最新版本您可以在Arduino的网站上找到Windows, Linux或MAC OSX的最新版本:https://www.arduino.cc/en/main/software

免费下载,安装到你的电脑上并启动它。

Arduino与with ESP8266模块之间的通信没有使用额外的库。请检查您ESP8266的波特率,并在代码中正确设置。

第 5 步:Arduino代码
下载Arduino代码(browser-control -arm-v3.ino), XXXXX替换为wifi路由器SSID, YYYYY替换为路由器密码。连接Arduino板到您的计算机USB端口,并上传代码。

一旦电路通电,手臂将移动到起始位置,ESP8266将尝试连接Wi-Fi网络。

警告:当代码开始运行时,机械臂将快速移动到它的初始位置。开机过程中注意不要弄伤或损坏附近的设备!

你可能要更换每个伺服电机的起始角度取决于你的伺服安装在哪里。

代码注释:

在设置之前,代码导入草图上使用的库。只使用了servo.h库。没有使用库来连接WiFi模块。

定义要使用的引脚,并声明全局变量。角#整数变量存储每个伺服的初始位置。如果你想让机器人从不同的位置开始,改变这些变量的值。

角度#sp是每个伺服的设定点。在代码执行期间,控制器将以给定的速度移动电机,直到它们达到设定值。

Servo_speed变量定义所有伺服的运动速度。如果你想要一个特定的伺服移动更快,增加它的值。

//Include libraries
#include <Servo.h>
//define variables
#define DEBUG true //display ESP8266 messages on Serial Monitor
#define SERV1 8    //servo 1 on digital port 8
#define SERV2 9    //servo 2 on digital port 9
#define SERV3 10   //servo 3 on digital port 10
#define SERV4 11   //servo 4 on digital port 11
#define SERV5 12   //servo 5 on digital port 12
#define SERV6 13   //servo 6 on digital port 13
Servo s1; //servo 1
Servo s2; //servo 2
Servo s3; //servo 3
Servo s4; //servo 4
Servo s5; //servo 5
Servo s6; //servo 6
//define starting angle for each servo
//choose a safe position to start from
//it will try to move instantaniously to that position when powered up!
//those angles will depend on the angle of each servo during the assemble
int angle1 = 90; //servo 1 current angle
int angle2 = 30; //servo 2 current angle
int angle3 = 0;  //servo 3 current angle
int angle4 = 90; //servo 4 current angle
int angle5 = 90; //servo 5 current angle
int angle6 = 45; //servo 6 current angle
int servo_speed = 6; //speed of the servos
int angle1sp = 90; //servo 1 set point
int angle2sp = 30; //servo 2 set point
int angle3sp = 0;  //servo 3 set point
int angle4sp = 90; //servo 4 set point
int angle5sp = 90; //servo 5 set point
int angle6sp = 45; //servo 6 set point
boolean display_angles = true; //boolean used to update the angle of each servo on Serial Monitor

在设置过程中,每个伺服附加到一个特定的引脚,其位置是启动的。

使用Arduino Mega的两个串口:一个用于serial Monitor通信,另一个用于与ESP8266-01模块通信。两个串行通信都在设置过程中启动。

与ESP8266模块的通信使用标准AT命令。

首先,Arduino为模块的其余部分发送一个命令(使用AT+RST)。它将重新启动模块。ESP8266模块可以在工作站工作,也可以作为接入点。它被设置为站模式(使用AT+CWMODE=1),并接收连接到WiFi路由器的命令(AT+ cw日本=SSID,PASSWORD)。while循环等待直到连接成功。

AT+CIFSR命令用于显示归属于ESP8266的IP地址。稍后将在控件接口上使用它。然后在端口80启动web服务器。这样,ESP8266将能够接收到该IP地址和端口的消息。

//SETUP
void setup() {
    //attach each servo to a pin and start its position
    s1.attach(SERV1);
    s1.write(angle1);
    s2.attach(SERV2);
    s2.write(angle2);
    s3.attach(SERV3);
    s3.write(angle3);
    s4.attach(SERV4);
    s4.write(angle4);
    s5.attach(SERV5);
    s5.write(angle5);
    s6.attach(SERV6);
    s6.write(angle6);
    //start serial communication
    Serial.begin(9600);
    Serial.println("Connecting...");
    Serial3.begin(9600);
    //Wi-Fi connection 
    sendData("AT+RSTrn", 2000, DEBUG); //reset module
    sendData("AT+CWMODE=1rn", 1000, DEBUG); //set station mode
    sendData("AT+CWJAP="XXXXX","YYYYY"rn", 2000, DEBUG);   //connect wifi network
    while(!Serial3.find("OK")) { //wait for connection
    } 
    sendData("AT+CIFSRrn", 1000, DEBUG); //show IP address
    sendData("AT+CIPMUX=1rn", 1000, DEBUG); //allow multiple connections
    sendData("AT+CIPSERVER=1,80rn", 1000, DEBUG); // start web server on port 80
}

主循环被一遍又一遍地重复。在每次扫描过程中,Arduino将检查是否有传入消息。如果是,它将读取整个字符串并将其分解为6个更小的字符串。每一个将代表每个伺服的设定值。

void loop() {
  if (Serial3.available())  //check if there is data available on ESP8266
    {
    if (Serial3.find("+IPD,")) //if there is a new command
      {
        String msg;
        Serial3.find("?"); //run cursor until command is found
        msg = Serial3.readStringUntil(' '); //read the message
        String command = msg.substring(0, 3); //command is informed in the first 3 characters. "srs" = command to move the six servos
        String valueStr1 = msg.substring(4, 7);   //next 3 characters inform the desired angle
        String valueStr2 = msg.substring(8,11);   //next 3 characters inform the desired angle
        String valueStr3 = msg.substring(12,15);   //next 3 characters inform the desired angle
        String valueStr4 = msg.substring(16,19);   //next 3 characters inform the desired angle
        String valueStr5 = msg.substring(20,23);   //next 3 characters inform the desired angle
        String valueStr6 = msg.substring(24,27);   //next 3 characters inform the desired angle
        int angle1sp = valueStr1.toInt();         //convert to integer
        int angle2sp = valueStr2.toInt();         //convert to integer
        int angle3sp = valueStr3.toInt();         //convert to integer
        int angle4sp = valueStr4.toInt();         //convert to integer
        int angle5sp = valueStr5.toInt();         //convert to integer
        int angle6sp = valueStr6.toInt();         //convert to integer

代码将增加/减少每个伺服的角度在小步骤,直到它匹配接收设定值。在每个循环结束时,延迟被用来限制电机的速度。

if (angle1 > angle1sp) {
    angle1 -= 1;
    s1.write(angle1);
  }
  if (angle1 < angle1sp) {
    angle1 += 1;
    s1.write(angle1);
  }
.
.
.
delay(100/servo_speed);

第 6 步:HTML界面
使用html和Javascript设计了一个简单的控制界面。下载它,解压并在你的浏览器中启动它。我在Firefox和谷歌Chrome浏览器中测试了它。

为了向Arduino发送命令,用户必须输入分配给ESP8266的IP地址。正如前面所描述的,您可以使用串行监视器获得它。幸运的是,IP在接下来的连接中会重复。

在这个控制界面上,用户可以使用一些滑动条为每个关节选择一个给定的角度。每个伺服器的电流角度显示在每条下面。

“添加位置到命令堆栈”按钮允许用户在文本框中存储手臂在命令堆栈上的当前位置。通过这种方式,可以存储位置序列,每个移动之间具有可配置的延迟。

各命令定义如下:sr1:angle1 sr2:angle2 sr3:angle3 sr4:angle4 sr5:angle5 sr6:angle6 delay:时间。角度用度数表示,时间用毫秒表示。用户也可以在文本框上手动编辑命令。

运行命令栈运行存储在命令栈上的命令序列。清除命令栈将擦除命令列表。用户也可以保存命令列表(在文本文件中)并稍后加载它。通过这种方式,可以存储命令序列并重复它们。

Html代码注释:

Html文件分为头部和主体部分。头部只显示一些元数据,并指示将在该文件上运行哪些javascript文件。

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="author" content="Igor Fonseca Albuquerque">
<title>Control interface</title>
<script src="jquery.js"></script>
<script src="myscript1.js"></script>
</head>

主体是定义所有输入(文本表单、按钮和滑动条)的地方。声明了一个文本框,让用户输入要发送的每个命令的IP地址。它从一个给定的IP地址(192.168.0.9)开始,但是您必须用从Serial Monitor获得的IP地址更新它。

<div style="margin: 0; width:500px; height:80px;">
    <form name="myform2" action="" method="GET">
        ESP8266 IP Address:
        <input type="text" name="inputbox" value="192.168.0.9">
    </form>
</div>

在六列表中增加了六个滑杆,每个伺服一个滑杆。滑动条使用范围类型输入定义,角度在0到180度之间。值参数给出每个伺服的起始角度,显示在每个条下面的文本框中。

用户可以通过用鼠标拖动滑块来改变角度。当释放鼠标按钮时,调用moveSrs()函数。这将在后面描述。

<th>
    <p style="margin: 0; position: relative; top: 0px; left: 0px; width:100px; height:20px;"> Servo 1 </p>
    <input type="range" id="s1Range" min="0" max="180" value="90" onmouseup="moveSrs(s1Range.value, s2Range.value, s3Range.value, s4Range.value, s5Range.value, s6Range.value)" onchange="updateTextInput1(this.value)" style="margin: 0; position: relative; top: 10px; left: 0px; width:200px; height:40px;" />
    <input type="text" id="s1textInput" value="90" style="margin: 0; position: relative; top: 10px; left: -10px; border: none;">
</th>

定义了一个按钮,用于将当前角度添加到命令堆栈中。addCommand()函数在单击时被调用。其右侧的文本框用于用户输入两个命令之间使用的时间延迟(以毫秒为单位)。

<input type="button" id="button1" value="Add position to command stack" onClick="addCommand(s1textInput.value, s2textInput.value, s3textInput.value, s4textInput.value, s5textInput.value, s6textInput.value, delayValue.value)" style="position: relative; top:60px; height:40px;">
    <input type="text" id="delayValue" value="1000" style="position: relative; top:60px; height:35px; width:50px;">

第二个表用于组织其他功能。定义了一个文本区域来存储命令堆栈。在它下面有两个按钮,用于调用runCommands()和clearCommads()函数。

<table style="margin: 0; position: relative; top: 80px; left: 0px; width:100%; height:80px;">
    <tr><td>Command stack:</td></tr>
        <tr>
            <td>
                <textarea id="inputTextToSave" cols="80" rows="14"></textarea>
            </td>
        </tr>
        <tr>
            <td>
                <button onclick="runCommands(inputTextToSave.value)" style="height:40px;">Run command stack</button>
                <button onclick="clearCommand()" style="height:40px;">Clear command stack</button>
                <p>
            </td>
        </tr><br>

在表的末尾,有一些用于保存和打开文本文件的按钮。

Javascript代码注释:

html接口调用两个Javascript文件:jquery.js和myscript.js。在myscript.js中,我设计了自己的函数来与机器人交互。

正如前面所描述的,无论何时移动(并释放)一个滑块,都会调用moveSrs()函数。它以每个伺服器的角度作为输入。它处理这些值(添加一些零,这样它总是有三个数字),并发送一个消息到ESP8266模块的IP地址。

function moveSrs(angle1, angle2, angle3, angle4, angle5, angle6)
{
    TextVar = myform2.inputbox.value;
    ArduinoVar = "http://" + TextVar + ":80";
    
    //add zeros
    if (angle1 < 100) {
        angle1 = "0" + angle1;
    }
    if (angle1 < 10) {
        angle1 = "0" + angle1;
    }
    .    
    .
    .
    //send command
    $.wait(5000).then($.get( ArduinoVar, { "srs": angle1 + " " + angle2 + " " + angle3 + " " + angle4 + " " + angle5 + " " + angle6 }, function(data){alert("data:" + data);}))    ;
    {Connection: close};
    
}

每个伺服都有一个updateTextInput#()函数。它只用于更新滑动条下的文本与伺服的当前角度。

//update text under scroll bars
function updateTextInput1(val) {
    document.getElementById('s1textInput').value=val;
}

addCommand()函数只需在堆栈文本框中添加一个具有适当角度和延迟的新行。另一方面,clearCommand()则清除该文本框。

//add command to the stack
function addCommand(val1, val2, val3, val4, val5, val6, val7) {
    document.getElementById('inputTextToSave').value = document.getElementById('inputTextToSave').value + "sr1:" + val1 + " sr2:" + val2 + " sr3:" + val3 + " sr4:" + val4 + " sr5:" + val5 + " sr6:" + val6 + " delay:" + val7 + String.fromCharCode(13, 10);
}
//clear command stack
function clearCommand() {
    document.getElementById('inputTextToSave').value = "";
}

runCommands()是处理命令堆栈的地方。它每次在线读取并将其拆分以获得该命令行中每个伺服的角度。我注意到使用了一个setTimout函数。时间变量'k'在每个命令行上按给定的时间(延迟值)递增。使用setTimout函数,一个新的命令只在给定的时间过后发送,并且ESP8266不会同时收到很多消息。否则,它的缓冲区将被超过,可能会崩溃。

//run command stack
function runCommands(val) {
    var k = 0;
    step = 0;
    var commands = val.split("n"),i;
    for (i = 0; i < commands.length - 1; i++) {
            setTimeout(function(data){
                var angle1 = commands[step].split(" ")[0];
                angle1 = angle1.split(":")[1];
                var angle2 = commands[step].split(" ")[1];
                angle2 = angle2.split(":")[1];
                var angle3 = commands[step].split(" ")[2];
                angle3 = angle3.split(":")[1];
                var angle4 = commands[step].split(" ")[3];
                angle4 = angle4.split(":")[1];
                var angle5 = commands[step].split(" ")[4];
                angle5 = angle5.split(":")[1];
                var angle6 = commands[step].split(" ")[5];
                angle6 = angle6.split(":")[1];
                moveSrs(angle1, angle2, angle3, angle4, angle5, angle6);
                step+=1;
            },k);
            
            var tempo = commands[step].split(" ")[6];
            tempo = tempo.split(":")[1];
            k += parseInt(tempo);            
    }
}

第 7 步:大功告成
 

插入USB数据线到你的电脑,打开串行显示器和电源机器人。

它会自动连接你的WiFi网络,并显示它的IP地址。保存这个数字。你现在可以移除USB连接线(甚至重置Arduino)。如果您试图将它再次连接到相同的网络,它可能会使用相同的IP地址。

打开浏览器的界面,输入之前见过的IP地址。电脑必须连接到同一个WiFi网络。

为每个关节选择角度并添加到命令堆栈中。任何两个命令之间都可以使用延迟。请注意,延迟必须足够大,以确保在发送新命令之前前一个命令已经结束(机器人已经到达最后一个设置点)。

您可以将命令堆栈保存在.txt文件中,以便以后使用。

如果您对此项目有任何想法、意见或问题,请在下方留言。

以上内容翻译自网络,原作者:Igor Fonseca Albuquerque,如涉及侵权,可联系删除。

相关推荐

电子产业图谱