224 lines
4.3 KiB
Lua
224 lines
4.3 KiB
Lua
-- PCA9685 PWM控制板 硬件脚本(测试)
|
|
|
|
|
|
-- 这个函数是辅助用的,它能够打印一张表出来
|
|
function print_table(t, indent)
|
|
indent = indent or 0
|
|
for k, v in pairs(t) do
|
|
if type(v) == 'table' then
|
|
print(string.rep(' ', indent) .. k .. ":")
|
|
print_table(v, indent + 2)
|
|
else
|
|
print(string.rep(' ', indent) .. k .. ": " .. tostring(v))
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
|
|
|
|
-- 【配置脚本】
|
|
-- 该脚本负责初始化PCA9685
|
|
-- FIXME(20260602-qing): 异常处理
|
|
function build(data)
|
|
|
|
-- 检查该参数是否是一张表
|
|
if type(data) ~= "table" then
|
|
return {
|
|
result = "ERR",
|
|
message = "Invalid Arguments: table"
|
|
}
|
|
end
|
|
|
|
print("-------- Lua builder func get a table --------")
|
|
print_table(data)
|
|
print("----------------------------------------------")
|
|
local fd = data.fd
|
|
|
|
-- 检查文件句柄参数是否存在
|
|
if fd == nil then
|
|
return {
|
|
result = "ERR",
|
|
message = "Invalid Arguments: fd"
|
|
}
|
|
end
|
|
|
|
local addr = data.address
|
|
|
|
-- 检查地址参数是否存在
|
|
if addr == nil then
|
|
return {
|
|
result = "ERR",
|
|
message = "Invalid Arguments: addr"
|
|
}
|
|
end
|
|
|
|
addr = tonumber(addr)
|
|
|
|
-- 设置PWM频率
|
|
local freq = 50.0
|
|
local prescale_val = 25000000.0 / (4096.0 * freq) - 1.0 -- 25MHz主频
|
|
local prescale = prescale_val + 0.5
|
|
|
|
-- 开始配置PCA9685
|
|
i2c_set_addr(fd, addr)
|
|
|
|
-- 重启PCA9685
|
|
i2c_write_reg(fd, 0x00, 0x80)
|
|
|
|
-- 等待振荡器启动
|
|
milli_sleep(5)
|
|
|
|
i2c_write_reg(fd, 0x00, 0x10) -- 进入SLEEP模式(允许改频率)
|
|
i2c_write_reg(fd, 0xFE, math.floor(prescale))
|
|
i2c_write_reg(fd, 0x00, 0x20) -- 退出SLEEP模式
|
|
|
|
-- 等待振荡器启动
|
|
milli_sleep(5)
|
|
|
|
-- 返回成功信号
|
|
return {
|
|
result = "OK"
|
|
}
|
|
|
|
end
|
|
|
|
-- 【销毁PCA9685的脚本】
|
|
-- 重置PCA9685
|
|
-- NOTE(20260612-qing): 其实可以不需要,因为我们只是清空设置
|
|
function destroy(data)
|
|
|
|
-- 检查该参数是否是一张表
|
|
if type(data) ~= "table" then
|
|
return {
|
|
result = "ERR",
|
|
message = "Invalid Arguments: table"
|
|
}
|
|
end
|
|
|
|
print("-------- Lua ender func get a table --------")
|
|
print_table(data)
|
|
print("--------------------------------------------")
|
|
|
|
local fd = data.fd
|
|
|
|
-- 检查fd参数是否存在
|
|
if fd == nil then
|
|
return {
|
|
result = "ERR",
|
|
message = "Invalid Arguments: fd"
|
|
}
|
|
end
|
|
|
|
local addr = data.address
|
|
|
|
-- 检查address参数是否存在
|
|
if addr == nil then
|
|
return {
|
|
result = "ERR",
|
|
message = "Invalid Arguments: addr"
|
|
}
|
|
end
|
|
|
|
addr = tonumber(addr)
|
|
|
|
-- 准备配置
|
|
i2c_set_addr(fd, addr)
|
|
|
|
-- 重启PCA9685
|
|
i2c_write_reg(fd, 0x00, 0x80)
|
|
|
|
-- 返回成功信号
|
|
return {
|
|
result = "OK"
|
|
}
|
|
|
|
end
|
|
|
|
|
|
-- 【调用PCA9685】
|
|
-- 将一个舵机通道转动到一个角度
|
|
-- NOTE(20260612-qing): 接收一个参数(表),返回一个结果(表)
|
|
function call(data)
|
|
|
|
-- 检查该参数是否是一张表
|
|
if type(data) ~= "table" then
|
|
return {
|
|
result = "ERR",
|
|
message = "Invalid Arguments: table"
|
|
}
|
|
end
|
|
|
|
print("-------- Lua caller func get a table --------")
|
|
print_table(data)
|
|
print("---------------------------------------------")
|
|
|
|
|
|
local fd = data.fd
|
|
|
|
-- 检查fd参数是否存在
|
|
if fd == nil then
|
|
return {
|
|
result = "ERR",
|
|
message = "Invalid Argument: fd"
|
|
}
|
|
end
|
|
|
|
local addr = data.address
|
|
|
|
-- 检查address参数是否存在
|
|
if addr == nil then
|
|
return {
|
|
result = "ERR",
|
|
message = "Invalid Argument: addr"
|
|
}
|
|
end
|
|
|
|
addr = tonumber(addr)
|
|
|
|
local channel = data.channel
|
|
|
|
-- 检查channel参数是否存在
|
|
if channel == nil then
|
|
return {
|
|
result = "ERR",
|
|
message = "Invalid Argument: channel"
|
|
}
|
|
end
|
|
|
|
local angle = data.angle
|
|
|
|
-- 检查angle参数是否存在
|
|
if angle == nil then
|
|
return {
|
|
result = "ERR",
|
|
message = "Invalid Argument: angle"
|
|
}
|
|
end
|
|
|
|
print(string.format("Lua hardware drive set angle: %d", angle))
|
|
|
|
-- 设置I2C地址
|
|
i2c_set_addr(fd, addr)
|
|
|
|
-- 计算需要的参数
|
|
local min = 0.5 -- 0度对应0.5ms
|
|
local max = 2.5 -- 180度对应2.5ms
|
|
local width = min + (max - min) * (angle / 180.0)
|
|
local offval = math.floor(width * 4096.0 / 20.0)
|
|
local reg = 0x06 + 4 * channel
|
|
|
|
-- 写I2C寄存器
|
|
i2c_write_reg(fd, reg + 0, (0 >> 0) & 0xFF) -- 1 * 8
|
|
i2c_write_reg(fd, reg + 1, (0 >> 8) & 0xFF) -- 2 * 8
|
|
i2c_write_reg(fd, reg + 2, (offval >> 0) & 0xFF) -- 3 * 8
|
|
i2c_write_reg(fd, reg + 3, (offval >> 8) & 0xFF) -- 4 * 8
|
|
|
|
-- 返回字典
|
|
return {
|
|
result = "OK"
|
|
}
|
|
|
|
end
|
|
|