使用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,如涉及侵权,可联系删除。