NodeMCU 和 Wi-Fi 远程控制应用程序,用于手机





5.00/5 (4投票s)
关于如何开发用于手机的 Wi-Fi 遥控 HTML5 应用程序,并将其与 NodeMCU 和兼容设备 (ESP8266 / ESP32) 一起用于物联网应用的步骤指南。
引言
如今,在物联网应用中使用手机作为遥控器已成为一种普遍做法,为此,存在多种开发替代方案,例如:
我们将在此展示的是一种使用 HTML5 和一些已知技术来开发原生移动应用程序的替代解决方案,例如:
- JQuery:一个 JavaScript 库,可以方便地操作网页中的元素和事件。
- Onsen UI:一个响应式的 CSS 组件框架,用于使用 HTML5、CSS、JavaScript 等技术开发移动 Web 应用程序。
- PhoneGap:一个用于从 Web 应用程序生成混合移动应用程序的框架。
混合移动应用程序是将原生组件和 Web 组件结合在一起的应用程序。
从用户的角度来看,混合应用程序与原生应用程序完全相同。但是,在内部,混合应用程序使用一个 WebView 组件,其中包含应用程序的大部分内容和逻辑。
项目
为了测试上述工具,我们将开发一个小型项目,如下所示:
- 一个连接到三个 LED 的 NodeMCU 板。
- 该板将连接到Wi-Fi 网络并运行一个Web 服务器,该服务器将等待客户端的请求。
- 客户端将是我们的手机上的遥控应用程序,它将显示一个屏幕来控制三个 LED。LED 1 和 2 可以通过按钮打开和关闭。而 LED 3,我们将通过滑块控制其亮度。
注意:为了更好地了解,请参阅下方我们项目已正常工作的图像和视频。
≈ 点击此处观看视频演示 ≈
第一步:原型
组装我们的实验需要以下组件:
- 面包板
- NodeMCU 或兼容卡 (Wemos, MKR1000, ESP8266 Standalone)
- 三个彩色 LED
- 三个 220 欧姆电阻
- 跳线
组装效果图如下:
第二步:NodeMCU Sketch
我们的 sketch 的基本功能是连接到 Wi-Fi 网络并创建一个 Web 服务器,该服务器将等待并响应带有 LED 控制命令的请求。
我们将使用 Arduino 自带的 IDE 进行开发。如果您还没有这样做,则需要用 ESP8266 软件配置环境。要做到这一点,请按照本文的步骤操作:使用 Arduino IDE 编程 ESP NodeMCU。
现在我们来看带有注释的源代码:
wifi_rc.ino
/*
NodeMCU Web server for wi-fi remote control
2019, José Augusto Cintra
www.josecintra.com/blog
*/
#include <esp8266wifi.h>
#include <wificlient.h>
#include <esp8266wifimulti.h>
#include <esp8266mdns.h>
#include <esp8266webserver.h>
ESP8266WiFiMulti wifiMulti; // For multiple wi-fi configuration
ESP8266WebServer server(80); // Create a webserver object that
// listens for HTTP request on port 80
// function prototypes for HTTP handlers
void handleRoot();
void handleRequest();
void handleNotFound();
void setup(void){
delay(1000);
pinMode(5, OUTPUT); //Led 1
pinMode(4, OUTPUT); //Led 2
digitalWrite(5, 0);
digitalWrite(4, 0);
analogWriteRange(100); //Led 3 (PWM)
analogWrite(0, 0);
Serial.begin(9600); //Start the Serial communication to send messages
//to the computer
delay(10);
Serial.println('\n');
wifiMulti.addAP("ssid1", "password1"); //add Wi-Fi networks you want to connect to
wifiMulti.addAP("ssid2", "password2");
Serial.println("Connecting ...");
int i = 0;
while (wifiMulti.run() != WL_CONNECTED) { //Wait for the Wi-Fi to connect:
//scan for Wi-Fi networks, and connect to
//the strongest of the networks above
delay(250);
Serial.print('.');
}
Serial.println('\n');
Serial.print("Connected to ");
Serial.println(WiFi.SSID()); // Tell us what network we're connected to
Serial.print("IP address:\t");
Serial.println(WiFi.localIP()); // Send the IP address of the ESP8266
// to the computer
if (MDNS.begin("esp8266")) { // Start the mDNS responder for esp8266.local
Serial.println("mDNS responder started");
} else {
Serial.println("Error setting up MDNS responder!");
}
server.on("/", HTTP_GET, handleRoot); // Call the 'handleRoot' function
// when a client requests URI "/"
server.on("/command", HTTP_POST, handleRequest); // Call the 'handRequest' function
// when a POST request is made
// to URI "/command"
server.onNotFound(handleNotFound); // When a client requests an unknown URI
server.begin(); // Actually start the server
Serial.println("HTTP server started");
return;
}
void loop(void){
server.handleClient(); // Listen for HTTP requests from clients
return;
}
void handleRoot() { // When URI / is requested,
// send a standard web page
server.send(200, "text/html", "Wi-fi Remote Control Example");
return;
}
void handleNotFound(){
server.send(404, "text/plain", "404: Not found"); // Send HTTP status 404
// (Not Found) when there's no handler for the URI in the request
return;
}
void handleRequest() { // If a POST request is made to URI /command
// Validate parameters
if(!server.hasArg("pin") || !server.hasArg("value") || server.arg("pin") == NULL ||
server.arg("value") == NULL) {
server.send(400, "text/plain", "400: Invalid Request"); // The request is invalid,
// so send HTTP status 400
return;
}
// Get the parameters: pin and value
String temp = "";
temp = server.arg("pin");
int pin = temp.toInt();
temp = server.arg("value");
int value = temp.toInt();
Serial.println(pin);
Serial.println(value);
if (pin >= 0 && pin < 17 && value >= 0 && value <= 100) {
if (pin == 0) {
analogWrite(pin, value);
} else {
digitalWrite(pin, value);
}
}
server.send(200, "text/html", "Wi-fi Remote Control Example");
return;
}
关注点
WiFiMulti
库允许您配置多个 Wi-Fi 网络的身份验证,从而轻松连接。请根据您的网络替换ssid
和password
。mDNS
库允许为 Esp 本地网络命名一个DNS
。在这种情况下,我们不使用此功能,因为 Android 不支持它。handleClient
方法启动一个循环,充当 Web 请求的监听器。- 有三个函数负责处理来自手机的请求:
- 当 URI 未找到时,将触发
handleNotFound
函数。 - 当收到标准的
GET
请求时,将触发handleRoot function
。在我们的情况下,此类响应被忽略。 - 由
server.on
条件触发的handleRequest
函数负责处理由手机上的遥控器触发的POST
请求。此时,我们将验证从遥控器发送的参数并采取适当的行动。
- 当 URI 未找到时,将触发
第三步:Web 应用
要开发遥控应用程序,我们需要下载 JQuery 和 OnsenUI 库,并根据下面描述的结构将它们解压到相应的文件夹中:
- app
config.xml ← Phonegap 配置文件的位置- www
index.html ← 主 HTML 文件- 资源文件
- img ← 应用图标在此处
icon-128.png
icon-256.png - js
wifi_rc.js ← 包含应用逻辑的 Js 文件 - lib
- Jquery ← 在此处解压 Jquery
- Onsenui ← 在此处解压 Onsenui
- img ← 应用图标在此处
- 资源文件
- www
此时,我们将关注 index.html 和 wifi_rc.js 文件,它们负责我们遥控器的呈现和编程,如下所示:
index.html
<!--
Wi-fi Remote Control with JQuery and Onsen UI
Demo by José Cintra
www.josecintra.com/blog
-->
<!DOCTYPE html>
<html lang="pt-br">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,
initial-scale=1, shrink-to-fit=no">
<meta name="Author" content="José Cintra"
<link rel="stylesheet" href="assets/lib/OnsenUI/css/onsenui.min.css">
<link rel="stylesheet" href="assets/lib/OnsenUI/css/onsen-css-components.min.css">
</head>
<body>
<ons-page modifier="material">
<ons-toolbar modifier="material">
<div class="center"><strong>Wi-Fi Remote Control</strong></div>
</ons-toolbar>
<br/>
<ons-card modifier="material">
<div class="content">
<ons-list modifier="material">
<ons-list-item modifier="material">
<div class="center" >
<strong>LED 1 </strong> <label id="led1v">OFF</label>
</div>
<div class="right">
<ons-switch id="led1" class="sw" modifier="material"></ons-switch>
</div>
</ons-list-item >
<ons-list-item modifier="material">
<div class="center" >
<strong>LED 2 </strong> <label id="led2v">OFF</label>
</div>
<div class="right">
<ons-switch id="led2" class="sw" modifier="material"></ons-switch>
</div>
</ons-list-item>
<ons-list-item modifier="material">
<div class="center">
<strong>LED 3 </strong> <label id="led3v">0</label>%
</div>
<div class="right">
<ons-range id="led3" class="rg" modifier="material"
style="width: 100%;" value="0" max = "100" ></ons-range>
</div>
</ons-list-item>
</ons-list>
</div>
</ons-card>
</ons-page>
<!-- Javascript -->
<script src="assets/lib/OnsenUI/js/onsenui.min.js"></script>
<script src="assets/lib/jquery/jquery-3.3.1.min.js"></script>
<script src="assets/js/wifi_rc.js"></script>
</body>
</html>
wifi_rc.js
//
/*
Wi-fi Remote Control with JQuery and Onsen UI
Demo by José Cintra
www.josecintra.com/blog
*/
$(function () {
// Server address and pin numbers of the board (ESP8266/32 and compatibles)
let addr = "http://192.168.0.33/command";
let pins = new Map([
[ '#led1', '05' ],
[ '#led2', '04' ],
[ '#led3', '00' ],
]);
// Click Event on switch Class
$('.sw').on('click', function (e) {
let onoff = ['OFF','ON'];
let id = "#" + $(this).attr("id"); // Get the id of the control
let pin = pins.get(id); // Pin number
let value = String(+$(id).prop('checked')); // On or Off
$(id + 'v').html(onoff[value]);
sendAjax(addr, pin, value);
});
// Input event on range class
$('.rg').on('input', function (e) {
let id = "#" + $(this).attr("id"); // Get the id of the control
let value = String($(id).val()); // Input range
$(id + 'v').html(value); // Notification
});
$('.rg').on('change', function (e) {
let id = "#" + $(this).attr("id"); // Get the id of the control
let pin = pins.get(id); // Pin number
let value = String($(id).val()); // Input range
sendAjax(addr, pin, value);
});
});
function sendAjax(addr, p, v) {
$.ajax({
method: "POST",
url: addr,
data: {pin: p, value: v}
});
}
关注点
- index.html 文件包含了应用程序的整个呈现部分,其中使用了 OnsenUI 框架提供的 CSS 元素。
- LED 1 和 LED 2 将由开关按钮控制,LED 3 将由
range
控件控制。重要的是要注意将在 JS 脚本中使用的id
和class
属性。 - wifi_rc.js 文件的 JavaScript 代码采用 ES6 标准。
- wifi_rc.js 文件中的
function()
事件仅在页面加载后发生一次。在这里,我们编程响应控件事件的操作。 - 为了表示
NodeMCU
中的引脚编号,我们使用MAP
结构。这些信息将与控件的值一起传递给sendAjax
方法,并发送到板的 Web 服务器。
第四步:手机应用程序
最后,在这一步,我们将生成可以安装在手机上的移动应用程序。为了使我们的 HTML5 应用程序能够作为原生应用安装,您需要使用 Phonegap 构建工具。
最简单的方法是使用 Phonegap Build 的云编译服务。
步骤如下:
- 在 Phonegap Build 服务中创建一个账户,选择付费或免费套餐。
- 创建将显示在手机上的应用程序图标。
- 创建一个 config.xml 文件并进行必要的设置。
- 压缩所有文件并上传进行编译。
- 请求应用程序编译。
- 选择所需的平台(Android、iPhone 或 Microsoft)并下载该平台的编译后的应用程序。
注意:图标文件必须是 png
格式,尺寸为 128 × 128 和 256 × 256。
以下是一个 config.xml
文件的示例:
config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<widget id="com.josecintra.wifi_rc" version="1.0.0"
xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="https://cordova.net.cn/ns/1.0">
<name>Wi-fi Remote Control</name>
<description>Example of building a wi-fi remote control with
HTML5/JQuery/Onsen UI and Phonegap. It will be used to control IoT devices,
such as NodeMCU and compatibles</description>
<author href="http://www.josecintra.com/blog"
email="josecintra@josecintra.com">Jose Cintra</author>
<icon src="www/assets/img/icon-256.png" width="256"
height="256" density="xxxhdpi" />
<icon src="www/assets/img/icon-128.png" width="128"
height="128" density="xhdpi" />
<preference name="android-targetSdkVersion" value="26" />
<preference name="orientation" value="portrait" />
<preference name="fullscreen" value="true" />
<preference name="DisallowOverscroll" value="true" />
<config-file parent="UIStatusBarHidden" platform="ios"
target="*-Info.plist"><true/></config-file>
<config-file parent="UIViewControllerBasedStatusBarAppearance"
platform="ios" target="*-Info.plist"><false/></config-file>
<preference name="deployment-target" value="10.0" />
<preference name="android-minSdkVersion" value="21" />
<access origin="*" />
<plugin name="cordova-custom-config" />
<plugin name="cordova-plugin-file" />
<plugin name="cordova-plugin-media" />
<plugin name="cordova-plugin-statusbar" />
<plugin name="cordova-plugin-whitelist" />
<engine name="ios" />
<engine name="android" />
</widget>
关注点
config.xml 文件包含生成应用程序所需的所有信息。其中,我们重点介绍:
- name:应用程序的名称。
- description:应用程序的描述。
- author:关于应用程序作者的信息。
- icon:将标识手机上应用程序的图标的名称。
- orientation:应用程序可以显示为
portrait
(竖屏)或landscape
(横屏)模式。如果未设置此参数,应用程序将适应手机的倾斜。 - access origin:定义应用程序可以访问的 URL。
除了这些之外,还有几十种其他设置。一个重要的点是选择插件,这些插件允许您为应用程序添加额外功能,例如访问相机、GPS 和手机的其他原生功能。有关构建过程的更多详细信息,请参阅此链接。
第五步:安装应用程序
在上一步中,我们生成了一个可以安装在手机上或在应用商店中供下载的应用程序。在我们的例子中,我们生成了一个扩展名为 apk 的Android 应用程序。
为了在不通过应用商店的情况下在手机上测试此应用,我们需要将 Android 配置为允许安装“未知来源”的应用。通常,此选项在安全部分。
之后,只需将应用程序复制到您的手机即可。这可以通过多种方式完成,例如 USB、Kies、Wi-Fi 或通过 Internet 链接。Android 本身将负责安装。
接下来是什么?
这是一个简单的物联网设备 Wi-Fi 遥控教学示例。此示例可以通过多种方式进行改进:
- 改进 Ajax 请求中的错误处理。
- 在 Wi-Fi 传输中采取安全措施。
- 提供 Wi-Fi 连接的存储选项和管理。
- 增强遥控器界面。
- 将应用程序发布到应用商店。
- 查阅互联网上的其他有用参考资料:
结束语
感谢阅读!
本教程中的所有文件都可以在 GitHub 上找到。啊!别忘了在 NodeMCU sketch 中配置您的 Wi-Fi 的 ssid
和 password
...
您可以在此处找到本文的葡萄牙语版本。
历史
- 2019 年 1 月 6 日:初始版本