esp32集成lua

参考

lua在线运行.luatos

lua菜鸟教程.runoob

嵌入式终端AtShell的精简版.csdn

工程目录

要下载 lua-5.4.2.tar.gz

bash 复制代码
lib/ 
└──lua-5.4.2/src/*
└──src
	 └──── LuaEngine.h
	 └──── LuaEngine.cpp
	 └────  LuaGPIO.h
	 └────  LuaGPIO.cpp
	 └────  main.cpp
platformio.ini 

源码

platformio.ini

bash 复制代码
[platformio]
src_dir = .

[env:pico32]
platform = espressif32
board = pico32
framework = arduino

monitor_speed = 115200
monitor_port = COM3

upload_port = COM3
upload_speed = 921600

build_flags =
    -Isrc
    -Ilib/lua-5.4.2/src
    -DLUA_32BITS

build_src_filter =
    +<src/>
    +<lib/lua-5.4.2/src/>
    -<lib/lua-5.4.2/src/lua.c>
    -<lib/lua-5.4.2/src/luac.c>

main.cpp

c 复制代码
#include <Arduino.h>
#include "LuaEngine.h"
#include "LuaGPIO.h"


struct Motor {
    int speed;
    float voltage;
    bool enable;
};

Motor  motor;
int    g_mode;
float  g_vol;
LuaField motorFields[] =
        {
                {
                        "speed",
                        LUA_FIELD_INT,
                        offsetof(Motor, speed),
                        0
                },


                {
                        "voltage",
                        LUA_FIELD_FLOAT,
                        offsetof(Motor, voltage),
                        0
                },


                {
                        "enable",
                        LUA_FIELD_BOOL,
                        offsetof(Motor, enable),
                        0
                }

        };


static int showMotorInfo(lua_State *L) {
    printf("g_mode=%d\r\n", g_mode);
    printf("g_vol=%f\r\n", g_vol);
    printf("motor.speed=%d\r\n", motor.speed);
    printf("motor.voltage=%f\r\n", motor.voltage);
    printf("motor.enable=%d\r\n", motor.enable);
    return 0;
}


void setup() {
    Serial.begin(115200);
    Lua.init();
    luaRegisterGPIO();
    //绑定变量
    LUA_BIND_INT(g_mode);
    LUA_BIND_FLOAT(g_vol);
    LUA_BIND_STRUCT(motor, motorFields, 3);
    //绑定函数
    LUA_BIND_FUNC(showMotorInfo);
    Serial.println("Lua Ready");
}


String script;

void loop() {
    while (Serial.available()) {
        String line = Serial.readStringUntil('\n');
        line.trim();
        if (line == "END") {
            Lua.run(script.c_str());
            script = "";
        } else {
            script += line;
            script += "\n";
        }
    }
}

LuaEngine.h

c 复制代码
#ifndef LUA_ENGINE_H
#define LUA_ENGINE_H

extern "C" {
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
}



#include <stddef.h>



enum LuaFieldType
{
    LUA_FIELD_INT,
    LUA_FIELD_FLOAT,
    LUA_FIELD_BOOL,
    LUA_FIELD_STRING
};


struct LuaField
{
    const char *name;
    LuaFieldType type;
    size_t offset;
    size_t size;
};


class LuaEngine
{
public:
    lua_State *L;
    void init();
    void run(const char *code);
    // 添加普通函数
    void registerFunction(const char *name,lua_CFunction func);
    // 创建模块
    void beginModule(const char *name);
    // 添加模块函数
    void addFunction(const char *name,lua_CFunction func);
    // 结束模块
    void endModule(const char *name);
    //变量绑定
    void bindInt(const char *name,int *ptr);
    void bindFloat(const char *name,float *ptr);
    void bindStruct(const char *name,void *ptr,const LuaField *fields,int count);
private:
    static int intIndex(lua_State *L);
    static int intNewIndex(lua_State *L);
    static int floatIndex(lua_State *L);
    static int floatNewIndex(lua_State *L);
    static int boolIndex(lua_State *L);
    static int boolNewIndex(lua_State *L);
    static int structIndex(lua_State *L);
    static int structNewIndex(lua_State *L);
};

//绑定
#define LUA_BIND_FUNC(func)               Lua.registerFunction(#func, func)
#define LUA_BIND_INT(v)                   Lua.bindInt(#v, &v)
#define LUA_BIND_FLOAT(v)                 Lua.bindFloat(#v, &v)
#define LUA_BIND_STRUCT(v,fields,count)   Lua.bindStruct(#v, &v, fields, count)

extern LuaEngine Lua;


#endif

LuaEngine.cpp

c 复制代码
#include "LuaEngine.h"
#include <Arduino.h>

LuaEngine Lua;


// 当前模块名字
void LuaEngine::init()
{
    L = luaL_newstate();

    luaL_openlibs(L);
}



void LuaEngine::run(const char *code)
{
    int ret = luaL_dostring(L,code);
    if(ret != LUA_OK)
    {
        Serial.print("Lua Error:");
        Serial.println(lua_tostring(L,-1));
        lua_pop(L,1);
    }
}



void LuaEngine::registerFunction(
        const char *name,
        lua_CFunction func
)
{
    lua_register(L,name,func);
}



void LuaEngine::beginModule(
        const char *name
)
{
    lua_newtable(L);
}



void LuaEngine::addFunction(
        const char *name,
        lua_CFunction func
)
{
    lua_pushcfunction(L,func);
    lua_setfield(L,-2,name);
}



void LuaEngine::endModule(const char *name)
{
    lua_setglobal(L,name);
}


//int绑定
struct LuaIntObject
{
    int *ptr;
};
int LuaEngine::intIndex(lua_State *L)
{
    LuaIntObject *obj =(LuaIntObject *)lua_touserdata(L,1);
    const char *key =lua_tostring(L,2);
    if(strcmp(key,"value")==0)
    {
        lua_pushinteger(L,*(obj->ptr));
        return 1;
    }
    return 0;
}
int LuaEngine::intNewIndex(lua_State *L)
{
    LuaIntObject *obj =(LuaIntObject *)lua_touserdata(L,1);
    const char *key =lua_tostring(L,2);
    if(strcmp(key,"value")==0)
    {
        *(obj->ptr)=luaL_checkinteger(L,3);
    }
    return 0;
}


void LuaEngine::bindInt(const char *name,int *ptr)
{
    LuaIntObject *obj =(LuaIntObject *)lua_newuserdata(L,sizeof(LuaIntObject));
    obj->ptr=ptr;
    lua_newtable(L);
    lua_pushcfunction(L,intIndex);
    lua_setfield(L,-2,"__index");
    lua_pushcfunction(L,intNewIndex);
    lua_setfield(L,-2,"__newindex");
    lua_setmetatable(L,-2);
    lua_setglobal(L,name);
}


//float绑定

struct LuaFloatObject
{
    float *ptr;
};

int LuaEngine::floatIndex(lua_State *L)
{
    LuaFloatObject *obj =(LuaFloatObject *)lua_touserdata(L,1);
    const char *key =lua_tostring(L,2);
    if(strcmp(key,"value")==0)
    {
        lua_pushnumber(L,*(obj->ptr));
        return 1;
    }
    return 0;
}



int LuaEngine::floatNewIndex(lua_State *L)
{
    LuaFloatObject *obj =(LuaFloatObject *)lua_touserdata(L,1);
    const char *key =lua_tostring(L,2);
    if(strcmp(key,"value")==0)
    {
        *(obj->ptr) =luaL_checknumber(L,3);
    }
    return 0;
}

void LuaEngine::bindFloat(
        const char *name,
        float *ptr
)
{
    LuaFloatObject *obj =(LuaFloatObject *)lua_newuserdata(L,sizeof(LuaFloatObject));
    obj->ptr=ptr;
    lua_newtable(L);
    lua_pushcfunction(L,floatIndex);
    lua_setfield(L,-2,"__index");
    lua_pushcfunction(L,floatNewIndex);
    lua_setfield(L,-2,"__newindex");
    lua_setmetatable(L,-2);
    lua_setglobal(L,name);
}



struct LuaStructObject
{
    void *ptr;
    const LuaField *fields;
    int count;
};



static LuaField *findField(LuaStructObject *obj,const char *name)
{
    for(int i=0;i<obj->count;i++)
    {
        if(strcmp(obj->fields[i].name,name)==0)
        {
            return (LuaField *)&obj->fields[i];
        }
    }
    return NULL;
}


int LuaEngine::structIndex(lua_State *L)
{
    LuaStructObject *obj =(LuaStructObject *)lua_touserdata(L,1);
    const char *key =lua_tostring(L,2);
    LuaField *field =findField(obj,key);
    if(field==NULL)return 0;
    uint8_t *addr =(uint8_t *)obj->ptr+field->offset;
    switch(field->type)
    {
        case LUA_FIELD_INT:  lua_pushinteger(L,*(int *)addr);break;
        case LUA_FIELD_FLOAT: lua_pushnumber(L,*(float *)addr);break;
        case LUA_FIELD_BOOL: lua_pushboolean(L,*(bool *)addr);break;
        case LUA_FIELD_STRING: lua_pushstring(L,(char *)addr);break;

    }
    return 1;
}


int LuaEngine::structNewIndex(lua_State *L)
{
    LuaStructObject *obj =(LuaStructObject *)lua_touserdata(L,1);
    const char *key =lua_tostring(L,2);
    LuaField *field =findField(obj,key);
    if(field==NULL) return 0;
    uint8_t *addr =(uint8_t *)obj->ptr+field->offset;
    switch(field->type)
    {
        case LUA_FIELD_INT: *(int *)addr =luaL_checkinteger(L,3);break;
        case LUA_FIELD_FLOAT: *(float *)addr =luaL_checknumber(L,3);break;
        case LUA_FIELD_BOOL: *(bool *)addr =lua_toboolean(L,3);break;
        case LUA_FIELD_STRING: strncpy((char *)addr,luaL_checkstring(L,3),field->size-1);break;
    }
    return 0;
}







void LuaEngine::bindStruct(const char *name,void *ptr,const LuaField *fields,int count)
{
    LuaStructObject *obj;
    obj =(LuaStructObject *)lua_newuserdata(L,sizeof(LuaStructObject));
    obj->ptr = ptr;
    obj->fields = fields;
    obj->count = count;
    lua_newtable(L);
    lua_pushcfunction(L,structIndex);
    lua_setfield(L,-2,"__index");
    lua_pushcfunction(L,structNewIndex);
    lua_setfield(L,-2,"__newindex");
    lua_setmetatable(L,-2);
    lua_setglobal(L,name);

}

LuaGPIO.h

c 复制代码
#ifndef LUA_GPIO_H
#define LUA_GPIO_H


void luaRegisterGPIO();


#endif

LuaGPIO.cpp

c 复制代码
#include <Arduino.h>

#include "LuaEngine.h"
#include "LuaGPIO.h"


static int lua_gpio_write(lua_State *L)
{
    int pin =luaL_checkinteger(L,1);
    int value =luaL_checkinteger(L,2);
    pinMode(pin,OUTPUT);
    digitalWrite(pin,value);
    return 0;
}



static int lua_gpio_read(lua_State *L)
{
    int pin =luaL_checkinteger(L,1);
    pinMode(pin,INPUT);
    lua_pushinteger(L,digitalRead(pin));
    return 1;
}



void luaRegisterGPIO()
{
    Lua.beginModule("gpio");
    //gpio.write(pin, value)
    Lua.addFunction("write",lua_gpio_write);
    // gpio.read(pin)
    Lua.addFunction("read",lua_gpio_read);
    Lua.endModule("gpio");
}

测试

读写全局变量

bash 复制代码
[20:47:29.752]发→◇g_mode.value=7;
g_vol.value=1.5;
motor.speed=5;
motor.voltage=5.3;
motor.enable=1;
showMotorInfo()
END
□
[20:47:29.765]收←◆g_mode=7
g_vol=1.500000
motor.speed=5
motor.voltage=5.300000
motor.enable=1

读按键

bash 复制代码
[18:25:11.359]发→◇s1=gpio.read(0)
print(s1); 
END
□
[18:25:11.367]收←◆1

算术运算

bash 复制代码
[18:27:31.432]发→◇s1=1+2
print(s1); 
END
□
[18:27:31.438]收←◆3

开灯

bash 复制代码
[18:29:51.824]发→◇gpio.write(2, 1)
END

关灯

bash 复制代码
[18:30:17.479]发→◇gpio.write(2, 0)
END
相关推荐
小努蛋17 小时前
linux编译openresty异常问题,lua_cjson.c:706:5: 错误: ‘for‘ 循环初始化声明只在 C99 或 C++ 模式下允许
开发语言·lua·openresty
rockey6273 天前
基于AScript的Lua脚本语言发布啦
c#·.net·lua·script·动态脚本
MC皮蛋侠客5 天前
Redis 系列(七):事务、Pipeline 与 Lua 脚本——从原子性到 Functions
数据库·redis·lua
l1t7 天前
用李红艳先生的DuckDB luajit插件批量计算数独
数据库·sql·lua·duckdb
智购科技自动售卖机厂家11 天前
从STM32到RK3588——自动售货机嵌入式主控方案的架构演进~YH
stm32·嵌入式硬件·物联网·架构·lua·零售·symfony
qq_3707730913 天前
Unity游戏xLua逆向实战:从SO版本识别到Lua脚本热替换全链路
游戏·unity·lua
星空露珠16 天前
迷你世界3.0API,事件监听
开发语言·数据结构·数据库·游戏·lua
ellis197017 天前
u3d插件xLua[二]例2:U3DScripting,例3:UIEvent分析
unity·lua
寒水馨19 天前
Windows下载、安装neovim-v0.12.4(附安装包nvim-win64.msi)
windows·编辑器·vim·lua·终端·lsp·neovim
烤代码的吐司君19 天前
Lua 脚本
开发语言·junit·lua