概要
esp32-arduino環境でluaを実行する方法を紹介します
単にesp32でluaを動かすソリューションはたくさんありますが、esp32 Arduinoでluaを使う方法がなかったので調べました。
Arduino IDEではなくplatformioを使った方法です。
ソースコード
- lib/
- lua/
- 本家リポジトリからクローンしてきただけ
- src/
- main.ino
- platformio.ini
Luaのための設定をbuild_flagsで行います。
esp32はlong longをサポートしていないようなのでLUA_32BITSを有効にします
またlua_writestring, lua_writestringerrorというLuaが何かを出力するための関数が必要なので登録しておきます(あとで定義します)
platformio.ini
[env:esp32]
platform = espressif32
board = esp32dev
framework = arduino
upload_speed = 921600
lib_deps =
board_f_cpu = 240000000L
board_f_flash = 80000000L
build_flags =
-DLUA_32BITS=1
-D"lua_writestring(s,l)=gprint(s)"
-D"lua_writestringerror(s,l)=gprint(s)"
src/main.ino
#include "luafunc.h"
void setup(){
Serial.begin(115200);
// Luaのコンテキストの作成
lua_State *L = luaL_newstate();
// Luaの標準関数群の登録
luaL_openlibs(L);
// ===== Lua文字列の評価 ====
if(luaL_dostring(L, "\
function mul(a, b)\
return a * b\
end\n")){
printf("run error %s\n", lua_tostring(L, -1));
}
// ===== C言語関数の登録 ====
// l_add関数をaddという名前で登録
lua_register(L, "add", l_add);
// l_print関数をprintという名前で登録
lua_register(L, "print", l_print);
// ===== Lua文字列の評価 + C言語関数の呼び出し ====
if(luaL_dostring(L, "\
print(\"Hello Lua!\")\
")){
printf("run error %s\n", lua_tostring(L, -1));
}
// ===== C言語からLua関数の呼び出し ====
// mul関数を呼び出し
lua_getglobal(L, "mul");
lua_pushnumber(L, 4); //引数1
lua_pushnumber(L, 5); //引数2
if (lua_pcall(L, 2, 1, 0)) {
fprintf(stderr, "cannot exec add. %s\n", lua_tostring(L, -1));
return;
}
// 戻り値の確認
if (lua_isnumber(L, -1)) {
int ret = lua_tointeger(L, -1);
printf("ret=%d\n", ret);
}
lua_pop(L, 1); // 戻り値を捨てる
lua_close(L);
}
void loop(){
}
systemは本来はOSのコマンドを実行することを期待しているようですが、esp32でそのようなことはできないので何もしない関数を作っておきます。
gprintはplatformio.iniで指定して、luaがなにか文字を出したいときに使う関数です。
src/luafunc.h
extern "C" {
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
int gprint(char* s){
printf(s);
return 0;
}
int system(const char* c){
//none
return 0;
}
int l_print(lua_State* L){
const char* s = lua_tostring(L, 1);
Serial.println(s);
return 0; // 戻り値なし
}
int l_add(lua_State* L){
int a = lua_tointeger(L, 1);
int b = lua_tointeger(L, 2);
lua_pushinteger(L, a + b);
return 1; // 戻り値が1つ
}
}
おわりに
このデモでは特に面白いことはしていませんが、LuaでESP32の制御が書けるので応用が広がりそうです。
参考
- Arduino を CLI で開発する #PlatformIOが素晴らしい
https://qiita.com/zakkied/items/cbbccdc1be4e4da9f7f9 - C と lua の連携方法メモ
https://qiita.com/miuk/items/82e5566ea01313a8b1af