ESP8266, jak uruchomić skrypt Lua w kodzie arduino
Architektura „embedding”
• Szkic C/C++ (host) inicjalizuje lua_State
, otwiera standardowe biblioteki Lua i (opcjonalnie) udostępnia funkcje GPIO, Wi-Fi itd.
• Skrypt Lua jest pobierany (LittleFS/SPIFFS, PROGMEM, UART, HTTP…) i wykonywany przez luaL_dostring()
lub luaL_loadbuffer()+lua_pcall()
.
• Łączność dwukierunkowa:
– C++ → Lua: lua_getglobal(L,"nazwa"); lua_pcall(...)
.
– Lua → C++: funkcje C rejestrowane przez lua_pushcfunction()
/ lua_setglobal()
.
Instalacja (przykład biblioteki ESP8266-Arduino-Lua)
a) Arduino IDE > Szkic > Dołącz bibliotekę > Dodaj ZIP → wskaż ZIP z repozytorium github.com/fdu/ESP8266-Arduino-Lua
.
b) W menu Plik > Przykłady pojawi się zestaw demo, m.in. ExecuteScriptFromSerial
.
c) Wybierz płytkę „NodeMCU 1.0 (ESP-12E)” lub inną zgodną, ustaw 80 MHz i 4 MB (FS 1 MB).
Minimalny szkic hosta
#include <Arduino.h>
#include <LittleFS.h>
extern "C"{
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
}
lua_State *L;
void setup(){
Serial.begin(115200);
LittleFS.begin();
L = luaL_newstate();
luaL_openlibs(L);
// Prosta funkcja GPIO dostępna w Lua: set_pin(pin,val)
auto set_pin = [](lua_State *L)->int{
int pin = luaL_checkinteger(L,1);
int val = luaL_checkinteger(L,2);
pinMode(pin,OUTPUT);
digitalWrite(pin,val);
return 0;
};
lua_pushcfunction(L,set_pin);
lua_setglobal(L,"set_pin");
// wczytaj skrypt z pliku /script.lua
File f = LittleFS.open("/script.lua","r");
if(f){
String code=f.readString();
if(luaL_dostring(L,code.c_str())!=LUA_OK){
Serial.println(lua_tostring(L,-1));
lua_pop(L,1);
}
f.close();
}
}
void loop(){
// przykład cyklicznego wywołania funkcji Lua tick()
lua_getglobal(L,"tick");
if(lua_isfunction(L,-1)){
if(lua_pcall(L,0,0,0)!=LUA_OK){
Serial.println(lua_tostring(L,-1));
lua_pop(L,1);
}
}else lua_pop(L,1);
delay(1000);
}
Przykładowy script.lua
:
print("Lua start")
function tick()
set_pin(2, 0) -- LED ON
tmr.delay(100000) -- 100 ms
set_pin(2, 1) -- LED OFF
end
Firmware NodeMCU – kiedy warto
Jeśli cała logika ma być w Lua, prościej raz wgrać firmware NodeMCU i pracować wyłącznie w Lua (pliki init.lua
, tmr
, wifi
, mqtt
). Tracimy jednak dostęp do ekosystemu bibliotek Arduino.
Zarządzanie pamięcią i wydajnością
• Jeden lua_State
.
• Unikać dużych tablic tworzonych w pętli.
• Manualny GC: lua_gc(L,LUA_GCCOLLECT,0);
w dłuższych projektach.
• Zadania twardoreal-czasowe (ISR, komunikacja wysokiej prędkości) pozostawić w C/C++.
pinMode
, digitalWrite
, analogRead
, millis
, delay
, Serial.print
. lua_newtable(L);
lua_pushcfunction(L,myFunc);
lua_setfield(L,-2,"myFunc");
lua_setglobal(L,"myModule");
pio run -t uploadfs
).ExecuteScriptFromSerial
, by zweryfikować, że interpreter działa. lua_tostring
) i drukuj na Serial. ESP.getFreeHeap()
) po wykonaniu większych fragmentów Lua. math
, io
) w pliku luaconf.h
.double
), co redukuje RAM o ~4 kB.Możesz włączyć interpreter Lua w szkic Arduino dla ESP8266 – najprościej użyć biblioteki ESP8266-Arduino-Lua, która kompiluje standardowy Lua 5.3 i udostępnia podstawowe API Arduino w skryptach. Wgrywasz bibliotekę, inicjalizujesz lua_State
, ładujesz skrypt z LittleFS i wykonujesz go przez luaL_dostring()
. Pamiętaj o ograniczeniach RAM i wydajności; dla czystszej obsługi w Lua można zamiast tego wgrać firmware NodeMCU, lecz wtedy rezygnujesz z kodu C++. Wybór zależy od tego, czy Lua ma być tylko warstwą konfiguracyjną (embedding), czy głównym językiem aplikacji.