|
|
@@ -1,341 +1,416 @@
|
|
|
--[[
|
|
|
-@module tfcard_app
|
|
|
-@summary TF卡文件操作测试模块
|
|
|
-@version 1.0.0
|
|
|
-@date 2025.08.25
|
|
|
-@author 王棚嶙
|
|
|
+@module onewire_multi_app
|
|
|
+@summary OneWire多DS18B20温度传感器应用演示模块(带切换功能)
|
|
|
+@version 002.002.000
|
|
|
+@date 2025.11.25
|
|
|
+@author 王棚嶙嶙
|
|
|
@usage
|
|
|
-本文件为TF卡的文件操作测试流程:
|
|
|
-1. 创建目录
|
|
|
-2. 创建并写入文件
|
|
|
-3. 检查文件是否存在
|
|
|
-4. 获取文件大小
|
|
|
-5. 读取文件内容
|
|
|
-6. 启动计数文件操作
|
|
|
-7. 文件追加测试
|
|
|
-8. 按行读取测试
|
|
|
-9. 读取后关闭文件
|
|
|
-10. 文件重命名
|
|
|
-11. 列举目录内容
|
|
|
-12. 删除文件
|
|
|
-13. 删除目录
|
|
|
-本文件没有对外接口,直接在main.lua中require "tfcard_app"就可以加载运行
|
|
|
-]]
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-local function tfcard_main_task() -- 开始进行主测试流程。
|
|
|
- -- ########## SPI初始化 ##########
|
|
|
- -- 如果使用核心板演示环境,请打开33——36行代码,同时关闭38——43行的代码。
|
|
|
- -- 如果使用开发板演示环境,请打开38——43行代码,同时关闭33——36行的代码。
|
|
|
- -- 在Air780EHM/EHV/EGH核心板上TF卡的的pin_cs为gpio8,spi_id为0.请根据实际硬件修改
|
|
|
- spi_id, pin_cs = 0, 8
|
|
|
- spi.setup(spi_id, nil, 0, 0, 400 * 1000)
|
|
|
- --初始化后拉高pin_cs,准备开始挂载TF卡
|
|
|
- gpio.setup(pin_cs, 1)
|
|
|
-
|
|
|
- -- Air780EHM/EHV/EGH开发板上的pin_cs为gpio16,spi_id为0.请根据实际硬件修改
|
|
|
- -- spi_id, pin_cs = 0, 16
|
|
|
- -- spi.setup(spi_id, nil, 0, 0, 400 * 1000)
|
|
|
- --设置片选引脚同一spi总线上的所有从设备在初始化时必须要先拉高CS脚,防止从设备之间互相干扰。
|
|
|
- -- 在Air780EHM/EHV/EGH开发板上,TF卡和ch390共用SPI0总线。
|
|
|
- -- gpio.setup(pin_cs, 1)
|
|
|
-
|
|
|
- -- ########## 开始进行tf卡挂载 ##########
|
|
|
- -- 挂载失败默认格式化,
|
|
|
- -- 如无需格式化应改为fatfs.mount(fatfs.SPI, "/sd", spi_id, pin_cs, 24 * 1000 * 1000, nil, 1, false),
|
|
|
- -- 一般是在测试硬件是否有问题的时候把格式化取消掉
|
|
|
- mount_ok, mount_err = fatfs.mount(fatfs.SPI, "/sd", spi_id, pin_cs, 24 * 1000 * 1000)
|
|
|
- if mount_ok then
|
|
|
- log.info("fatfs.mount", "挂载成功", mount_err)
|
|
|
- else
|
|
|
- log.error("fatfs.mount", "挂载失败", mount_err)
|
|
|
- goto resource_cleanup
|
|
|
- end
|
|
|
-
|
|
|
- -- ########## 获取SD卡的可用空间信息并打印。 ##########
|
|
|
- data, err = fatfs.getfree("/sd")
|
|
|
- if data then
|
|
|
- --打印SD卡的可用空间信息
|
|
|
- log.info("fatfs", "getfree", json.encode(data))
|
|
|
- else
|
|
|
- --打印错误信息
|
|
|
- log.info("fatfs", "getfree", "err", err)
|
|
|
- goto resource_cleanup
|
|
|
+本模块演示多DS18B20温度传感器的完整功能:
|
|
|
+1. 多传感器切换控制
|
|
|
+2. 电源管理(GPIO控制)
|
|
|
+3. 按键切换传感器
|
|
|
+4. 多路温度同时监测
|
|
|
+5. 使用引脚复用功能(pins.setup)
|
|
|
+]]
|
|
|
+
|
|
|
+log.info("onewire_multi_app", "多传感器模块版本: 002.002.000")
|
|
|
+
|
|
|
+-- 设置所有GPIO引脚电压为3.3V,确保DS18B20传感器正常供电
|
|
|
+pm.ioVol(pm.IOVOL_ALL_GPIO, 3300)
|
|
|
+
|
|
|
+-- GPIO2和GPIO31控制电源,确保DS18B20供电正常
|
|
|
+gpio.setup(2, 1) -- GPIO2输出高电平
|
|
|
+gpio.setup(31, 1) -- GPIO31输出高电平
|
|
|
+
|
|
|
+-- 传感器配置
|
|
|
+local sensor_config = {
|
|
|
+ {pin = 2, channel = 0, name = "GPIO2(默认)"}, -- GPIO2使用通道0
|
|
|
+ {pin = 54, channel = 3, name = "引脚54(复用)"} -- 引脚54使用通道3
|
|
|
+}
|
|
|
+
|
|
|
+local current_sensor = 1 -- 当前使用的传感器索引
|
|
|
+
|
|
|
+-- DS18B20命令定义
|
|
|
+local CMD_CONVERT_T = 0x44 -- 温度转换命令
|
|
|
+local CMD_READ_SCRATCHPAD = 0xBE -- 读取暂存器命令
|
|
|
+local CMD_SKIP_ROM = 0xCC -- 跳过ROM命令
|
|
|
+
|
|
|
+-- 全局状态变量
|
|
|
+local task_running = false
|
|
|
+local switch_pressed = false
|
|
|
+
|
|
|
+-- CRC8校验函数
|
|
|
+local function crc8_check(data)
|
|
|
+ if not data or #data == 0 then
|
|
|
+ return false
|
|
|
end
|
|
|
-
|
|
|
- -- 列出所有挂载点,如不需要,可注释掉。
|
|
|
- data = io.lsmount()
|
|
|
- log.info("fs", "lsmount", json.encode(data))
|
|
|
-
|
|
|
- -- ########## 功能: 启用fatfs调试模式 ##########
|
|
|
- -- fatfs.debug(1) -- 若挂载失败,可以尝试打开调试信息,查找原因.(设置调试模式)
|
|
|
-
|
|
|
- -- 执行tfcard文件操作演示
|
|
|
- log.info("文件操作", "===== 开始文件操作 =====")
|
|
|
-
|
|
|
- dir_path = "/sd/io_test"
|
|
|
-
|
|
|
- -- 1. 创建目录
|
|
|
- if io.mkdir(dir_path) then
|
|
|
- log.info("io.mkdir", "目录创建成功", "路径:" .. dir_path)
|
|
|
- else
|
|
|
- -- 检查是否目录已存在
|
|
|
- if io.exists(dir_path) then
|
|
|
- log.warn("io.mkdir", "目录已存在,跳过创建", "路径:" .. dir_path)
|
|
|
- else
|
|
|
- log.error("io.mkdir", "目录创建失败且目录不存在", "路径:" .. dir_path)
|
|
|
- goto resource_cleanup
|
|
|
+
|
|
|
+ local crc = 0
|
|
|
+ for i = 1, #data - 1 do
|
|
|
+ crc = crc ~ data:byte(i)
|
|
|
+ for j = 1, 8 do
|
|
|
+ if crc & 0x01 then
|
|
|
+ crc = (crc >> 1) ~ 0x8C
|
|
|
+ else
|
|
|
+ crc = crc >> 1
|
|
|
+ end
|
|
|
end
|
|
|
end
|
|
|
+
|
|
|
+ return crc == data:byte(#data)
|
|
|
+end
|
|
|
|
|
|
- -- 2. 创建并写入文件
|
|
|
- file_path = dir_path .. "/boottime"
|
|
|
- file = io.open(file_path, "wb")
|
|
|
- if file then
|
|
|
- file:write("这是io库API文档示例的测试内容")
|
|
|
- file:close()
|
|
|
- --在LuatOS文件操作中,执行file:close()是必须且关键的操作,它用于关闭文件句柄,释放资源,并确保数据被正确写入磁盘。
|
|
|
- -- 如果不执行file:close(),可能会导致数据丢失、文件损坏或其他不可预测的问题。
|
|
|
- log.info("文件创建", "文件写入成功", "路径:" .. file_path)
|
|
|
- else
|
|
|
- log.error("文件创建", "文件创建失败", "路径:" .. file_path)
|
|
|
- goto resource_cleanup
|
|
|
+-- 计算温度值
|
|
|
+local function calculate_temperature(data)
|
|
|
+ if not data or #data < 2 then
|
|
|
+ log.warn("onewire_multi_app", "温度数据无效或长度不足")
|
|
|
+ return nil
|
|
|
end
|
|
|
-
|
|
|
- -- 3. 检查文件是否存在
|
|
|
- if io.exists(file_path) then
|
|
|
- log.info("io.exists", "文件存在", "路径:" .. file_path)
|
|
|
- else
|
|
|
- log.error("io.exists", "文件不存在", "路径:" .. file_path)
|
|
|
- goto resource_cleanup
|
|
|
+
|
|
|
+ local temp_raw = data:byte(1) + (data:byte(2) * 256)
|
|
|
+
|
|
|
+ if temp_raw > 32767 then
|
|
|
+ temp_raw = temp_raw - 65536
|
|
|
end
|
|
|
-
|
|
|
- -- 4. 获取文件大小
|
|
|
- file_size = io.fileSize(file_path)
|
|
|
- if file_size then
|
|
|
- log.info("io.fileSize", "文件大小:" .. file_size .. "字节", "路径:" .. file_path)
|
|
|
- else
|
|
|
- log.error("io.fileSize", "获取文件大小失败", "路径:" .. file_path)
|
|
|
- goto resource_cleanup
|
|
|
+
|
|
|
+ local temperature = temp_raw * 0.0625
|
|
|
+
|
|
|
+ if temperature < -55.0 or temperature > 125.0 then
|
|
|
+ log.warn("onewire_multi_app", "温度值超出有效范围:", temperature)
|
|
|
+ return nil
|
|
|
end
|
|
|
+
|
|
|
+ return temperature
|
|
|
+end
|
|
|
|
|
|
- -- 5. 读取文件内容
|
|
|
- file = io.open(file_path, "rb")
|
|
|
- if file then
|
|
|
- content = file:read("*a")
|
|
|
- log.info("文件读取", "路径:" .. file_path, "内容:" .. content)
|
|
|
- file:close()
|
|
|
- else
|
|
|
- log.error("文件操作", "无法打开文件读取内容", "路径:" .. file_path)
|
|
|
- goto resource_cleanup
|
|
|
+-- 电源控制函数
|
|
|
+local function power_control(on)
|
|
|
+ log.info("onewire_multi_app", "电源控制:", on and "开启" or "关闭")
|
|
|
+ if on then
|
|
|
+ sys.wait(100) -- 等待电源稳定
|
|
|
end
|
|
|
+ return true
|
|
|
+end
|
|
|
|
|
|
- -- 6. 启动计数文件操作
|
|
|
- count = 0
|
|
|
- --以只读模式打开文件
|
|
|
- file = io.open(file_path, "rb")
|
|
|
- if file then
|
|
|
- data = file:read("*a")
|
|
|
- log.info("启动计数", "文件内容:", data, "十六进制:", data:toHex())
|
|
|
- count = tonumber(data) or 0
|
|
|
- file:close()
|
|
|
- else
|
|
|
- log.warn("启动计数", "文件不存在或无法打开")
|
|
|
-
|
|
|
+-- 初始化指定传感器
|
|
|
+local function init_sensor(sensor_idx)
|
|
|
+ local config = sensor_config[sensor_idx]
|
|
|
+
|
|
|
+ log.info("onewire_multi_app", "初始化传感器:", config.name, "引脚:", config.pin, "通道:", config.channel)
|
|
|
+
|
|
|
+ if config.pin == 54 then
|
|
|
+ pins.setup(config.pin, "ONEWIRE")
|
|
|
+ log.info("onewire_multi_app", "配置引脚54为ONEWIRE复用功能")
|
|
|
end
|
|
|
+
|
|
|
+ onewire.init(config.channel)
|
|
|
+ onewire.timing(config.channel, false, 0, 480, 70, 70, 410, 70, 10, 10, 15, 70)
|
|
|
+
|
|
|
+ log.info("onewire_multi_app", "传感器初始化完成:", config.name)
|
|
|
+ return config.channel
|
|
|
+end
|
|
|
|
|
|
- log.info("启动计数", "当前值:", count)
|
|
|
- count=count + 1
|
|
|
- log.info("启动计数", "更新值:", count)
|
|
|
-
|
|
|
- file = io.open(file_path, "wb")
|
|
|
- if file then
|
|
|
- file:write(tostring(count))
|
|
|
- file:close()
|
|
|
- log.info("文件写入", "路径:" .. file_path, "内容:", count)
|
|
|
+-- 检测DS18B20设备是否存在
|
|
|
+local function detect_ds18b20_device(channel)
|
|
|
+ local present = onewire.reset(channel, true)
|
|
|
+ if present then
|
|
|
+ log.info("onewire_multi_app", "通道", channel, "检测到DS18B20设备")
|
|
|
else
|
|
|
- log.error("文件写入", "无法打开文件", "路径:" .. file_path)
|
|
|
- goto resource_cleanup
|
|
|
+ log.warn("onewire_multi_app", "通道", channel, "未检测到DS18B20设备")
|
|
|
end
|
|
|
+ return present
|
|
|
+end
|
|
|
|
|
|
- -- 7. 文件追加测试
|
|
|
- append_file = dir_path .. "/test_a"
|
|
|
- -- 清理旧文件
|
|
|
- os.remove(append_file)
|
|
|
+-- 初始化OneWire总线
|
|
|
+local function init_onewire_bus(channel)
|
|
|
+ log.info("onewire_multi_app", "初始化OneWire总线,通道:", channel)
|
|
|
+ onewire.init(channel)
|
|
|
+ onewire.timing(channel, false, 0, 480, 70, 70, 410, 70, 10, 10, 15, 70)
|
|
|
+ log.info("onewire_multi_app", "OneWire总线初始化完成,通道:", channel)
|
|
|
+ return true
|
|
|
+end
|
|
|
|
|
|
- -- 创建并写入初始内容
|
|
|
- file = io.open(append_file, "wb")
|
|
|
- if file then
|
|
|
- file:write("ABC")
|
|
|
- file:close()
|
|
|
- log.info("文件创建", "路径:" .. append_file, "初始内容:ABC")
|
|
|
- else
|
|
|
- log.error("文件创建", "无法创建文件", "路径:" .. append_file)
|
|
|
- goto resource_cleanup
|
|
|
+-- 读取DS18B20温度
|
|
|
+local function read_ds18b20_temperature(channel)
|
|
|
+ log.info("onewire_multi_app", "读取DS18B20温度,通道:", channel)
|
|
|
+
|
|
|
+ local tbuff = zbuff.create(2)
|
|
|
+ local rbuff = zbuff.create(9)
|
|
|
+
|
|
|
+ local present = onewire.reset(channel, true)
|
|
|
+ if not present then
|
|
|
+ log.warn("onewire_multi_app", "通道", channel, "设备未响应")
|
|
|
+ return nil
|
|
|
end
|
|
|
-
|
|
|
- -- 追加内容
|
|
|
- file = io.open(append_file, "a+")
|
|
|
- if file then
|
|
|
- file:write("def")
|
|
|
- file:close()
|
|
|
- log.info("文件追加", "路径:" .. append_file, "追加内容:def")
|
|
|
- else
|
|
|
- log.error("文件追加", "无法打开文件进行追加", "路径:" .. append_file)
|
|
|
- goto resource_cleanup
|
|
|
-
|
|
|
+
|
|
|
+ tbuff:set(0, CMD_SKIP_ROM)
|
|
|
+ tbuff:set(1, CMD_CONVERT_T)
|
|
|
+ local succ = onewire.tx(channel, tbuff, 0, 2, false, true, true)
|
|
|
+ if not succ then
|
|
|
+ log.warn("onewire_multi_app", "通道", channel, "发送温度转换命令失败")
|
|
|
+ return nil
|
|
|
end
|
|
|
-
|
|
|
- -- 验证追加结果
|
|
|
- file = io.open(append_file, "r")
|
|
|
- if file then
|
|
|
- data = file:read("*a")
|
|
|
- log.info("文件验证", "路径:" .. append_file, "内容:" .. data, "结果:",
|
|
|
- data == "ABCdef" and "成功" or "失败")
|
|
|
- file:close()
|
|
|
- else
|
|
|
- log.error("文件验证", "无法打开文件进行验证", "路径:" .. append_file)
|
|
|
- goto resource_cleanup
|
|
|
+
|
|
|
+ log.info("onewire_multi_app", "等待温度转换完成...")
|
|
|
+ sys.wait(750)
|
|
|
+
|
|
|
+ local succ = onewire.reset(channel, true)
|
|
|
+ if not succ then
|
|
|
+ log.warn("onewire_multi_app", "通道", channel, "读取时设备未响应")
|
|
|
+ return nil
|
|
|
end
|
|
|
-
|
|
|
- -- 8. 按行读取测试
|
|
|
- line_file = dir_path .. "/testline"
|
|
|
- file = io.open(line_file, "w")
|
|
|
- if file then
|
|
|
- file:write("abc\n")
|
|
|
- file:write("123\n")
|
|
|
- file:write("wendal\n")
|
|
|
- file:close()
|
|
|
- log.info("文件创建", "路径:" .. line_file, "写入3行文本")
|
|
|
- else
|
|
|
- log.error("文件创建", "无法创建文件", "路径:" .. line_file)
|
|
|
- goto resource_cleanup
|
|
|
+
|
|
|
+ tbuff:set(0, CMD_SKIP_ROM)
|
|
|
+ tbuff:set(1, CMD_READ_SCRATCHPAD)
|
|
|
+ succ = onewire.tx(channel, tbuff, 0, 2, false, true, true)
|
|
|
+ if not succ then
|
|
|
+ log.warn("onewire_multi_app", "通道", channel, "发送读取命令失败")
|
|
|
+ return nil
|
|
|
end
|
|
|
-
|
|
|
- -- 按行读取文件
|
|
|
- file = io.open(line_file, "r")
|
|
|
- if file then
|
|
|
- log.info("按行读取", "路径:" .. line_file, "第1行:", file:read("*l"))
|
|
|
- log.info("按行读取", "路径:" .. line_file, "第2行:", file:read("*l"))
|
|
|
- log.info("按行读取", "路径:" .. line_file, "第3行:", file:read("*l"))
|
|
|
- file:close()
|
|
|
- else
|
|
|
- log.error("按行读取", "无法打开文件", "路径:" .. line_file)
|
|
|
- goto resource_cleanup
|
|
|
+
|
|
|
+ rbuff:resize(9)
|
|
|
+ local succ, rx_len = onewire.rx(channel, 9, nil, rbuff, 0, false, false, false)
|
|
|
+ if not succ or rx_len ~= 9 then
|
|
|
+ log.warn("onewire_multi_app", "通道", channel, "温度数据接收失败,长度:", rx_len or 0)
|
|
|
+ return nil
|
|
|
end
|
|
|
-
|
|
|
- -- 9. 文件重命名
|
|
|
- old_path = append_file
|
|
|
- new_path = dir_path .. "/renamed_file.txt"
|
|
|
- success, err = os.rename(old_path, new_path)
|
|
|
- if success then
|
|
|
- log.info("os.rename", "文件重命名成功", "原路径:" .. old_path, "新路径:" .. new_path)
|
|
|
-
|
|
|
- -- 验证重命名结果
|
|
|
- if io.exists(new_path) and not io.exists(old_path) then
|
|
|
- log.info("验证结果", "重命名验证成功", "新文件存在", "原文件不存在")
|
|
|
+
|
|
|
+ local crc8c = crypto.crc8(rbuff:query(0,8), 0x31, 0, true)
|
|
|
+ if crc8c == rbuff[8] then
|
|
|
+ local temp_low = rbuff[0]
|
|
|
+ local temp_high = rbuff[1]
|
|
|
+ local temp_raw = temp_low + (temp_high * 256)
|
|
|
+
|
|
|
+ if temp_raw > 32767 then
|
|
|
+ temp_raw = temp_raw - 65536
|
|
|
+ end
|
|
|
+
|
|
|
+ local temperature = temp_raw * 0.0625
|
|
|
+
|
|
|
+ if temperature >= -55.0 and temperature <= 125.0 then
|
|
|
+ log.info("onewire_multi_app", "温度读取成功,通道", channel, ":", string.format("%.2f°C", temperature))
|
|
|
+ return temperature
|
|
|
else
|
|
|
- log.error("验证结果", "重命名验证失败")
|
|
|
+ log.warn("onewire_multi_app", "温度值超出有效范围:", temperature)
|
|
|
+ return nil
|
|
|
end
|
|
|
else
|
|
|
- log.error("os.rename", "重命名失败", "错误:" .. tostring(err), "原路径:" .. old_path)
|
|
|
- goto resource_cleanup
|
|
|
+ log.warn("onewire_multi_app", "CRC校验失败,期望:", string.format("0x%02X", crc8c),
|
|
|
+ "实际:", string.format("0x%02X", rbuff[8]))
|
|
|
+ return nil
|
|
|
end
|
|
|
+end
|
|
|
|
|
|
- -- 10. 列举目录内容
|
|
|
- log.info("目录操作", "===== 开始目录列举 =====")
|
|
|
+-- 切换传感器
|
|
|
+local function switch_onewire_sensor()
|
|
|
+ log.info("onewire_multi_app", "切换传感器...")
|
|
|
+
|
|
|
+ local old_config = sensor_config[current_sensor]
|
|
|
+ onewire.deinit(old_config.channel)
|
|
|
+
|
|
|
+ current_sensor = (current_sensor % #sensor_config) + 1
|
|
|
+ local new_config = sensor_config[current_sensor]
|
|
|
+
|
|
|
+ local channel = init_sensor(current_sensor)
|
|
|
+
|
|
|
+ log.info("onewire_multi_app", "切换到传感器:", new_config.name, "通道:", channel)
|
|
|
+ return channel
|
|
|
+end
|
|
|
|
|
|
- ret, data = io.lsdir(dir_path, 50, 0) -- 50表示最多返回50个文件,0表示从目录开头开始
|
|
|
- if ret then
|
|
|
- log.info("fs", "lsdir", json.encode(data))
|
|
|
- else
|
|
|
- log.info("fs", "lsdir", "fail", ret, data)
|
|
|
- goto resource_cleanup
|
|
|
+-- 初始化硬件
|
|
|
+local function init_hardware()
|
|
|
+ log.info("onewire_multi_app", "初始化硬件配置...")
|
|
|
+
|
|
|
+ gpio.setup(gpio.PWR_KEY, function()
|
|
|
+ switch_pressed = true
|
|
|
+ log.info("onewire_multi_app", "切换按键被按下")
|
|
|
+ end, gpio.PULLUP, gpio.RISING)
|
|
|
+
|
|
|
+ local channel = init_sensor(current_sensor)
|
|
|
+ local detected = detect_ds18b20_device(channel)
|
|
|
+
|
|
|
+ if not detected then
|
|
|
+ log.warn("onewire_multi_app", "第一个传感器未检测到,尝试第二个传感器...")
|
|
|
+ current_sensor = 2
|
|
|
+ channel = init_sensor(current_sensor)
|
|
|
+ detected = detect_ds18b20_device(channel)
|
|
|
end
|
|
|
+
|
|
|
+ log.info("onewire_multi_app", "硬件初始化完成")
|
|
|
+ log.info("onewire_multi_app", "当前使用传感器:", sensor_config[current_sensor].name)
|
|
|
+
|
|
|
+ return detected
|
|
|
+end
|
|
|
|
|
|
- -- 11. 删除文件测试
|
|
|
- -- 测试删除renamed_file.txt文件
|
|
|
- if os.remove(new_path) then
|
|
|
- log.info("os.remove", "文件删除成功", "路径:" .. new_path)
|
|
|
-
|
|
|
- -- 验证renamed_file.txt删除结果
|
|
|
- if not io.exists(new_path) then
|
|
|
- log.info("验证结果", "renamed_file.txt文件删除验证成功")
|
|
|
- else
|
|
|
- log.error("验证结果", "renamed_file.txt文件删除验证失败")
|
|
|
- end
|
|
|
- else
|
|
|
- log.error("io.remove", "renamed_file.txt文件删除失败", "路径:" .. new_path)
|
|
|
- goto resource_cleanup
|
|
|
+-- 演示OneWire初始化功能
|
|
|
+local function demonstrate_onewire_init()
|
|
|
+ log.info("demo", "=== 1. 多通道onewire.init()演示 ===")
|
|
|
+ for i, config in ipairs(sensor_config) do
|
|
|
+ log.info("demo", "初始化通道", config.channel, "对应引脚", config.pin, config.name)
|
|
|
+ onewire.init(config.channel)
|
|
|
end
|
|
|
+ log.info("demo", "OneWire初始化演示完成")
|
|
|
+end
|
|
|
|
|
|
- -- 测试删除testline文件
|
|
|
- if os.remove(line_file) then
|
|
|
- log.info("os.remove", "testline文件删除成功", "路径:" .. line_file)
|
|
|
+-- 演示时序配置功能
|
|
|
+local function demonstrate_onewire_timing()
|
|
|
+ log.info("demo", "=== 2. 多通道onewire.timing()演示 ===")
|
|
|
+ for i, config in ipairs(sensor_config) do
|
|
|
+ log.info("demo", "配置通道", config.channel, "的DS18B20标准时序")
|
|
|
+ onewire.timing(config.channel, false, 0, 480, 70, 70, 410, 70, 10, 10, 15, 70)
|
|
|
+ end
|
|
|
+ log.info("demo", "时序配置演示完成")
|
|
|
+end
|
|
|
|
|
|
- -- 验证删除结果
|
|
|
- if not io.exists(line_file) then
|
|
|
- log.info("验证结果", "testline文件删除验证成功")
|
|
|
- else
|
|
|
- log.error("验证结果", "testline文件删除验证失败")
|
|
|
- end
|
|
|
- else
|
|
|
- log.error("io.remove", "testline文件删除失败", "路径:" .. line_file)
|
|
|
- goto resource_cleanup
|
|
|
+-- 演示设备检测功能
|
|
|
+local function demonstrate_device_detection()
|
|
|
+ log.info("demo", "=== 3. 多通道设备检测演示 ===")
|
|
|
+ for i, config in ipairs(sensor_config) do
|
|
|
+ local present = onewire.reset(config.channel, true)
|
|
|
+ log.info("demo", "通道", config.channel, config.name, "检测状态:", present and "检测到设备" or "未检测到设备")
|
|
|
end
|
|
|
+ log.info("demo", "设备检测演示完成")
|
|
|
+end
|
|
|
|
|
|
- if os.remove(file_path) then
|
|
|
- log.info("os.remove", "文件删除成功", "路径:" .. file_path)
|
|
|
+-- 演示电源控制功能
|
|
|
+local function demonstrate_power_control()
|
|
|
+ log.info("demo", "=== 4. 电源控制演示 ===")
|
|
|
+ power_control(true)
|
|
|
+ power_control(false)
|
|
|
+ log.info("demo", "电源控制演示完成")
|
|
|
+end
|
|
|
|
|
|
- -- 验证删除结果
|
|
|
- if not io.exists(file_path) then
|
|
|
- log.info("验证结果", "boottime文件删除验证成功")
|
|
|
- else
|
|
|
- log.error("验证结果", "boottime文件删除验证失败")
|
|
|
- end
|
|
|
- else
|
|
|
- log.error("io.remove", "boottime文件删除失败", "路径:" .. file_path)
|
|
|
- goto resource_cleanup
|
|
|
+-- 演示传感器切换功能
|
|
|
+local function demonstrate_sensor_switching()
|
|
|
+ log.info("demo", "=== 5. 传感器切换功能演示 ===")
|
|
|
+ local original_sensor = current_sensor
|
|
|
+
|
|
|
+ for i = 1, #sensor_config do
|
|
|
+ local channel = switch_onewire_sensor()
|
|
|
+ local detected = detect_ds18b20_device(channel)
|
|
|
+ log.info("demo", "切换到传感器", current_sensor, "检测状态:", detected and "成功" or "失败")
|
|
|
+ sys.wait(500)
|
|
|
end
|
|
|
+
|
|
|
+ current_sensor = original_sensor
|
|
|
+ init_sensor(current_sensor)
|
|
|
+ log.info("demo", "传感器切换演示完成,恢复原始传感器")
|
|
|
+end
|
|
|
|
|
|
- -- 12. 删除目录(不能删除非空目录,所以在删除目录前要确保目录内没有文件或子目录)
|
|
|
- if io.rmdir(dir_path) then
|
|
|
- log.info("io.rmdir", "目录删除成功", "路径:" .. dir_path)
|
|
|
-
|
|
|
- -- 验证删除结果
|
|
|
- if not io.exists(dir_path) then
|
|
|
- log.info("验证结果", "目录删除验证成功")
|
|
|
- else
|
|
|
- log.error("验证结果", "目录删除验证失败")
|
|
|
- end
|
|
|
- else
|
|
|
- log.error("io.rmdir", "目录删除失败", "路径:" .. dir_path)
|
|
|
- goto resource_cleanup
|
|
|
+-- 演示位操作功能
|
|
|
+local function demonstrate_bit_operations()
|
|
|
+ log.info("demo", "=== 6. 位操作功能演示 ===")
|
|
|
+ for i, config in ipairs(sensor_config) do
|
|
|
+ onewire.bit(config.channel, 1)
|
|
|
+ log.info("demo", "通道", config.channel, "发送位: 1")
|
|
|
+
|
|
|
+ local bit_value = onewire.bit(config.channel)
|
|
|
+ log.info("demo", "通道", config.channel, "读取位值:", bit_value)
|
|
|
end
|
|
|
+ log.info("demo", "位操作演示完成")
|
|
|
+end
|
|
|
+
|
|
|
+-- 演示调试模式功能
|
|
|
+local function demonstrate_debug_mode()
|
|
|
+ log.info("demo", "=== 7. 调试模式演示 ===")
|
|
|
+ log.info("demo", "调试模式当前状态: 关闭(可通过取消注释开启)")
|
|
|
+ -- for i, config in ipairs(sensor_config) do
|
|
|
+ -- onewire.debug(config.channel, true)
|
|
|
+ -- log.info("demo", "开启通道", config.channel, "的调试模式")
|
|
|
+ -- end
|
|
|
+ log.info("demo", "调试模式演示完成")
|
|
|
+end
|
|
|
|
|
|
- log.info("文件操作", "===== 文件操作完成 =====")
|
|
|
+-- 演示资源释放功能
|
|
|
+local function demonstrate_resource_cleanup()
|
|
|
+ log.info("demo", "=== 8. 资源释放演示 ===")
|
|
|
+ for i, config in ipairs(sensor_config) do
|
|
|
+ onewire.deinit(config.channel)
|
|
|
+ log.info("demo", "释放通道", config.channel, "的资源")
|
|
|
+ end
|
|
|
+ log.info("demo", "资源释放演示完成")
|
|
|
+
|
|
|
+ -- 重新初始化所有通道
|
|
|
+ for i, config in ipairs(sensor_config) do
|
|
|
+ init_sensor(i)
|
|
|
+ end
|
|
|
+end
|
|
|
|
|
|
- -- ########## 功能: 收尾功能演示##########
|
|
|
- -- 卸载文件系统和关闭SPI
|
|
|
- ::resource_cleanup::
|
|
|
+-- 演示多传感器OneWire API接口
|
|
|
+local function demonstrate_multi_onewire_apis()
|
|
|
+ log.info("onewire_multi_app", "开始演示多传感器OneWire API接口...")
|
|
|
+
|
|
|
+ demonstrate_onewire_init()
|
|
|
+ demonstrate_onewire_timing()
|
|
|
+ demonstrate_device_detection()
|
|
|
+ demonstrate_power_control()
|
|
|
+ demonstrate_sensor_switching()
|
|
|
+ demonstrate_bit_operations()
|
|
|
+ demonstrate_debug_mode()
|
|
|
+ demonstrate_resource_cleanup()
|
|
|
+
|
|
|
+ log.info("onewire_multi_app", "多传感器API演示完成")
|
|
|
+end
|
|
|
|
|
|
- log.info("结束", "开始执行关闭操作...")
|
|
|
- -- 如已挂载需先卸载文件系统,未挂载直接关闭SPI
|
|
|
- if mount_ok then
|
|
|
- if fatfs.unmount("/sd") then
|
|
|
- log.info("文件系统", "卸载成功")
|
|
|
+-- 多传感器应用主函数
|
|
|
+local function multi_sensor_app_main()
|
|
|
+ log.info("onewire_multi_app", "启动多传感器应用")
|
|
|
+
|
|
|
+ if not init_hardware() then
|
|
|
+ log.error("onewire_multi_app", "所有传感器都未检测到,请检查硬件连接")
|
|
|
+ log.warn("onewire_multi_app", "硬件连接提示:")
|
|
|
+ log.warn("onewire_multi_app", "1. 传感器1连接GPIO2 (默认OneWire功能)")
|
|
|
+ log.warn("onewire_multi_app", "2. 传感器2连接引脚54 (复用为GPIO3/ONEWIRE)")
|
|
|
+ log.warn("onewire_multi_app", "3. 确保GPIO31/GPIO2已设置为高电平供电")
|
|
|
+ return
|
|
|
+ end
|
|
|
+
|
|
|
+ task_running = true
|
|
|
+ log.info("onewire_multi_app", "开始多传感器连续监测...")
|
|
|
+ log.info("onewire_multi_app", "按PWR_KEY按键可切换传感器")
|
|
|
+
|
|
|
+ while task_running do
|
|
|
+ if switch_pressed then
|
|
|
+ switch_pressed = false
|
|
|
+ switch_onewire_sensor()
|
|
|
+ end
|
|
|
+
|
|
|
+ local config = sensor_config[current_sensor]
|
|
|
+ local temperature = read_ds18b20_temperature(config.channel)
|
|
|
+
|
|
|
+ if temperature then
|
|
|
+ log.info("onewire_multi_app",
|
|
|
+ "传感器" .. current_sensor .. "(" .. config.name .. "):",
|
|
|
+ string.format("%.2f°C", temperature))
|
|
|
else
|
|
|
- log.error("文件系统", "卸载失败")
|
|
|
+ log.warn("onewire_multi_app", "传感器" .. current_sensor .. "读取失败")
|
|
|
end
|
|
|
+
|
|
|
+ sys.wait(1000)
|
|
|
+ end
|
|
|
+
|
|
|
+ for i, config in ipairs(sensor_config) do
|
|
|
+ onewire.deinit(config.channel)
|
|
|
end
|
|
|
+
|
|
|
+ log.info("onewire_multi_app", "多传感器应用结束")
|
|
|
+end
|
|
|
|
|
|
- -- 2. 关闭SPI接口
|
|
|
- spi.close(spi_id)
|
|
|
- log.info("SPI接口", "已关闭")
|
|
|
+-- 启动多传感器应用任务
|
|
|
+local function start_multi_sensor_app()
|
|
|
+ sys.taskInit(function()
|
|
|
+ demonstrate_multi_onewire_apis()
|
|
|
+ multi_sensor_app_main()
|
|
|
+ end)
|
|
|
+end
|
|
|
|
|
|
+-- 模块初始化函数
|
|
|
+local function init_module()
|
|
|
+ log.info("onewire_multi_app", "多传感器应用模块初始化")
|
|
|
+ start_multi_sensor_app()
|
|
|
end
|
|
|
|
|
|
-sys.taskInit(tfcard_main_task)
|
|
|
+-- 启动模块
|
|
|
+init_module()
|
|
|
+
|
|
|
+log.info("onewire_multi_app", "多传感器应用模块加载完成")
|