Esp8266 進階之路32【高階篇】當esp8266遇到 Html,該怎麼內建網頁控制裝置,理清內建網頁的實現過程,實現無需路由器手機也可以控制esp8266。(附帶韌體)
阿新 • • 發佈:2018-12-18
一、前言;
- 這個月也快結束了,時間真快,我伺服器知識自學依然在路途中,這幾天聽到熱點網頁配置
esp8266
連線路由器,那麼我想這個不是很複雜,不過需要一些通訊協議的基礎,以及對esp8266
的SDK
開發的熟悉,這幾天擼了幾下也就輕鬆弄出來了!不過我今天給大家帶來的是實現的原理,我是用作於gpio
口控制,也就是一盞燈的點亮點滅!當然了,你可以沿著我思路去做網頁內建配網哦!
二、整體思路;
- 必須要知道的知識:
- ①:以手機瀏覽器為例,其訪問指定的
ip
地址,過程是怎麼樣的?
我們都在用手機瀏覽器,很少知道他是怎麼實現訪問互動資料的。這裡我們把
esp8266作為
伺服器端,手機瀏覽器作為客戶端,一般地,都是get
請求,除非指定post
提交,而請求的資料格式,大家可以去百度下http
協議的資料格式,這裡不再累贅!而請求之後,esp8266
那肯定是要以http
協議資料來回復內容的,這內容也就包含了gpio
的管腳狀態!從而實現了資料互動!
- ②:編寫好的
html
對應燒錄的地址,應該怎麼注意什麼?
這裡我就不再多說
html
的檔案怎麼編寫,這需要一定的前端知識。對應的燒錄地址必須在程式碼塊外的地址燒錄,大家不懂哪些是程式碼塊外的地址,可以去看看我上個月寫的25q16
儲存晶片的分佈,點我檢視!,之後我們需要在程式碼中讀取這個網頁,之後傳送給客戶端就可以了!
三、編寫一個簡單的Html
檔案;
- 非常簡單,我這裡直接上程式碼:
- 用的是
post
提交,不是get
請求! - 當點選開燈,傳送
powerOn=1
,點選關燈傳送powerOn=0
- 注意編碼是
utf-8
!
- 用的是
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"></meta><title>esp8266內建網頁單開關燈</title></head>
<body>
<h2 align="center">esp8266熱點內建網頁單開關燈By半顆心臟</h2>
<h3 align="center">%s</h3>
<form method="post"action="setLight">
<table align="center"><tr><td>開燈:</td><td>
<button name="powerOn"type="submit"value="1">點我開燈</button>
</td></tr><tr><td>關燈:</td><td>
<button name="powerOff"type="submit"value="0">點我關燈</button>
</td></tr>
</table>
</form>
</body>
</html>
用電腦瀏覽器開啟預覽如下:
四、esp8266
程式設計;
看標題大家都知道,這個裝置
esp8266
是作為一個熱點讓客戶端去主動連線,那麼esp8266
必須要開啟熱點模式,我這裡讓它固定一個ip
地址192.168.5.1
,當然了,你也可以不設定固定地址,因為預設就是192.168.4.1
!開啟熱點之後,等待客戶端連線,如果客戶端有成功連線後,開啟tcp
伺服器(其實就是web伺服器第一步
),這時候就是一直處於和客戶端連線互動資料的狀態了!
4.1 配置熱點模式,開啟軟路由!
下面程式碼中的
webEsp8266
是裝置發出的熱點名字,xh12345678
是密碼,192, 168, 5, 1
是固定自定義的ip
地址,允許最大四個的客戶端連線,而且分配的ip
是從192, 168, 5, 100
到192, 168, 5, 105
;
wifi_set_opmode(SOFTAP_MODE);
struct softap_config *config = (struct softap_config *) zalloc(
sizeof(struct softap_config)); // 初始化
wifi_softap_get_config(config);
sprintf(config->ssid, "webEsp8266");
sprintf(config->password, "xh12345678");
config->authmode = AUTH_WPA_WPA2_PSK;
config->ssid_len = 0;
config->max_connection = 4;
wifi_softap_set_config(config); // Set ESP8266 soft-AP config
free(config);
struct station_info * station = wifi_softap_get_station_info();
while (station) {
printf("bssid : MACSTR, ip : IPSTR/n", MAC2STR(station->bssid),
IP2STR(&station->ip));
station = STAILQ_NEXT(station, next);
}
wifi_softap_free_station_info(); // Free it by calling functionss
wifi_softap_dhcps_stop(); // disable soft-AP DHCP server
//配置dhcp,固定esp8266的ip為 192, 168, 5, 1
struct ip_info info;
IP4_ADDR(&info.ip, 192, 168, 5, 1);
IP4_ADDR(&info.gw, 192, 168, 5, 1);
IP4_ADDR(&info.netmask, 255, 255, 255, 0);
wifi_set_ip_info(SOFTAP_IF, &info);
struct dhcps_lease dhcp_lease;
IP4_ADDR(&dhcp_lease.start_ip, 192, 168, 5, 100); //分配的網段ip開始
IP4_ADDR(&dhcp_lease.end_ip, 192, 168, 5, 105); //分配的網段ip結束
wifi_softap_set_dhcps_lease(&dhcp_lease);
wifi_softap_dhcps_start(); // 使能 soft-AP DHCP 服務
4.2 建立tcp
伺服器!
程式碼比較複雜,總的來說,先初始化
socket
,之後bind
繫結埠號,大家都知道瀏覽器的預設訪問的埠是80
,那麼這裡也肯定是80
,然後監聽這個埠,阻塞等待訊息!
int32 listenfd;
int32 ret = 0;
char input[1024] = { 0 };
char output[1024] = { 0 };
struct sockaddr_in server_addr, remote_addr;
int stack_counter = 0;
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY;
server_addr.sin_len = sizeof(server_addr);
server_addr.sin_port = htons(80);
printf("[XHLogUtils] Task_local_server init succeed!!! \n");
/* Create socket for incoming connections */
do {
listenfd = socket(AF_INET, SOCK_STREAM, 0);
printf("[XHLogUtils] Create socket for incoming connections !!! \n");
if (listenfd == -1) {
printf(
"[XHLogUtils] Create socket for incoming connections -1 !!! \n");
vTaskDelay(1000 / portTICK_RATE_MS);
}
} while (listenfd == -1);
/* Bind to the local port */
do {
ret = bind(listenfd, (struct sockaddr * )&server_addr,
sizeof(server_addr));
printf("[XHLogUtils] Create socket binding !!! \n");
if (ret != 0) {
printf("Create socket binding = -1 \n");
vTaskDelay(1000 / portTICK_RATE_MS);
}
} while (ret != 0);
do {
// Listen to the local connection
ret = listen(listenfd, 4);
printf("[XHLogUtils] Create socket listening !!! \n");
if (ret != 0) {
printf(
"[XHLogUtils] Create socket listening = -1 will close!!! \n");
vTaskDelay(1000 / portTICK_RATE_MS);
}
} while (ret != 0);
int32 client_sock;
int32 len = sizeof(struct sockaddr_in);
for (;;) {
printf(
"[XHLogUtils] Task_local_server block here waiting remote connect request !!! \n");
/*block here waiting remote connect request*/
if ((client_sock = accept(listenfd, (struct sockaddr * )&remote_addr,
(socklen_t * )&len)) < 0) {
printf("[XHLogUtils] acceptting < 0...\n");
continue;
} else {
printf("[XHLogUtils] acceptting > 0...\n");
}
}