09 onewire
作者:王棚嶙 | 最后修改:2026-04-13
一、概述
OneWire(单总线)是一种由Dallas Semiconductor(现Maxim Integrated)开发的通信协议,它只需要一根数据线(加上地线)即可实现双向通信。这种协议广泛应用于温度传感器(如DS18B20)、存储器、ADC/DAC等设备。LuatOS支持OneWire协议,允许开发者方便地与各种单总线设备进行通信。
1.1 OneWire协议简介
- 协议特点:单线双向通信,节省IO资源
- 通信速率:标准模式16kbps,高速模式142kbps
- 拓扑结构:总线型拓扑,支持多设备并联
- 设备类型:温度传感器、存储器、ADC、DAC等
- 供电方式:支持寄生供电和外部供电
1.2 硬件接口特性
- 管脚映射:可参考各型号管脚复用表,配置管脚作为OneWire总线
- 上拉电阻:需要4.7kΩ上拉电阻到VCC(3.3V)
- 总线电容:建议总线电容不超过1000pF
- 电缆长度:标准模式下可达100米
1.3 设备地址说明
OneWire设备地址由8字节组成:
--[[
设备地址格式:
字节0:家族码(Family Code)
字节1-6:序列号(Serial Number)
字节7:CRC校验码
常见家族码:
0x10:DS18S20温度传感器
0x28:DS18B20温度传感器
0x22:DS1822温度传感器
0x42:DS28EA00温度传感器
]]
二、准备硬件环境
参考:硬件环境清单第二章节内容,准备以及组装好硬件环境。
1、Air8000A核心板一块
2、TYPE-C USB数据线一根
3、ds18b20传感器两个
4、Air8000A核心板和数据线的硬件接线方式为
- Air8000A核心板通过TYPE-C USB口供电;(核心板USB旁边的开关拨到on一端)
- TYPE-C USB数据线直接插到核心板的TYPE-C USB座子,另外一端连接电脑USB口;
5、Air8000A核心板和ds18b20传感器接线方式
2.1 单传感器连接
| Air8000A核心板 | DS18B20传感器 |
|---|---|
| VDD_EXT | VCC |
| GPIO2 | DQ |
| GND | GND |
连接图:

2.2 多传感器连接
| Air8000A核心板 | DS18B20传感器1 |
|---|---|
| VDD_EXT | VCC |
| GPIO2 | DQ |
| 任意GND | GND |
| Air8000A核心板 | DS18B20传感器2 |
|---|---|
| GPIO20 | VCC |
| GPIO3 | DQ |
| 任意GND | GND |
连接图:

三、软件环境
在开始实践本示例之前,先筹备一下软件环境:
1、Luatools工具;
2、内核固件文件(底层core固件文件):本demo开发测试时使用的固件为Air8000 V2032 版本固件,本demo对固件版本没有什么特殊要求,所以你如果要测试本demo时,可以直接使用最新版本的内核固件;如果发现最新版本的内核固件测试有问题,可以使用我们开发本demo时使用的内核固件版本来对比测试;
3、 luatos需要的脚本和资源文件
脚本和资源文件点我,查看demo链接
lib脚本文件:使用Luatools烧录时,勾选 添加默认lib 选项,使用默认lib脚本文件;
准备好软件环境之后,接下来查看如何烧录项目文件到Air8000核心板,将本篇文章中演示使用的项目文件烧录到Air8000核心板中。
四、演示功能概述
4.1 主程序入口模块 (main.lua)
- 初始化项目信息和版本号
- 初始化看门狗,并定时喂狗
- 启动一个循环定时器,每隔3秒钟打印一次总内存,实时的已使用内存,历史最高的已使用内存情况方便分析内存使用是否有异常
- 加载onewire_single_app模块(通过require "onewire_single_app")
- 加载onewire_multi_app模块(通过require "onewire_multi_app")
4.2 单传感器模式 (onewire_single_app.lua)
- 使用GPIO2默认OneWire功能,硬件通道0模式,无需引脚复用
- 完整的CRC8数据校验机制,确保数据可靠性
- 设备自动识别和ROM验证,支持设备类型检测
- 3秒间隔连续温度监测,实时温度报警功能
- zbuff缓冲区优化,提高数据传输效率
4.3 多传感器模式 (onewire_multi_app.lua)
4.3.1 单总线多设备挂载原理:
-
物理连接:所有DS18B20的VDD、GND、DQ引脚分别并联到同一组单总线
-
设备识别:每个DS18B20出厂时烧录了全球唯一的64位ROM ID
-
总线扫描:主机发送SEARCH ROM(0xF0)命令发现总线上的所有设备
-
设备选择:通过MATCH ROM(0x55)命令+目标设备ROM ID选择特定设备通信
-
分时操作:每次只与一个设备通信,避免总线冲突
4.3.2 分时复用测试逻辑(2秒切换一次):
-
前2秒:使用总线端A设备(引脚98,ROM ID: 28-9F-C4-93-00-00-00-14)
-
按PWR_KEY后2秒:切换使用总线端B设备(引脚30,ROM ID: 28-59-F2-53-00-00-00-14)
-
循环切换:按键一次切换一个设备,实现同一条总线的分时使用
4.3.3 核心测试流程:
- 初始化当前引脚的OneWire总线
- 发送SEARCH ROM命令扫描总线上的设备
- 读取并验证设备的64位ROM ID(家族码+序列号+CRC)
- 使用MATCH ROM(0x55)命令选择目标设备
- 发送温度转换命令(0x44)并等待完成
- 读取温度数据并进行CRC校验
- 输出设备ROM ID、温度值、读取成功率
五、核心代码
log.info("onewire_single_app", "单传感器模块版本")
-- 设置所有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)
-- 发送温度转换命令
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", "单传感器应用模块加载完成")
log.info("onewire_multi_app", "多传感器模块版本: 1.0.0")
-- 设置所有GPIO引脚电压为3.3V,确保DS18B20传感器正常供电
pm.ioVol(pm.IOVOL_ALL_GPIO, 3300)
-- GPIO20控制传感器电源使能,确保DS18B20供电正常
gpio.setup(20, 1)
-- 硬件配置(双设备模式:支持引脚30和98切换)
local onewire_pin = 98
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", "支持引脚: 98 和 30 循环切换")
log.info("onewire_multi_app", "电源控制: GPIO20(已设置为高电平)")
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
-- 单总线分时使用引脚切换(同一条总线,分时复用)
-- 核心逻辑:使用GPIO98和GPIO30两个引脚连接同一条OneWire总线,实现分时复用
-- 应用场景:当需要在同一总线上分时访问不同设备时使用
-- 技术原理:通过切换总线连接引脚,实现同一条物理总线的分时使用
-- 切换效果:
-- - GPIO98:当前时间段连接设备A(ROM ID: 28-9F-C4-93-00-00-00-14)
-- - GPIO30:切换到时间段连接设备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 == 98 then
-- 从98切换到30
-- 将PIN98配置为GPIO3功能,不再作为OneWire使用
log.info("onewire_multi_app", "将PIN98配置为GPIO3", pins.setup(98, "GPIO3"))
-- 设置GPIO3为高电平输出(开漏模式,高电平由上拉电阻提供)
log.info("onewire_multi_app", "将GPIO3设置为高电平输出(OneWire总线空闲状态)", gpio.setup(3, 1))
onewire_pin = 30
log.info("onewire_multi_app", "切换到引脚30")
else
-- 从30切换到98
-- 将PIN30配置为GPIO2功能,不再作为OneWire使用
log.info("onewire_multi_app", "将PIN30配置为GPIO2", pins.setup(30, "GPIO2"))
-- 设置GPIO2为高电平输出(开漏模式,高电平由上拉电阻提供)
log.info("onewire_multi_app", "将GPIO2设置为高电平输出(OneWire总线空闲状态)", gpio.setup(2, 1))
onewire_pin = 98
log.info("onewire_multi_app", "切换到引脚98")
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", "启动双传感器应用(引脚30和98)")
-- 初始化硬件
if not init_hardware() then
log.error("onewire_multi_app", "硬件初始化失败,任务无法启动")
return
end
-- 初始化OneWire总线(GPIO20已在init_hardware中设置为高电平供电)
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. 传感器连接引脚98或30")
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按键可切换引脚(30和98)")
-- 主循环:按键切换设备,分时读取温度
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", "双传感器应用模块加载完成(30和98切换)")
六、运行结果展示
1、搭建好硬件环境;
2、Luatools 烧录内核固件和 脚本代码;
3、烧录成功后,自动开机运行,查看打印日志,如果正常运行,会打印如下日志;
6.1 单传感器模式
- 使用GPIO2默认OneWire功能,硬件通道0模式,无需引脚复用
- 完整的CRC8数据校验机制,确保数据可靠性
- 设备自动识别和ROM验证,支持设备类型检测
- 3秒间隔连续温度监测,实时温度报警功能
- zbuff缓冲区优化,提高数据传输效率
(1)单传感器演示
[2025-11-25 15:14:59.660][000000000.387] I/user.onewire_single_app 单传感器模块版本:1.0.0
[2025-11-25 15:14:59.683][000000000.387] I/user.onewire_single_app 单传感器应用模块加载完成
[2025-11-25 15:14:59.705][000000000.387] I/user.onewire_single_app 启动单传感器应用
[2025-11-25 15:14:59.721][000000000.388] I/user.onewire_single_app 初始化OneWire总线...
[2025-11-25 15:14:59.737][000000000.388] I/user.onewire_single_app OneWire总线初始化完成,使用GPIO2默认引脚
[2025-11-25 15:14:59.755][000000000.388] I/user.onewire_single_app 检测DS18B20设备...
[2025-11-25 15:14:59.769][000000000.395] I/user.onewire_single_app 探测到DS18B20 2859F253000000 14
[2025-11-25 15:14:59.793][000000000.396] I/user.onewire_single_app 开始连续温度监测...
[2025-11-25 15:14:59.817][000000000.405] I/user.onewire_single_app 温度转换完成
[2025-11-25 15:14:59.842][000000000.418] I/user.onewire_single_app 温度读取成功: 26.12°C
[2025-11-25 15:14:59.858][000000000.419] I/user.onewire_single_app 温度正常: 26.12°C
[2025-11-25 15:15:00.727][000000003.428] I/user.onewire_single_app 温度转换完成
[2025-11-25 15:15:00.751][000000003.441] I/user.onewire_single_app 温度读取成功: 26.12°C
[2025-11-25 15:15:00.766][000000003.442] I/user.onewire_single_app 温度正常: 26.12°C
[2025-11-25 15:15:03.755][000000006.451] I/user.onewire_single_app 温度转换完成
[2025-11-25 15:15:03.771][000000006.464] I/user.onewire_single_app 温度读取成功: 26.12°C
[2025-11-25 15:15:03.788][000000006.465] I/user.onewire_single_app 温度正常: 26.12°C
[2025-11-25 15:15:06.775][000000009.474] I/user.onewire_single_app 温度转换完成
[2025-11-25 15:15:06.794][000000009.487] I/user.onewire_single_app 温度读取成功: 26.12°C
[2025-11-25 15:15:06.817][000000009.488] I/user.onewire_single_app 温度正常: 26.12°C
[2025-11-25 15:15:09.800][000000012.497] I/user.onewire_single_app 温度转换完成
[2025-11-25 15:15:09.812][000000012.510] I/user.onewire_single_app 温度读取成功: 26.12°C
[2025-11-25 15:15:09.832][000000012.511] I/user.onewire_single_app 温度正常: 26.12°C
[2025-11-25 15:15:12.830][000000015.520] I/user.onewire_single_app 温度转换完成
[2025-11-25 15:15:12.842][000000015.533] I/user.onewire_single_app 温度读取成功: 26.12°C
[2025-11-25 15:15:12.856][000000015.534] I/user.onewire_single_app 温度正常: 26.12°C
6.2 多传感器模式 (onewire_multi_app.lua)
6.2.1 单总线多设备挂载原理:
-
物理连接:所有DS18B20的VDD、GND、DQ引脚分别并联到同一组单总线
-
设备识别:每个DS18B20出厂时烧录了全球唯一的64位ROM ID
-
总线扫描:主机发送SEARCH ROM(0xF0)命令发现总线上的所有设备
-
设备选择:通过MATCH ROM(0x55)命令+目标设备ROM ID选择特定设备通信
-
分时操作:每次只与一个设备通信,避免总线冲突
(2)单总线分时复用演示
[2025-11-25 15:10:27.765][000000000.393] I/user.onewire_multi_app 多传感器模块版本: 1.0.0
[2025-11-25 15:10:27.826][000000000.394] I/user.onewire_multi_app 双传感器应用模块加载完成(30和98切换)
[2025-11-25 15:10:27.910][000000000.394] I/user.onewire_multi_app 启动双传感器应用(引脚30和98)
[2025-11-25 15:10:27.968][000000000.394] I/user.onewire_multi_app 初始化硬件配置...
[2025-11-25 15:10:28.023][000000000.395] I/user.onewire_multi_app 硬件初始化完成
[2025-11-25 15:10:28.067][000000000.395] I/user.onewire_multi_app 初始引脚: 引脚98 (ONEWIRE功能)
[2025-11-25 15:10:28.115][000000000.396] I/user.onewire_multi_app 切换按键: PWR_KEY
[2025-11-25 15:10:28.174][000000000.396] I/user.onewire_multi_app 支持引脚: 98 和 30 循环切换
[2025-11-25 15:10:28.235][000000000.396] I/user.onewire_multi_app 电源控制: GPIO31/GPIO2 (已设置为高电平)
[2025-11-25 15:10:28.284][000000000.396] I/user.onewire_multi_app 电源控制: 开启
[2025-11-25 15:10:28.312][000000000.497] I/user.onewire_multi_app 初始化OneWire总线,通道: 0
[2025-11-25 15:10:28.350][000000000.508] I/user.onewire_multi_app OneWire总线初始化完成,通道: 0,引脚:98
[2025-11-25 15:10:28.468][000000000.709] I/user.onewire_multi_app 检测DS18B20设备,引脚: 98
[2025-11-25 15:10:28.502][000000000.710] I/user.onewire_multi_app 检测到DS18B20设备响应
[2025-11-25 15:10:28.531][000000000.710] I/user.onewire_multi_app 开始双传感器连续监测...
[2025-11-25 15:10:28.561][000000000.710] I/user.onewire_multi_app 按PWR_KEY按键可切换引脚(30和98)
[2025-11-25 15:10:28.592][000000000.711] I/user.onewire_multi_app 第1次读取,引脚:98
[2025-11-25 15:10:28.625][000000000.711] I/user.onewire_multi_app 开始读取DS18B20温度,引脚: 98
[2025-11-25 15:10:28.653][000000000.711] I/user.onewire_multi_app 读取设备ROM ID
[2025-11-25 15:10:28.685][000000000.718] I/user.onewire_multi_app ROM ID校验成功: 289FC493000000 14
[2025-11-25 15:10:28.719][000000000.719] I/user.onewire_multi_app 开始温度转换
[2025-11-25 15:10:28.747][000000000.726] I/user.onewire_multi_app 等待温度转换完成
[2025-11-25 15:10:28.777][000000001.478] I/user.onewire_multi_app 温度转换完成
[2025-11-25 15:10:28.800][000000001.478] I/user.onewire_multi_app 读取温度数据
[2025-11-25 15:10:28.828][000000001.491] I/user.onewire_multi_app CRC校验和温度计算
[2025-11-25 15:10:28.860][000000001.492] I/user.onewire_multi_app 温度读取成功: 25.75°C
[2025-11-25 15:10:28.890][000000001.492] I/user.onewire_multi_app 引脚98温度: 25.75°C 成功率: 100.0%
[2025-11-25 15:10:29.029][000000003.493] I/user.onewire_multi_app 第2次读取,引脚:98
[2025-11-25 15:10:29.063][000000003.493] I/user.onewire_multi_app 开始读取DS18B20温度,引脚: 98
[2025-11-25 15:10:29.094][000000003.493] I/user.onewire_multi_app 读取设备ROM ID
[2025-11-25 15:10:29.124][000000003.500] I/user.onewire_multi_app ROM ID校验成功: 289FC493000000 14
[2025-11-25 15:10:29.158][000000003.501] I/user.onewire_multi_app 开始温度转换
[2025-11-25 15:10:29.192][000000003.508] I/user.onewire_multi_app 等待温度转换完成
[2025-11-25 15:10:29.220][000000004.260] I/user.onewire_multi_app 温度转换完成
[2025-11-25 15:10:29.251][000000004.260] I/user.onewire_multi_app 读取温度数据
[2025-11-25 15:10:29.281][000000004.273] I/user.onewire_multi_app CRC校验和温度计算
[2025-11-25 15:10:29.308][000000004.274] I/user.onewire_multi_app 温度读取成功: 25.81°C
[2025-11-25 15:10:29.342][000000004.274] I/user.onewire_multi_app 引脚98温度: 25.81°C 成功率: 100.0%
6.2.2 分时复用测试逻辑(2秒切换一次):
-
前2秒:使用总线端A设备(引脚98,ROM ID: 28-9F-C4-93-00-00-00-14)
-
按PWR_KEY后2秒:切换使用总线端B设备(引脚30,ROM ID: 28-59-F2-53-00-00-00-14)
-
循环切换:按键一次切换一个设备,实现同一条总线的分时使用
(3)单总线分时复用按键切换演示
[2025-11-25 15:10:34.504][000000010.718] I/user.onewire_multi_app 切换按键被按下
[2025-11-25 15:10:35.624][000000011.838] I/user.onewire_multi_app 切换OneWire引脚...
[2025-11-25 15:10:35.647][000000011.859] I/user.onewire_multi_app 将PIN984配置为GPIO3 true
[2025-11-25 15:10:35.677][000000011.859] I/user.onewire_multi_app 将GPIO3设置为高电平输出 function: 0C7F4648
[2025-11-25 15:10:35.698][000000011.859] I/user.onewire_multi_app 切换到引脚30
[2025-11-25 15:10:35.721][000000011.860] I/user.onewire_multi_app 当前使用引脚: 30
[2025-11-25 15:10:35.745][000000011.860] I/user.onewire_multi_app 将引脚30配置为ONEWIRE功能 true
[2025-11-25 15:10:35.769][000000011.880] I/user.onewire_multi_app 引脚切换完成,当前使用: 引脚30
[2025-11-25 15:10:36.167][000000012.380] I/user.onewire_multi_app 初始化OneWire总线,通道: 0
[2025-11-25 15:10:36.189][000000012.391] I/user.onewire_multi_app OneWire总线初始化完成,通道: 0,引脚:30
[2025-11-25 15:10:36.275][000000012.490] I/user.onewire_multi_app 第5次读取,引脚:30
[2025-11-25 15:10:36.296][000000012.491] I/user.onewire_multi_app 开始读取DS18B20温度,引脚: 30
[2025-11-25 15:10:36.315][000000012.491] I/user.onewire_multi_app 读取设备ROM ID
[2025-11-25 15:10:36.335][000000012.498] I/user.onewire_multi_app ROM ID校验成功: 2859F253000000 14
[2025-11-25 15:10:36.361][000000012.499] I/user.onewire_multi_app 开始温度转换
[2025-11-25 15:10:36.390][000000012.506] I/user.onewire_multi_app 等待温度转换完成
[2025-11-25 15:10:37.038][000000013.258] I/user.onewire_multi_app 温度转换完成
[2025-11-25 15:10:37.063][000000013.258] I/user.onewire_multi_app 读取温度数据
[2025-11-25 15:10:37.084][000000013.271] I/user.onewire_multi_app CRC校验和温度计算
[2025-11-25 15:10:37.107][000000013.272] I/user.onewire_multi_app 温度读取成功: 26.00°C
[2025-11-25 15:10:37.130][000000013.272] I/user.onewire_multi_app 引脚30温度: 26.00°C 成功率: 100.0%
七、注意事项
暂无