資料介紹
描述
項(xiàng)目概況
在這個(gè)例子中,我們將弄清楚如何制作一個(gè)基于 ESP32 的網(wǎng)絡(luò)服務(wù)器來(lái)控制 LED 狀態(tài),它可以從世界任何地方訪(fǎng)問(wèn)。
我在這個(gè)項(xiàng)目中使用了 Mac 計(jì)算機(jī),但您可以在任何可以運(yùn)行 Arduino IDE 的計(jì)算機(jī)上執(zhí)行此操作,即使是在像 Raspberry Pi 這樣的廉價(jià)低功耗計(jì)算機(jī)上也是如此。
使用 Arduino IDE 準(zhǔn)備 ESP32
為了開(kāi)始使用 Arduino IDE 和 Arduino 編程語(yǔ)言對(duì) ESP32 進(jìn)行編程,您需要一個(gè)特殊的附加組件。通過(guò)以下鏈接了解如何在 Mac OS 上為 ESP32 準(zhǔn)備 Arduino IDE 。
所需材料
對(duì)于本教程,您需要以下項(xiàng)目:
構(gòu)建電路
按照下面的示意圖進(jìn)行連接。
首先將 ESP32 和 GND 上的 3V3 電源電壓輸出連接到面包板上。使用 GPIO 引腳 23 作為數(shù)字輸出引腳,通過(guò)電阻將 LED 連接到 ESP32。之后,將 16x2 LCD 顯示器的 SDA 引腳連接到 GPIO 引腳 21,將 SCL 連接到 GPIO 引腳 22。
SPIFFS 文件系統(tǒng)快速概覽
SPIFFS全稱(chēng)是“Serial Peripheral Interface Flash File System”,即通過(guò)SPI傳輸數(shù)據(jù)的閃存文件系統(tǒng)。相應(yīng)地,SPIFFS 是一種簡(jiǎn)化的文件系統(tǒng),專(zhuān)為具有通過(guò) SPI 總線(xiàn)傳輸數(shù)據(jù)的閃存芯片(例如 ESP32 閃存)的微控制器而設(shè)計(jì)。
在以下情況下,SPIFFS 最適合與 ESP32 一起使用:
- 創(chuàng)建用于存儲(chǔ)設(shè)置的文件。
- 永久數(shù)據(jù)存儲(chǔ)。
- 創(chuàng)建文件來(lái)存儲(chǔ)少量數(shù)據(jù)(而不是為此使用 microSD 卡)。
- 存儲(chǔ)用于創(chuàng)建 Web 服務(wù)器的 HTML 和 CSS 文件。
在 Mac OS 上安裝 SPIFFS 引導(dǎo)加載程序
您可以直接使用 Arduino IDE 上的插件創(chuàng)建、保存和寫(xiě)入存儲(chǔ)在 ESP32 文件系統(tǒng)中的文件。
首先,確保您安裝了最新版本的 Arduino IDE,然后執(zhí)行以下操作:
- 打開(kāi)以下鏈接并下載壓縮包“ ESP32FS-1.0.zip”
- 轉(zhuǎn)到位于Documents文件夾中的 Arduino IDE 目錄。創(chuàng)建一個(gè)tools文件夾(如果不存在)。在tools目錄中創(chuàng)建另一個(gè)文件夾ESP32FS。在ESP32FS內(nèi)部創(chuàng)建另一個(gè),稱(chēng)為tool 。
- 將步驟 1 中下載的 ZIP 存檔解壓縮到工具文件夾中。
- 重新啟動(dòng)您的 Arduino IDE。
- 查看插件是否安裝成功,打開(kāi)Arduino IDE,點(diǎn)擊“Tools”,查看該菜單中是否有“ESP32 Sketch Data Upload”項(xiàng)。
安裝庫(kù)
ESPAsyncWebServer 和 AsyncTCP 庫(kù)允許您使用 ESP32 文件系統(tǒng)中的文件創(chuàng)建 Web 服務(wù)器。有關(guān)這些庫(kù)的更多信息,請(qǐng)查看以下鏈接。
安裝 ESPAsyncWebServer 庫(kù)
- 單擊此處下載圖書(shū)館的 ZIP 存檔。
- 解壓縮此存檔。您應(yīng)該獲得 ESPAsyncWebServer-master 文件夾。
- 將其重命名為“ESPAsyncWebServer”。
安裝 AsyncTCP 庫(kù)
- 單擊此處下載圖書(shū)館的 ZIP 存檔。
- 解壓縮此存檔。您應(yīng)該獲得 AsyncTCP-master 文件夾。
- 將其重命名為“AsyncTCP”。
將 ESPAsyncWebServer 和 AsyncTCP 文件夾移動(dòng)到位于Documents目錄內(nèi)的庫(kù)文件夾中。
最后,重啟 Arduino IDE。
使用以下內(nèi)容創(chuàng)建一個(gè) index.html 文件
切換按鈕的 HTML/CSS 模板取自以下來(lái)源。另外創(chuàng)建了兩個(gè) JS 腳本。第一個(gè)在顯示 HTML 頁(yè)面之前檢查 LED 的當(dāng)前狀態(tài)。第二個(gè)用于通過(guò)更改復(fù)選框的狀態(tài)來(lái)更改 LED 的狀態(tài)。
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>
使用以下內(nèi)容創(chuàng)建一個(gè) style.css 文件
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);
}
Arduino代碼
主要是,代碼基于使用 SPIFFS 從 ESP32 Web 服務(wù)器獲取的 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(){
}
使用 SPIFFS 加載器上傳 arduino 代碼和文件
- 打開(kāi) Arduino 代碼的 sketch 文件夾。
- 在此文件夾中,創(chuàng)建一個(gè)名為“data”的新文件夾。
- 在數(shù)據(jù)文件夾中,您需要放置index.html和style.css。
- 上傳Arduino代碼
- 然后,要上傳文件,請(qǐng)單擊“工具”>“ESP32 草圖數(shù)據(jù)上傳”上的 Arduino IDE
測(cè)試本地網(wǎng)絡(luò)服務(wù)器
確定ESP32 web服務(wù)器IP地址,可以通過(guò)兩種方式找到。
- Arduino IDE 上的串口監(jiān)視器(工具 > 串口監(jiān)視器)
- 液晶顯示
接下來(lái),打開(kāi)您選擇的 Web 瀏覽器并將以下 IP 地址粘貼到地址欄中。你應(yīng)該得到類(lèi)似于下面截圖的輸出。
使用 Ngrok 從世界任何地方訪(fǎng)問(wèn)本地 Web 服務(wù)器
Ngrok 是一個(gè)平臺(tái),允許您組織從外部互聯(lián)網(wǎng)遠(yuǎn)程訪(fǎng)問(wèn) Web 服務(wù)器或在您的 PC 上運(yùn)行的某些其他服務(wù)。通過(guò)在 ngrok 開(kāi)始時(shí)創(chuàng)建的安全隧道組織訪(fǎng)問(wèn)。
- 點(diǎn)擊此鏈接并注冊(cè)。
- 創(chuàng)建帳戶(hù)后,登錄并轉(zhuǎn)到“身份驗(yàn)證”選項(xiàng)卡。復(fù)制“您的隧道授權(quán)令牌”字段中的行。
- 單擊導(dǎo)航欄中的“下載”選項(xiàng)卡。
- 選擇與您的操作系統(tǒng)匹配的 ngrok 版本并下載。
- 解壓縮下載的文件夾并運(yùn)行命令行。
- 通過(guò)輸入以下命令連接您的帳戶(hù)
./ngrok authtoken <YOUR_AUTH_TOKEN>
- 在端口 80 上啟動(dòng) HTTP 隧道
./ngrok http Your_IP_Address:80
如果一切都正確完成,那么隧道狀態(tài)應(yīng)該變?yōu)椤霸诰€(xiàn)”,并且重定向鏈接應(yīng)該出現(xiàn)在“轉(zhuǎn)發(fā)”列中。通過(guò)將此鏈接輸入瀏覽器,您可以從世界任何地方訪(fǎng)問(wèn)網(wǎng)絡(luò)服務(wù)器。
我希望您發(fā)現(xiàn)本指南有用,并感謝閱讀。我已經(jīng)向您展示了一個(gè)控制 LED 的簡(jiǎn)單示例,但是您可以通過(guò)將 LED 替換為您想要控制的另一個(gè)輸出(例如繼電器)來(lái)使任務(wù)復(fù)雜化。
如果您有任何問(wèn)題或反饋?在下面發(fā)表評(píng)論。如果你喜歡這篇文章,請(qǐng)訂閱我的博客來(lái)支持我。感謝大家的贊許!
- 使用ESP32 Web服務(wù)器進(jìn)行家庭自動(dòng)化設(shè)置
- 基于ESP32的矩陣WiFi留言板 0次下載
- 基于ESP8266的Web服務(wù)器 1次下載
- 用ESP32制作網(wǎng)絡(luò)服務(wù)器
- NodeMCU ESP8266啟用AJAX的Web服務(wù)器
- ESP32 CAM WEB服務(wù)器及入門(mén)指南
- 使用TTGO ESP32和Visuino從互聯(lián)網(wǎng)上獲取天氣數(shù)據(jù)
- 使用TTGO ESP32和Visuino從互聯(lián)網(wǎng)獲取股票數(shù)據(jù)
- 通過(guò)使用ESP8266 NodeMCU Web服務(wù)器來(lái)控制的電子元件
- ESP32 LED控制器板
- 最簡(jiǎn)單DIY基于ESP8266的物聯(lián)網(wǎng)智能小車(chē)②(webserver服務(wù)器網(wǎng)頁(yè)高級(jí)遙控版) 0次下載
- 調(diào)用Lua新建的WEB服務(wù)器 操作Nodemcu esp8266 控制繼電器實(shí)現(xiàn)物聯(lián)網(wǎng)
- 使用ESP32-CAM板訪(fǎng)問(wèn)網(wǎng)絡(luò) 43次下載
- 帶有BME280的ESP32 Web服務(wù)器的高級(jí)氣象站 18次下載
- 如何建立一個(gè)帶Arduino IDE的ESP8266 Web服務(wù)器 2次下載
- 顯示Web服務(wù)器中的內(nèi)存使用情況 881次閱讀
- ESP32 IDF創(chuàng)建WEB SERVER的流程 4325次閱讀
- 異步串行到以太網(wǎng)設(shè)備服務(wù)器 749次閱讀
- 基于ESP32的簡(jiǎn)易web服務(wù)器設(shè)計(jì) 3990次閱讀
- 使用ESP32連接騰訊云實(shí)現(xiàn)遠(yuǎn)程控制 3745次閱讀
- 基于ESP32制造有趣的超級(jí)馬里奧主題時(shí)鐘 4783次閱讀
- 如何使用ESP8266制作可配置的Web服務(wù)器 1.3w次閱讀
- dfrobotBeetle-ESP32控制器簡(jiǎn)介 2974次閱讀
- 嵌入式Web服務(wù)器BOA移植與測(cè)試設(shè)計(jì)概述 1864次閱讀
- 應(yīng)用服務(wù)器配置要求及方案 3.2w次閱讀
- 應(yīng)用服務(wù)器是什么_應(yīng)用服務(wù)器有哪些 3.4w次閱讀
- 根服務(wù)器關(guān)了會(huì)怎么樣_美國(guó)會(huì)關(guān)掉中國(guó)根服務(wù)器 1.4w次閱讀
- 互聯(lián)網(wǎng)汽車(chē)是什么意思_互聯(lián)網(wǎng)汽車(chē)有什么功能 1.8w次閱讀
- 一文讀懂應(yīng)用服務(wù)器與Web服務(wù)器的區(qū)別 3002次閱讀
- 一種嵌入式Web服務(wù)器的設(shè)計(jì)方案 4306次閱讀
下載排行
本周
- 1A7159和A7139射頻芯片的資料免費(fèi)下載
- 0.20 MB | 55次下載 | 5 積分
- 2PIC12F629/675 數(shù)據(jù)手冊(cè)免費(fèi)下載
- 2.38 MB | 36次下載 | 5 積分
- 3PIC16F716 數(shù)據(jù)手冊(cè)免費(fèi)下載
- 2.35 MB | 18次下載 | 5 積分
- 4dsPIC33EDV64MC205電機(jī)控制開(kāi)發(fā)板用戶(hù)指南
- 5.78MB | 8次下載 | 免費(fèi)
- 5STC15系列常用寄存器匯總免費(fèi)下載
- 1.60 MB | 7次下載 | 5 積分
- 6模擬電路仿真實(shí)現(xiàn)
- 2.94MB | 4次下載 | 免費(fèi)
- 7PCB圖繪制實(shí)例操作
- 2.92MB | 2次下載 | 免費(fèi)
- 8零死角玩轉(zhuǎn)STM32F103—指南者
- 26.78 MB | 1次下載 | 1 積分
本月
- 1ADI高性能電源管理解決方案
- 2.43 MB | 452次下載 | 免費(fèi)
- 2免費(fèi)開(kāi)源CC3D飛控資料(電路圖&PCB源文件、BOM、
- 5.67 MB | 141次下載 | 1 積分
- 3基于STM32單片機(jī)智能手環(huán)心率計(jì)步器體溫顯示設(shè)計(jì)
- 0.10 MB | 137次下載 | 免費(fèi)
- 4A7159和A7139射頻芯片的資料免費(fèi)下載
- 0.20 MB | 55次下載 | 5 積分
- 5PIC12F629/675 數(shù)據(jù)手冊(cè)免費(fèi)下載
- 2.38 MB | 36次下載 | 5 積分
- 6如何正確測(cè)試電源的紋波
- 0.36 MB | 19次下載 | 免費(fèi)
- 7PIC16F716 數(shù)據(jù)手冊(cè)免費(fèi)下載
- 2.35 MB | 18次下載 | 5 積分
- 8Q/SQR E8-4-2024乘用車(chē)電子電器零部件及子系統(tǒng)EMC試驗(yàn)方法及要求
- 1.97 MB | 8次下載 | 10 積分
總榜
- 1matlab軟件下載入口
- 未知 | 935121次下載 | 10 積分
- 2開(kāi)源硬件-PMP21529.1-4 開(kāi)關(guān)降壓/升壓雙向直流/直流轉(zhuǎn)換器 PCB layout 設(shè)計(jì)
- 1.48MB | 420062次下載 | 10 積分
- 3Altium DXP2002下載入口
- 未知 | 233088次下載 | 10 積分
- 4電路仿真軟件multisim 10.0免費(fèi)下載
- 340992 | 191367次下載 | 10 積分
- 5十天學(xué)會(huì)AVR單片機(jī)與C語(yǔ)言視頻教程 下載
- 158M | 183335次下載 | 10 積分
- 6labview8.5下載
- 未知 | 81581次下載 | 10 積分
- 7Keil工具M(jìn)DK-Arm免費(fèi)下載
- 0.02 MB | 73810次下載 | 10 積分
- 8LabVIEW 8.6下載
- 未知 | 65988次下載 | 10 積分
評(píng)論
查看更多