1. 程式人生 > >NODEMCU除錯心得6

NODEMCU除錯心得6

關於網路協議 HTTP

按照約定,這次要講非常exciting的內容,網路協議Networking protocols。

  • 這部分並不好寫,內容很龐雜,會分成若干部分。

  • 網路協議我們在前面已經提及,TCP/IP協議就是最重要的網路協議。在AT指令和lua韌體的例程中,我們建立了TCP/IP的客戶端和伺服器,實現無線通訊和遠端控制。在電腦端,我們可以用TCP/IP的網路除錯助手,也可以用c++或python自己編寫客戶端和伺服器,和nodemcu通訊。

但是今天我們就要談談更exciting,也是應用最廣泛的網路協議:

超文字傳輸協議HTTP

  • 對,就是你上網最先輸的那四個字母。

首先我們要把HTTP,TCP和IP的關係理一理,瞭解什麼是網路協議。

  • 按慣例,為了保持文件的獨立性,先把關鍵資料放上。

資料篇

Nodemcu

Lua

網路協議

這兩本書是TCP/IP協議的經典之作,因為版權問題,恕在下不能給出連結
- computer networking, a top-down approach. Jim Kuross & Keith Ross

不少國外大學的制定教材,通俗易懂,入門必備
- TCP/IP Illustrated, Volume 1, The Protocols. W. Richard Stevens

被譽為網路聖經的第一卷,經典中的經典,網路工程師人手一本。不過內容組織上和上一本正相反,是從下到上

HTML和CSS

既然要講超文字傳輸協議,就不能不提超文字標記語言HTML,相信大家都有了解
- Head First HTML with CSS. Elisabeth Freeman & Eric Freeman.

本來學語言就很痛苦,還要看學霸白富美和高富帥秀恩愛,實在有點不能忍。

但是,這本書確實經典,在排行榜上一直領先。排版非常活剝,效果也不錯,可以很快上手

如果想更深入,可以看下面這兩本,主要針對HTML的具體樣式:CSS(層疊樣式表):
- Css Mastery Advanced Web Standards Solutions. Andy Budd with Cameron Moll and Simon Collison
- CSS, the Definitive Guide.

Eric A. Meyer

HTTP 與網路協議

HyperText Transfer Protocol, HTTP

即超文字傳輸協議,是網際網路的核心。 我們上網happy刷的網頁都是基於HTTP協議。

HTTP和Hypertext出現之前,網路只是用在大學和研究機構中,傳個實驗資料或資料什麼的,並沒有什麼WWW全球資訊網和花花綠綠的網頁。

  • 所謂Hypertext超文字,就是一堆超連結組成的文字。比如說本教程前面提供了一堆資料連結,就可以算是超文字。
  • 最常見的超文字就是網站網頁,通過超連結形成有組織和層級的資料庫

HTTP協議位於網路的頂層

,屬於應用層協議,凌駕於TCP(傳輸控制協議)和IP(網路協議)之上。

  • 後兩者屬於傳輸層和網路層。傳輸層位於網路層之上。

  • 網路層的再下一層是連連結層,主要是wifi,光纖燈物理裝置的驅動協議,實現與底層硬體的連線和控制。

  • 最下一層就是物理層,也就是wifi,光纖,乙太網,路由器等硬體物理裝置。

以上就是網路協議的五層模型

而TCP/IP協議簇

就是與五層網路模型配套的各層網路協議包。此外還有基於OSI模型的七層網路模型

簡單講, TCP/IP協議簇的運作模式

就是傳輸網路資訊的層層打包。

網路應用基於網路資訊的傳輸,實現客戶端與伺服器之間的互動。
位於最高層的應用發出書面指示。而最底層的硬體就是快遞員,負責把這封信給送出去。

  • 為了實現某一功能,某伺服器的網路應用層(比如nodemcu)要向客戶端(比如手機上的瀏覽器)傳送一串資訊,指定資訊屬於HTTP協議。

    資訊被應用層打包,資訊前加上應用層的標籤資訊,明確屬於哪種包裹(應用層協議除了HTTP,還有FTP,SMTP...)

  • 傳輸層接到應用層指示,在客戶端和伺服器之間開闢一條傳輸通道,它把很長的資訊打包成一小段小一段,並且有一整套的校驗機制,確保資訊可靠傳送。

    資料分割後二次打包,頭部附上響應傳輸層標籤,明確快遞收件人和寄件人,確定了快遞路線,控制寄件時間,並且監督快遞安全送達

  • 網路層接到傳輸層指示,負責把資料從傳送端傳輸到接收端。傳送端和接收到都有唯一的IP地址,就像快遞收件地址和寄件地址。

    資訊三次打包,加上IP資訊,明確收貨地址和寄件地址

  • 有了收件地址和寄件地址,就需要這兩個地址派快遞員送信,就是伺服器nodemcu的wifi裝置和客戶端(手機)的wifi裝置。

    資料四次打包,加上客戶端和服務端的wifi硬體資訊,明確誰是快遞員。

  • 上述手續辦完之後,快遞員(硬體裝置)會忠於職守,把快遞送達。

lua韌體提供了對各層網路協議的支援,底層協議不用我們關心。我們要關注的是應用層的協議,或者再下一層的傳輸層協議。

應用層HTTP是基於傳輸層TCP協議的。與TCP傳輸一樣,HTTP也分為客戶端和伺服器端,這裡特指nodemcu作為HTTP的客戶端和伺服器。

lua韌體中有現成的HTTP客戶端模組,對於伺服器端,大部分需要自己編寫。接下來,我們就看一個HTTP伺服器例程。

Step 1

韌體資料夾中的HTTP示例程式我沒有除錯通過,因此我參考的是另一個版本的伺服器程式,程式包可以點這裡下載,檔名是dht11_webserver.lua

為了介紹HTML,HTTP和TCP協議,我對原始碼進行了修改
- 示例程式是用TCP/IP協議實現的HTTP伺服器,在電腦和手機的瀏覽器裡輸入nodemcu的IP地址,就可以進入伺服器
- 本伺服器網頁,也就是HTML檔案,包括三個部分:標題,圖片和段落。每重新整理一次,伺服器返回nodemcu當前剩餘的記憶體
- 伺服器程式碼如下,檔名為LUAserver.lua

        -- LUA Webserver --

        dofile("import_image.lua")

        srv=net.createServer(net.TCP)
        srv:listen(80,function(conn)
            conn:on("receive",function(conn,payload)
                print("Heap = "..node.heap().." Bytes")
                print("Print payload:\n"..payload)

                -- write HTML
                head =   "<html><head><title>ESP8266 Webserver</title></head>"
                body =   "<body><h1>Welcome to Nodemcu</h1>"
                para =   "<p>The size of the memory available: "..tostring(node.heap()).." Bytes </p>"
                image1 =  "<img src=\""..png1
                image2 =  png2.."\" width = \"50\" height = \"50\" />"
                ending = "</body></html>"

                reply1 = head..body..image1
                reply2 = image2..para..ending
                payloadLen = string.len(reply1) + string.len(reply2)

                conn:send("HTTP/1.1 200 OK\r\n")
                conn:send("Content-Length:" .. tostring(payloadLen) .. "\r\n")
                conn:send("Connection:close\r\n\r\n")
                conn:send(reply1)
                conn:send(reply2)

                collectgarbage()
            end)

             conn:on("sent",function(conn)
                conn:close()
            end)

        end)

下面對程式碼進行解釋

首先看HTML部分,

程式第八行(算上註釋)-- write HTML以下的內容,到空白行為止

  • head..HTML檔案以<html>開始,</html>結束。檔案開頭要有<html>,

    之後的第一部分是head,以<head>開始,</head>結束。這裡用來確定標題title

    title的格式是<title>...</title>,title的內容ESP8266 Webserver會顯示在網頁的標籤上

  • body..body部分是HTML的主體,同樣以<body>開始,</body>結束

    <h1> 代表第一個標題,格式是<h1>...<\h1>

  • para.. 標題以下是段落部分,以<p>開始,</p>結束

    這裡要顯示nodemcu的剩餘記憶體大小,用函式node.heap()得到數值,並用tostring()轉換成字串,再用..將前後的字串連成一體

  • image1..,image2.. 是HTML插入的影象,本來是一句,因為太大分成了兩部分。

    最簡單格式為<img src="XX.XX">,XX.XX代表影象名和字尾,比如nodmcu.png,圖片檔案通常和HTML檔案放在一起,或放在專門的資料夾。

    但是,在nodemcu裡不能這樣做

    nodemcu檔案系統中,並沒有存放HTML文件。而傳送的HTML是作為程式碼內嵌在程式中。

    同樣,影象檔案也作為程式碼內嵌到程式中.我們可以將png等影象檔案轉換成base64編碼,影象檔案用很長的字串表示。

    在另一個lua檔案import_image.lua中,我們定義了影象的base64字串png1和png2.檔案有1k多,太大所以分成了兩個。當本程式執行時,首先dofile(“import_image.lua”),得到影象字串

    結尾處的width = \"50\" height = \"50\"定義影象的大小,50兩邊"前要加轉義符/,否則編譯會報錯

  • end..部分用</body></html>結束body部分和整個html

    然後我們從頭開始看

  • dofile()用來匯入html的image資料,前面已經講過

  • net.createServer()建立TCP伺服器,這是建立HTTP伺服器的基礎
  • srv是建立的service伺服器子模組,下面有方法listen(),也就是監聽函式

    listen()監聽函式是整個程式的主體,一直到程式碼最後一個end)結束

    listen()的回撥函式function(conn)體內包含了兩個事件觸發函式conn:on("receive"...end)conn:on("send"...end),

    • 二者分別在接收到客戶端的資訊後和伺服器傳送訊息後執行其內部的回撥函式function(conn,payload)function(conn)

    • 最內層的兩個匿名函式function(conn,payload)function(conn)可以呼叫最上層封閉函式的變數,connpayload

      conn代表TCP協議建立的從伺服器到客戶端的連線通道

      payload是伺服器從客戶端接收到的訊息或請求

  • conn:on("receive",...end)中的recieve,代表事件是接收到客戶端的資訊,回撥函式function(conn,payload)的兩個變數上面已經解釋過了,下面的程式碼只到第一個end),都是它的body

  • 兩行print()函式分別顯示nodemcu還有多少記憶體,以及接收到的客戶端資訊payload
  • head..ending..是html程式碼,上面已經解釋過了
  • HTML程式碼比較大,而TCP一次發包的大小不能大於1460byte,所以我們手動把程式碼打成兩個包,reply1reply2
  • 並且統計了兩個包的總長度,定義了payloadLen。這個payload是伺服器要發給客戶端的payload,上一個payload是從客戶端發過來的。

  • 下面有五個連續的conn:send(),代表伺服器要向客戶端通過HTTP協議傳送payload資訊。也是HTTP協議對paylaod資訊的打包過程。

    後兩條是被打包的reply1和reply2 我們要傳輸的HTML文件。

    前三條是HTTP的頭部資訊,第一條明確是HTTP,第二條確定打包資訊payload的長度,第三條關閉HTTP傳輸

    • 在確認客戶端收到完整的資訊後才會關閉TCP連線。
  • collectgarbage()l收集垃圾,釋放記憶體

  • conn:on("send"..)當上述payload也就是HTML檔案被髮送,就把TCP的conn連線關閉。

    這樣從客戶端接收到payload資訊,到向客戶端傳送payload資訊,就完成了一次對話過程

    當瀏覽器(也就是客戶端)重新整理一次,客戶器重新向伺服器傳送paylaod,上述對話過程會再進行一次。但是伺服器不會儲存每次對話的相關資訊。

Step2

接下來我們開始實際操作。
- 首先請確認nodemcu已經連上了你家路由。請參考關於lua關於nodemcu的點點滴滴相關內容。
- 上傳import_image.lua,操作如下圖。這是伺服器HTML的內嵌圖片base64程式碼,我把這個檔案和本文件一起上傳到論壇上。注意要用Upload,不要用Save to Esp
這裡寫圖片描述
fig1

你也可以上傳自己的base64程式碼,有網站可以將圖片線上轉換成base64。

但是這個圖片不能太大。最好不要超過2k,否則會報錯。因為記憶體裡有lua的直譯器執行,空閒的記憶體也就10k左右。

同時代碼要打包放到幾個字串中。因為send一次傳送量不能超過1460byte

  • 上傳LUAserver.lua文件(step1中的程式碼),如果用Save to Esp有時會報錯,重啟後多試幾次
  • 執行dofile(“LUAbserver.lua”)命令,(用Save to Esp會自動執行)
  • 開啟電腦或手機瀏覽器,確保已經連線無線。輸入nodemcu的IP地址。(connect_wifi.lua程式中會給出,一般是192.168.1.XXX)
  • 在瀏覽器上回顯示如下介面:
    這裡寫圖片描述
    fig2

  • 在esplore介面上回顯示nodemcu的可用記憶體,以及從瀏覽器客戶端收到的payload資訊,如下

    > Heap = 13608 Bytes
    Print payload:
    GET / HTTP/1.1
    Host: 192.168.1.7
    User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
    Accept-Encoding: gzip, deflate
    Connection: keep-alive
    Cache-Control: max-age=0
    
  • 每次重新整理網頁,伺服器就返回nodemcu當前的可用記憶體,它是動態變化的。

這部分就到這裡,

這一節我們介紹了網路協議及其運作方式,給出一個nodemcu伺服器例程,順便介紹了HTML的基本語法。

  • nodemcu的可用記憶體不大,因此HTML中嵌入不了太大的圖片。建議最好不嵌入圖片,本文只是一個示例。

  • nodemcu作伺服器的最大好處是多個使用者端可以訪問,比如手機,平板,電腦,只要有瀏覽器就能訪問。

  • 它的缺點就是記憶體小,因此只能作很簡單的伺服器,結構太複雜或者嵌入大圖片,就會耗盡記憶體。

  • 本節的例程是用伺服器傳輸nodemcu的狀態資訊,當然也可以傳遞從外設的資訊,感興趣的朋友可以自己試一試。

下一節,講如何在客戶端上控制nodemcu的外設,例如控制gpio操縱nodemcu上的LED,實現遠端開關功能。

相關推薦

NODEMCU除錯心得6

關於網路協議 HTTP 按照約定,這次要講非常exciting的內容,網路協議Networking protocols。 這部分並不好寫,內容很龐雜,會分成若干部分。 網路協議我們在前面已經提及,TCP/IP協議就是最重要的網路協議。在AT指令和lua韌體

NODEMCU除錯心得2

關於LUA 和智慧雲平臺相似,nodemcu就是esp12的核心板加一個USB轉串列埠模組,晶片貌似比普通的USB轉TTL模組上的靠譜,電路板上用了比較貴的鉭電容,穩定性估計不錯。 雖然號稱是LUA專用平臺,但是你刷好韌體,用其它的SDK開發一點問題

NODEMCU除錯心得7

關於網路協議 HTTP 2 上一節,我們用nodemcu伺服器向客戶端傳送nodemcu的記憶體資訊。這一節反過來,我們介紹如何用客戶端控制nodemcu。 先介紹一個簡單的例子,用客戶端控制nodemcu的GPIO4,實現nodemcu的藍色LED遠端開關

NODEMCU除錯心得1

NODEMCU除錯心得 網上沒有nodemcu的中文資料,英文資料也比較零碎。結合自己的除錯過程,整理一個。 資料篇 github上的英文入門教程,一共三頁,強烈推薦。 有點混亂的官方

團隊項目心得(6.15)

後端 時間 跳轉 nbsp 比較 team 掌握 規劃 等等 之前嘗試使用了Teambition,效果還算是不錯,各種任務需求都比較清晰。後端目前的任務算是,開始紮實地一個功能一個功能地實現了。過程中出現了各種問題,css文件無法加載,超鏈接不能跳轉等等,在詳實的文檔幫

shell指令碼除錯心得

1 將指令碼產生的結果檔案和臨時檔案放入自己的資料夾下,不要放在原來的地方,好一起檢視 2 在除錯的時候,可以吧臨時檔案的刪除命令註釋掉,檢視臨時檔案具體的生成形式 3 在除錯的不明白的地方 用echo $var 4 用日誌txt,儲存echo的記錄和錯誤記錄 sh /xusywap.s

STM32F103C8t6和MCP2515CAN除錯心得

前言     由於STM32微控制器自帶CAN控制器,所以STM32和MCP2515 CAN控制器聯合使用的場景不多。正好一個特殊的需求使用了MCP2515和STM32,在這裡說一下硬體連結需要注意的地方。 1.硬體     主控晶片STM32F1

js斷點除錯心得總結

js斷點除錯心得 1.斷點除錯是啥?難不難? 進入工作中,才知道了斷點除錯是多麼的重要,作為一名程式設計師,必須要學會熟練使用除錯工具,斷點除錯就是經常用到的,斷點除錯其實並不是多麼複雜的一件事,簡單的理解無外呼就是開啟瀏覽器,開啟sources找到js檔案,在行號上點一下罷了

STM32 低功耗 除錯心得

MCU在進入STOP模式的時候,GPIO的狀態都是保持在進入低功耗模式之前的狀態,在最小系統中,MCU的GPIO都是懸空的,所以設定為何種狀態都不會影響到功耗。但當連線到外設後,外設的電平狀態和所連線的GPIO不一致的時候,就會產生電流。也就是所謂的漏電流!   解決辦法:將GPIO的對應GPI

除錯心得

主要記錄對做基於stm32F103自平衡小車除錯時候的一些深刻感悟(以後會繼續更新) 1.寫完MPU6050時,測資料資料顯示一次(或者一直為零)然後就不動了。 發現這個問題後,我先是除錯程式碼發現是dmp庫中的dmp_read_fifo(gyro, accel, quat, &se

(C/C++學習心得)6.陣列指標和指標陣列

說明:int (*p)[4] 和 int *p[4](陣列指標和指標陣列),如果你是一個初學者,也許當你看到這兩個名詞的時候,已經懵了。其實,只要你理解了其中的含義.這兩個名詞對你來說會相當簡單並且很有趣,下面,我們就來深入探討一下究竟什麼是陣列指標,什麼是指標陣列。 一.指標陣列 1.前面我們已經學過陣列

AM437x AM335x gpio驅動除錯心得

#include <linux/init.h> #include <linux/module.h> #include <linux/leds.h> #include <linux/io.h> #include <linux/

教你編譯除錯Elasticsearch 6.3.2原始碼

前言 想深入理解 Elasticsearch,閱讀它的原始碼是很有必要的,一來可以瞭解它內部的具體實現,有助於調優,二來可以瞭解優秀開源專案的程式碼架構,提高我們的程式碼架構能力等 閱讀Elasticsearch原始碼的第一步是搭建除錯環境,然後作者在這個過

PCIe除錯心得_DMA part1

1.PCIe的DMA介紹在PCIe中需要使用DMA的專案,一定要先看XAPP1052,裡面包含一個DMA的參考設計,對初學者有極大的幫助。 XAPP1052中包含FPGA原始碼和驅動程式原始碼,其中FPGA原始碼最主要的檔案為:1、《TX_ENGINE.v》:是產生TLP包的邏輯,包含讀TLP請求用於DMA

【QT】除錯心得(1)

1、報錯“filed has incomplete type QIcon”。 前向宣告的類或結構體只能用來定義指標或引用。 例如: private: QIcon * m_iconStart; QIcon *m_iconStop; (*

使用Eclipse基於Maven的Spring MVC 除錯心得(二)--- Spring配置

3.Spring專案的web.xml配置 在Dynamic Web Project中,web.xml可謂是最重要的檔案之一,它的配置包括:1)請求地址(url-pattern)與處理類(servlet-class)之間通過servlet-name來進行的對映(servle

串列埠WiFi的除錯心得

WiFi模組的微控制器開發 一直以來都在開發微控制器,最近有智慧家居的案子需要開發用到WiFi模組,於是剛剛上手RAK411;經過半年時間的瞭解/學習,總結如下: 一、概念: 1)、Wi-Fi:大部分微控制器工程師的理解就是手機/筆記本上面和家裡路由器的這些東西叫WiFi,

關於伺服器端程式設計的程式除錯心得

對某些需要在編譯以後放到伺服器端或者叢集執行的程式,在沒有除錯工具的情況下,解決問題的方法主要是通過輸出語句(將info輸出到日誌中),分為以下步奏: 1、對問題的定位 將程式分為幾大邏輯,根據順序逐個大邏輯進行測試(不要放過任何一部分,不要認為某個部分一定不會出錯,往往出

DSP除錯心得

1、 (1)、報錯如下: -------------------------  tam2012112701.pjt - Debug  ------------------------- [Linking...] "C:\CCStudio_v3.3\C2000\cgt

SDL除錯心得(MFC SDL 視窗放大後 畫面卡死)

同一個視窗控制代碼在多次使用SDL_CreateWindowFrom和SDL_DestroyWindow以後,發現程式執行正常,但視訊顯示不出來的問題。 第一次將Hwnd傳遞給SDL_CreateWindowFrom,建立一個顯示視窗給SDL,隨後在不使用的時候,呼叫SDL_DestroyWindow