1
在这个例子中,我们将弄清楚如何制作一个基于 ESP32 的网络服务器来控制 LED 状态,它可以从世界任何地方访问。
我在这个项目中使用了 Mac 计算机,但您可以在任何可以运行 Arduino IDE 的计算机上执行此操作,即使是在像 Raspberry Pi 这样的廉价低功耗计算机上也是如此。
为了开始使用 Arduino IDE 和 Arduino 编程语言对 ESP32 进行编程,您需要一个特殊的附加组件。通过以下链接了解如何在 Mac OS 上为 ESP32 准备 Arduino IDE 。
对于本教程,您需要以下项目:
按照下面的示意图进行连接。
首先将 ESP32 和 GND 上的 3V3 电源电压输出连接到面包板上。使用 GPIO 引脚 23 作为数字输出引脚,通过电阻将 LED 连接到 ESP32。之后,将 16x2 LCD 显示器的 SDA 引脚连接到 GPIO 引脚 21,将 SCL 连接到 GPIO 引脚 22。
SPIFFS全称是“Serial Peripheral Interface Flash File System”,即通过SPI传输数据的闪存文件系统。相应地,SPIFFS 是一种简化的文件系统,专为具有通过 SPI 总线传输数据的闪存芯片(例如 ESP32 闪存)的微控制器而设计。
在以下情况下,SPIFFS 最适合与 ESP32 一起使用:
您可以直接使用 Arduino IDE 上的插件创建、保存和写入存储在 ESP32 文件系统中的文件。
首先,确保您安装了最新版本的 Arduino IDE,然后执行以下操作:
ESPAsyncWebServer 和 AsyncTCP 库允许您使用 ESP32 文件系统中的文件创建 Web 服务器。有关这些库的更多信息,请查看以下链接。
安装 ESPAsyncWebServer 库
安装 AsyncTCP 库
将 ESPAsyncWebServer 和 AsyncTCP 文件夹移动到位于Documents目录内的库文件夹中。
最后,重启 Arduino IDE。
切换按钮的 HTML/CSS 模板取自以下来源。另外创建了两个 JS 脚本。第一个在显示 HTML 页面之前检查 LED 的当前状态。第二个用于通过更改复选框的状态来更改 LED 的状态。
html>
<html>
<head>
<title>Internet controlled LED using ESP32 based web servertitle>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="data:,">
<link rel="stylesheet" type="text/css" href="style.css">
// Verify the current status of LED
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", function(event) {
var button_text = "";
button_text = document.getElementById("status").innerHTML;
if (button_text == "ON") {
document.getElementById("switch1").checked = true;
}
else if (button_text == "OFF") {
document.getElementById("switch1").checked = false;
}
});
script>
// Change the state of LED
<script type="text/javascript">
function fun1()
{
var text = document.getElementById("status").innerHTML;
var chbox=document.getElementById("switch1");
if (chbox.checked == true && text == "OFF") {
window.location.pathname = '/on';
chbox.checked = true;
}
else
{
window.location.pathname = '/off';
chbox.checked = false;
}
}
script>
head>
<body >
<h1>Internet controlled LED using ESP32 based web server <div id="status" style = "display: none;">%STATE%div>h1>
<span class="switch">
<span class="switch-border1">
<span class="switch-border2">
<input id="switch1" type="checkbox" onclick="fun1()"/>
<label for="switch1">label>
<span class="switch-top">span>
<span class="switch-shadow">span>
<span class="switch-handle">span>
<span class="switch-handle-left">span>
<span class="switch-handle-right">span>
<span class="switch-handle-top">span>
<span class="switch-handle-bottom">span>
<span class="switch-handle-base">span>
<span class="switch-led switch-led-green">
<span class="switch-led-border">
<span class="switch-led-light">
<span class="switch-led-glow">span>
span>
span>
span>
<span class="switch-led switch-led-red">
<span class="switch-led-border">
<span class="switch-led-light">
<span class="switch-led-glow">span>
span>
span>
span>
span>
span>
span>
body>
html>
body {
font-family: arial, verdana, sans-serif;
font-size: 8px;
background: #1E1E20;
text-align: center;
}
h1{
color: white;
font-size:30px;
}
.switch {
display: inline-block;
margin: 10em 2em;
position: relative;
border-radius: 3.5em;
-webkit-box-shadow: 0 0 0.5em rgba(255,255,255,0.2);
-moz-box-shadow: 0 0 0.5em rgba(255,255,255,0.2);
box-shadow: 0 0 0.5em rgba(255,255,255,0.2);
}
.switch label {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
display: block;
position: absolute;
top: 0;
left: 0;
z-index: 10;
}
.switch input {
display: none;
}
.switch span {
display: block;
-webkit-transition: top 0.2s;
-moz-transition: top 0.2s;
-ms-transition: top 0.2s;
-o-transition: top 0.2s;
transition: top 0.2s;
}
.switch-border1 {
border: 0.1em solid #000;
border-radius: 3.5em;
-webkit-box-shadow: 0 0.2em rgba(255, 255, 255, 0.2);
-moz-box-shadow: 0 0.2em rgba(255, 255, 255, 0.2);
box-shadow: 0 0.2em rgba(255, 255, 255, 0.2);
}
.switch-border2 {
width: 6.6em;
height: 12.6em;
position: relative;
border: 0.1em solid #323232;
background-image: -webkit-gradient(linear, left top, right top, from(#2D2D2D), color-stop(0.5, #4B4B4B), to(#2D2D2D));
background-image: -webkit-linear-gradient(left, #2D2D2D, #4B4B4B, #2D2D2D);
background-image: -moz-linear-gradient(left, #2D2D2D, #4B4B4B, #2D2D2D);
background-image: -ms-linear-gradient(left, #2D2D2D, #4B4B4B, #2D2D2D);
background-image: -o-linear-gradient(left, #2D2D2D, #4B4B4B, #2D2D2D);
background-image: linear-gradient(to right, #2D2D2D, #4B4B4B, #2D2D2D);
border-radius: 3.4em;
}
.switch-border2:before,
.switch-border2:after {
content: '';
display: block;
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
z-index: 0;
opacity: .3;
border-radius: 3.4em;
}
.switch-border2:before {
background: -webkit-gradient(linear, left top, left bottom, from(#000), to(rgba(0,0,0,0)));
background: -webkit-linear-gradient(#000, rgba(0,0,0,0));
background: -moz-linear-gradient(#000, rgba(0,0,0,0));
background: -ms-linear-gradient(#000, rgba(0,0,0,0));
background: -o-linear-gradient(#000, rgba(0,0,0,0));
background: linear-gradient(#000, rgba(0,0,0,0));
}
.switch-border2:after {
background: -webkit-gradient(linear, left top, left bottom, from(rgba(0,0,0,0)), to(#000));
background: -webkit-linear-gradient(rgba(0,0,0,0), #000);
background: -moz-linear-gradient(rgba(0,0,0,0), #000);
background: -ms-linear-gradient(rgba(0,0,0,0), #000);
background: -o-linear-gradient(rgba(0,0,0,0), #000);
background: linear-gradient(rgba(0,0,0,0), #000);
}
.switch-top {
width: 100%;
height: 84%;
position: absolute;
top: 8%;
left: 0;
z-index: 1;
background-image: -webkit-gradient(linear, left top, right top, from(#2D2D2D), color-stop(0.5, #4B4B4B), to(#2D2D2D));
background-image: -webkit-linear-gradient(left, #2D2D2D, #4B4B4B, #2D2D2D);
background-image: -moz-linear-gradient(left, #2D2D2D, #4B4B4B, #2D2D2D);
background-image: -ms-linear-gradient(left, #2D2D2D, #4B4B4B, #2D2D2D);
background-image: -o-linear-gradient(left, #2D2D2D, #4B4B4B, #2D2D2D);
background-image: linear-gradient(to right, #2D2D2D, #4B4B4B, #2D2D2D);
border-radius: 3.4em;
}
.switch-shadow {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
z-index: 2;
border-radius: 3.4em;
-webkit-box-shadow: 0 0 2em black inset;
-moz-box-shadow: 0 0 2em black inset;
box-shadow: 0 0 2em black inset;
}
.switch-handle-left,
.switch-handle-right {
content: '';
display: block;
width: 3.6em;
height: 0;
position: absolute;
top: 6.6em;
z-index: 2;
border-bottom: 4.5em solid #111;
border-left: 0.7em solid transparent;
border-right: 0.7em solid transparent;
border-radius: 0;
}
.switch-handle-left {
left: 0.8em;
}
.switch-handle-right {
right: 0.8em;
}
.switch-handle {
width: 3.6em;
height: 4.5em;
position: absolute;
top: 6.6em;
left: 1.5em;
z-index: 3;
background: #333;
background-image: -webkit-gradient(linear, left top, right top, from(#111), color-stop(0.4, #777), color-stop(0.5, #888), color-stop(0.6, #777), to(#111));
background-image: -webkit-linear-gradient(left, #111, #777 40%, #888, #777 60%, #111);
background-image: -moz-linear-gradient(left, #111, #777 40%, #888, #777 60%, #111);
background-image: -ms-linear-gradient(left, #111, #777 40%, #888, #777 60%, #111);
background-image: -o-linear-gradient(left, #111, #777 40%, #888, #777 60%, #111);
background-image: linear-gradient(to right, #111, #777 40%, #888, #777 60%, #111);
border-radius: 0;
}
.switch-handle-top {
width: 5em;
height: 5em;
position: absolute;
top: 8.5em;
left: 0.8em;
z-index: 4;
background-color: #555;
background-image: -webkit-gradient(linear, left top, right top, from(#5F5F5F), to(#878787));
background-image: -webkit-linear-gradient(left, #5F5F5F, #878787);
background-image: -moz-linear-gradient(left, #5F5F5F, #878787);
background-image: -ms-linear-gradient(left, #5F5F5F, #878787);
background-image: -o-linear-gradient(left, #5F5F5F, #878787);
background-image: linear-gradient(to right, #5F5F5F, #878787);
border-top: 0.2em solid #AEB2B3;
border-radius: 2.5em;
}
.switch-handle-bottom {
width: 3.6em;
height: 3.6em;
position: absolute;
top: 4.7em;
left: 1.5em;
z-index: 3;
background: #333;
background-image: -webkit-gradient(linear, left top, right top, from(#111), color-stop(0.4, #777), color-stop(0.5, #888), color-stop(0.6, #777), to(#111));
background-image: -webkit-linear-gradient(left, #111, #777 40%, #888, #777 60%, #111);
background-image: -moz-linear-gradient(left, #111, #777 40%, #888, #777 60%, #111);
background-image: -ms-linear-gradient(left, #111, #777 40%, #888, #777 60%, #111);
background-image: -o-linear-gradient(left, #111, #777 40%, #888, #777 60%, #111);
background-image: linear-gradient(to right, #111, #777 40%, #888, #777 60%, #1 11);
border-top: 0.2em solid #141414;
border-radius: 1.8em;
}
.switch-handle-base {
width: 4.2em;
height: 4.2em;
position: absolute;
top: 3.8em;
left: 1.2em;
z-index: 2;
border-top: 0.2em solid rgba(255,255,255,0.35);
border-radius: 2.1em;
-webkit-box-shadow: 0 0 0.5em rgba(0,0,0,0.8) inset;
-moz-box-shadow: 0 0 0.5em rgba(0,0,0,0.8) inset;
box-shadow: 0 0 0.5em rgba(0,0,0,0.8) inset;
}
.switch-led {
position: absolute;
left: 2em;
border-radius: 1.4em;
}
.switch-led-border {
border: 0.2em solid black;
border-radius: 1.3em;
}
.switch-led-light {
border-radius: 1.1em;
-webkit-box-shadow: 0 0 0.5em rgba(255,255,255,0.5) inset;
-moz-box-shadow: 0 0 0.5em rgba(255,255,255,0.5) inset;
box-shadow: 0 0 0.5em rgba(255,255,255,0.5) inset;
}
.switch-led-glow {
width: 2em;
height: 2em;
position: relative;
border-radius: 1em;
}
.switch-led-glow:before {
content: '';
display: block;
width: 0.6em;
height: 0.6em;
position: absolute;
top: 0.3em;
left: 0.7em;
background: rgba(255,255,255,0.2);
border-radius: 0.3em;
-webkit-box-shadow: 0 0 1em rgba(255,255,255,0.75);
-moz-box-shadow: 0 0 1em rgba(255,255,255,0.75);
box-shadow: 0 0 1em rgba(255,255,255,0.75);
}
.switch-led-glow:after {
content: '';
display: block;
width: 0;
height: 0;
position: absolute;
top: 0;
left: 0;
opacity: 0.2;
filter: alpha(opacity=20);
border: 1em solid #fff;
border-color: transparent #fff transparent #fff;
border-radius: 1em;
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-ms-transform: rotate(45deg);
-o-transform: rotate(45deg);
transform: rotate(45deg);
}
.switch-led:after {
display: block;
width: 100%;
position: absolute;
left: 0;
color: #666;
font-family: arial, verdana, sans-serif;
font-weight: bold;
text-align: center;
text-shadow: 0 0.1em rgba(0,0,0,0.7);
}
.switch-led-green:after {
content: 'ON';
top: -1.8em;
}
.switch-led-red:after {
content: 'OFF';
bottom: -1.8em;
}
.switch-led-green {
top: -5em;
border-top: 0.1em solid rgba(0,161,75,0.5);
border-bottom: 0.1em solid rgba(255,255,255,0.25);
}
.switch-led-green .switch-led-light {
background: rgb(0,161,75);
border: 0.1em solid rgb(0,104,56);
}
.switch-led-red {
bottom: -5em;
border-top: 0.1em solid rgba(237,28,36,0.2);
border-bottom: 0.1em solid rgba(255,255,255,0.25);
-webkit-box-shadow: 0 0 3em rgb(237,28,36);
-moz-box-shadow: 0 0 3em rgb(237,28,36);
box-shadow: 0 0 3em rgb(237,28,36);
}
.switch-led-red .switch-led-light {
background: rgb(237,28,36);
border: 0.1em solid rgb(161,30,45);
}
.switch-led-red .switch-led-glow {
background: #fff;
background: rgba(255, 255, 255, 0.3);
filter: alpha(opacity=30);
}
/* Switch on */
.switch input:checked~.switch-handle-left, .switch input:checked~.switch-handle-right {
top: 1.5em;
border-bottom: 0;
border-top: 4.5em solid #111;
}
.switch input:checked~.switch-handle {
top: 1.5em;
}
.switch input:checked~.switch-handle-top {
top: -1em;
border-top: 0;
border-bottom: 0.2em solid #AEB2B3;
}
.switch input:checked~.switch-handle-bottom {
top: 4.2em;
border-top: 0;
border-bottom: 0.2em solid #141414;
}
.switch input:checked~.switch-handle-base {
top: 4.5em;
border-top: 0;
border-bottom: 0.2em solid rgba(255,255,255,0.35);
}
.switch input:checked~.switch-led-green {
-webkit-box-shadow: 0 0 3em rgb(0,161,75);
-moz-box-shadow: 0 0 3em rgb(0,161,75);
box-shadow: 0 0 3em rgb(0,161,75);
}
.switch input:checked~.switch-led-green .switch-led-glow {
background: #fff;
background: rgba(255, 255, 255, 0.4);
filter: alpha(opacity=40);
}
.switch input:checked~.switch-led-red {
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none;
}
.switch input:checked~.switch-led-red .switch-led-glow {
background: rgba(255, 255, 255, 0);
filter: alpha(opacity=0);
}
主要是,代码基于使用 SPIFFS 从 ESP32 Web 服务器获取的 Arduino 代码和如何在 Arduino IDE 上使用带 ESP32 的 I2C LCD。
// Import required libraries
#include "WiFi.h"
#include "ESPAsyncWebServer.h"
#include "SPIFFS.h"
#include
// Replace with your network credentials
const char* ssid = "YourNetworkName";
const char* password = "YourPassword";
// set the LCD number of columns and rows
int lcdColumns = 16;
int lcdRows = 2;
// set LCD address, number of columns and rows
// if you don't know your display address, run an I2C scanner sketch
LiquidCrystal_I2C lcd(0x27, lcdColumns, lcdRows);
// Set LED GPIO
const int ledPin = 23;
// Stores LED state
String ledState;
// Create AsyncWebServer object on port 80
AsyncWebServer server(80);
// Replaces placeholder with LED state value
String processor(const String& var){
Serial.println(var);
if(var == "STATE"){
if(digitalRead(ledPin)){
ledState = "ON";
}
else{
ledState = "OFF";
}
Serial.print(ledState);
return ledState;
}
return String();
}
void setup(){
// initialize LCD
lcd.init();
// turn on LCD backlight
lcd.backlight();
// Serial port for debugging purposes
Serial.begin(115200);
pinMode(ledPin, OUTPUT);
// Initialize SPIFFS file server
if(!SPIFFS.begin(true)){
Serial.println("An Error has occurred while mounting SPIFFS");
return;
}
// Connect to Wi-Fi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi..");
}
// Print IP address of web server on serial interface
Serial.println(WiFi.localIP());
// Print IP address of web server on LCD display
lcd.setCursor(0, 0);
lcd.print("IP address is ");
lcd.setCursor(0, 1);
lcd.print(WiFi.localIP());
// Route for root / web page
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(SPIFFS, "/index.html", String(), false, processor);
});
// Route to load style.css file
server.on("/style.css", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(SPIFFS, "/style.css", "text/css");
});
// Route to set GPIO to HIGH
server.on("/on", HTTP_GET, [](AsyncWebServerRequest *request){
digitalWrite(ledPin, HIGH);
request->send(SPIFFS, "/index.html", String(), false, processor);
});
// Route to set GPIO to LOW
server.on("/off", HTTP_GET, [](AsyncWebServerRequest *request){
digitalWrite(ledPin, LOW);
request->send(SPIFFS, "/index.html", String(), false, processor);
});
// Start server
server.begin();
}
void loop(){
}
确定ESP32 web服务器IP地址,可以通过两种方式找到。
接下来,打开您选择的 Web 浏览器并将以下 IP 地址粘贴到地址栏中。你应该得到类似于下面截图的输出。
Ngrok 是一个平台,允许您组织从外部互联网远程访问 Web 服务器或在您的 PC 上运行的某些其他服务。通过在 ngrok 开始时创建的安全隧道组织访问。
./ngrok authtoken <YOUR_AUTH_TOKEN>
./ngrok http Your_IP_Address:80
如果一切都正确完成,那么隧道状态应该变为“在线”,并且重定向链接应该出现在“转发”列中。通过将此链接输入浏览器,您可以从世界任何地方访问网络服务器。
我希望您发现本指南有用,并感谢阅读。我已经向您展示了一个控制 LED 的简单示例,但是您可以通过将 LED 替换为您想要控制的另一个输出(例如继电器)来使任务复杂化。
如果您有任何问题或反馈?在下面发表评论。如果你喜欢这篇文章,请订阅我的博客来支持我。感谢大家的赞许!
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表德赢Vwin官网 网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
全部0条评论
快来发表一下你的评论吧 !