赞
踩
本文作者:默。默是铁熊的创客好友,经常与铁熊分享创意项目。
前段时间有个老师对我说:每到开学季,学校就要印刷学生的录取名单并进行张贴,为此学校每年都要耗费大量的人力物力。学校里面教学活动很多,传统的通知都是通过张贴海报之类的方式进行公布,但是在信息化高速发展的今天,许多消息的发布已经不需要传统的纸质媒介了,我们可以通过网站在线查询。然而一个网站的开发是十分复杂的,涉及到的知识很多,大部分人不可能有这么多的时间和精力去学习网站开发。
考虑到这些难点,结合我与那位老师交流以及解决该问题的过程,本教程将教你利用 ESP32 开发板搭建一个实用的网络服务器。该方案利用 ESP32 开发板托管网页,通过数据库查询信息,然后通过网页进行显示。同时也可以对网页进行可视化编辑,让没有任何基础的人都能够轻松地设计一个实用网页 ,而你需要做的仅仅是提供你要呈现的数据 。
下面让我们先来看看这个项目的演示视频,该演示项目中我们托管了4个不同服务的网页:
M5 是指基于 ESP32 的 M5 Core2 开发板,Server 代表它是一个网络服务器,而 X 代表了无限可能,故名 M5 Server X,运用 M5 Server X 我们能够将任何数据或者服务通过网页的形式呈现,而无需任何前端或者后端开发的知识。
通过访问 ESP32 的 IP 地址查看网页;
设置自定义域名访问;
服务后台管理功能;
可视化网页修改;
数据库数据处理;
SD 卡配置文件加载。
M5 Core2
基于 ESP32 开发,支持 WiFi、蓝牙;
16M 闪存,8M PSRAM;
内置扬声器,电源指示灯,震动马达,RTC,I2S 功放,电容式触摸屏,电源键,复位键;
TF 卡插槽(支持最大 16GB);
内置锂电池,配备电源管理芯片;
独立小板内置 6 轴 IMU,PDM 麦克风;
M-Bus 总线插座。
下面开始详细讲解程序设计过程。
我们使用 Arduino IDE 软件来编写本项目的程序,开发板选择 M5Stack-Core2。至于如何在 Arduino 中配置 ESP32 的开发环境,不在本文的介绍范围,请自行查阅相关资料。
为了达到我们的预期目标,我们先绘制功能的思维导图,再根据思维导图逐步实现 M5 Server X 的程序设计。
下面我们来具体讨论 M5 Server X 各个子功能是如何实现的。
我们想要访问一个网页必须要知道网络的路径,那么 M5 Server X 如何获取我们访问的路径参数,以及发送对应的网页呈现给我们呢,下面是一个简单的例子,我们上传该程序 。
- #include <WiFi.h>
- #include <WebServer.h> //引入相应库
-
- const char *ssid = "********";
- const char *password = "********";
-
- WebServer server(80); //声明WebServer对象
-
- void handleArg1() //回调函数
- {
- String arg = server.pathArg(0);
- server.send(200, "text/plain", "This is the link/{},The parameters are:" + arg);
- }
-
- void handleArg2() //回调函数
- {
- String arg0 = server.pathArg(0);
- String arg1 = server.pathArg(1);
- server.send(200, "text/plain", "This is the link/{}/{},The parameters are:" + arg0 + " & " + arg1);
- }
-
- void setup() {
- Serial.begin(115200);
- Serial.println();
-
- WiFi.mode(WIFI_STA);
- WiFi.setSleep(false);
- WiFi.begin(ssid, password);
- while (WiFi.status() != WL_CONNECTED)
- {
- delay(500);
- Serial.print(".");
- }
- Serial.println("Connected");
- Serial.print("IP Address:");
- Serial.println(WiFi.localIP());
-
- server.on("/{}", handleArg1); //注册链接与回调函数
- server.on("/{}/{}", handleArg2); //注册链接与回调函数
-
- server.begin(); //启动服务器
- Serial.println("Web server started");
- }
-
- void loop() {
- server.handleClient(); //处理来自客户端的请求
- }
上传完程序,打开串口监视器。如下图所示,我们观察到路由器给 M5 Core2 分配的 IP 地址是 192.168.1.28,记住该地址。
我们通过浏览器访问:192.168.1.28/arduino/png,发现浏览器返回数据如下:
在这里我们有两个路径参数,分别是 arduino 与 png,你也可以试一下只有一个路径参数的情况 。在这个例子当中,我们路径参数以文本的形式给我们呈现,那么如何访问某一个特定的路径发送一个HTML文件呢,在这里只需要判断的路径参数是否是我们定义的路径就行了,例子如下: - const char HTML1[] PROGMEM = R"rawliteral(
- //HTML源代码
- )rawliteral";
-
- const char HTML2[] PROGMEM = R"rawliteral(
- //HTML源代码
- )rawliteral";
-
- const char HTML3[] PROGMEM = R"rawliteral(
- //HTML源代码
- )rawliteral";
-
- void handleArg1() //回调函数
- {
- String arg = server.pathArg(0);
- if (String(arg).equals(String(""))) {
- // 访问路径为空(根目录)
- server.send(200, "text/html", HTML1);
- } else if (String(arg).equals(String("m5"))) {
- // 自定义路径"m5"
- server.send(200, "text/html", HTML2);
- } else {
- // 无效路径(未定义)
- server.send(200, "text/html", HTML3);
- }
- }
在这个例子中,我们考虑了3种路径情况,分别是访问路径为空(根目录),自定义路径(m5)与无效路径(未定义)。当我们访问对应的路径时,M5 Server X 能够给浏览器返回的不同的 html 文本,浏览器将自动渲染该页面。
我们将网页内容定义在 HTML 字符串中。如何设计网页内容呢?我们可以在浏览器中访问一个喜欢的网页,然后点击鼠标右键选择“查看页面源代码”就能看到该网页的源代码,将页面源代码复制并替换到程序中注释的地方,同时将原 HTML 文件的资源引用的相对路径改为绝对路径,这样我们便能够得到由 M5 Server X 托管的网页。对于二级路径的情况也和一级路径类似,我们通过不同的层级路径就可以使用一个 M5 Core2 托管许多不同类型的网页。
这里推荐几个实用的网页模板网站:
17 素材网(https://www.17sucai.com/)
highcharts 图表网(https://www.highcharts.com.cn/)
其中 17 素材网拥有大量的 html 网页特效、网站模板、素材等。提供在线预览功能,我们可以很方便的找到心仪的网页模板;highcharts 图表网拥有丰富的交互式图表,例如带交互特效的折线图、面积图、柱形图、散点图等,能够让我们以动态的方式直观地观察数据变换情况,是数据分析的不二选择。
通过查看网页源代码的方式,我们已经获取到了网页的模板,但是我们并没有 Web 开发的任何基础,似乎无从下手呀?有没有一种可视化、所见即所得的方式让我们修改网页呢?答案是肯定的,这里我介绍3个可视化网页修改的编辑器。
菜鸟教程在线 HTML 编辑器(https://www.runoob.com/try/try.php?filename=tryhtml_headers)
W3School 网页编辑器(https://www.w3school.com.cn/tiy/t.asp?f=eg_html_basic)
HTML 编辑器(https://www.redcoolmedia.net/onlineeditor/samples/plugins/wysiwygarea/htmleditor.php?filenamex=/tmp/FZRNWIKZ)
其中菜鸟教程在线 HTML 编辑器与 W3School 网页编辑器均可以实时修改网页源代码并预览其各种网页特效,HTML 编辑器能够像 Word 一样编辑 HTML,十分便利,唯一的缺点就是不能渲染动态的 js 特效,适合静态网页的可视化修改。下面以 W3School 网页编辑器为例,简述如何获得网页模板并进行可视化编辑。
通过 17 素材网查询关键词寻找合适的网页素材(例如我们需要一个登陆页面);
选择需要的网页素材;
点击查看预览效果;
右键单击,选择查看网页源代码并全选复制(所有网页均可使用此方法);
粘贴网页源代码到 W3School 网页编辑器,点击运行代码(网页未正确渲染);
将网页引用样式资源由相对路径修改为绝对路径(修改后网页成功渲染);
观察网页显示文字,在网页源代码中查找并替换对应的字符串,修改完成后重新运行代码;
增加调试代码,使用网页弹窗调试页面(目的是获取表单构造URL)。
M5 Server X 使用的要点是网页样式文件 CSS,JS 和多媒体等文件均放在云端,通过绝对路径的方式进行引用,这样做的目的是 M5 Server X 只需要少量的带宽也能流畅的使用。如何获取输入表单字符串网上有很多教程,这里不再赘述,这里介绍几个实用的网页调试函数:
window.location.href(获取当前URL路径)
window.location(跳转到指定URL)
alert()(网页弹窗)
现在我们能够可视化的修改任意网页,如果我们要获取的是一个动态网页呢?例如学生成绩单中,表格的模板是固定的,而变化的仅是姓名分数等信息。对于这种通用模板,变化的数据我们可以通过占位符来表示该数据,例如下图中的 data 占位符:
表中的 data0 ~ data9 都是数据变量 ,我们可以采取键值对的形式,将数据保存到云端或者本地的数据库当中。这里我们采取学号作为标签来保存这些数据,例如000 000,张三,男,六一班,90,80,90,90,90,100
其中000
作为标签,而000,张三,男,六一班,90,80,90,90,90,100
作为值 data0 ~ data9,分别代表了标签值中的具体数据,将上面的表格进行文本替换后得到下面的表格:
这里推荐一个支持批量数据提交的网络数据库 tinywebdb(http://tinywebdb.appinventor.space/)。至于它是什么,这里不赘述,大家可以百度搜索,这里仅介绍如何获取该数据库的标签值。我们注册 tinywebdb 账号并登录后可以看到它提供的 API 接口文档如下:
我们先通过它的数据导入功能导入一条数据:
通过数据浏览功能查看刚导入的数据:
我们根据 tinywebdb 的 API 文档编写一个程序获取数据库的数据:
- #include <WiFi.h>
- #include <HTTPClient.h>
-
- const char *ssid = "********";
- const char *password = "********";
-
- String User = "share"; //数据库用户账号名
- String Secret = "everyone"; //数据库用户密钥
- String tag = "000"; //标签
-
- void setup() {
- Serial.begin(115200);
- Serial.println();
-
- WiFi.mode(WIFI_STA);
- WiFi.setSleep(false);
- WiFi.begin(ssid, password);
-
- while (WiFi.status() != WL_CONNECTED) {
- delay(500);
- Serial.print(".");
- }
- Serial.println("Connected");
- Serial.print("IP Address:");
- Serial.println(WiFi.localIP());
-
- if (WiFi.status() == WL_CONNECTED) {
- HTTPClient http;
- http.begin(String("http://tinywebdb.appinventor.space/api?user=" + User + "&secret=" + Secret + "&action=get&tag=") + String(tag));
- int httpCode = http.GET();
- if (httpCode > 0) {
- String Request_result = http.getString();
- Serial.println(Request_result);
- } else {
- Serial.println("Invalid response!");
- }
- http.end();
- }
- }
-
- void loop() {
- }
打开串口监视器,返回数据如下,当访问有效标签时,返回我们保存的正确数据,当访问未定义的标签时返回 null,我们能都通过判断该值知道我们是否输入正确网页地址,从而返回不同的网页。
通过 API 返回数据后,我们需要解析该 JSON 字符串。解析程序如下,这里我们需要引用ArduinoJson.h
这个 JSON 字符串解析库。
- StaticJsonDocument<64> doc;
- DeserializationError error = deserializeJson(doc, Request_result);
- if (error) {
- Serial.print("deserializeJson() failed: ");
- Serial.println(error.c_str());
- return;
- }
- const char* root_000 = doc["000"]; // "000,张三,男,六一班,90,80,90,90,90,100"
得到解析的数据后,再将该数据构造为 json 数组,对构造后的数据进行二次解析便能获取数组的每一项,将数组的每一项数据替换占位符 data 便能得到呈现的有效 html 文件,具体代码见附录程序。
我们可以通过串口监视器获取设备的 IP 地址进行访问,但是路由器的分配的 IP 地址是变化的,这点很不方便,那么我们能不能给它设置一个好记的域名,让我们局域网内访问该设备呢?这里可以使用 ESPmDNS 域名解析达到该目的。代码如下:
- #include <ESPmDNS.h>
-
- void setup() {
- Serial.begin(115200);
- if (!MDNS.begin("M5Core2")) {//自定义域名
- Serial.println("Error setting up MDNS responder!");
- }
- MDNS.addService("http", "tcp", 80); //启用DNS服务
- }
-
- void loop() {
- }
通过域名解析,我们只要和设备在同一局域网内,访问 http://m5core2 就能访问 M5 Server X 获取相应的网页服务了。
通过前面的讲解,我们已经能够实现访问一个链接并跳转到某一个网页了。那么问题来了,如何快速修改网页呢?因为 M5core2 可以使用 SD 卡,所以我们可以这样做:将网页和账号信息保存到 SD 当中,需要更改网页或者连接网络等信息时,直接修改SD卡中的文件,设备初始化的时候读取 SD 卡,那么就完成了网页的修改,这比我们直接修改程序要简单便捷多了。读取 SD 卡文件的程序如下:
- #include "FS.h"
- #include <SD.h>
- #include <SD_MMC.h>
-
- SPIClass sdSPI(VSPI); //定义SD卡软SPI管脚
- #define SD_MISO 38
- #define SD_MOSI 23
- #define SD_SCLK 18
- #define SD_CS 4
-
- String readFile(fs::FS &fs, const char * path) { //读取SD卡指定路径文件
- File file = fs.open(path);
- if (!file) {
- Serial.println("Failed to open file for reading");
- }
- String data = "";
- while (file.available()) {
- data = String(data) + String(char(file.read()));
- }
- file.close();
- return data;
- }
-
- void setup() {
- Serial.begin(115200);
- sdSPI.begin(SD_SCLK, SD_MISO, SD_MOSI, SD_CS); //初始化SD卡SPI
- if (!SD.begin(SD_CS, sdSPI)) {
- Serial.println("Card Mount Failed");
- return;
- }
- Serial.println(readFile(SD, "/admin.txt"));
- }
-
- void loop() {
- }
在程序中我们可以直接输入 TXT 或者 HTML 文件的路径,便可读取该文件中的内容。这里我们读取了 SD 卡根目录下的 admin.txt 文件,该文件作为配置文件用来保存网络信息、数据库信息与服务信息,该文件内容如下,不存在的服务用 null 表示:
- {
- "ssid": "ChinaNet-5678",//连接WiFi名称
- "password": "1234567890",//连接WiFi密码
- "user": "peien",//数据库账号名
- "secret": "52e2c018",//数据库密钥
- "admin": "12345678",//管理密码
- "server1": "score",//服务1
- "server2": "arduino",//服务2
- "server3": "Login",//服务3
- "server4": "Light"//服务4
- }
M5 Server X 服务框架如下:
M5 Server X 通过域名或 IP 加服务名访问不同服务主页,例如 http://m5core2/score/000,其中 m5core2
为域名或者 IP,score
为服务名,000
为查询参数,数据库通过键值对存储数据,为了确保数据标签的唯一性,我们采取服务加参数的形式代表某个具体数据。如成绩查询服务当中,000 为实际的学号,那我们就将数据标签设置为 score_000,使用下划线增加标签的可读性,如果我们需要登录账号和密码那就将账号和密码构造为一个标签。例如演示视频案例四当中,我们就将账号和密码作为服务参数进行传递输入,当输入账号 peien、密码 123 时,数据标签被构造为 Login_peien_123。
M5 Server X 服务响应的逻辑如下,访问根目录返回 Home_page.html 页面,该页面我们默认为代码雨,实际你可以设置为所有服务的导航页面,通过标签或者按钮跳转到子服务页面。Log_in.html 为某个子服务的服务主页,当服务开启时有两种情况,当提交参数正确时,通过 replace 函数查找占位符并替换数据,返回 success.html 页面,当提交参数错误时,返回 mistake.html(404)页面,当我们禁用某项服务时,无论提交参数是否正确,都会返回 Not_open.html(服务未开放或者无此服务)页面。
配置文件下有七个文件,其中 admin.txt、Home_page.html、Not_open.html 为公共文件,不同子服务用不同文件夹(英文文件夹名)区分。每个子服务文件夹下均有 Log_in.html、success.html、mistake.html 三个 HTML 文件。示意图如下,其中子服务文件夹非必需,是否启用该服务由 admin.txt 配置决定。对于没有的服务用 null 表示,当服务名为 null 时设备初始化将跳过该服务不加载该服务文件 。
M5 Server X 的后台功能主要有登录、服务器管理与设备信息查询,其中如何绘制控制页面与触摸屏的使用在往期《DIY掌上POS机,或许是最小的收银POS机了!》这篇教程中有详细的描述,这里就不再赘述。
以上就是 M5 Server X 的项目介绍,如果你不想下载 IDE 只想体验该项目,那么你可以访问 https://docs.m5stack.com/zh_CN/download 根据你自己的系统下载 M5Burner 烧录工具进行安装,打开软件按照下面的步骤进行烧录体验,其中 SD 卡网页模板与配置文件请通过本教程附件进行下载,直接解压到的 SD 卡修改网络信息即可体验。
烧录固件;
将附件提供的模板解压到 SD 卡;
打开 admin.txt 文件修改网络信息;
SD 卡插入 M5Core2 并重启设备;
等待 M5Core2 初始化并进入控制主页;
按演示视频控制设备与查看服务器管理与账号信息显示页面;
访问 http://m5core2/ 进入代码雨主页;
访问 http://m5core2/score 查看学生成绩(学号为000);
访问 http://m5core2/arduino 通过关键词m5core2进行搜索;
访问 http://m5core2/Login 查看学生成绩(用户名peien密码123);
访问 http://m5core2/Light 控制灯泡(开关分别代表了两个URL,自行修改为自己的接口);
分别输入正确信息与错误信息,启用服务与禁用服务,体验 M5 Server X。
有了上面的理论基础,我们便能完成 M5 Server X 的项目制作了,其中具体实现细节由于篇幅限制,这里就不再讨论,大家可以下载程序源代码进行查看,其中必要的程序说明已经注释,对此项目有任何建议或者疑问均可评论区留言。
使用 M5 Server X 你能够轻松打造自己的个人网站,当然你也可以使用普通 ESP32 完成此项目,但可能相对麻烦些,但这样一个 10 多块钱的个人服务器还有什么可嫌弃的呢。如果你想给别人分享你的网页服务,可以使用内网穿透服务,这个大家就自行百度了,在上面的思维导图当中我们提供了本项目用到的网页素材网、可视化编辑平台、自建数据库等链接,大家可以下载附件进行查阅学习。
我是默,我们下期见。
关注本公众号“铁熊玩创客”,回复“ M5 Server X ”获取完整代码。
欢迎转发朋友圈。如需转载,请注明出处和原作者。
点个赞与在看支持一下吧 ↓↓↓
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。