シリアルの代わりに Wifi インターフェイスを使用して、Lua スクリプトを NodeMCU にアップロードできますか?
私が見つけたチュートリアルと例はすべてシリアル インターフェイス、つまりケーブルを使用して NodeMCU をプログラムしていますが、何も接続せずに (スマートフォンまたはブラウザーを使用して) プログラムを変更したいと考えています。
すべてのモジュールをwifi経由でアップロードします。bootstrap.lua
まず、通常の方法 (USB 経由) でプログラムをアップロードします。このプログラムを使用して、実際の (より大きな) ペイロードをアップロードできます。ブートストラップ プログラムは次のとおりです。
ip, mask, host = wifi.sta.getip()
port, path, pgm = 80, "/upload", "u.lc"
file.remove(pgm) ; file.open(pgm, "w+") payloadFound = false
local conn = net.createConnection(net.TCP, 0)
conn:on("connection", function(conn)
conn:send("GET "..path.."/"..pgm.." HTTP/1.0\r\n".."Host: "..host.."\r\nConnection: close\r\nAccept: */*\r\n\r\n") end)
conn:on("receive", function(conn, payload)
if (payloadFound) then file.write(payload) file.flush()
else payloadOffset = string.find(payload, "\r\n\r\n")
if (payloadOffset) then
file.write(string.sub(payload, payloadOffset + 4)) file.flush() payloadFound = true
end end end)
conn:on("disconnection", function(conn) file.close() dofile(pgm) end) conn:connect(port,host)
最初の行は、ゲートウェイ サーバーを、プログラムのアップロード元の Web サーバーとして使用します。2 行目は、アップロードするプログラムのポート ( 80
)、パス ( /upload
)、および名前 ( ) を設定します。u.lc
次に、ファイルを取得し、最後に実行します (最後の行)。
これを実行する前に、ワイヤレス接続をアクティブにしておく必要があります。もちろん、Web サーバーはアクティブで、ペイロードは/upload/u.lc
.
当然、固定値を変更したり、動的にすることもできます。
ところで、圧縮形式は最初のアップロードを高速にするためにあります。オプションをluatool.py
使用してアップロードし--dofile
ます。
後でプログラム ( u.lc
) を更新するには、 を単純に繰り返しdofile("bootstrap.lua")
ます。
Myu.lc
は、ファイルの長いリスト (主に ) をアップロードするステージ 2 ブートストラップです.lc
。おそらく、この短い答えにはあまりにも関与しています。
最後に、これは大まかにhttps://github.com/Manawyrm/ESP8266-HTTP/に基づいていることに言及する必要があります。
HTH
サイズ制限のない別のソリューションがあります。また、他の Web サーバーを必要としないため、ワークステーションから直接ファイルを送信できます。以下のファイルは、チップへの/からのアップロードとダウンロードの両方を提供します。
編集: 以下のソース例を、ESP8266 および ESP32 で実行される、ファイルのアップロード、名前変更、バックアップ、削除、およびもちろん提供できるファイル マネージャーに開発しました (WiFi 接続の違いは抽象化されています) 。プロジェクトはここにあります。(NodeMCUに依存します。)
残念ながら、Web ブラウザーで使用される標準のアップロード スキームは使用されません。アップロードするための JavaScript ファイルが最後に提供されます。SendTo フォルダーに js へのショートカットを作成して、すべてのファイルのコンテキスト メニューの [送信先] オプションのリストに追加することは可能ですが、単一ファイルの選択しか処理できません。(選択した複数のファイルを処理するには、シェル拡張が必要です。)
通常のブラウザ ダウンロードをサポートしています。
このスキームは、特定の XMLHTTPRequest 規則に大きく依存していることに注意してください。つまり、POST の本文は、要求に続く 2 番目または後続のフレームで送信されます。そうでない場合、コードは最初のリクエストのペイロードで最初の \r\n\r\n を見つけ、その後のデータをファイルに追加する必要があります。
headerBlock = "\r\nContent-type: text/html\r\nConnection: close\r\nAccess-Control-Allow-Origin: *\r\nCache-Control: no-cache\r\n\r\n"
local currentFileName = ""
local isPostData = false
print("filexfer")
local srv=net.createServer(net.TCP, 60)
srv:listen(80,
function(conn)
local function writefile(name, mode, data)
if (file.open("temp_" .. name, mode) == nil) then
return -1
end
file.write(data)
file.close()
end
conn:on("disconnection",
function(conn)
isPostData = false
end
)
conn:on("sent",
function(conn)
currentFileName = ""
isPostData = false
conn:close()
end
)
conn:on("receive",
function(conn, payload)
tmr.wdclr();
local s, e, m, buf, k, v
local tbl = {}
local i = 1
local retval = ""
if isPostData then
writefile(currentFileName, "a+", payload)
else
s, e = string.find(payload, "HTTP", 1, true)
if e ~= nil then
buf = string.sub(payload, 1, s - 2)
for m in string.gmatch(buf, "/?([%w+%p+][^/+]*)") do
tbl[i] = m
i = i + 1
end
m = nil
if #tbl > 2 then
local cmd = tbl[2]
if (tbl[3] ~= nil) and (tbl[3] ~= "/") then
currentFileName = tbl[3]
--else return an error
end
if (cmd == "put") then
writefile(currentFileName, "w+", "")
end
if (cmd == "append") then
isPostData = true
end
if (cmd == "persist") then
file.rename("temp_" .. currentFileName, currentFileName)
end
buf = ""
if retval == nil then
retval = "[nil]"
end
buf = "HTTP/1.1 200 OK" .. headerBlock .. retval
else
local filename = "index.html"
if tbl[2] ~= nil and tbl[2] ~= "/" then
filename = tbl[2]
end
require("fileupload")(conn, filename)
buf = ""
end
conn:send(buf)
end
end
end
)
end
)
これは fileupload.lua で、行 75 付近の require の呼び出しによって参照されます (チップが要求元のホストにファイルを送信しているため、upload です)。通常のブラウザーを使用して、任意のサイズのファイルを簡単にダウンロードできます。ファイル名が渡されない場合、デフォルトは「index.html」になります。
local module =...
return function(conn, fname)
local buf
tmr.wdclr()
if file.list()[fname] ~= nil then
file.open(fname, "r")
buf = "HTTP/1.1 200 OK" .. headerBlock
else
file.open("error404.html", "r")
buf = "HTTP/1.1 404 FILE NOT FOUND" .. headerBlock
end
conn:on ("sent",
function(sck)
function sendfile(sck)
buf = file.read(255)
if buf ~= nil then
sck:send(buf)
else
sck:close()
if module ~= nil then
package.loaded[module] = nil
end
module = nil
return
end
end
sck:on("sent", sendfile)
sck:on("disconnection",
function(sck)
print("[disconnection fileupload.sendfile]", node.heap())
end
)
sendfile(sck)
end
)
conn:on ("receive",
function(sck, pl)
sck:close()
end
)
if buf == nil then
buf = ""
end
conn:send(buf)
end
これは、チップへのアップロードに使用されるクライアント側の JavaScript ファイルです。アップロードするファイルの完全パスまたは相対パスを最初/唯一の引数として渡します。(引数が渡されない場合、エラーがスローされます。)
var filepath = WScript.Arguments(0);
var fso = new ActiveXObject("Scripting.FileSystemObject");
var str = fso.OpenTextFile(filepath, 1);
var file = fso.GetFile(filepath);
var filename = file.Name;
var buf = "";
var xhr = new ActiveXObject("MSXML2.XMLHTTP.6.0");
xhr.open("GET", "http://192.168.4.1/put/" + filename, false);
xhr.send();
while (str.AtEndOfStream == false)
{
buf = str.read(255);
xhr.open("POST", "http://192.168.4.1/append/" + filename, false);
xhr.send(buf);
}
str.close();
xhr.open("GET", "http://192.168.4.1/persist/" + filename, false);
xhr.send();
はい、可能です。これは自家製のオプションのようなものですが、ある程度機能します。もちろん、唯一の制限はサイズですが、それ以外はかなりうまく機能します。を見てみましょう:
http://www.instructables.com/id/ESP8266-WiFi-File-Management/
PHP プログラムを作成する方法が必要です (私は C# で作成しました) 別の言語でコードを作成できない場合は、このユーザーが作成したものをダウンロードして再利用し、独自の PHP サーバーを使用できます。行く。
ご不明な点がございましたら、お問い合わせください。
上記のソリューションのバリエーションがあります ( http://www.instructables.com/id/ESP8266-WiFi-File-Management/ ) が、PHP Web サーバーの代わりにデスクトップ .NET アプリケーションが使用されますhttps://github.com/ Orudnev/.Net-WiFi-File-Manager-for-ESP8266 . Web サーバーをインストールしたくない場合は、FileManager.exe アプリケーションを起動するだけで十分です。