Android手机控制机械臂

本篇教程中,我们将学习如何使用ESP8266WiFi开发板来制作一个简易的机械臂,可以使用手机发送命令给esp8266开发板,开发板接收到命令从而控制机械臂的运动。

一、软件和硬件

1.材料

ESP8266WiFi开发板
迷你机械臂(SG90舵机)
按键开关一个
10KΩ电阻一个
面包板+若干跳线
Android手机+零知星球APP:零知星球APP可在“软件下载”中下载

2.组装

机械臂的组装可以参照说明书进行装配:迷你手臂 装配说明书.pdf(点击下载)

组装完成后成品如图所示:

硬件连接

实物连接图如下:

这里我们使用步进电机代替了底座的舵机,底座使用舵机注意将代码中的步进电机部分注释掉,并将注释的舵机部分取消注释。

二、方法步骤

为了保证ESP8266能够和手机正常通信,我们需要将代码中的WiFi账号密码修改成你所需要连接的WiFi,同时手机也连接同一WiFi


							
    //ESP8266作为服务器连接到WiFi
    const char *ssid = "zaixinjian2019";  //要连接的WiFi名称
    const char *password = "2019zaixinjiancp";  //要连接WiFi的密码
							
						

因为每个人组装完机械臂之后,舵机的可旋转角度范围都会不一向,所以以下部分代码的参数要根据实际情况来修改以下


							
	pos2 = map(pitch,0,90,100,180);  //后面两个参数100,180改成组装机械臂后舵机能旋转的角度范围
	pos3 = map(roll,-90,90,0,180);					
						
						

												
	int pos = 110;
	if(pos == 110)  //这里的角度110,30也改成你组装成机械臂后舵机实际的旋转角度范围
	{
	        for (pos; pos>30; pos--)
	        {
	                myservo.write(pos);
	                Serial.println(pos);
	                delay(20);
	        }
	}
	else if(pos == 30)
	{
	        for (pos; pos<110; pos++)
	        {
	                myservo.write(pos);
	                Serial.println(pos);
	                delay(20);
	        }
	}			
											
											

完整代码如下:


												
	/**********************************************************
	*    文件: ESP8266_Arm.ino      by 零知实验室([url=http://www.lingzhilab.com]www.lingzhilab.com[/url])
	*    -^^- 零知开源,让电子制作变得更简单! -^^-
	*    时间: 2019/06/17 14:12
	*    说明:
	************************************************************/
	#include <ESP8266WiFi.h>
	//#include <Stepper.h>
	#include <Servo.h>
	 
	//#define STEPS 256
	#define key D8
	#define port  8888  //端口号
	 
	WiFiServer server(port);
	//Stepper stepper(STEPS,D1,D3,D2,D4);
	Servo myservo;
	Servo myservo2;
	Servo myservo3;
	WiFiClient client;
	 
	//ESP8266作为服务器连接到WiFi
	const char *ssid = "zaixinjian2019";  //要连接的WiFi名称
	const char *password = "2019zaixinjiancp";  //要连接WiFi的密码
	 
	int count = 32;
	int value = 0;
	int pitch;
	int roll;
	int pos2,pos3;
	int beforepos2,beforepos3;
	 
	// 复位或上电后运行一次:
	void setup() {
	        //在这里加入初始化相关代码,只运行一次:
	        Serial.begin(9600);
	         
	        pinMode(key,INPUT_PULLUP);
	         
	        WiFi.mode(WIFI_STA);
	        WiFi.begin(ssid, password); //连接WiFi
	//        stepper.setSpeed(20);
	        myservo.attach(D5);
	        myservo2.attach(D6);
	        myservo3.attach(D7);
	        //        myservo.write(pos);
	         
	        // 等待ESP8266连接上WiFi
	        Serial.println("Connecting to Wifi");
	        while (WiFi.status() != WL_CONNECTED) {
	                delay(50);
	                Serial.print(".");
	                delay(50);
	        }
	         
	        Serial.println("");
	        Serial.print("Connected to ");
	        Serial.println(ssid);
	         
	        Serial.print("IP address: ");
	        Serial.println(WiFi.localIP());
	        Serial.print("port:");
	        Serial.println(port);
	        server.begin();
	         
	}
	 
	//一直循环执行:
	void loop() {
	        // 在这里加入主要程序代码,重复执行:
	        client = server.available();
	         
	        if (client) {
	                if(client.connected())
	                {
	                        Serial.println("Client Connected");
	                }
	                 
	                while(client.connected()){  //WiFi连接上后循环执行下面的代码
	                         
	                        getCom();
	                         
	                        beforepos2 = pos2;
	                        beforepos3 = pos3;
	                         
	                        pos2 = map(pitch,0,90,100,180);  //后面两个参数100,180改成组装机械臂后舵机能旋转的角度范围
	                        pos3 = map(roll,-90,90,0,180);
	                         
	                        Holder();
	                         
	                        armControl();
	                         
	                }
	                client.stop();
	                Serial.println("Client disconnected");
	        }
	}
	 
	void getCom()  //获取手机发送的命令
	{
	         
	        if(client.available()>0)  //判断ESP8266缓冲区是否有数据
	        {
	                pitch=client.parseInt();  //parseInt函数将第一个整型数据赋值给pitch,并将缓冲区的数据删除
	                roll=client.parseInt();  //第一个整型数据赋值给了pitch,并删除了缓冲区的数据,所以第二个数据变成了第一个
	                Serial.print("pitch=");
	                Serial.print(pitch);
	                Serial.print("  roll=");
	                Serial.println(roll);
	        }
	         
	}
	 
	void armControl()
	{
	        if(pitch>15&&roll>-20&&roll<20)  //控制机械臂前臂的上下运动
	        {
	                if(pos2>=beforepos2)
	                {
	                        for(int i=beforepos2;i<=pos2;i++)
	                        {
	                                myservo2.write(i);
	                                delay(10);
	                        }
	                                 
	                }
	                else if(pos2<beforepos2)
	                {
	                        for(int i=beforepos2;i>=pos2;i--)
	                        {
	                                myservo2.write(i);
	                                delay(10);
	                        }
	                                 
	                }
	        }
	         
	        if(roll>15&&roll<90&&roll>-90&&roll<-15)  //底座舵机
	        {
	                if(pos3>=beforepos3)
	                {
	                        for(int i=beforepos3;i<=pos3;i++)
	                        {
	                                myservo3.write(i);
	                                delay(10);
	                        }
	                }
	                else if(pos3<beforepos3)
	                {
	                        for(int i=beforepos3;i>=pos3;i--)
	                        {
	                                myservo3.write(i);
	                                delay(10);
	                        }
	                }
	        }
	         
	//        if(pitch>15&&roll>20)  //底座步进电机控制机械臂左右运动
	//        {
	//                if(count>=64)  //控制步进电机在一定范围内转动
	//                        return;
	//                stepper.step(8);
	//                count++;
	//                Serial.println(count);
	//        }
	//
	//        if(pitch>15&&roll<-20)
	//        {
	//                if(count<=0)
	//                        return;
	//                stepper.step(-8);
	//                count--;
	//                Serial.println(count);
	//        }
	}
	 
	void Holder()  //按键控制夹子的开合
	{
	        value = digitalRead(key);
	        if(value == HIGH)
	        {
	                int pos=110;  //这里的角度110,30也改成你组装成机械臂后舵机实际的旋转角度范围
	                if(pos == 110)
	                {
	                        for (pos; pos>30; pos--)
	                        {
	                                myservo.write(pos);
	                                Serial.println(pos);
	                                delay(20);
	                        }
	                }
	                else if(pos == 30)
	                {
	                        for (pos; pos<110; pos++)
	                        {
	                                myservo.write(pos);
	                                Serial.println(pos);
	                                delay(20);
	                        }
	                }
	        }
	}					
						
						
						
			
			

然后点击验证,通过后再点击上传,将程序上传到ESP8266开发板中了。

以上的步骤都完成以后,我们就可以打开手机中的零知星球APP来控制机械臂了。

效果如下