Lua 模块参考
Ameba-Claw 的 Lua 运行时提供两类内置扩展库:驱动层模块(lua_driver_*)直接封装片上外设;应用层模块(lua_module_*)提供系统服务与高级功能。所有模块均通过标准 require() 加载,无需手动链接。
运行环境
Lua 运行时有两个独立环境:
Skill 沙箱:执行 Skill 脚本时的受限环境。
io、os、debug等标准库以及load、loadfile、dofile、rawget、rawset、rawequal、rawlen等函数被移除。可用标准库:base、package、coroutine、table、string、utf8、math。REPL 环境:通过
AT+CLAW=lua进入的交互式环境,无沙箱限制,可访问全部模块。
下表汇总各模块的可用范围:
模块 |
功能摘要 |
Skill |
REPL |
|---|---|---|---|
|
引脚输入/输出/中断回调 |
✓ |
✓ |
|
I2C 主从通信 |
✓ |
✓ |
|
SPI 主从传输 |
✓ |
✓ |
|
硬件实时时钟 |
✓ |
✓ |
|
屏幕绘图(矢量 + 文字) |
✓ |
✓ |
|
录音与播放 |
✓ |
✓ |
|
Capability 调用桥接 |
✓ |
✓ |
|
JSON 解析与序列化 |
✓ |
✓ |
|
系统时间与延时 |
✓ |
✓ |
|
VFS 文件读写 |
✓ |
✓ |
|
软件定时器(后台执行代码) |
✓ |
✓ |
|
UDP 数据包收发 |
✓ |
✓ |
|
向 Agent 消息总线发布事件 |
✓ |
✓ |
|
事件驱动式按键检测 |
✓ |
✓ |
|
USB 大容量存储文件读写 |
✓ |
✓ |
|
USB UVC 摄像头帧采集 |
✓ |
✓ |
|
UART 串口收发 |
— |
✓ |
|
PWM 波形输出 |
— |
✓ |
|
LCD 控制器底层操作 |
— |
✓ |
|
GT911 触摸屏事件 |
— |
✓ |
|
硬件精确计时(微秒级) |
— |
✓ |
|
WS2812 可编程 LED 灯带 |
— |
✓ |
|
DHT11 温湿度传感器 |
— |
✓ |
|
模拟量电压采集(单次/连续) |
— |
✓ |
|
片内电容触摸按键检测 |
— |
✓ |
|
红外原始波形发送/接收 |
— |
✓ |
|
片内硬件温度监测 |
— |
✓ |
|
Wi-Fi 接入点连接管理 |
— |
✓ |
驱动层模块
驱动层模块封装片上外设的硬件寄存器操作,提供 Lua 可直接调用的外设访问接口。
gpio
控制通用输入/输出引脚,支持读写电平、配置上下拉电阻,以及注册边沿中断回调。
函数 |
说明 |
|---|---|
|
配置方向;dir: |
|
写入电平;val: |
|
读取当前引脚电平 |
|
上下拉;pull: |
|
配置中断触发沿;edge: |
|
使能引脚中断 |
|
禁止引脚中断 |
|
注册中断回调函数 |
|
取消回调注册 |
|
处理积压的中断事件,需在主循环中调用 |
local gpio = require("gpio")
-- 输出模式:驱动 LED
gpio.set_direction("PA_22", "out")
gpio.set_level("PA_22", 1)
-- 输入模式:读取按键状态
gpio.set_direction("PB_5", "in")
gpio.set_pull("PB_5", "up")
local level = gpio.get_level("PB_5")
-- 边沿中断回调
gpio.set_irq("PB_5", "fall")
gpio.irq_enable("PB_5")
gpio.on("PB_5", function(pin) print(pin .. " triggered") end)
i2c
以主设备(Master)身份访问 I2C 总线,支持总线扫描、单字节及块读写,同一总线可挂多个设备句柄。
函数 |
说明 |
|---|---|
|
获取 I2C 总线句柄(内部引用计数,可多次调用) |
|
返回总线上所有响应设备的 7 位地址列表 |
|
创建指向指定地址的设备句柄;addr 为 7 位整数 |
|
释放总线(引用归零时才反初始化) |
|
从设备读取 len 字节 |
|
读取单字节(0–255) |
|
向设备写入字符串数据 |
|
写入单字节 |
|
释放设备句柄 |
local i2c = require("i2c")
local bus = i2c.bus()
-- 扫描总线设备地址
for _, a in ipairs(bus:scan()) do
print(string.format("found: 0x%02X", a))
end
-- 读取 BMP280 寄存器 0xD0(芯片 ID)
local dev = bus:device(0x76)
dev:write_byte(0xD0)
local chip_id = dev:read_byte()
dev:close()
bus:close()
spi
以主设备身份进行 SPI 全双工数据传输,支持轮询、中断和 DMA 三种传输模式。
函数 |
说明 |
|---|---|
|
创建 SPI 主设备句柄;config: |
|
轮询写入字符串,返回实际写入字节数 |
|
轮询读取 len 字节 |
|
DMA 异步写入 |
|
DMA 异步读取 |
|
释放句柄 |
local spi = require("spi")
local s = spi.new({
pin_clk = "PB_18",
pin_mosi = "PB_19",
pin_miso = "PB_20",
cpol = 0,
cpha = 0,
div = 4,
})
s:write("\x9F") -- JEDEC ID 命令
local id = s:read(3)
s:close()
uart
访问硬件 UART 串口,支持按长度或按行读取,可设定超时时间。
函数 |
说明 |
|---|---|
|
创建串口句柄;port: 0–3;opt: |
|
写入字符串或字节数组,返回实际写入字节数 |
|
读取最多 len 字节;timeout 内返回已收到的数据 |
|
按行读取(遇换行或超时返回) |
|
返回 RX FIFO 中可读字节数 |
|
清空 RX 缓冲区 |
|
释放串口 |
local uart = require("uart")
local u = uart.new(1, "PB_2", "PB_3", 115200)
u:write("AT\r\n")
local resp = u:read_line(256, 1000) -- 最多等待 1 秒
print(resp)
u:close()
pwm
通过硬件定时器(TIM4–TIM7)输出 PWM 波形,每个定时器最多支持 4 个通道,可独立调节占空比。
函数 |
说明 |
|---|---|
|
创建 PWM 句柄;config: |
|
开启或关闭 PWM 输出 |
|
设置占空比,范围 0.0–100.0 |
|
修改频率(仅在该定时器只有一个通道时允许) |
|
释放句柄 |
local pwm = require("pwm")
local sys = require("sys")
local p = pwm.new({
pin = "PB_5",
timer_idx = 4,
channel = 0,
frequency_hz = 1000,
duty_percent = 50.0,
})
p:set_enabled(true)
-- 呼吸灯渐亮
for i = 0, 100, 5 do
p:set_duty(i)
sys.sleep_ms(30)
end
p:close()
rtc
读取和设置芯片内置的实时时钟,支持每日定时报警和周期性唤醒。
函数 |
说明 |
|---|---|
|
初始化 RTC(幂等,可多次调用) |
|
设置当前时间 |
|
返回 |
|
应用时区偏移后返回本地时间 |
|
设置每日定时报警(H:M:S) |
|
检查报警是否已触发 |
|
清除报警标志 |
|
设置周期性唤醒(1–131072 秒) |
|
检查周期唤醒是否已触发 |
|
取消报警 |
|
取消周期唤醒 |
local rtc = require("rtc")
rtc.init()
rtc.set_time(2025, 1, 1, 8, 0, 0)
local t = rtc.get_local_time(8) -- UTC+8
print(string.format("%04d-%02d-%02d %02d:%02d:%02d",
t.year, t.mon, t.mday, t.hour, t.min, t.sec))
audio
录制 PCM 音频数据(DMIC 输入)或播放音频(I2S 输出),支持 WAV 文件操作和流式 PCM 读写。
函数 |
说明 |
|---|---|
|
创建录音句柄;rate: 采样率 Hz;ch: 1 或 2;bits: 8/16/32 |
|
创建播放句柄 |
|
录制 ms 毫秒并保存为 WAV 文件到 VFS |
|
播放 VFS 中的 WAV 文件 |
|
播放指定频率的纯音(Hz,持续 ms 毫秒) |
|
设置增益;dir: |
|
开始录音 |
|
读取一段 PCM 数据(最大 4096 字节) |
|
停止录音 |
|
写入 PCM 数据进行播放,返回实际写入字节数 |
local audio = require("audio")
-- 录制 5 秒并保存为 WAV
audio.record_wav("vfs:/tmp/rec.wav", 5000)
-- 回放
audio.play_wav("vfs:/tmp/rec.wav")
touch
读取 GT911 电容触摸屏的触摸事件,返回坐标和动作类型,需在 board.json 中配置对应设备 ID。
函数 |
说明 |
|---|---|
|
初始化 GT911;device_id 对应 board.json 中的设备标识 |
|
非阻塞拉取一个事件 |
|
触摸面板宽度(像素) |
|
触摸面板高度(像素) |
|
停止读取任务并释放资源 |
事件 type 取值:"down"(按下)、"move"(移动)、"up"(抬起)。
lcdc
直接操作 LCD 控制器(LCDC),支持 RGB 连续扫描和 MCU 命令/数据两种模式。对于大多数绘图需求,建议使用更高层的 display 模块。
函数 |
说明 |
|---|---|
|
初始化 RGB 模式;config: |
|
初始化 MCU 模式 |
|
发送命令字节 |
|
写入显示数据 |
|
启动 DMA 将数据搬运至显示屏 |
|
使能显示输出 |
|
触发帧更新 |
|
关闭 LCD 控制器 |
adc
从支持 ADC 功能的 GPIO 引脚读取模拟电压。硬件为单实例,同时仅允许一个句柄打开;支持软件触发("sw",默认)和自动扫描("auto")两种模式。
函数 |
说明 |
|---|---|
|
打开 1–12 个 ADC 通道;mode: |
|
(SW 模式)触发单次采样,返回 |
|
(SW 模式)启动/停止连续转换;不带参数或 |
|
(SW 模式)FIFO 中是否有待读样本 |
|
(SW 模式)从 FIFO 弹出一条原始计数值;FIFO 空时返回 nil |
|
(AUTO 模式)采集 count 个样本(1–256),返回 |
|
释放通道,引脚恢复 GPIO 模式 |
local adc = require("adc")
local sys = require("sys")
-- 软件触发单引脚采样
local ch = adc.new("PA_13")
for i = 1, 5 do
local r = ch:read()
print(string.format("sample %d: %d mV", i, r[6]))
sys.sleep_ms(200)
end
ch:close()
-- 自动模式:双通道 8 次采样
local ch2 = adc.new("PA_13", "PA_14", "auto")
local results = ch2:read_auto(8)
for _, r in ipairs(results) do
print(string.format("ch=%d %d mV", r.ch, r.mv))
end
ch2:close()
captouch
读取片上 CapTouch 控制器的电容触摸按键状态,轮询模式,不注册中断。适用于芯片内置触摸引脚(PA_16–PA_24 等),与外接 GT911 面板的 touch 模块无关。
备注
captouch.new() 后需等待约 500–1000 ms,让硬件 ETC 基线自校准完成再读取数据。
函数 |
说明 |
|---|---|
|
打开电容触摸按键;opts: |
|
返回 |
|
检查第 idx 个按键(1-based)是否被按下 |
|
返回设备名称 |
|
释放句柄 |
local captouch = require("captouch")
local sys = require("sys")
local dev = captouch.new("PA_20")
sys.sleep_ms(1000) -- 等待基线稳定
for i = 1, 20 do
local s = dev:read()
local k = s.keys[1]
print(string.format("smooth=%d baseline=%d delta=%d pressed=%s",
k.smooth, k.benchmark, k.delta, tostring(k.pressed)))
sys.sleep_ms(100)
end
dev:close()
ir
发送或接收红外原始波形(符号数组)。TX 和 RX 共用同一硬件外设,不可同时使用;载波频率可配置,默认 38 kHz。NEC 等协议编解码需由调用方在 Lua 层实现。
函数 |
说明 |
|---|---|
|
打开 IR 外设;tx_pin/rx_pin 可传 nil(仅启用一个方向);opts: |
|
发送原始波形;symbols: |
|
接收原始帧;成功返回符号数组,超时返回 |
|
返回 |
|
释放硬件 |
local ir = require("ir")
-- 发送(轮询模式)
local tx = ir.new("PA_25", nil)
local syms = {}
-- 以 NEC 协议填充 syms 后调用 send_raw
tx:send_raw(syms, "poll")
tx:close()
-- 接收(等待 10 秒)
local rx = ir.new(nil, "PA_26")
local frames, err = rx:receive(10000)
if frames then
for i, s in ipairs(frames) do
print(i, s.level, s.duration_us)
end
else
print("no signal:", err)
end
rx:close()
thermal
读取片内硬件温度传感器(Thermal Monitor),支持查询当前温度、历史峰值及上电温度,支持摄氏度和华氏度输出。
函数 |
说明 |
|---|---|
|
初始化温度传感器(引用计数,可多次调用) |
|
当前温度(摄氏度) |
|
当前温度(华氏度) |
|
自上次 |
|
自上次 |
|
上电时记录的温度(℃) |
|
清除最高温度记录 |
|
清除最低温度记录 |
|
释放句柄(引用归零时关闭硬件时钟) |
local thermal = require("thermal")
local sys = require("sys")
local t = thermal.new()
for i = 1, 5 do
print(string.format("temp: %.1f °C", t:read()))
sys.sleep_ms(1000)
end
print("max:", t:max_temp(), " min:", t:min_temp())
t:close()
usb_msc
通过 USB 主机接口访问大容量存储设备(U 盘),提供文件读写、目录列举和路径删除操作。标准调用顺序为 init → wait_ready → mount → 文件操作 → umount → deinit。
备注
usb_msc 与 usb_uvc 共用 USB 主机控制器,同一时刻只能有一个处于活跃状态。
函数 |
说明 |
|---|---|
|
初始化 USB 主机及 MSC 类驱动 |
|
等待设备枚举完成;默认超时 10000 ms |
|
挂载文件系统,返回盘符(如 |
|
卸载文件系统 |
|
停止 USB 主机 |
|
写入文件;文件不存在则创建 |
|
读取文件全部内容 |
|
返回条目数组,每条含 |
|
删除文件或目录 |
local msc = require("usb_msc")
msc.init()
local ok, err = msc.wait_ready(10000)
if not ok then error(err) end
local drive = msc.mount()
msc.write_file(drive .. "hello.txt", "Hello USB!")
local data = msc.read_file(drive .. "hello.txt")
print(data)
for _, e in ipairs(msc.list_dir(drive)) do
print(e.name, e.size, e.is_dir)
end
msc.umount()
msc.deinit()
usb_uvc
通过 USB 主机接口采集 UVC 摄像头帧数据,支持 MJPEG、YUV 和 H.264 格式,提供流参数配置、启停和逐帧读取接口。
备注
usb_uvc 与 usb_msc 共用 USB 主机控制器,同一时刻只能有一个处于活跃状态。
函数 |
说明 |
|---|---|
|
初始化 USB 主机及 UVC 类驱动 |
|
等待摄像头枚举完成;默认超时 10000 ms |
|
配置流参数;opts: |
|
开启视频流 |
|
获取一帧原始数据;默认超时 1000 ms |
|
停止视频流 |
|
停止 USB 主机 |
local uvc = require("usb_uvc")
local file = require("file")
uvc.init()
uvc.wait_ready(10000)
uvc.set_param({width=640, height=480, fps=15, format="mjpeg"})
uvc.stream_on()
local frame, err = uvc.get_frame(2000)
if frame then
file.write("vfs:/tmp/frame.jpg", frame)
print("frame size:", #frame)
else
print("no frame:", err)
end
uvc.stream_off()
uvc.deinit()
高级应用模块
高级应用模块提供系统服务、通信协议和高级功能,大多数可在 Skill 沙箱中使用。
cap
在 Skill 脚本内部调用已注册的 C 层 Capability,以 JSON 字符串传递参数并接收结果。
函数 |
说明 |
|---|---|
|
调用 Capability;返回 |
|
返回所有已注册 Capability 的 JSON 目录 |
cap.call 始终返回两个值,必须同时捕获:
local cap = require("cap")
local cjson = require("cjson")
-- 正确:同时接收状态和结果
local ok, result = cap.call("get_weather", '{"city":"Beijing"}')
if not ok then
return '{"error":' .. cjson.encode(result) .. '}'
end
local data = cjson.decode(result)
警告
只写 local result = cap.call(...) 时,result 实际持有布尔状态值,JSON 结果被丢弃。
sys
查询设备运行时间和执行毫秒级延时,所有时间从设备上电时刻开始计数。
函数 |
说明 |
|---|---|
|
单调毫秒计数(约 49 天溢出归零;不是 Unix 时间戳) |
|
设备启动后经过的秒数 |
|
阻塞等待 ms 毫秒 |
local sys = require("sys")
local t0 = sys.millis()
sys.sleep_ms(1000)
print("elapsed:", sys.millis() - t0, "ms")
备注
sys 没有 Unix 时间戳函数。需要日历时间请使用 rtc 模块;Skill 沙箱中无法使用 os.time()。
cjson
JSON 数据的编解码,支持嵌套对象、数组和所有 JSON 基本类型。
函数 |
说明 |
|---|---|
|
将 JSON 字符串解析为 Lua table 或基本类型 |
|
将 Lua 值序列化为紧凑 JSON;自动区分数组和对象 |
local cjson = require("cjson")
local obj = cjson.decode('{"x":1,"y":[2,3]}')
print(obj.x, obj.y[1]) -- 1 2
local s = cjson.encode({status="ok", code=200})
print(s) -- {"status":"ok","code":200}
file
读写 vfs:/ 路径下的文件,路径中未包含 vfs: 前缀时自动补全。
函数 |
说明 |
|---|---|
|
返回 |
|
判断文件是否存在 |
|
读取文件全部内容(二进制安全) |
|
写入二进制数据;文件不存在则创建 |
|
删除文件 |
|
重命名文件 |
|
加载并执行脚本,返回脚本的返回值 |
local file = require("file")
file.write("vfs:/tmp/hello.txt", "Hello, Ameba!")
local content = file.read("vfs:/tmp/hello.txt")
print(content)
for name, size in pairs(file.list()) do
print(name, size)
end
timer
在后台运行 Lua 代码片段的软件定时器,最多同时运行 8 个,回调超时保护为 5 秒。
函数 |
说明 |
|---|---|
|
启动定时器;ms: 间隔毫秒;code: Lua 代码字符串;repeat: 是否重复;返回 id |
|
按 id 停止定时器 |
|
返回所有活跃定时器的信息数组 |
local timer = require("timer")
-- 每 2 秒打印一次(重复执行)
local id = timer.start(2000, [[
local sys = require("sys")
print("tick:", sys.uptime())
]], true)
require("sys").sleep_ms(10000)
timer.stop(id)
udp
收发 UDP 数据包,适合局域网内设备间的低延迟通信。
函数 |
说明 |
|---|---|
|
创建已连接的 UDP socket |
|
向已连接的目标发送数据 |
|
创建监听 socket |
|
接收数据包;timeout: -1 无限等待,0 不阻塞,>0 毫秒 |
|
关闭 socket |
local udp = require("udp")
-- 发送
local tx = udp.open("192.168.1.100", 9000)
udp.send(tx, "hello")
udp.close(tx)
-- 接收(超时 500ms)
local rx = udp.bind(9000)
local data, from_ip = udp.recv(rx, 1024, 500)
if data then print(from_ip, data) end
udp.close(rx)
event
向 Agent 消息总线发布事件,Skill 可借此主动推送通知或触发自定义事件流程。
函数 |
说明 |
|---|---|
|
发布一条消息事件;src 为 Capability 名称,text 为消息正文 |
|
发布触发器事件;payload 为可选 JSON 字符串 |
|
阻塞等待 GPIO 事件;nil 表示超时 |
local event = require("event")
event.publish_message("my_skill", "default", "123", "传感器温度超限!")
display
在屏幕上绘制图形、文字和像素,提供矢量图形(抗锯齿)和快速路径两套绘图 API,通过 present() 将帧缓冲推送到面板。
初始化与帧控制
函数 |
说明 |
|---|---|
|
初始化显示屏(device_id 来自 board.json) |
|
释放显示资源 |
|
控制背光开关 |
|
开始新帧;opt: |
|
将帧缓冲刷新到屏幕 |
|
屏幕宽度(只读属性) |
|
屏幕高度(只读属性) |
基础绘图
函数 |
说明 |
|---|---|
|
全屏填充纯色(0xRRGGBB) |
|
填充矩形 |
|
绘制单像素 |
|
画线;w 为可选线宽 |
|
矩形边框;thick 为线宽 |
|
填充圆角矩形 |
|
圆形边框 |
|
批量填充圆;tbl: |
|
圆弧;s/e 为起止角度(度) |
|
填充三角形 |
文字
函数 |
说明 |
|---|---|
|
绘制文本;px 字号可选 14/20/24/26 |
|
在矩形框内对齐文本;align: |
|
测量文本所占像素尺寸 |
像素块
函数 |
说明 |
|---|---|
|
贴图;buf 为 RGB565 原始数据字符串;fmt: |
|
设置裁剪区域 |
|
取消裁剪 |
local display = require("display")
display.init("lcd_0")
display.backlight(true)
display.begin_frame({clear=true, color=0x000000})
display.fill_round_rect(20, 20, 200, 60, 10, 0x1E90FF)
display.draw_text(30, 35, "Hello Ameba!", 0xFFFFFF, nil, 20)
display.present()
led_strip
驱动 WS2812/WS2812B 可编程 LED 灯带,通过 SPI 接口以波形编码方式输出控制信号,每颗灯颜色独立可控。
函数 |
说明 |
|---|---|
|
创建灯带句柄;config: |
|
检查是否收到停止指令( |
|
设置第 i 颗灯颜色(1-based);RGB 各 0–255 |
|
用 HSV 设置;h: 0–359;s/v: 0–255 |
|
将所有灯设为同一 RGB 颜色 |
|
将所有灯设为同一 HSV 颜色 |
|
熄灭所有灯 |
|
将颜色数据通过 DMA 推送到灯带 |
|
释放句柄 |
local led = require("led_strip")
local sys = require("sys")
local strip = led.new({spi=0, mosi="PB_8", count=30})
for offset = 0, 359 do
if led.stop_requested() then break end
for i = 1, 30 do
strip:set_pixel_hsv(i, (offset + i * 12) % 360, 255, 180)
end
strip:show()
sys.sleep_ms(20)
end
strip:close()
environmental_sensor
读取 DHT11 温湿度传感器的数据,通过单总线协议采集温度和相对湿度,含校验和验证。
函数 |
说明 |
|---|---|
|
创建 DHT11 句柄;pin 为数据引脚 |
|
返回 |
|
温度(摄氏度) |
|
相对湿度(%) |
|
返回传感器型号字符串 |
|
释放句柄 |
local env = require("environmental_sensor")
local s = env.new({pin="PB_8"})
local data = s:read()
print(string.format("%.1f°C %.1f%%RH", data.temperature, data.humidity))
s:close()
basictimer
基于硬件定时器(TIM0–TIM3)的高精度计时工具,精度可达微秒级,适合测量精确时间间隔。
函数 |
说明 |
|---|---|
|
创建定时器;idx: 0–3;clk: |
|
启动计数 |
|
停止计数 |
|
读取当前计数寄存器值 |
|
读取中断触发次数 |
|
清零中断计数 |
|
修改计时周期(微秒) |
|
释放硬件定时器 |
local bt = require("basictimer")
local sys = require("sys")
local t = bt.new(0, 1000) -- TIM0,周期 1000μs
t:start()
sys.sleep_ms(100)
print("IRQ count:", t:get_irq_count()) -- ≈ 100
t:stop()
t:close()
wifi
连接 Wi-Fi 接入点并查询连接状态,调用过程含 DHCP 等待,为阻塞操作,仅 REPL 环境可用。
函数 |
说明 |
|---|---|
|
连接 AP 并等待 DHCP;成功返回 true |
|
返回当前是否处于已连接状态 |
local wifi = require("wifi")
local ok = wifi.connect("MySSID", "MyPassword")
if ok then print("Wi-Fi connected") end
编写 Skill 脚本
入口函数
每个 Skill 脚本必须定义名为 run 的入口函数,Agent 调用 Skill 时将调用此函数并传入参数:
function run(args)
-- args 是已解码的 Lua table,可直接访问字段
-- 返回值必须是 JSON 字符串
return '{"status":"ok"}'
end
备注
args 是已解码的 Lua table,不是 JSON 字符串,可直接访问字段,如 args.pin、args.times。返回值必须是 JSON 字符串,Agent 将其作为工具调用结果解析。
文件路径约定
路径 |
用途 |
|---|---|
|
临时脚本,重启后自动清除,适合测试 |
|
持久化用户脚本,重启后保留;不受 Skill 目录管理 |
|
Agent 可调用的 Skill;必须位于此路径才能被注册 |
Lua 5.4 位运算
Ameba-Claw 使用 Lua 5.4,不加载 bit 模块,请使用原生运算符:
运算 |
正确写法 |
错误写法(Lua 5.1 风格) |
|---|---|---|
按位与 |
|
|
按位或 |
|
|
按位异或 |
|
|
右移 |
|
|
左移 |
|
|
系统时间与延时
sys 模块提供从设备上电起的单调计数,不提供 Unix 时间戳:
local sys = require("sys")
local ms = sys.millis() -- 单调毫秒计数(不是 Unix 时间戳)
local up = sys.uptime() -- 启动后秒数(浮点),可用于超时判断
sys.sleep_ms(500) -- 阻塞等待 500 毫秒
备注
sys.millis() 和 sys.uptime() 均从上电时刻开始计数,不代表现实时间,断电重启后归零。如需日历时间,请使用 rtc 模块。
完整示例:GPIO 闪烁 LED
以下是控制 PA_22 引脚做 LED 闪烁的完整 Skill 脚本:
local gpio = require("gpio")
local sys = require("sys")
function run(args)
local pin = args.pin or "PA_22"
local times = args.times or 6
gpio.set_direction(pin, "out")
for i = 1, times do
gpio.set_level(pin, i % 2)
sys.sleep_ms(500)
end
gpio.set_direction(pin, "in")
return '{"status":"ok"}'
end
将此文件保存至 vfs:/skills/blink_led/scripts/main.lua 后,通过 AT 命令调用:
AT+CLAW=skill,blink_led
AT+CLAW=skill,blink_led,{"pin":"PA_22","times":10}