init: Air780EPM 官方 LuatOS 项目代码基线
- 来源: 合宙 LuatOS 官方仓库 air780epm 模块完整代码 - 路径: luatos/air780epm/module/Air780EPM/demo 含官方 demo(含 mqtt/mqtts/socket/uart 等) - 后续: 基于 demo 开发 UART<->MQTT 数据上报功能
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
--[[
|
||||
@module main
|
||||
@summary OneWire综合演示项目主文件(单传感器 + 多传感器)
|
||||
@version 001.999.000
|
||||
@date 2025.11.25
|
||||
@author 王棚嶙
|
||||
@usage
|
||||
本演示项目整合单DS18B20和多DS18B20传感器功能:
|
||||
1. 单传感器模式:GPIO2默认OneWire功能、硬件通道0模式、CRC校验、3秒间隔连续监测
|
||||
2. 多传感器模式:引脚54/23切换、PWR_KEY按键控制、电源管理、2秒间隔双路监测
|
||||
3. 完整的OneWire API接口演示、错误处理、设备检测、温度报警
|
||||
]]
|
||||
|
||||
-- 项目信息
|
||||
PROJECT = "onewire_demo"
|
||||
VERSION = "001.999.000"
|
||||
|
||||
|
||||
|
||||
|
||||
-- 在日志中打印项目名和项目版本号
|
||||
log.info("main", PROJECT, VERSION)
|
||||
|
||||
|
||||
|
||||
-- 如果内核固件支持errDump功能,此处进行配置,【强烈建议打开此处的注释】
|
||||
-- 因为此功能模块可以记录并且上传脚本在运行过程中出现的语法错误或者其他自定义的错误信息,可以初步分析一些设备运行异常的问题
|
||||
-- 以下代码是最基本的用法,更复杂的用法可以详细阅读API说明文档
|
||||
-- 启动errDump日志存储并且上传功能,600秒上传一次
|
||||
-- if errDump then
|
||||
-- errDump.config(true, 600)
|
||||
-- end
|
||||
|
||||
|
||||
-- 使用LuatOS开发的任何一个项目,都强烈建议使用远程升级FOTA功能
|
||||
-- 可以使用合宙的iot.openluat.com平台进行远程升级
|
||||
-- 也可以使用客户自己搭建的平台进行远程升级
|
||||
-- 远程升级的详细用法,可以参考fota的demo进行使用
|
||||
|
||||
|
||||
-- 启动一个循环定时器
|
||||
-- 每隔3秒钟打印一次总内存,实时的已使用内存,历史最高的已使用内存情况
|
||||
-- 方便分析内存使用是否有异常
|
||||
-- sys.timerLoopStart(function()
|
||||
-- log.info("mem.lua", rtos.meminfo())
|
||||
-- log.info("mem.sys", rtos.meminfo("sys"))
|
||||
-- end, 3000)
|
||||
|
||||
-- 在加载以下两个功能的时候建议分别打开,避免同时初始化OneWire总线,导致资源冲突
|
||||
-- 单设备模式:使用GPIO2默认OneWire功能
|
||||
-- 双设备模式:GPIO2默认 + 引脚54复用
|
||||
|
||||
-- 加载单传感器应用模块
|
||||
-- require("onewire_single_app")
|
||||
|
||||
-- 加载多传感器应用模块
|
||||
require("onewire_multi_app")
|
||||
|
||||
|
||||
-- 启动系统主循环
|
||||
sys.run()
|
||||
@@ -0,0 +1,367 @@
|
||||
--[[
|
||||
@module onewire_multi_app
|
||||
@summary OneWire多DS18B20温度传感器应用演示模块(54和23切换版本)
|
||||
@version 1.0.0
|
||||
@date 2025.11.25
|
||||
@author 王棚嶙
|
||||
@usage
|
||||
本模块演示多DS18B20温度传感器的完整功能:
|
||||
1. 双传感器切换控制(引脚54和23)
|
||||
2. 电源管理(GPIO控制)
|
||||
3. 按键切换传感器
|
||||
4. 双路温度同时监测
|
||||
5. 使用引脚复用功能(pins.setup)
|
||||
]]
|
||||
|
||||
log.info("onewire_multi_app", "多传感器模块版本: 1.0.0")
|
||||
|
||||
-- 设置所有GPIO引脚电压为3.3V,确保DS18B20传感器正常供电
|
||||
pm.ioVol(pm.IOVOL_ALL_GPIO, 3300)
|
||||
|
||||
-- 和GPIO31控制传感器电源使能,确保DS18B20供电正常
|
||||
gpio.setup(31, 1)
|
||||
|
||||
-- 硬件配置(双设备模式:支持引脚54和23切换)
|
||||
local onewire_pin = 54
|
||||
local switchover_pin = gpio.PWR_KEY
|
||||
|
||||
-- DS18B20命令定义
|
||||
local CMD_CONVERT_T = 0x44
|
||||
local CMD_READ_SCRATCHPAD = 0xBE
|
||||
local CMD_READ_ROM = 0x33
|
||||
|
||||
-- 全局状态变量
|
||||
local pwr_key_pressed = false
|
||||
|
||||
-- PWR_KEY按键中断处理函数
|
||||
-- 功能:处理引脚切换按键事件,设置标志位供主循环查询
|
||||
local function handle_pwr_key_interrupt()
|
||||
pwr_key_pressed = true
|
||||
log.info("onewire_multi_app", "切换按键被按下")
|
||||
end
|
||||
|
||||
-- 初始化硬件配置
|
||||
local function init_hardware()
|
||||
log.info("onewire_multi_app", "初始化硬件配置...")
|
||||
|
||||
-- 配置PWR_KEY按键,使用上升沿触发并添加防抖
|
||||
gpio.debounce(switchover_pin, 100)
|
||||
gpio.setup(switchover_pin, handle_pwr_key_interrupt, gpio.PULLUP, gpio.RISING)
|
||||
|
||||
-- 初始配置当前引脚为ONEWIRE功能
|
||||
pins.setup(onewire_pin, "ONEWIRE")
|
||||
|
||||
log.info("onewire_multi_app", "硬件初始化完成")
|
||||
log.info("onewire_multi_app", "初始引脚: 引脚" .. onewire_pin .. " (ONEWIRE功能)")
|
||||
log.info("onewire_multi_app", "切换按键: PWR_KEY")
|
||||
log.info("onewire_multi_app", "支持引脚: 54 和 23 循环切换")
|
||||
log.info("onewire_multi_app", "电源控制: GPIO31/GPIO2 (已设置为高电平)")
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
-- 时序要求:DS18B20上电后需要稳定时间,100ms延时确保电源稳定
|
||||
-- 技术背景:DS18B20在电源切换后需要tREC(恢复时间)完成内部初始化
|
||||
-- 实际测试:无延时可能导致设备检测失败或温度读取异常
|
||||
-- 建议值:最小50ms,推荐100ms以确保可靠性
|
||||
local function power_stabilization_delay()
|
||||
log.info("onewire_multi_app", "电源稳定延时(确保DS18B20内部电路就绪)")
|
||||
sys.wait(100) -- DS18B20 tREC恢复时间,最小50ms,推荐100ms
|
||||
end
|
||||
|
||||
-- 单总线分时使用引脚切换(同一条总线,分时复用)
|
||||
-- 核心逻辑:使用GPIO54和GPIO23两个引脚连接同一条OneWire总线,实现分时复用
|
||||
-- 应用场景:当需要在同一总线上分时访问不同设备时使用
|
||||
-- 技术原理:通过切换总线连接引脚,实现同一条物理总线的分时使用
|
||||
-- 切换效果:
|
||||
-- - GPIO54:当前时间段连接设备A(ROM ID: 28-9F-C4-93-00-00-00-14)
|
||||
-- - GPIO23:切换到时间段连接设备B(ROM ID: 28-59-F2-53-00-00-00-14)
|
||||
-- 注意:这不是多总线并行,而是单总线的分时复用策略
|
||||
local function switch_onewire_pin()
|
||||
log.info("onewire_multi_app", "切换OneWire引脚...")
|
||||
|
||||
-- 关闭当前OneWire总线
|
||||
onewire.deinit(0)
|
||||
|
||||
|
||||
-- 分时复用切换逻辑
|
||||
-- 技术原理:将当前不使用的引脚配置为GPIO功能并输出高电平
|
||||
-- 目的:确保非活动设备处于高阻态,避免干扰当前连接的设备
|
||||
-- 电气特性:GPIO设置为开漏输出模式,高电平由上拉电阻提供
|
||||
if onewire_pin == 54 then
|
||||
-- 从54切换到23
|
||||
-- 将PIN54配置为GPIO3功能,不再作为OneWire使用
|
||||
log.info("onewire_multi_app", "将PIN54配置为GPIO3", pins.setup(54, "GPIO3"))
|
||||
-- 设置GPIO3为高电平输出(开漏模式,高电平由上拉电阻提供)
|
||||
log.info("onewire_multi_app", "将GPIO3设置为高电平输出(OneWire总线空闲状态)", gpio.setup(3, 1))
|
||||
onewire_pin = 23
|
||||
log.info("onewire_multi_app", "切换到引脚23")
|
||||
else
|
||||
-- 从23切换到54
|
||||
-- 将PIN23配置为GPIO2功能,不再作为OneWire使用
|
||||
log.info("onewire_multi_app", "将PIN23配置为GPIO2", pins.setup(23, "GPIO2"))
|
||||
-- 设置GPIO2为高电平输出(开漏模式,高电平由上拉电阻提供)
|
||||
log.info("onewire_multi_app", "将GPIO2设置为高电平输出(OneWire总线空闲状态)", gpio.setup(2, 1))
|
||||
onewire_pin = 54
|
||||
log.info("onewire_multi_app", "切换到引脚54")
|
||||
end
|
||||
|
||||
log.info("onewire_multi_app", "当前使用引脚:", onewire_pin)
|
||||
|
||||
-- 配置新引脚为ONEWIRE功能
|
||||
-- 分时复用原理:将选中的引脚配置为OneWire功能,连接到对应设备
|
||||
-- 连接过程:先断开之前的设备连接,再连接新的设备
|
||||
-- 电气特性:确保当前连接的设备具有完整的OneWire通信能力
|
||||
log.info("onewire_multi_app", "将引脚" .. onewire_pin .. "配置为ONEWIRE功能", pins.setup(onewire_pin, "ONEWIRE"))
|
||||
|
||||
log.info("onewire_multi_app", "引脚切换完成,当前使用: 引脚" .. onewire_pin)
|
||||
end
|
||||
|
||||
-- 初始化OneWire总线
|
||||
local function init_onewire_bus()
|
||||
log.info("onewire_multi_app", "初始化OneWire总线,通道: 0")
|
||||
|
||||
-- 配置当前引脚
|
||||
pins.setup(onewire_pin, "ONEWIRE")
|
||||
|
||||
-- 初始化OneWire总线
|
||||
onewire.init(0)
|
||||
|
||||
-- 配置DS18B20标准时序参数
|
||||
onewire.timing(0, false, 0, 500, 500, 15, 240, 70, 1, 15, 10, 2)
|
||||
|
||||
log.info("onewire_multi_app", "OneWire总线初始化完成,通道: 0,引脚:" .. onewire_pin)
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
-- 检测DS18B20设备是否存在(分时复用场景)
|
||||
-- 分时逻辑:在当前连接的引脚上发送复位脉冲,检测该设备响应
|
||||
-- 单总线场景:只有当前连接的引脚上的设备会响应复位脉冲
|
||||
-- 返回值:true表示当前引脚连接的设备响应,false表示无设备响应
|
||||
local function detect_ds18b20_device()
|
||||
log.info("onewire_multi_app", "检测DS18B20设备,引脚: " .. onewire_pin)
|
||||
|
||||
-- 发送复位脉冲并检测设备
|
||||
local present = onewire.reset(0, true)
|
||||
|
||||
if present then
|
||||
log.info("onewire_multi_app", "检测到DS18B20设备响应")
|
||||
return true
|
||||
else
|
||||
log.warn("onewire_multi_app", "未检测到DS18B20设备响应")
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
-- 读取DS18B20温度(单总线分时复用)
|
||||
-- 核心流程:读ROM ID → 选设备 → 温度转换 → 读数据 → CRC校验
|
||||
local function read_ds18b20_temperature()
|
||||
log.info("onewire_multi_app", "开始读取DS18B20温度,引脚: " .. onewire_pin)
|
||||
|
||||
local tbuff = zbuff.create(10)
|
||||
local succ, crc8c, range, t
|
||||
local rbuff = zbuff.create(9)
|
||||
|
||||
-- 读取设备ROM ID(每个设备唯一)
|
||||
log.info("onewire_multi_app", "读取设备ROM ID(64位唯一标识)")
|
||||
|
||||
local id = zbuff.create(8)
|
||||
id:set()
|
||||
|
||||
succ, rx_data = onewire.rx(0, 8, 0x33, id, false, true, true)
|
||||
if not succ then
|
||||
log.warn("onewire_multi_app", "读取ROM ID失败")
|
||||
return nil
|
||||
end
|
||||
|
||||
-- 检查设备类型码(DS18B20应为0x28)
|
||||
if id[0] ~= 0x28 then
|
||||
log.warn("onewire_multi_app", "非DS18B20设备,类型码:", mcu.x32(id[0]))
|
||||
return nil
|
||||
end
|
||||
|
||||
-- CRC校验设备ID
|
||||
crc8c = crypto.crc8(id:query(0, 7), 0x31, 0, true)
|
||||
if crc8c ~= id[7] then
|
||||
log.warn("onewire_multi_app", "ROM ID CRC校验不对",
|
||||
"计算值:", mcu.x32(crc8c), "期望值:", mcu.x32(id[7]))
|
||||
log.info("onewire_multi_app", "完整ROM ID:", id:query(0, 7):toHex())
|
||||
return nil
|
||||
end
|
||||
|
||||
log.info("onewire_multi_app", "ROM ID校验成功:", id:query(0, 7):toHex())
|
||||
|
||||
-- 通过MATCH ROM选择设备(确保只选中目标设备)
|
||||
log.info("onewire_multi_app", "开始温度转换(通过ROM匹配选择设备)")
|
||||
|
||||
-- 构建命令缓冲区:MATCH ROM(0x55) + 目标设备ROM ID + 温度转换命令(0x44)
|
||||
-- 0x55是MATCH ROM命令,后面必须跟64位目标设备的ROM ID
|
||||
tbuff:write(0x55) -- MATCH ROM命令
|
||||
tbuff:copy(nil, id) -- 复制64位ROM ID(确保选择正确的设备)
|
||||
tbuff:write(0xb8)
|
||||
tbuff[tbuff:used() - 1] = 0x44 -- CONVERT T温度转换命令
|
||||
|
||||
succ = onewire.tx(0, tbuff, false, true, true)
|
||||
if not succ then
|
||||
log.warn("onewire_multi_app", "发送温度转换命令失败")
|
||||
return nil
|
||||
end
|
||||
|
||||
-- 第三步:等待转换完成
|
||||
log.info("onewire_multi_app", "等待温度转换完成")
|
||||
|
||||
-- 等待一段时间让转换完成
|
||||
sys.wait(750)
|
||||
|
||||
-- 发送复位脉冲检查设备
|
||||
succ = onewire.reset(0, true)
|
||||
if not succ then
|
||||
log.warn("onewire_multi_app", "等待转换完成时设备未响应")
|
||||
return nil
|
||||
end
|
||||
|
||||
-- 检查转换是否完成
|
||||
if onewire.bit(0) > 0 then
|
||||
log.info("onewire_multi_app", "温度转换完成")
|
||||
end
|
||||
|
||||
-- 第四步:读取温度数据
|
||||
log.info("onewire_multi_app", "读取温度数据")
|
||||
|
||||
-- 构建读取命令:匹配ROM(0x55) + ROM ID + 读取暂存器命令(0xBE)
|
||||
tbuff[tbuff:used() - 1] = 0xbe
|
||||
succ = onewire.tx(0, tbuff, false, true, true)
|
||||
if not succ then
|
||||
log.warn("onewire_multi_app", "发送读取命令失败")
|
||||
return nil
|
||||
end
|
||||
|
||||
-- 接收9字节温度数据
|
||||
succ, rx_data = onewire.rx(0, 9, nil, rbuff, false, false, false)
|
||||
if not succ then
|
||||
log.warn("onewire_multi_app", "温度数据接收失败")
|
||||
return nil
|
||||
end
|
||||
|
||||
-- 第五步:CRC校验和温度计算
|
||||
log.info("onewire_multi_app", "CRC校验和温度计算")
|
||||
|
||||
-- CRC校验
|
||||
crc8c = crypto.crc8(rbuff:toStr(0, 8), 0x31, 0, true)
|
||||
if crc8c == rbuff[8] then
|
||||
-- 计算温度值
|
||||
range = (rbuff[4] >> 5) & 0x03
|
||||
t = rbuff:query(0, 2, false, true)
|
||||
t = t * (5000 >> range)
|
||||
t = t / 10000
|
||||
|
||||
-- 范围检查
|
||||
if t >= -55.0 and t <= 125.0 then
|
||||
log.info("onewire_multi_app", "温度读取成功:", string.format("%.2f°C", t))
|
||||
return t
|
||||
else
|
||||
log.warn("onewire_multi_app", "温度值超出有效范围:", t)
|
||||
return nil
|
||||
end
|
||||
else
|
||||
log.warn("onewire_multi_app", "温度数据CRC校验不对",
|
||||
"计算值:", mcu.x32(crc8c), "期望值:", mcu.x32(rbuff[8]))
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
-- 简化版温度读取(用于快速测试)
|
||||
local function quick_read_ds18b20()
|
||||
log.info("onewire_multi_app", "快速读取温度,引脚: " .. onewire_pin)
|
||||
|
||||
-- 首先检测设备是否存在
|
||||
if not detect_ds18b20_device() then
|
||||
return nil
|
||||
end
|
||||
|
||||
-- 使用完整读取函数
|
||||
return read_ds18b20_temperature()
|
||||
end
|
||||
|
||||
-- 单总线分时复用主函数(同一条总线,分时访问不同设备)
|
||||
local function multi_sensor_app_main()
|
||||
log.info("onewire_multi_app", "启动双传感器应用(引脚54和23)")
|
||||
|
||||
-- 初始化硬件
|
||||
if not init_hardware() then
|
||||
log.error("onewire_multi_app", "硬件初始化失败,任务无法启动")
|
||||
return
|
||||
end
|
||||
|
||||
-- 初始化OneWire总线
|
||||
init_onewire_bus()
|
||||
|
||||
-- 电源稳定延时:确保DS18B20内部电路就绪
|
||||
power_stabilization_delay()
|
||||
|
||||
-- 检测设备
|
||||
local device_present = detect_ds18b20_device()
|
||||
|
||||
if not device_present then
|
||||
log.error("onewire_multi_app", "未检测到设备响应")
|
||||
log.warn("onewire_multi_app", "硬件连接提示:")
|
||||
log.warn("onewire_multi_app", "1. 传感器连接引脚54或23")
|
||||
log.warn("onewire_multi_app", "2. 确保GPIO31/GPIO2已设置为高电平供电")
|
||||
log.warn("onewire_multi_app", "3. 确保4.7kΩ上拉电阻正确安装")
|
||||
log.warn("onewire_multi_app", "4. 检查传感器VDD、GND、DQ连接")
|
||||
-- 关闭OneWire总线
|
||||
onewire.deinit(0)
|
||||
return
|
||||
end
|
||||
|
||||
log.info("onewire_multi_app", "开始双传感器连续监测...")
|
||||
log.info("onewire_multi_app", "按PWR_KEY按键可切换引脚(54和23)")
|
||||
|
||||
-- 主循环:按键切换设备,分时读取温度
|
||||
local read_count = 0
|
||||
local success_count = 0
|
||||
|
||||
while true do
|
||||
read_count = read_count + 1
|
||||
|
||||
-- 检查按键状态
|
||||
if pwr_key_pressed then
|
||||
pwr_key_pressed = false
|
||||
switch_onewire_pin()
|
||||
|
||||
-- 重新初始化OneWire总线
|
||||
init_onewire_bus()
|
||||
end
|
||||
|
||||
log.info("onewire_multi_app", "第" .. read_count .. "次读取,引脚:" .. onewire_pin)
|
||||
|
||||
-- 尝试读取温度
|
||||
local temperature = read_ds18b20_temperature()
|
||||
|
||||
if temperature then
|
||||
success_count = success_count + 1
|
||||
log.info("onewire_multi_app", "引脚" .. onewire_pin .. "温度:",
|
||||
string.format("%.2f°C", temperature),
|
||||
"成功率:", string.format("%.1f%%", success_count/read_count*100))
|
||||
|
||||
-- 简单的温度报警逻辑
|
||||
if temperature > 30 then
|
||||
log.warn("onewire_multi_app", "温度偏高:", string.format("%.2f°C", temperature))
|
||||
elseif temperature < 10 then
|
||||
log.warn("onewire_multi_app", "温度偏低:", string.format("%.2f°C", temperature))
|
||||
end
|
||||
else
|
||||
log.warn("onewire_multi_app", "本次读取失败")
|
||||
log.info("onewire_multi_app", "成功率:", string.format("%.1f%%", success_count/read_count*100))
|
||||
end
|
||||
|
||||
-- 等待下一次读取
|
||||
sys.wait(2000)
|
||||
end
|
||||
end
|
||||
log.info("onewire_multi_app", "双传感器应用模块加载完成(54和23切换)")
|
||||
-- 启动多传感器应用任务
|
||||
sys.taskInit(multi_sensor_app_main)
|
||||
|
||||
@@ -0,0 +1,203 @@
|
||||
--[[
|
||||
@module onewire_single_app
|
||||
@summary OneWire单DS18B20温度传感器应用演示模块(GPIO2默认模式)
|
||||
@version 1.0.0
|
||||
@date 2025.11.25
|
||||
@author 王棚嶙
|
||||
@usage
|
||||
本模块演示单DS18B20温度传感器的完整功能:
|
||||
1. 使用GPIO2默认OneWire功能
|
||||
2. 硬件通道0模式,无需引脚复用
|
||||
3. 优化的时序参数和错误处理
|
||||
4. 连续温度监测
|
||||
5. 完整的OneWire API接口演示
|
||||
]]
|
||||
|
||||
|
||||
log.info("onewire_single_app", "单传感器模块版本:1.0.0")
|
||||
|
||||
-- 设置所有GPIO引脚电压为3.3V,确保DS18B20传感器正常供电
|
||||
pm.ioVol(pm.IOVOL_ALL_GPIO, 3300)
|
||||
|
||||
-- DS18B20命令定义
|
||||
local CMD_CONVERT_T = 0x44
|
||||
local CMD_READ_SCRATCHPAD = 0xBE
|
||||
local CMD_SKIP_ROM = 0xCC
|
||||
local CMD_READ_ROM = 0x33
|
||||
|
||||
-- 单传感器应用主函数
|
||||
local function single_sensor_app_main()
|
||||
log.info("onewire_single_app", "启动单传感器应用")
|
||||
|
||||
-- 初始化OneWire总线(使用硬件通道0模式)
|
||||
log.info("onewire_single_app", "初始化OneWire总线...")
|
||||
onewire.init(0)
|
||||
onewire.timing(0, false, 0, 500, 500, 15, 240, 70, 1, 15, 10, 2)
|
||||
log.info("onewire_single_app", "OneWire总线初始化完成,使用GPIO2默认引脚")
|
||||
|
||||
|
||||
|
||||
-- 检测DS18B20设备
|
||||
log.info("onewire_single_app", "检测DS18B20设备...")
|
||||
|
||||
local succ, rx_data
|
||||
local id = zbuff.create(8)
|
||||
local crc8c
|
||||
|
||||
-- 清空ID缓冲区
|
||||
id:set()
|
||||
|
||||
-- 读取设备ROM ID(使用手动配置的引脚)
|
||||
succ, rx_data = onewire.rx(0, 8, 0x33, id, false, true, true)
|
||||
|
||||
local detected = false
|
||||
local device_id = nil
|
||||
|
||||
if succ then
|
||||
-- 检查家族码(DS18B20为0x28)
|
||||
if id[0] == 0x28 then
|
||||
-- CRC校验
|
||||
crc8c = crypto.crc8(id:query(0,7), 0x31, 0, true)
|
||||
if crc8c == id[7] then
|
||||
log.info("onewire_single_app", "探测到DS18B20", id:query(0, 7):toHex())
|
||||
detected = true
|
||||
device_id = id
|
||||
else
|
||||
log.warn("onewire_single_app", "ROM ID CRC校验不对", mcu.x32(crc8c), mcu.x32(id[7]))
|
||||
end
|
||||
else
|
||||
log.warn("onewire_single_app", "ROM ID不正确", mcu.x32(id[0]))
|
||||
end
|
||||
else
|
||||
log.warn("onewire_single_app", "未检测到DS18B20设备,请检查硬件连接")
|
||||
log.info("onewire_single_app", "硬件连接提示:")
|
||||
log.info("onewire_single_app", "1. DS18B20 DATA引脚 -> GPIO2 (默认OneWire功能)")
|
||||
log.info("onewire_single_app", "2. 确保上拉电阻4.7kΩ连接DATA到3.3V")
|
||||
log.info("onewire_single_app", "3. 使用硬件通道0模式,无需引脚复用配置")
|
||||
end
|
||||
|
||||
if not detected then
|
||||
log.warn("onewire_single_app", "设备检测失败,任务无法启动")
|
||||
log.info("onewire_single_app", "单传感器应用启动完成")
|
||||
onewire.deinit(0)
|
||||
return
|
||||
end
|
||||
|
||||
log.info("onewire_single_app", "开始连续温度监测...")
|
||||
|
||||
-- 读取DS18B20温度数据(单总线单设备模式)
|
||||
-- 与多传感器模式的对比:
|
||||
-- - 单传感器:使用SKIP ROM(0xCC)直接通信,无需ROM ID
|
||||
-- - 多传感器:使用MATCH ROM(0x55)选择设备,需要目标ROM ID
|
||||
--
|
||||
-- 单设备读取流程:
|
||||
-- 1. SKIP ROM:发送0xCC命令,跳过ROM ID识别
|
||||
-- 2. 温度转换:发送CONVERT T(0x44)启动温度转换
|
||||
-- 3. 读取数据:发送READ SCRATCHPAD(0xBE)读取温度数据
|
||||
-- 4. CRC校验:验证数据完整性
|
||||
--
|
||||
-- 优势:通信简单高效,无需设备寻址
|
||||
-- 限制:只能用于总线上只有一个设备的场景
|
||||
local function read_temperature(dev_id)
|
||||
local tbuff = zbuff.create(10)
|
||||
local rbuff = zbuff.create(9)
|
||||
local succ, crc8c, range, t
|
||||
|
||||
-- 发送SKIP ROM命令(0xCC) - 跳过ROM识别,直接与设备通信
|
||||
-- 工作原理:所有设备都会响应SKIP ROM命令,无需发送64位ROM ID
|
||||
-- 适用场景:总线上只有一个设备,无需设备寻址和选择
|
||||
-- 优势:通信效率高,无需传输ROM ID,简化通信流程
|
||||
-- 风险:如果总线上有多个设备,所有设备会同时响应,造成冲突
|
||||
tbuff:write(0xcc,0xb8)
|
||||
|
||||
-- 发送温度转换命令
|
||||
tbuff[tbuff:used() - 1] = 0x44
|
||||
succ = onewire.tx(0, tbuff, false, true, true)
|
||||
if not succ then
|
||||
log.warn("onewire_single_app", "发送温度转换命令失败")
|
||||
return nil
|
||||
end
|
||||
|
||||
-- 等待转换完成(使用位检测)
|
||||
local conversion_complete = false
|
||||
local max_wait = 100
|
||||
local wait_count = 0
|
||||
|
||||
while wait_count < max_wait do
|
||||
succ = onewire.reset(0, true)
|
||||
if not succ then
|
||||
log.warn("onewire_single_app", "等待转换完成时设备未响应")
|
||||
return nil
|
||||
end
|
||||
if onewire.bit(0) > 0 then
|
||||
log.info("onewire_single_app", "温度转换完成")
|
||||
conversion_complete = true
|
||||
break
|
||||
end
|
||||
sys.wait(10)
|
||||
wait_count = wait_count + 1
|
||||
end
|
||||
|
||||
if not conversion_complete then
|
||||
log.warn("onewire_single_app", "温度转换超时")
|
||||
return nil
|
||||
end
|
||||
|
||||
-- 读取温度数据
|
||||
tbuff[tbuff:used() - 1] = 0xBE
|
||||
succ = onewire.tx(0, tbuff, false, true, true)
|
||||
if not succ then
|
||||
log.warn("onewire_single_app", "发送读取命令失败")
|
||||
return nil
|
||||
end
|
||||
|
||||
succ, rx_data = onewire.rx(0, 9, nil, rbuff, false, false, false)
|
||||
if not succ or rbuff:used() ~= 9 then
|
||||
log.warn("onewire_single_app", "温度数据读取失败")
|
||||
return nil
|
||||
end
|
||||
|
||||
-- CRC校验
|
||||
crc8c = crypto.crc8(rbuff:toStr(0,8), 0x31, 0, true)
|
||||
if crc8c == rbuff[8] then
|
||||
range = (rbuff[4] >> 5) & 0x03
|
||||
t = rbuff:query(0,2,false,true)
|
||||
t = t * (5000 >> range)
|
||||
t = t / 10000
|
||||
log.info("onewire_single_app", "温度读取成功:", string.format("%.2f°C", t))
|
||||
return t
|
||||
else
|
||||
log.warn("onewire_single_app", "RAM DATA CRC校验不对", mcu.x32(crc8c), mcu.x32(rbuff[8]))
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
-- 主循环 - 连续温度监测
|
||||
while true do
|
||||
local temperature = read_temperature(device_id)
|
||||
|
||||
if temperature then
|
||||
-- 简单的温度报警逻辑(示例)
|
||||
if temperature > 30 then
|
||||
log.warn("onewire_single_app", "温度偏高:", string.format("%.2f°C", temperature))
|
||||
elseif temperature < 10 then
|
||||
log.warn("onewire_single_app", "温度偏低:", string.format("%.2f°C", temperature))
|
||||
else
|
||||
log.info("onewire_single_app", "温度正常:", string.format("%.2f°C", temperature))
|
||||
end
|
||||
else
|
||||
log.warn("onewire_single_app", "本次读取失败,继续下一次")
|
||||
end
|
||||
|
||||
-- 等待下一次读取
|
||||
sys.wait(3000)
|
||||
end
|
||||
|
||||
log.info("onewire_single_app", "单传感器连续读取任务结束")
|
||||
log.info("onewire_single_app", "单传感器应用启动完成")
|
||||
end
|
||||
|
||||
log.info("onewire_single_app", "单传感器应用模块加载完成")
|
||||
|
||||
-- 启动单传感器应用任务
|
||||
sys.taskInit(single_sensor_app_main)
|
||||
@@ -0,0 +1,212 @@
|
||||
> 王棚嶙
|
||||
|
||||
# OneWire综合演示项目
|
||||
|
||||
## 功能模块介绍
|
||||
|
||||
本demo演示了完整的DS18B20温度传感器OneWire单总线协议实现。项目采用模块化架构,分别实现单传感器和多传感器应用场景。
|
||||
|
||||
1、main.lua:主程序入口 <br>
|
||||
2、onewire_single_app.lua:演示单传感器功能模块(GPIO2默认OneWire功能,硬件通道0模式,3秒间隔连续监测)<br>
|
||||
3、onewire_multi_app.lua:演示多传感器功能模块(引脚54/23切换,PWR_KEY按键控制,2秒间隔双路监测)<br>
|
||||
|
||||
## 演示功能概述
|
||||
|
||||
### 主程序入口模块 (main.lua)
|
||||
|
||||
- 初始化项目信息和版本号
|
||||
- 初始化看门狗,并定时喂狗
|
||||
- 启动一个循环定时器,每隔3秒钟打印一次总内存,实时的已使用内存,历史最高的已使用内存情况方便分析内存使用是否有异常
|
||||
- 加载onewire_single_app模块(通过require "onewire_single_app")
|
||||
- 加载onewire_multi_app模块(通过require "onewire_multi_app")
|
||||
|
||||
### 单传感器模式 (onewire_single_app.lua)
|
||||
- 使用GPIO2默认OneWire功能,硬件通道0模式,无需引脚复用
|
||||
- 完整的CRC8数据校验机制,确保数据可靠性
|
||||
- 设备自动识别和ROM验证,支持设备类型检测
|
||||
- 3秒间隔连续温度监测,实时温度报警功能
|
||||
- zbuff缓冲区优化,提高数据传输效率
|
||||
|
||||
|
||||
### 多传感器模式 (onewire_multi_app.lua - 单总线多设备演示)
|
||||
|
||||
|
||||
**单总线多设备挂载原理**:
|
||||
1. **物理连接**:所有DS18B20的VDD、GND、DQ引脚分别并联到同一组单总线
|
||||
2. **设备识别**:每个DS18B20出厂时烧录了全球唯一的64位ROM ID
|
||||
3. **总线扫描**:主机发送SEARCH ROM(0xF0)命令发现总线上的所有设备
|
||||
4. **设备选择**:通过MATCH ROM(0x55)命令+目标设备ROM ID选择特定设备通信
|
||||
5. **分时操作**:每次只与一个设备通信,避免总线冲突
|
||||
|
||||
**分时复用测试逻辑**(按键切换设备):
|
||||
- **引脚54**:连接设备A(ROM ID: 28-9F-C4-93-00-00-00-14)
|
||||
- **引脚23**:连接设备B(ROM ID: 28-59-F2-53-00-00-00-14)
|
||||
- **PWR_KEY按键**:按一次切换一个设备,实现同一条总线的分时使用
|
||||
|
||||
**核心测试流程**:
|
||||
1. 初始化当前引脚的OneWire总线
|
||||
2. 发送SEARCH ROM命令扫描总线上的设备
|
||||
3. 读取并验证设备的64位ROM ID(家族码+序列号+CRC)
|
||||
4. 使用MATCH ROM(0x55)命令选择目标设备
|
||||
5. 发送温度转换命令(0x44)并等待完成
|
||||
6. 读取温度数据并进行CRC校验
|
||||
7. 输出设备ROM ID、温度值、读取成功率
|
||||
|
||||
|
||||
|
||||
## 演示硬件环境
|
||||
1、Air780EPM核心板一块
|
||||
|
||||
2、TYPE-C USB数据线一根
|
||||
|
||||
3、ds18b20传感器两个
|
||||
|
||||
4、Air780EPM核心板和数据线的硬件接线方式为
|
||||
|
||||
- Air780EPM核心板通过TYPE-C USB口供电;(核心板USB旁边的开关拨到on一端)
|
||||
|
||||
- TYPE-C USB数据线直接插到核心板的TYPE-C USB座子,另外一端连接电脑USB口;
|
||||
|
||||
5、Air780EPM核心板和ds18b20传感器接线方式
|
||||
|
||||
### 单传感器连接
|
||||
|
||||
| Air780EPM核心板 | DS18B20传感器 |
|
||||
| --------------- | -------------------|
|
||||
| VDD_EXT | VCC |
|
||||
| 23/GPIO2 | DQ |
|
||||
| GND | GND |
|
||||
|
||||
连接图:
|
||||
|
||||

|
||||
|
||||
### 多传感器连接
|
||||
|
||||
|
||||
| Air780EPM核心板 | DS18B20传感器1 |
|
||||
| --------------- | -------------------|
|
||||
| VDD_EXT | VCC |
|
||||
| 23/GPIO2 | DQ |
|
||||
| 任意GND | GND |
|
||||
|
||||
| Air780EPM核心板 | DS18B20传感器2 |
|
||||
| --------------- | -------------------|
|
||||
| 32/GPIO31 | VCC |
|
||||
| 54/CAM_MCLK | DQ |
|
||||
| 任意GND | GND |
|
||||
|
||||
连接图:
|
||||
|
||||

|
||||
|
||||
## 演示软件环境
|
||||
|
||||
1、Luatools下载调试工具: https://docs.openluat.com/air780epm/common/Luatools/
|
||||
|
||||
2、内核固件版本:
|
||||
Air780EPM:https://docs.openluat.com/air780epm/luatos/firmware/version/
|
||||
|
||||
## 演示核心步骤
|
||||
1、搭建好硬件环境
|
||||
|
||||
2、通过Luatools将demo与固件烧录到核心板或开发板中
|
||||
|
||||
3、烧录好后,板子开机将会在Luatools上看到如下打印:
|
||||
|
||||
```lua
|
||||
(1)单传感器演示
|
||||
[2025-11-24 23:46:59.904][000000000.251] I/user.main onewire_demo 1.0.0
|
||||
[2025-11-24 23:46:59.932][000000000.258] I/user.onewire_single_app 单传感器模块版本: 002.002.000
|
||||
[2025-11-24 23:46:59.970][000000000.258] I/user.onewire_single_app 单传感器应用模块加载完成
|
||||
[2025-11-24 23:47:00.002][000000000.259] I/user.onewire_single_app 启动单传感器应用
|
||||
[2025-11-24 23:47:00.032][000000000.259] I/user.onewire_single_app 初始化OneWire总线...
|
||||
[2025-11-24 23:47:00.064][000000000.259] I/user.onewire_single_app OneWire总线初始化完成,使用GPIO2默认引脚
|
||||
[2025-11-24 23:47:00.096][000000000.259] I/user.onewire_single_app 检测DS18B20设备...
|
||||
[2025-11-24 23:47:00.124][000000000.267] I/user.onewire_single_app 探测到DS18B20 2859F253000000 14
|
||||
[2025-11-24 23:47:00.159][000000000.267] I/user.onewire_single_app 开始连续温度监测...
|
||||
[2025-11-24 23:47:00.186][000000000.276] I/user.onewire_single_app 温度转换完成
|
||||
[2025-11-24 23:47:00.216][000000000.289] I/user.onewire_single_app 温度读取成功: 85.00°C
|
||||
[2025-11-24 23:47:00.246][000000000.290] W/user.onewire_single_app 温度偏高: 85.00°C
|
||||
[2025-11-24 23:47:00.409][000000003.299] I/user.onewire_single_app 温度转换完成
|
||||
[2025-11-24 23:47:00.436][000000003.312] I/user.onewire_single_app 温度读取成功: 28.25°C
|
||||
[2025-11-24 23:47:00.465][000000003.313] I/user.onewire_single_app 温度正常: 28.25°C
|
||||
[2025-11-24 23:47:03.404][000000006.322] I/user.onewire_single_app 温度转换完成
|
||||
[2025-11-24 23:47:03.437][000000006.335] I/user.onewire_single_app 温度读取成功: 28.25°C
|
||||
[2025-11-24 23:47:03.469][000000006.335] I/user.onewire_single_app 温度正常: 28.25°C
|
||||
|
||||
(2)双传感器演示
|
||||
[2025-11-24 23:49:45.699][000000000.260] I/user.onewire_multi_app 双传感器应用模块加载完成(54和23切换)
|
||||
[2025-11-24 23:49:45.732][000000000.261] I/user.onewire_multi_app 启动双传感器应用(引脚54和23)
|
||||
[2025-11-24 23:49:45.761][000000000.261] I/user.onewire_multi_app 初始化硬件配置...
|
||||
[2025-11-24 23:49:45.789][000000000.261] I/user.onewire_multi_app 硬件初始化完成
|
||||
[2025-11-24 23:49:45.822][000000000.262] I/user.onewire_multi_app 初始引脚: 引脚54 (ONEWIRE功能)
|
||||
[2025-11-24 23:49:45.859][000000000.262] I/user.onewire_multi_app 切换按键: PWR_KEY
|
||||
[2025-11-24 23:49:45.898][000000000.262] I/user.onewire_multi_app 支持引脚: 54 和 23 循环切换
|
||||
[2025-11-24 23:49:45.932][000000000.262] I/user.onewire_multi_app 电源控制: GPIO31/GPIO2 (已设置为高电平)
|
||||
[2025-11-24 23:49:45.963][000000000.262] I/user.onewire_multi_app 电源控制: 开启
|
||||
[2025-11-24 23:49:45.997][000000000.363] I/user.onewire_multi_app 初始化OneWire总线,通道: 0
|
||||
[2025-11-24 23:49:46.026][000000000.374] I/user.onewire_multi_app OneWire总线初始化完成,通道: 0,引脚:54
|
||||
[2025-11-24 23:49:46.059][000000000.573] I/user.onewire_multi_app 检测DS18B20设备,引脚: 54
|
||||
[2025-11-24 23:49:46.089][000000000.575] I/user.onewire_multi_app 检测到DS18B20设备响应
|
||||
[2025-11-24 23:49:46.117][000000000.575] I/user.onewire_multi_app 开始双传感器连续监测...
|
||||
[2025-11-24 23:49:46.148][000000000.575] I/user.onewire_multi_app 按PWR_KEY按键可切换引脚(54和23)
|
||||
[2025-11-24 23:49:46.181][000000000.575] I/user.onewire_multi_app 第1次读取,引脚:54
|
||||
[2025-11-24 23:49:46.212][000000000.575] I/user.onewire_multi_app 开始读取DS18B20温度,引脚: 54
|
||||
[2025-11-24 23:49:46.243][000000000.576] I/user.onewire_multi_app 读取设备ROM ID
|
||||
[2025-11-24 23:49:46.272][000000000.583] I/user.onewire_multi_app ROM ID校验成功: 289FC493000000 14
|
||||
[2025-11-24 23:49:46.297][000000000.583] I/user.onewire_multi_app 开始温度转换
|
||||
[2025-11-24 23:49:46.325][000000000.590] I/user.onewire_multi_app 等待温度转换完成
|
||||
[2025-11-24 23:49:46.401][000000001.341] I/user.onewire_multi_app 温度转换完成
|
||||
[2025-11-24 23:49:46.433][000000001.342] I/user.onewire_multi_app 读取温度数据
|
||||
[2025-11-24 23:49:46.466][000000001.354] I/user.onewire_multi_app CRC校验和温度计算
|
||||
[2025-11-24 23:49:46.499][000000001.355] I/user.onewire_multi_app 温度读取成功: 27.44°C
|
||||
[2025-11-24 23:49:46.530][000000001.355] I/user.onewire_multi_app 引脚54温度: 27.44°C 成功率: 100.0%
|
||||
[2025-11-24 23:49:46.630][000000003.355] I/user.onewire_multi_app 第2次读取,引脚:54
|
||||
[2025-11-24 23:49:46.665][000000003.356] I/user.onewire_multi_app 开始读取DS18B20温度,引脚: 54
|
||||
[2025-11-24 23:49:46.698][000000003.356] I/user.onewire_multi_app 读取设备ROM ID
|
||||
[2025-11-24 23:49:46.727][000000003.363] I/user.onewire_multi_app ROM ID校验成功: 289FC493000000 14
|
||||
[2025-11-24 23:49:46.765][000000003.363] I/user.onewire_multi_app 开始温度转换
|
||||
[2025-11-24 23:49:46.799][000000003.371] I/user.onewire_multi_app 等待温度转换完成
|
||||
[2025-11-24 23:49:46.982][000000004.122] I/user.onewire_multi_app 温度转换完成
|
||||
[2025-11-24 23:49:47.010][000000004.123] I/user.onewire_multi_app 读取温度数据
|
||||
[2025-11-24 23:49:47.043][000000004.135] I/user.onewire_multi_app CRC校验和温度计算
|
||||
[2025-11-24 23:49:47.077][000000004.136] I/user.onewire_multi_app 温度读取成功: 27.50°C
|
||||
[2025-11-24 23:49:47.110][000000004.137] I/user.onewire_multi_app 引脚54温度: 27.50°C 成功率: 100.0%
|
||||
[2025-11-24 23:49:48.999][000000006.137] I/user.onewire_multi_app 第3次读取,引脚:54
|
||||
[2025-11-24 23:49:49.030][000000006.138] I/user.onewire_multi_app 开始读取DS18B20温度,引脚: 54
|
||||
[2025-11-24 23:49:49.061][000000006.138] I/user.onewire_multi_app 读取设备ROM ID
|
||||
[2025-11-24 23:49:49.094][000000006.145] I/user.onewire_multi_app ROM ID校验成功: 289FC493000000 14
|
||||
[2025-11-24 23:49:49.124][000000006.145] I/user.onewire_multi_app 开始温度转换
|
||||
[2025-11-24 23:49:49.154][000000006.153] I/user.onewire_multi_app 等待温度转换完成
|
||||
[2025-11-24 23:49:49.778][000000006.904] I/user.onewire_multi_app 温度转换完成
|
||||
[2025-11-24 23:49:49.806][000000006.905] I/user.onewire_multi_app 读取温度数据
|
||||
[2025-11-24 23:49:49.836][000000006.917] I/user.onewire_multi_app CRC校验和温度计算
|
||||
[2025-11-24 23:49:49.866][000000006.918] I/user.onewire_multi_app 温度读取成功: 27.50°C
|
||||
[2025-11-24 23:49:49.907][000000006.919] I/user.onewire_multi_app 引脚54温度: 27.50°C 成功率: 100.0%
|
||||
|
||||
(3)双传感器按键切换演示
|
||||
[2025-11-24 23:49:51.147][000000008.278] I/user.onewire_multi_app 切换按键被按下
|
||||
[2025-11-24 23:49:51.783][000000008.919] I/user.onewire_multi_app 切换OneWire引脚...
|
||||
[2025-11-24 23:49:51.821][000000008.939] I/user.onewire_multi_app 将PAD54配置为GPIO3 true
|
||||
[2025-11-24 23:49:51.856][000000008.940] I/user.onewire_multi_app 将GPIO3设置为高电平输出 function: 0C7F4A10
|
||||
[2025-11-24 23:49:51.897][000000008.940] I/user.onewire_multi_app 切换到引脚23
|
||||
[2025-11-24 23:49:51.933][000000008.940] I/user.onewire_multi_app 当前使用引脚: 23
|
||||
[2025-11-24 23:49:51.965][000000008.941] I/user.onewire_multi_app 将引脚23配置为ONEWIRE功能 true
|
||||
[2025-11-24 23:49:51.994][000000008.961] I/user.onewire_multi_app 引脚切换完成,当前使用: 引脚23
|
||||
[2025-11-24 23:49:52.324][000000009.461] I/user.onewire_multi_app 初始化OneWire总线,通道: 0
|
||||
[2025-11-24 23:49:52.356][000000009.471] I/user.onewire_multi_app OneWire总线初始化完成,通道: 0,引脚:23
|
||||
[2025-11-24 23:49:52.431][000000009.571] I/user.onewire_multi_app 第4次读取,引脚:23
|
||||
[2025-11-24 23:49:52.474][000000009.571] I/user.onewire_multi_app 开始读取DS18B20温度,引脚: 23
|
||||
[2025-11-24 23:49:52.519][000000009.572] I/user.onewire_multi_app 读取设备ROM ID
|
||||
[2025-11-24 23:49:52.563][000000009.579] I/user.onewire_multi_app ROM ID校验成功: 2859F253000000 14
|
||||
[2025-11-24 23:49:52.593][000000009.579] I/user.onewire_multi_app 开始温度转换
|
||||
[2025-11-24 23:49:52.622][000000009.587] I/user.onewire_multi_app 等待温度转换完成
|
||||
[2025-11-24 23:49:53.203][000000010.338] I/user.onewire_multi_app 温度转换完成
|
||||
[2025-11-24 23:49:53.239][000000010.339] I/user.onewire_multi_app 读取温度数据
|
||||
[2025-11-24 23:49:53.272][000000010.351] I/user.onewire_multi_app CRC校验和温度计算
|
||||
[2025-11-24 23:49:53.302][000000010.352] I/user.onewire_multi_app 温度读取成功: 27.81°C
|
||||
[2025-11-24 23:49:53.332][000000010.353] I/user.onewire_multi_app 引脚23温度: 27.81°C 成功率: 100.0%
|
||||
|
||||
|
||||
```
|
||||
Reference in New Issue
Block a user