2
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

posted at

updated at

Organization

esp32-arduinoでluaを使う

概要

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の制御が書けるので応用が広がりそうです。

参考

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
2
Help us understand the problem. What are the problem?