6
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

esp32-arduinoでluaを使う

Last updated at Posted at 2018-06-16

概要

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

参考

6
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?