外网远程控制LED小灯的实现

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/a201577F0546/article/details/52260305

注:该项目参考自Arduino中文社区kevinzhang19701楼主的帖子
:小题大做之远程LED控制
http://www.arduino.cn/forum.php?mod=viewthread&tid=8463&fromuid=84650
(出处: Arduino中文社区)
在这里十分感谢这位老师。
我觉得这个很有潜力,控制LED小灯只是开始,有了这个基本的项目,就可以拓展为外网远程控制其他一些家庭电器,俨然可以成为智能家居的一个切入点。

1预备工作:

1.由于需要可以通过外网来控制小灯,所以内网穿透是必不可少的。
我们选择了花生壳来实现。
首先要找到花生壳官网(Oray)进行注册,然后你会获得一个免费的域名,这个免费的域名的长相十分奇怪不容记忆,但是免费送的并且仅仅只是实验测试用的所以就不要抱怨了。(当然你可以升级为付费版商业版的,域名端口都可以定制)
得到域名之后需要开启内网穿透服务,建议不想花费太多的话可以开启免费版(但是开通还是需要缴纳少量的费用)。我用的就是免费版的服务,足够这个项目用的。有一点需要注意,免费版的服务解析速度偏慢,而且有流量限制(每月1G),所以呢,网页如果需要加载很多图片视频的话,那么就得考虑升级个人商业版了。建议一切从简,学到原理最重要。
2.准备一台电脑来作为服务器。
当然实验阶段的话,可以用自己的笔记本或者一台二手旧电脑,不用担心性能,对这个实验项目古董电脑都绰绰有余了。(当然土豪就当我什么都没说,直接去某宝买专业的服务器或者工作站好了,至于工作站或者服务器的使用和配置方法去问度娘吧)

2硬件部分:

1.控制器部分:Arduino UNO R3 开发板

2.Ethernet W5100

这里写图片描述

3.导线,面包板,200欧(或者1K欧姆)的电阻两个,两个LED,路由器,网线

这里写图片描述

4.两件叠加效果图:

这里写图片描述

5.接线效果图:

这里写图片描述

3软件部分:

(默认JAVA开发环境已经配置好了,没有配好JAVA环境先配置环境)
1.Arduino IDE:
下载链接:https://yunpan.cn/cMjJIsprnQbad 访问密码 f834
Arduino IDE的安装十分简单不再多说了。
2.Tomcat:
下载链接:https://yunpan.cn/cMjJTDtkc8UDb 访问密码 fe5c
Tomcat也需要配置环境变量哦
3.MySQL:
下载链接:https://yunpan.cn/cMjJC35LDecxx 访问密码 071f
4.MySQL Workbench:
下载链接:https://yunpan.cn/cMjJ7bb4rPzJI 访问密码 b6d7
Workbench这个软件是搭配MySQL来使用的,它是MySQL的图形界面
5.eclipse jee:
下载链接:https://yunpan.cn/cMjZyfFRnfgCi 访问密码 0ac4
6.JDBC:
下载链接:https://yunpan.cn/cMjVsNUAMetP3 访问密码 4ad5
6.花生壳客户端:
下载链接:https://yunpan.cn/cMjZVw8hqcd33 访问密码 052e

4逻辑部分:

逻辑应该很清楚了:客户端可以通过外网访问到服务器,
服务器上有两个servlet:ControlServletResponseServlet
ControlServlet:主要接受来自于外网访客对LED开/关状态的变化,并要将这些变化状态写入MySQL数据库(对应0和1)
ResponseServlet:主要是回答W5100每隔1秒向服务器提交的LED状态查询。
然后
Arduino板子上的sketch只完成一个工作:
每隔1秒向服务器查询数据库里最新的LED状态,然后刷新LED高低电平。

5代码部分:

Arduino代码:

 #include <SPI.h>
#include <Ethernet.h>
byte mac[]    = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress dnserver(192, 168, 0,105);
IPAddress     ip(192, 168,0,111);
EthernetClient client;
char c;
String result;
void setup() {
  Serial.begin(9600);
  Ethernet.begin(mac, ip);
  delay(3000);
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  Serial.println("Ethernet connecting...");

}

void loop() {
  if (client.connect(dnserver, 80)) 
  {
      Serial.println("Connected");
      client.println("POST http://192.168.0.105:80/remoteControlByYuancong/ResponseServlet HTTP/1.1");
      client.println("Host:192.168.0.105");
      client.println();
      delay(1000);
     // Serial.println(client.available());//为什么返回值比实际的字符串长度多2?
       while(client.available())
       {
        c = client.read();
        result += c;
       }
       //Serial.println("==");
       Serial.println(result.substring(0,156));
       Serial.println(result.substring(147,156));
       Serial.println(result.substring(147,151));
      if (result.substring(147,151).equals("A2=1"))
      {
        digitalWrite(2, HIGH);
      }
      else
      {
        digitalWrite(2, LOW);
      }
      if (result.substring(152,156).equals("A3=1"))
      {
        digitalWrite(3, HIGH);
      }
      else
      {
        digitalWrite(3, LOW);
      }
    client.stop();
    result = "";
  } 


  else 
  {
    Serial.println("connection failed");
  }


}

web代码:

<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>遥控</title>
<style type="text/css">

body{
    margin:0px;
    text-align:center;    /*居中*/
}

div{
    box-sizing:border-box;          /*盒子宽高设置以border为标准*/
}

#top{
    height:50px;         
    margin:0 auto ;
}
.container{
    width:270px;
    height:480px;
    margin:0 auto;
    background-color:#FFFFFF;
    background-image:url("images/76.jpg");
    <!--border-radius:10px;-->
    border-style:solid; 
    border-width:2px; 
    border-color:gray;
    box-shadow:5px 5px 5px gray;

}
.className{
  line-height:50px;
  height:50px;
  width:180px;
  color:#ffffff;
  background-color:#f78d12;
  font-size:17px;
  font-weight:normal;
  font-family:Arial;
  border:3px solid #3d465e;
  -webkit-border-top-left-radius:40px;
  -moz-border-radius-topleft:40px;
  border-top-left-radius:40px;
  -webkit-border-top-right-radius:40px;
  -moz-border-radius-topright:40px;
  border-top-right-radius:40px;
  -webkit-border-bottom-left-radius:40px;
  -moz-border-radius-bottomleft:40px;
  border-bottom-left-radius:40px;
  -webkit-border-bottom-right-radius:40px;
  -moz-border-radius-bottomright:40px;
  border-bottom-right-radius:40px;
  -moz-box-shadow: inset 0px 0px 0px 0px #ffffff;
  -webkit-box-shadow: inset 0px 0px 0px 0px #ffffff;
  box-shadow: inset 0px 0px 0px 0px #ffffff;
  text-align:center;
  display:inline-block;
  text-decoration:none;
}.className:hover{
  background-color:#f8cd04;
}

#login{
width:270px;
height:202px;
background-color:;

}
#twopart{
    width:360;
    height:16px;
    background-color:;

}
input.ys{
color: #ffffff;
height: 30px;
background-color: #f78d12;
}

</style>
<link rel="shortcut icon" href="xiaoTuBiao.ico" type="image/x-icon" />
</head>
<body>
<script LANGUAGE = "JavaScript" >
 function checkvalue()
 {
 alert('已提交');
 return true;

 } </script>

<div id="top"></div>
<div class="container" >
<p style="color:#ffffff;font-size:20px"></p>
<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>

<div id="login">
<form name='form1'action="http://15440a9z84.iask.in:41498/remoteControlByYuancong/ControlServlet?p=1" method="post" >
<a href='javascript:document.form1.submit();' class='className' onclick="checkvalue()">开启遥控器</a>
</form>
</div>
<a href="index.html">返回主页</a>
</div>
</body>
</html>

ControlServlet:

package remoteControlByYuancong;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.mysql.jdbc.Connection;
import com.mysql.jdbc.Statement;

/**
 * Servlet implementation class ContronlServlet
 * 这个进行主要功能操作
 */
@WebServlet("/ControlServlet")
public class ControlServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    /**
     * @see HttpServlet#HttpServlet()
     */

    public ControlServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException 
    {
        response.setContentType("text/html;charset=UTF-8");

        String p=request.getParameter("p"); 

//request.getParameter()方法是用来获取URL中的参数的
        String a2 = "0";
        String a3 = "0";
        String n  = "0";

        String a2s = "0";
        String a3s = "0";

        Connection conn = null;
        Statement stmt = null;
        ResultSet rs1 = null;
        int s=0;
        try (PrintWriter out = response.getWriter()) 
        {
            if (p.equals("1"))
            {
                try
                {
                    Class.forName("com.mysql.jdbc.Driver");
                    System.out.println("成功加载数据库");
                    conn = (Connection) DriverManager.getConnection("jdbc:mysql://localhost:3306/mydata","root" ,"521314");
                    stmt = (Statement) conn.createStatement();
                    System.out.println("正在");
                    System.out.println("查询最后一条记录...");
                    rs1 = stmt.executeQuery("SELECT * FROM t1 ORDER BY aid DESC LIMIT 1;");
                    System.out.println("完成");

                    while(rs1.next())
                    {
                        n = rs1.getString(2);//第二列
                        if (n.equals("1"))
                        {
                            a2s = "1";
                        }
                        else
                        {
                            a2s = "0";
                        }
                        n = rs1.getString(3);
                        if (n.equals("1"))
                        {
                            a3s = "1";
                        }
                        else
                        {
                            a3s = "0";
                        }

                    }

                }

                catch (SQLException ex) 
                {
                    System.out.println("Error in connection: " + ex.toString());
                    System.out.println("SQLException: " + ex.getMessage());
                    System.out.println("SQLState: " + ex.getSQLState());
                    System.out.println("VendorError: " + ex.getErrorCode());
                } catch (ClassNotFoundException e) {
                    // TODO 自动生成的 catch 块
                    e.printStackTrace();
                } 
                /* TODO output your page here. You may use following sample code. */
                out.println("<!DOCTYPE html>");
                out.println("<html>");
                out.println("<head>");
                out.println("<title>Remote Controlled LEDs.</title>");
                out.println("<meta charset=\"UTF-8\">");
                out.println("</head>");
                out.println("<body onLoad=\"setForm();\">");
                out.println("<br><br>");
                out.println("巨丑遥控器");
                out.println("<form id=\"f1\" method=\"POST\" action=\"http://15440a9z84.iask.in:41498/remoteControlByYuancong/ControlServlet?p=2\">");
                out.println("<table align=\"center\" border=\"1\">");
                out.println("<tr>");
                out.println("<td>A2:</td>");
                if (a2s.equals("0"))
                {
                    out.println("<td><input type=\"radio\" name=\"a2\" value=\"0\" checked>Off</td>");
                    out.println("<td><input type=\"radio\" name=\"a2\" value=\"1\">On</td>");
                }
                else
                {
                    out.println("<td><input type=\"radio\" name=\"a2\" value=\"0\">Off</td>");
                    out.println("<td><input type=\"radio\" name=\"a2\" value=\"1\" checked>On</td>");
                }
                out.println("</tr>");
                out.println("<tr>");
                out.println("<td>A3:</td>");
                if (a3s.equals("0"))
                {
                    out.println("<td><input type=\"radio\" name=\"a3\" value=\"0\" checked>Off</td>");
                    out.println("<td><input type=\"radio\" name=\"a3\" value=\"1\">On</td>");
                }
                else
                {
                    out.println("<td><input type=\"radio\" name=\"a3\" value=\"0\">Off</td>");
                    out.println("<td><input type=\"radio\" name=\"a3\" value=\"1\" checked>On</td>");
                }
                out.println("</tr>");
                out.println("<tr>");
                out.println("<td colspan=\"3\" align=\"center\"><input type=\"submit\" value=\"确认\"></td>");
                out.println("</tr>");
                out.println("</table>");
                out.println("</form>");
                out.println("</body>");
                out.println("</html>");
                //System.out.println("aaa");
            }


            else
            {
                if (!request.getParameter("a2").equals("1"))
                {
                    a2 = "0";
                }
                else
                {
                    a2 = "1";
                }
                if (!request.getParameter("a3").equals("1"))
                {
                    a3 = "0";
                }
                else
                {
                    a3 = "1";
                }


                try
                {

                    conn = (Connection) DriverManager.getConnection("jdbc:mysql://localhost:3306/mydata","root" ,"521314");
                    stmt = (Statement) conn.createStatement();
                    System.out.println("正在");
                    System.out.println("追加记录......");
                    s = stmt.executeUpdate("INSERT INTO t1 (a2,a3) VALUES ('"
                            + a2 + "','"
                            + a3 + "')");
                    System.out.println("完成");
                    //这个s只是起到了一个储存返回值的作用,但是对这个返回值的操作,原来的代码并没有写
                    //也因此IDE检测到这个s没有使用过所以给了警报

                }
                catch (SQLException ex) 
                {
                    System.out.println("Error in connection: " + ex.toString());
                    System.out.println("SQLException: " + ex.getMessage());
                    System.out.println("SQLState: " + ex.getSQLState());
                    System.out.println("VendorError: " + ex.getErrorCode());
                }
                /* TODO output your page here. You may use following sample code. */
//应该是生成了一个新的页面吧
                out.println("<!DOCTYPE html>");
                out.println("<html>");
                out.println("<head>");
                out.println("<title>Remote Controlled LEDs.</title>");
                out.println("<meta charset=\"UTF-8\">");
                out.println("</head>");
                out.println("<body onLoad=\"setForm();\">");
                out.println("<br><br>");
                out.println("<form id=\"f1\" method=\"POST\" action=\"http://15440a9z84.iask.in:41498/remoteControlByYuancong/ControlServlet?p=2\">");
                out.println("<table align=\"center\" border=\"1\">");
                out.println("<tr>");
                out.println("<td>A2:</td>");
                if (a2.equals("0"))
                {
                    out.println("<td><input type=\"radio\" name=\"a2\" value=\"0\" checked>Off</td>");
                    out.println("<td><input type=\"radio\" name=\"a2\" value=\"1\">On</td>");
                }
                else
                {
                    out.println("<td><input type=\"radio\" name=\"a2\" value=\"0\">Off</td>");
                    out.println("<td><input type=\"radio\" name=\"a2\" value=\"1\" checked>On</td>");
                }
                out.println("</tr>");
                out.println("<tr>");
                out.println("<td>A3:</td>");
                if (a3.equals("0"))
                {
                    out.println("<td><input type=\"radio\" name=\"a3\" value=\"0\" checked>Off</td>");
                    out.println("<td><input type=\"radio\" name=\"a3\" value=\"1\">On</td>");
                }
                else
                {
                    out.println("<td><input type=\"radio\" name=\"a3\" value=\"0\">Off</td>");
                    out.println("<td><input type=\"radio\" name=\"a3\" value=\"1\" checked>On</td>");
                }
                out.println("</tr>");

                out.println("<tr>");
                out.println("<td colspan=\"3\" align=\"center\"><input type=\"submit\" value=\"确认\"></td>");
                out.println("</tr>");
                out.println("</table>");
                out.println("</form>");
                out.println("</body>");
                out.println("</html>");

            }
        }
    }






    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        processRequest(request, response);
    }

    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        processRequest(request, response);

    }

}

ResponseServlet:

package remoteControlByYuancong;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.mysql.jdbc.Connection;
import com.mysql.jdbc.Statement;
/**
 * Servlet implementation class ResponseServlet
 * 这里写回答Arduino板子的servlet
 */
@WebServlet("/ResponseServlet")
public class ResponseServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    /**
     * @see HttpServlet#HttpServlet()
     */
    public ResponseServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException 
    {
        String a2 = "0";
        String a3 = "0";
        String n  = "0";

        response.setContentType("text/text");
        try (PrintWriter out1 = response.getWriter()) 
        {
            Connection conn = null;
            Statement stmt = null;
            ResultSet rs1 = null;
            int s = 0;

            try
            {
                Class.forName("com.mysql.jdbc.Driver");
                System.out.println("成功加载数据库");
                conn = (Connection) DriverManager.getConnection("jdbc:mysql://localhost/mydata?" +
                                   "user=root&password=521314");
                stmt = (Statement) conn.createStatement();
                System.out.println("==");
                System.out.println("查询最后一条记录...");
                rs1 = stmt.executeQuery("SELECT * FROM t1 ORDER BY aid DESC LIMIT 1;");

                while(rs1.next())
                {
                    n = rs1.getString(2);
                    if (n.equals("1"))
                    {
                        a2 = "1";
                    }
                    else
                    {
                        a2 = "0";
                    }
                    n = rs1.getString(3);
                    if (n.equals("1"))
                    {
                        a3 = "1";
                    }
                    else
                    {
                        a3 = "0";
                    }

                }
            }
            catch (SQLException ex) 
            {
                System.out.println("Error in connection: " + ex.toString());
                System.out.println("SQLException: " + ex.getMessage());
                System.out.println("SQLState: " + ex.getSQLState());
                System.out.println("VendorError: " + ex.getErrorCode());
            } catch (ClassNotFoundException e) {
                // TODO 自动生成的 catch 块
                e.printStackTrace();
            } 

            /* TODO output your page here. You may use following sample code. */
            //out1.println("<!DOCTYPE html>");
           // out1.println("<html>");
           // out1.println("<head>");
          //  out1.println("<title>Servlet myservlet2</title>");
           // out1.println("<meta charset=\"UTF-8\">");
           // out1.println("</head>");
           // out1.println("<body>");
            out1.println("A2=" + a2 + ",A3=" + a3 );
           // out1.println("</body>");
           // out1.println("</html>");

        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        processRequest(request,response);
    }

    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub

        processRequest(request,response);

    }
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>

}

eclipse项目结构:
这里写图片描述

MySQL

将MySQL已经图形界面正确安装好以后
打开workbench
这里写图片描述

6服务器方面

6.1内网穿透的准备

6.1.1花生壳的准备

1打开花生壳进入内网穿透管理页面:
这里写图片描述
2.添加映射:
这里写图片描述

6.1.2路由器的准备

1.进入路由器管理页面(我用的是水星路由,其他的路由器设置过程类似)选择高级设置–高级用户
2添加虚拟服务器:
这里写图片描述
这里写图片描述
3.打开DMZ主机
这里写图片描述
4.打开DDNS
这里写图片描述

6.2.将web项目部署到Tomcat:

因为eclipse默认是把web项目部署到名字空间下的文件夹里,所以我们要设置eclipse将项目自动部署到Tomcat下。
Step1:
找到如图所示的选项并执行。
这里写图片描述

Step2:
找到如图所示的选项并执行。
这里写图片描述

Step3:
点击open
这里写图片描述

Step4:
依图操作
这里写图片描述

Step5:
退出保存重启eclipse然后重新运行此项目,接着你去Tomcat的webapps文件夹下就可以找到你的项目了。
2.配置Tomcat
进入Tomcat安装目录的conf文件夹找到 server.xml
这里推荐用 Notepad++打开。
找到

<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>

将端口号(port)8080改成80;接着在找到标签,
在之前加上:

<Context path=""docBase="你的项目名称"debug="0"reloadable="true"/>

关闭并保存。到这里就大功告成了庆祝一下
后记:
这篇博文其实有很多细节都没说,但是我想在一篇博文里面塞那么多东西只会显得太臃肿杂乱,我就先把主要的部分写了出来,在实际做的时候。作为小白,比我刚开始学习kevinzhang楼主老师的帖子的时候,我就遇到了很多困难,比如,没有用过eclipse做web项目的我,对如何创建一个项目,如何让eclipse连接MySQL,如何使用JDBC来与数据库交互。。。等等都是以一无所知,帖子里也没有讲,我只能自学。我没有用过花生壳,帖子里也没有详细讲如何使用。那些没有讲的东西都是需要靠自学才能了解的。然而那些让我困扰的东西,我会另写博客来说明,当然你也可以去自己百度。

展开阅读全文

没有更多推荐了,返回首页