Browse Source

add: 视频教程代码示例

liujingjing 7 months ago
parent
commit
837c3058cd
16 changed files with 1259 additions and 0 deletions
  1. 21 0
      module/Air780EPM/demo/780EPM视频教程示例代码/04_输出helloworld/main.lua
  2. 59 0
      module/Air780EPM/demo/780EPM视频教程示例代码/05_语法速成/main.lua
  3. 26 0
      module/Air780EPM/demo/780EPM视频教程示例代码/07_创建你的第一个协程/main.lua
  4. 52 0
      module/Air780EPM/demo/780EPM视频教程示例代码/09_多任务协程/main.lua
  5. 33 0
      module/Air780EPM/demo/780EPM视频教程示例代码/11_点亮led灯/main.lua
  6. 33 0
      module/Air780EPM/demo/780EPM视频教程示例代码/12_模拟按键控制LED/main.lua
  7. 45 0
      module/Air780EPM/demo/780EPM视频教程示例代码/13_ADC采集电压/main.lua
  8. 71 0
      module/Air780EPM/demo/780EPM视频教程示例代码/18_sring库/main.lua
  9. 64 0
      module/Air780EPM/demo/780EPM视频教程示例代码/21_串口UART演练(1)/main.lua
  10. 214 0
      module/Air780EPM/demo/780EPM视频教程示例代码/23_4G雷达物位计_串口TTL/Radar.lua
  11. 53 0
      module/Air780EPM/demo/780EPM视频教程示例代码/23_4G雷达物位计_串口TTL/main.lua
  12. 192 0
      module/Air780EPM/demo/780EPM视频教程示例代码/25_RS485实战演练/Radar_485.lua
  13. 53 0
      module/Air780EPM/demo/780EPM视频教程示例代码/25_RS485实战演练/main.lua
  14. 141 0
      module/Air780EPM/demo/780EPM视频教程示例代码/27_I2C实战演练(SHT20数据采集)/main.lua
  15. 52 0
      module/Air780EPM/demo/780EPM视频教程示例代码/27_I2C实战演练(SHT20数据采集)/pins_Air780EPM.json
  16. 150 0
      module/Air780EPM/demo/780EPM视频教程示例代码/30_双路DS18B20数据采集/DS18B20.lua

+ 21 - 0
module/Air780EPM/demo/780EPM视频教程示例代码/04_输出helloworld/main.lua

@@ -0,0 +1,21 @@
+
+-- LuaTools需要PROJECT和VERSION这两个信息
+PROJECT = "helloworld"
+VERSION = "1.0.0"
+
+-- 引入必要的库文件(lua编写), 内部库不需要require
+sys = require("sys")
+
+-- log.info("main", "hello world")
+
+-- print(_VERSION)
+
+sys.timerLoopStart(function()
+    print("hello world")
+end, 3000)
+
+
+-- 用户代码已结束---------------------------------------------
+-- 结尾总是这一句
+sys.run()
+-- sys.run()之后后面不要加任何语句!!!!!

+ 59 - 0
module/Air780EPM/demo/780EPM视频教程示例代码/05_语法速成/main.lua

@@ -0,0 +1,59 @@
+--=============================================================
+--1.变量
+--全局变量
+PROJECT = "Luat_OS"--
+VERSION = "1.0.0" --
+--局部变量
+local name="合宙"
+--=============================================================
+--2.关键字
+_G.sys = require("sys")
+--=============================================================
+--3.打印
+print(PROJECT,VERSION)
+log.info(PROJECT,VERSION)
+--=============================================================
+--4.注释
+--print(PROJECT,VERSION)
+--log.info(PROJECT,VERSION)
+--print(PROJECT,VERSION)
+--log.info(PROJECT,VERSION)
+--=============================================================
+--6.字符串
+local name1="我是"
+local name_all=name1..name..PROJECT
+log.info(name_all)
+--=============================================================
+--7.条件判断
+n = 5
+if n < 10 then
+    log.info('n小于10')
+end
+--=============================================================
+--8.循环
+local result = 0
+local num = 1
+while num <= 10 do
+    result = result + num
+    num = num + 1
+end
+log.info(result)
+--=============================================================
+--9.函数
+function hello()
+    log.info('你好,LuatOS')
+end
+hello()--执行这个函数
+--=============================================================
+--10.数组
+t = {"我","今年",40,"岁"}
+log.info(t[1]) --打印数组里面第一个东西
+log.info(t[2]) --打印数组里面第二个东西
+log.info(t[3]) --打印数组里面第三个东西
+log.info(t[4]) --打印数组里面第四个东西
+--=============================================================
+--5.程序结束
+--我们的代码已结束
+sys.run()-- 结尾总是这一句
+--=============================================================
+

+ 26 - 0
module/Air780EPM/demo/780EPM视频教程示例代码/07_创建你的第一个协程/main.lua

@@ -0,0 +1,26 @@
+-- LuaTools需要PROJECT和VERSION这两个信息
+PROJECT = "task"--项目名称
+VERSION = "1.0.0"--程序版本号
+
+-- 引入必要的库文件(lua编写), 内部库不需要require
+sys = require("sys")--引入sys系统调度
+
+log.info("main", PROJECT)--打印一下项目名称
+
+function test()--定义一个函数,名字就是test()
+    while 1 do
+        log.info(PROJECT, "我是一个函数")
+        sys.wait(1000)--等待1000毫秒后,执行下一个语句
+        log.info("这个函数的作用就是", "等待一秒后打印这条信息")
+    end
+    
+end
+
+-- 创建任务test并执行
+sys.taskInit(test)--这里就是创建了一个协程
+
+
+-- 用户代码已结束---------------------------------------------
+-- 结尾总是这一句
+sys.run()
+-- sys.run()之后后面不要加任何语句!!!!!

+ 52 - 0
module/Air780EPM/demo/780EPM视频教程示例代码/09_多任务协程/main.lua

@@ -0,0 +1,52 @@
+-- LuaTools需要PROJECT和VERSION这两个信息
+PROJECT = "multitasking"--多任务
+VERSION = "1.0.0"--程序版本号
+
+-- 引入必要的库文件(lua编写), 内部库不需要require
+sys = require("sys")--引入sys系统调度
+--打印一下项目名称
+log.info("main", "多任务",PROJECT)
+--=============================================================
+--烧水的协程
+function boil_water()--烧水 
+    while 1 do
+        log.info("开始烧水")
+        sys.wait(5000)--烧水5秒后
+        sys.publish("水烧开了")
+        log.info("水壶提示并发消息:", "水烧开了!!!")
+        break
+    end    
+end
+--=============================================================
+--扫地的协程
+function sweep_floor()--扫地
+    while 1 do
+        local result = sys.waitUntil("水烧开了",1000)--等待超时时间1000ms,超过就返回false而且不等了
+        if result then
+            log.info("水烧开了:", "我去关火")
+            sys.publish("水烧开了,不扫地了去沏茶")
+            break
+        else
+            log.info("水还没烧开:", "我要继续扫地")
+        end
+    end    
+end
+--=============================================================
+--沏茶的协程
+function make_tea()--沏茶
+    while 1 do
+        local result = sys.waitUntil("水烧开了,不扫地了去沏茶")--一直等待超,程序阻塞到这里了
+        if result then
+            log.info( "收到消息了,可以沏茶了")
+        end
+    end    
+end
+--=============================================================
+sys.taskInit(boil_water)--这里就是创建了烧水的协程
+sys.taskInit(sweep_floor)--这里就是创建了扫地的协程
+sys.taskInit(make_tea)--这里就是创建了沏茶的协程
+--=============================================================
+-- 用户代码已结束---------------------------------------------
+-- 结尾总是这一句
+sys.run()
+-- sys.run()之后后面不要加任何语句!!!!!

+ 33 - 0
module/Air780EPM/demo/780EPM视频教程示例代码/11_点亮led灯/main.lua

@@ -0,0 +1,33 @@
+-- LuaTools需要PROJECT和VERSION这两个信息
+PROJECT = "LED"
+VERSION = "1.0.0"
+-- 引入必要的库文件(lua编写), 内部库不需要require
+sys = require("sys")
+--=============================================================
+log.info("点亮一个LED灯")
+gpio.setup(27, 1)
+--=============================================================
+function LED()
+    while 1 do
+--[[         gpio.set(27,1)
+        log.info("亮")
+        sys.wait(1000)
+        gpio.set(27,0)
+        log.info("灭") 
+        sys.wait(1000) ]]
+        LED_toggle(1000)
+    end   
+end
+--=============================================================
+function LED_toggle(time)
+        sys.wait(time)
+        gpio.toggle(27)
+        log.info("翻转")
+end
+--=============================================================
+sys.taskInit(LED)
+--=============================================================
+-- 用户代码已结束---------------------------------------------
+-- 结尾总是这一句
+sys.run()
+-- sys.run()之后后面不要加任何语句!!!!!

+ 33 - 0
module/Air780EPM/demo/780EPM视频教程示例代码/12_模拟按键控制LED/main.lua

@@ -0,0 +1,33 @@
+-- LuaTools需要PROJECT和VERSION这两个信息
+PROJECT = "Control_LED"
+VERSION = "1.0.0"
+-- 引入必要的库文件(lua编写), 内部库不需要require
+sys = require("sys")
+--=============================================================
+log.info("按键控制LED灯")
+gpio.setup(27, 1)
+gpio.setup(2, 1)--摄像头的供电LDO
+gpio.setup(28, 1)--LCD的供电LDO
+gpio.setup(34, nil,gpio.PULLUP)
+--gpio.setup(34, nil,gpio.PULLDOWN)
+--=============================================================
+function LED()
+    while 1 do
+        local resalt=gpio.get(34)
+        log.info("GPIO34的电平=",resalt)
+        if resalt==1 then
+            gpio.set(27,1)
+            sys.wait(500)
+        else
+            gpio.set(27,0)
+            sys.wait(500)
+        end
+    end   
+end
+--=============================================================
+sys.taskInit(LED)
+--=============================================================
+-- 用户代码已结束---------------------------------------------
+-- 结尾总是这一句
+sys.run()
+-- sys.run()之后后面不要加任何语句!!!!!

+ 45 - 0
module/Air780EPM/demo/780EPM视频教程示例代码/13_ADC采集电压/main.lua

@@ -0,0 +1,45 @@
+-- LuaTools需要PROJECT和VERSION这两个信息
+PROJECT = "ADC"
+VERSION = "1.0.0"
+
+-- sys库是标配
+sys = require("sys")
+--=============================================================
+local function MY_ADC()
+-- 读取CPU温度, 单位为0.001摄氏度, 是内部温度, 非环境温度
+    while 1 do
+    sys.wait(1000)
+    adc.open(adc.CH_CPU)
+    local temp = adc.get(adc.CH_CPU)
+    log.info("CPU温度=",temp/1000)
+    --adc.close(adc.CH_CPU)
+-- adc.CH_CPU,CPU内部温度的通道id,内部通道,直接获取,不占用ADC 0-3,不外接任何电路
+-- 读取VBAT供电电压, 单位为mV
+--=============================================================
+    sys.wait(1000)
+    adc.open(adc.CH_VBAT)
+    local vbat = adc.get(adc.CH_VBAT)
+    log.info("VBAT供电电压",vbat/1000)
+    --adc.close(adc.CH_VBAT)
+-- adc.CH_VBAT,VBAT供电电压的通道id,内部通道,直接获取,不占用ADC 0-3,不外接任何电路
+-- adc.CH_CPU 和 adc_CH_VBAT 在做读取动作之前,不需要像 ADC 0-3通道一样先打开adc.setRange(range)函数
+--=============================================================
+    sys.wait(1000)
+--修改IO电平,都可以通过LuatOS软件设置为1.8V/2.8V/3.0V/3.3V
+    pm.ioVol(pm.IOVOL_ALL_GPIO, 3300) 
+-- 设置ADC引脚的测量范围0-3.6V,这种方式被测电压不可经过外部电阻分压后再挂在ADC上;
+    adc.setRange(adc.ADC_RANGE_MAX)
+-- 打开adc通道0,并读取
+    adc.open(0) 
+    local ADC0=adc.get(0)
+    log.info("adc0=", ADC0,"mV") -- 返回电压值;
+--=============================================================
+    end
+end
+--=============================================================
+sys.taskInit(MY_ADC)
+--=============================================================
+-- 用户代码已结束---------------------------------------------
+-- 结尾总是这一句
+sys.run()
+-- sys.run()之后后面不要加任何语句!!!!!

+ 71 - 0
module/Air780EPM/demo/780EPM视频教程示例代码/18_sring库/main.lua

@@ -0,0 +1,71 @@
+-- LuaTools需要PROJECT和VERSION这两个信息
+PROJECT = "stringtest"
+VERSION = "2.0.0"
+-- sys库是标配
+_G.sys = require("sys")
+
+sys.taskInit(function ()
+    sys.wait(1000) -- 免得看不到日志
+    --================================================
+    -- 字符串的声明和生成
+    local str="LuatOS" 
+    log.info("字符串str=",str)
+    --================================================
+    --================================================
+    -- 转义字符
+    log.info("字符串回车换行,但不显示回车换行的字符")
+    local str = "LuatOS\n\r" 
+    log.info("带不显示字符的字符串str=",str)
+    --================================================
+    --================================================
+    -- 字符串的拼接
+    local str = "LuatOS" 
+    local str1 = "你好," 
+    log.info("字符串str=",str,"字符串str1=",str1)
+    local str2=str1..str
+    log.info("拼接的字符串str2=",str2)
+    --================================================
+    --================================================
+    -- 数字转字符串
+    local n= 13
+    local str1 = "你好" 
+    log.info("数字n=",n,"字符串str1=",str1)
+    local str2=tostring(n)..str1
+    log.info("拼接的字符串str2=",str2)
+    --================================================
+    --================================================
+    -- 字符串转数字
+    local n= 12
+    local str1 = "13"
+    log.info("数字n=", n,"字符串str1=",str1)
+    local n1=tonumber(str1)+n
+    log.info("数字12+字符串“13”=",n1)
+    --================================================
+    --================================================
+    -- 字符串转十六进制
+    local hex = string.toHex("LuatOS")
+    -- 获取字符串的HEX字符串显示
+    log.info("LuatOS字符串转十六进制", hex)
+    -- 获取指定位置的值, 注意lua的下标是1开始的
+    --================================================
+    --================================================
+    -- 十六进制转字符串
+    local str = string.fromHex("4C7561744F53")
+    log.info("十六进制转字符串str=",str)
+    --================================================
+    -- 合成式,组合十六进制数
+    local str = string.char(0x01, 0x00, 0xF1, 0x3A)
+    local hex = string.toHex(str)
+    log.info("组合十六进制数=",hex) 
+    --================================================
+    -- 获取指定位置的值, 注意lua的下标是1开始的
+    local str = "LuatOS"
+    log.info("第一个字符是str[1]", string.byte(str, 1))
+    log.info("第四个字符是str[4]", string.byte(str, 4))
+    --================================================
+end)
+
+-- 用户代码已结束---------------------------------------------
+-- 结尾总是这一句
+sys.run()
+-- sys.run()之后后面不要加任何语句!!!!!

+ 64 - 0
module/Air780EPM/demo/780EPM视频教程示例代码/21_串口UART演练(1)/main.lua

@@ -0,0 +1,64 @@
+-- LuaTools需要PROJECT和VERSION这两个信息
+PROJECT = "uart_irq"
+VERSION = "1.0.0"
+
+log.info("main", PROJECT, VERSION)
+
+-- 引入必要的库文件(lua编写), 内部库不需要require
+sys = require("sys")
+
+if wdt then
+    --添加硬狗防止程序卡死,在支持的设备上启用这个功能
+    wdt.init(9000)--初始化watchdog设置为9s
+    sys.timerLoopStart(wdt.feed, 3000)--3s喂一次狗
+end
+
+log.info("main", "uart demo")
+
+local uartid = 1 -- 根据实际设备选取不同的uartid
+
+--初始化
+uart.setup(
+    uartid,--串口id
+    115200,--波特率
+    8,--数据位
+    1--停止位
+)
+
+
+--循环发数据
+sys.timerLoopStart(uart.write,5000, uartid, "LuatOS")
+-- 收取数据会触发回调, 这里的"receive" 是固定值
+uart.on(uartid, "receive", function(id, len)
+    local s = ""
+    repeat
+        s = uart.read(id, 128)
+        if #s > 0 then -- #s 是取字符串的长度
+            -- 如果传输二进制/十六进制数据, 部分字符不可见, 不代表没收到
+            -- 关于收发hex值,请查阅 https://doc.openluat.com/article/583
+            log.info("uart", "receive", id, #s, s)
+            -- log.info("uart", "receive", id, #s, s:toHex())
+        end
+        -- 如使用2024.5.13之前编译的ESP32C3/ESP32S3固件, 恢复下面的代码可以正常工作
+        -- if #s == len then
+        --     break
+        -- end
+    until s == ""
+end)
+
+-- 并非所有设备都支持sent事件
+uart.on(uartid, "sent", function(id)
+    log.info("uart", "sent", id)
+end)
+
+-- sys.taskInit(function()
+--     while 1 do
+--         sys.wait(500)
+--     end
+-- end)
+
+
+-- 用户代码已结束---------------------------------------------
+-- 结尾总是这一句
+sys.run()
+-- sys.run()之后后面不要加任何语句!!!!!

+ 214 - 0
module/Air780EPM/demo/780EPM视频教程示例代码/23_4G雷达物位计_串口TTL/Radar.lua

@@ -0,0 +1,214 @@
+
+--重要声明!!!
+--该代码仅供学习参考使用,未经量产验证;
+--思路可以借鉴,但是不要直接用在项目开发上,一定要结合自己项目做!!!
+--================================================================
+
+local Radar = {}--RS485空气开关控制
+log.info("4G_RTU", "Radar")
+kong_Value=0--空高
+liao_Value=0--料高
+Radar_State=0--雷达状态2024.11.16雷达状态,等于0表示未连接,1表示连接成功
+--=============================================================
+local uartid = 2        -- 根据实际设备选取不同的uartid,2代表uart2
+--初始化串口
+local result = uart.setup(
+    uartid,--串口id
+    115200,--波特率
+    8,--数据位
+    1--停止位
+)
+log.info("uart2", "雷达串口初始化完成")
+--=============================================================
+--读雷达命令
+local Device_Address=0x01  --根据实际情况设置
+--读雷达状态,功能码03
+--1.同时读取空高/料高:01 03 00 00 00 04 44 09
+local Read_Radar_Date=string.char(Device_Address,0x03,0x00,0x00,0x00,0x04,0x44,0x09)
+--2.同时读取空高/料高/SNR/温度:01 03 00 00 00 08 44 0C
+local Read_4_Date=string.char(Device_Address,0x03,0x00,0x00,0x00,0x08,0x44,0x0C)
+--3.同时读取空高/料高/SNR/温度/湿度/俯仰角/横滚角:01 03 00 00 00 0E C4 0E
+local Read_7_Date=string.char(Device_Address,0x03,0x00,0x00,0x00,0x0E,0xC4,0x0E)
+--4.读取波特率:01 03 20 01 00 01 DE 0A
+local Read_Baud_rate=string.char(Device_Address,0x03,0x20,0x01,0x00,0x01,0xDE,0x0A)
+--=============================================================
+--crc16校验函数
+function crc16(buf,len)
+    local init = 0xFFFF;
+    local poly = 0xA001;
+    local ret = init;
+    local byte=0;
+    for j=1,len,1 do
+        byte = string.byte(buf,j);
+        ret=((ret ~ byte) & 0xFFFF);
+        for i=1,8,1 do
+            if((ret & 0x0001)>0) then
+                ret = (ret >> 1);
+                ret = ((ret ~ poly) & 0xFFFF);
+            else
+                ret= (ret >> 1);
+            end;
+        end
+    end
+    local hi = ((ret >> 8) & 0xFF);
+    local lo = (ret & 0xFF);
+    ret = ((lo << 8) | hi);
+    return ret;
+end
+--=============================================================
+function get_warn()--判断报警标志位
+    if warn_type==1 and liao_Value<warn_data  then
+        my_type=0
+        log.info("正常水位")
+    elseif warn_type==1 and liao_Value>warn_data and liao_Value<warn_high_data  then
+        my_type=0
+        log.info("告警水位")
+    elseif warn_type==1 and liao_Value>warn_high_data  then
+        my_type=1
+        log.info("超高水位告警")
+    --================   
+    elseif warn_type==2 and kong_Value>warn_kong_data  then
+        my_type=0
+        log.info("正常空高")
+    elseif warn_type==2 and kong_Value<warn_kong_data and kong_Value>warn_kong_high_data then
+        my_type=0
+        log.info("告警空高休眠")
+    elseif warn_type==2 and kong_Value<warn_kong_high_data  and kong_Value>0 then
+        my_type=2
+        log.info("空高超高告警")
+    end
+end
+--=============================================================
+--采集雷达数据
+local function get_radar_date()
+    while true do
+        sys.waitUntil("IP_READY",3000)
+        --给三秒的联网时间,联不上也给雷达供电
+        gpio.setup(27, 1)--3819使能打开,GPIO27,PIN脚=16
+        gpio.setup(38, 1, gpio.PULLUP)--12V输出打开,GPIO38,PIN脚=51,对照表是对的2024.7.24
+        sys.wait(10000)--在等2秒后测试雷达是否在线
+        uart.write(uartid,Read_4_Date)
+        log.info("发送读波特率命令")
+        sys.wait(2000)--在等2秒后测试雷达是否在线
+        if Radar_State==1 then
+            log.info("雷达在线")
+        else--雷达不在线,尝试一次断电,不管成功与否,20秒后都会断电
+            log.info("雷达不在线")
+            Radar_State=0--标志位置成0
+            gpio.setup(27, 0)--3819使能打开,GPIO27,PIN脚=16,不回
+            sys.wait(2000)--等2秒放电
+            gpio.setup(27, 1)--3819使能打开,GPIO27,PIN脚=16
+            sys.wait(6000)--在等2秒后测试雷达是否在线
+            uart.write(uartid,Read_4_Date)
+            log.info("雷达重新上电完成")
+        end  
+    end
+end
+--=============================================================
+--注册串口事件回调
+        uart.on(uartid, "receive", function(id, len)
+            local s = ""
+            repeat --repeadt类似C语言的do…while循环,repeat重复执行循环,直到until指定条件为真
+                s = uart.read(id, len)
+                --log.info("uart", "receive", id, #s, s)
+                log.info("串口2", "receive", id, #s, s:toHex())
+                --log.info("第三个数string.byte(s,3)=", string.byte(s,3))
+                if #s > 0  then -- #s 是取字符串的长度,string.byte(s,3)==8判断师回复的那条命令
+                    -- 如果传输二进制/十六进制数据, 部分字符不可见, 不代表没收到
+                    -- 关于收发hex值,请查阅 https://doc.openluat.com/article/583
+                    log.info("第三个数string.byte(s,3)=", string.byte(s,3))
+                    local crc16=crc16(s,#s-2)
+                    local crc16_high=crc16 >> 8
+                    local crc16_low=crc16 & 0xFF
+                    log.info("CRC校验高位",crc16_high,"CRC校验低位",crc16_low)
+                    --打印其hex字符串形式
+                    --数据转换为数值string.byte,用于crc校验
+                    local receive_crc_high = string.byte(s,#s-1)
+                    local receive_crc_low = string.byte(s,#s)
+                    local receive_Switch_state = string.byte(s,#s-2)
+                    log.info("接收到的CRC校验高位", "接收到的CRC校验低位", receive_crc_high, receive_crc_low)
+                    log.info("uart", "receive", id, #s, s:toHex())
+                    --=============================================================
+                    --识别读取数据并将数据赋值给空高料高变量
+                    --if crc16_high==receive_crc_high and crc16_low==receive_crc_low and string.byte(s,3)==8 then
+                    if crc16_high==receive_crc_high and crc16_low==receive_crc_low and string.byte(s,3)==16 then--判断10数据
+                        --注意,string.byte(s,3)==16,收到字符串的第3个数据,判断时要转换为十进制数,第三个数为0x10,十进制数为16
+                        log.info("crc检验通过数据合法")
+                        --先将字符串转为hex格式
+                        local hexStr, len = string.toHex(s) -- 返回值"3132",2,后面的2是长度
+                        --log.info("收到的16进制字符串=",hexStr,len)
+                        --print(hexStr,len) -- 将输出 3132
+                        --截取空高数据,并加上0x个前缀
+                        local kong_high="0x"..string.sub(hexStr,7,14)--将0x拼接到字符串上,string.sub(hexStr,7,14)是一个数字算一个
+                        --截取料高数据,并加上0x个前缀
+                        local liao_high="0x"..string.sub(hexStr,15,22)--将0x拼接到字符串上
+                        --信噪比
+                        local SNR_Date="0x"..string.sub(hexStr,23,30)--将0x拼接到字符串上
+                        --雷达温度
+                        local temp_Date="0x"..string.sub(hexStr,31,38)--将0x拼接到字符串上
+                        log.info("空高16进制字符串=",kong_high)
+                        log.info("料高16进制字符串=",liao_high)
+                        log.info("信噪比16进制字符串=",SNR_Date)
+                        log.info("雷达温度比16进制字符串=",temp_Date)
+                        --将hex格式转化为浮点型数据
+                        local kong_temp = string.pack("<L",kong_high)
+                        kong_Value = string.unpack("f",kong_temp)
+                        log.info("空高=",kong_Value)
+                        local liao_temp = string.pack("<L",liao_high)
+                        liao_Value = string.unpack("f",liao_temp)
+                        log.info("料高=",liao_Value)
+                        local SNR_temp = string.pack("<L",SNR_Date)
+                        SNR = string.unpack("f",SNR_temp)
+                        log.info("信噪比=",SNR)
+                        local xinhao_temp = string.pack("<L",temp_Date)
+                        Radar_temp = string.unpack("f",xinhao_temp)
+                        log.info("雷达温度=",Radar_temp)                               
+                        --uart.write(1, s)--正常采集不透传给串口1,也就是传给蓝牙
+                        log.info("采集空高回传串口1", "receive", id, #s, s)
+                        get_warn()--采集完雷达,设置报警标志位
+                        sys.publish("雷达完成")
+                        Radar_State=1--2024.11.16,雷达在线标志位
+                    --=============================================================
+                    --如果不是采集命令,则透传给串口1
+                    elseif crc16_high==receive_crc_high and crc16_low==receive_crc_low then
+                        log.info("串口2透传给串口1数据且雷达在线了", "receive", id, #s, s)
+                        -- log.info("uart", "receive", id, #s, s:toHex())
+                        uart.write(1, s)--暂时不透传给串口1
+                    elseif crc16_high~=receive_crc_high or crc16_low~=receive_crc_low then
+                        log.info("无数据或crc检验不通过")
+                        --my_type=3--水位故障标志位--这里会导致出现正常数据报故障的问题
+                        kong_Value=-100--空高
+                        liao_Value=-100--料高
+                        uart.write(1, s)--暂时不透传给串口1
+                        --两种情况,一种是采集失败,一种是采集回波曲线
+                        end
+                end
+                if #s == len then
+                    --log.info("程序经过这里1")
+                    break
+                end
+            until s == ""
+            --log.info("程序经过这里2")
+        end)
+--=============================================================
+--=============================================================
+-- 并非所有设备都支持sent事件
+uart.on(uartid, "sent", function(id)
+    log.info("uart", "sent", id)
+end)
+--=============================================================
+--开启协程
+sys.taskInit(get_radar_date)
+--=============================================================
+--测试串口时使用
+--循环发数据
+--sys.timerLoopStart(uart.write,5000,uartid,Read_Radar_Date)
+--=============================================================
+
+--=============================================================
+--crc16校验函数用法
+--local data = string.pack("BBBBBB", 0x01, 0x03, 0x00, 0x00, 0x00, 0x02);--需要校验CRC16的内容
+--local datacrc = crc16(data,6);
+--print( datacrc >> 8 )		--输出196 == 0xC4
+--print( datacrc & 0xFF )		--输出11  == 0x0B
+--=============================================================

+ 53 - 0
module/Air780EPM/demo/780EPM视频教程示例代码/23_4G雷达物位计_串口TTL/main.lua

@@ -0,0 +1,53 @@
+
+--=============================================================
+PROJECT = "12V_4G_RTU"--名字之间不能有空格,否则影响远程更新的名字识别
+VERSION = "1.0.6" --版本号2023.8.2,必须是3个数,否则升级会失败,系统忽略中间的0
+--=============================================================
+-- sys库是标配--需要用到的其他库,下载时需要添加进来
+_G.sys = require("sys")--前面加-G表示全局引入?
+_G.sysplus = require("sysplus")--加强版的sys库,用于操作网络
+--_G.libnet = require "libnet"--网络相关的库
+--_G.libfota = require"libfota"--远程升级
+--=============================================================
+--=============================================================
+--引入自己定义的文件
+_G.require("Radar")--串口2雷达采集
+--_G.require("Radar_485")--串口3采集485雷达
+log.info("main", PROJECT,VERSION)--2023.11.8
+--=============================================================
+--=============================================================
+--设置看门狗
+if wdt then
+    --添加硬狗防止程序卡死,在支持的设备上启用这个功能
+    wdt.init(9000)--初始化watchdog设置为9s
+    sys.timerLoopStart(wdt.feed, 3000)--3s喂一次狗
+end
+--=============================================================
+--=============================================================
+--查看内存情况,正式版需注释掉
+sys.taskInit(function ()
+    while true do
+        sys.wait(3000)
+        log.info("lua", rtos.meminfo())
+        log.info("sys", rtos.meminfo("sys"))
+    end
+end)
+--=============================================================
+-- 如果运营商自带的DNS不好用,可以用下面的公用DNS
+-- socket.setDNS(nil,1,"223.5.5.5")
+-- socket.setDNS(nil,2,"114.114.114.114")
+
+--socket.sntp()--读取时间
+--socket.sntp("ntp.aliyun.com") --自定义sntp服务器地址
+--socket.sntp({"ntp.aliyun.com","ntp1.aliyun.com","ntp2.aliyun.com"}) --sntp自定义服务器地址
+--sys.subscribe("NTP_UPDATE", function()--订阅NTP_UPDATE这个消息,成功则打印系统时间
+--log.info("sntp", "time", os.date())
+--end)
+--sys.subscribe("NTP_ERROR", function()--订阅NTP_ERROR这个消息,失败则打印错误
+--log.info("socket", "sntp error")
+--socket.sntp()--再次获取时间
+--end)
+-- 用户代码已结束---------------------------------------------
+-- 结尾总是这一句
+sys.run()
+

+ 192 - 0
module/Air780EPM/demo/780EPM视频教程示例代码/25_RS485实战演练/Radar_485.lua

@@ -0,0 +1,192 @@
+--重要声明!!!
+--该代码仅供学习参考使用,未经量产验证;
+--思路可以借鉴,但是不要直接用在项目开发上,一定要结合自己项目做!!!
+--================================================================
+
+local Radar_485 = {}--RS485空气开关控制
+kong_Value_485=0--空高
+liao_Value_485=0--料高
+SNR_485=0--雷达信号强度
+Radar_temp_485=-100
+--=============================================================
+local uartid =1       -- 根据实际设备选取不同的uartid,2代表uart2,串口3为LCD复用
+--=============================================================
+local RE_DE_PIN=24--收发控制引脚,780EPM的引脚引脚是20,GPIO24
+local LDO_EN=1--RS485芯片供电控制引脚
+gpio.setup(LDO_EN, 1)
+--RS485专用的初始化
+uart.setup(
+ uartid, --串口ID
+ 115200,--波特率
+ 8,--数据位
+ 1,--停止位
+ uart.NONE,--校验位
+ uart.LSB,--高低位顺序
+ 1024,--数据缓存区大小 
+ RE_DE_PIN,--收发切换引脚
+ 0, --电平状态
+ 8000--收发切换时间
+)--收发的切换时间,极限为2000us
+log.info("uart1", "485雷达串口初始化完成")
+--=============================================================
+--=============================================================
+--读雷达命令
+local Device_Address=0x01  --根据实际情况设置
+--读雷达状态,功能码03
+--1.同时读取空高/料高:01 03 00 00 00 04 44 09
+local Read_Radar_Date=string.char(Device_Address,0x03,0x00,0x00,0x00,0x04,0x44,0x09)
+--2.同时读取空高/料高/SNR/温度:01 03 00 00 00 08 44 0C--低功耗雷达
+--local Read_4_Date=string.char(Device_Address,0x03,0x00,0x00,0x00,0x08,0x44,0x0C)--低功耗雷达
+--2.同时读取空高/料高/SNR/温度:01 03 00 00 00 0A C5 CD--四线制485雷达
+local Read_4_Date=string.char(Device_Address,0x03,0x00,0x00,0x00,0x0A,0xC5,0xCD)
+--3.同时读取空高/料高/SNR/温度/湿度/俯仰角/横滚角:01 03 00 00 00 0E C4 0E
+--=============================================================
+--=============================================================
+--crc16校验函数
+function crc16(buf,len)
+    local init = 0xFFFF;
+    local poly = 0xA001;
+    local ret = init;
+    local byte=0;
+    for j=1,len,1 do
+        byte = string.byte(buf,j);
+        ret=((ret ~ byte) & 0xFFFF);
+        for i=1,8,1 do
+            if((ret & 0x0001)>0) then
+                ret = (ret >> 1);
+                ret = ((ret ~ poly) & 0xFFFF);
+            else
+                ret= (ret >> 1);
+            end;
+        end
+    end
+    local hi = ((ret >> 8) & 0xFF);
+    local lo = (ret & 0xFF);
+    ret = ((lo << 8) | hi);
+    return ret;
+end
+--=============================================================
+--=============================================================
+--采集雷达数据
+local function get_radar_date()
+    while true do
+        --sys.waitUntil("读雷达")
+        log.info("读485空高数值")
+        sys.wait(2000)--2秒读一次高度
+        -- uart.write(uartid,Read_Radar_Date)
+        -- log.info("串口发送完成",Read_Radar_Date)
+        uart.write(uartid,Read_4_Date)
+        log.info("485雷达采集发送完成",Read_4_Date)
+        --=============================================================
+        --注册串口事件回调
+        uart.on(uartid, "receive", function(id, len)
+            local s = ""
+            repeat --repeadt类似C语言的do…while循环,repeat重复执行循环,直到until指定条件为真
+                s = uart.read(id, len)
+                --log.info("uart", "receive", id, #s, s)
+                log.info("串口2", "receive", id, #s, s:toHex())
+                --log.info("第三个数string.byte(s,3)=", string.byte(s,3))
+                if #s > 0  then -- #s 是取字符串的长度,string.byte(s,3)==8判断师回复的那条命令
+                    -- 如果传输二进制/十六进制数据, 部分字符不可见, 不代表没收到
+                    -- 关于收发hex值,请查阅 https://doc.openluat.com/article/583
+                    log.info("第三个数string.byte(s,3)=", string.byte(s,3))
+                    local crc16=crc16(s,#s-2)
+                    local crc16_high=crc16 >> 8
+                    local crc16_low=crc16 & 0xFF
+                    log.info("CRC校验高位",crc16_high,"CRC校验低位",crc16_low)
+                    --打印其hex字符串形式
+                    --数据转换为数值string.byte,用于crc校验
+                    local receive_crc_high = string.byte(s,#s-1)
+                    local receive_crc_low = string.byte(s,#s)
+                    local receive_Switch_state = string.byte(s,#s-2)
+                    log.info("接收到的CRC校验高位", "接收到的CRC校验低位", receive_crc_high, receive_crc_low)
+                    log.info("uart", "receive", id, #s, s:toHex())
+                    --=============================================================
+                    --识别读取数据并将数据赋值给空高料高变量
+                    if crc16_high==receive_crc_high and crc16_low==receive_crc_low and string.byte(s,3)==20 then--物位计的判断
+                    --if crc16_high==receive_crc_high and crc16_low==receive_crc_low and string.byte(s,3)==16 then--判断10数据
+                        --注意,string.byte(s,3)==16,收到字符串的第3个数据,判断时要转换为十进制数,第三个数为0x10,十进制数为16--低功耗雷达
+                        --注意,string.byte(s,3)==16,收到字符串的第3个数据,判断时要转换为十进制数,第三个数为0x14,十进制数为20--四线制雷达
+                        log.info("crc检验通过数据合法")
+                        --先将字符串转为hex格式
+                        local hexStr, len = string.toHex(s) -- 返回值"3132",2,后面的2是长度
+                        --log.info("收到的16进制字符串=",hexStr,len)
+                        --print(hexStr,len) -- 将输出 3132
+                        --截取空高数据,并加上0x个前缀
+                        --local kong_high="0x"..string.sub(hexStr,7,14)--将0x拼接到字符串上,string.sub(hexStr,7,14)是一个数字算一个(低功耗雷达)
+                        local kong_high="0x"..string.sub(hexStr,11,18)--物位计
+                        --截取料高数据,并加上0x个前缀
+                        --local liao_high="0x"..string.sub(hexStr,15,22)--将0x拼接到字符串上(低功耗雷达)
+                        local liao_high="0x"..string.sub(hexStr,19,26)--物位计
+                        --信噪比
+                        --local SNR_Date="0x"..string.sub(hexStr,23,30)--将0x拼接到字符串上(低功耗雷达)
+                        local SNR_Date="0x"..string.sub(hexStr,27,34)--物位计
+                        --雷达温度
+                        --local temp_Date="0x"..string.sub(hexStr,31,38)--将0x拼接到字符串上(低功耗雷达)
+                        local temp_Date="0x"..string.sub(hexStr,35,42)--物位计
+                        log.info("空高16进制字符串=",kong_high)
+                        log.info("料高16进制字符串=",liao_high)
+                        log.info("信噪比16进制字符串=",SNR_Date)
+                        log.info("雷达温度比16进制字符串=",temp_Date)
+                        --将hex格式转化为浮点型数据
+                        local kong_temp = string.pack("<L",kong_high)
+                        kong_Value_485 = string.unpack("f",kong_temp)
+                        log.info("空高kong_Value_485=",kong_Value_485)
+                        local liao_temp = string.pack("<L",liao_high)
+                        liao_Value_485= string.unpack("f",liao_temp)
+                        log.info("料高liao_Value_485=",liao_Value_485)
+                        local SNR_temp = string.pack("<L",SNR_Date)
+                        SNR_485 = string.unpack("f",SNR_temp)
+                        log.info("信噪比SNR_485=",SNR_485)
+                        local xinhao_temp = string.pack("<L",temp_Date)
+                        Radar_temp_485 = string.unpack("f",xinhao_temp)
+                        log.info("雷达温度Radar_temp_485=",Radar_temp_485)                               
+                        --uart.write(1, s)--正常采集不透传给串口1,也就是传给蓝牙
+                        log.info("发布雷达完成消息", "receive", id, #s, s)
+                        sys.publish("雷达完成")
+                    --=============================================================
+                    --如果不是采集命令,则透传给串口1
+                    elseif crc16_high==receive_crc_high and crc16_low==receive_crc_low then
+                        log.info("串口2透传给串口1数据", "receive", id, #s, s)
+                        -- log.info("uart", "receive", id, #s, s:toHex())
+                        uart.write(1, s)--暂时不透传给串口1
+                    elseif crc16_high~=receive_crc_high or crc16_low~=receive_crc_low then
+                        log.info("无数据或crc检验不通过")
+                        kong_Value_485=-100--空高
+                        liao_Value_485=-100--料高
+                        uart.write(1, s)--暂时不透传给串口1
+                        --两种情况,一种是采集失败,一种是采集回波曲线
+                        end
+                end
+                if #s == len then
+                    --log.info("程序经过这里1")
+                    break
+                end
+            until s == ""
+            --log.info("程序经过这里2")
+        end)
+        --=============================================================
+    end
+end
+--=============================================================
+--=============================================================
+-- 并非所有设备都支持sent事件
+uart.on(uartid, "sent", function(id)
+    log.info("uart", "sent", id)
+end)
+--=============================================================
+--开启协程
+sys.taskInit(get_radar_date)
+--=============================================================
+--测试串口时使用
+--循环发数据
+--sys.timerLoopStart(uart.write,5000,uartid,Read_Radar_Date)
+--=============================================================
+
+--=============================================================
+--crc16校验函数用法
+--local data = string.pack("BBBBBB", 0x01, 0x03, 0x00, 0x00, 0x00, 0x02);--需要校验CRC16的内容
+--local datacrc = crc16(data,6);
+--print( datacrc >> 8 )		--输出196 == 0xC4
+--print( datacrc & 0xFF )		--输出11  == 0x0B
+--=============================================================

+ 53 - 0
module/Air780EPM/demo/780EPM视频教程示例代码/25_RS485实战演练/main.lua

@@ -0,0 +1,53 @@
+
+--=============================================================
+PROJECT = "12V_4G_RTU"--名字之间不能有空格,否则影响远程更新的名字识别
+VERSION = "1.0.6" --版本号2023.8.2,必须是3个数,否则升级会失败,系统忽略中间的0
+--=============================================================
+-- sys库是标配--需要用到的其他库,下载时需要添加进来
+_G.sys = require("sys")--前面加-G表示全局引入?
+_G.sysplus = require("sysplus")--加强版的sys库,用于操作网络
+--_G.libnet = require "libnet"--网络相关的库
+--_G.libfota = require"libfota"--远程升级
+--=============================================================
+--=============================================================
+--引入自己定义的文件
+--_G.require("Radar")--串口2雷达采集
+_G.require("Radar_485")--串口3采集485雷达
+log.info("main", PROJECT,VERSION)--2023.11.8
+--=============================================================
+--=============================================================
+--设置看门狗
+if wdt then
+    --添加硬狗防止程序卡死,在支持的设备上启用这个功能
+    wdt.init(9000)--初始化watchdog设置为9s
+    sys.timerLoopStart(wdt.feed, 3000)--3s喂一次狗
+end
+--=============================================================
+--=============================================================
+--查看内存情况,正式版需注释掉
+sys.taskInit(function ()
+    while true do
+        sys.wait(3000)
+        log.info("lua", rtos.meminfo())
+        log.info("sys", rtos.meminfo("sys"))
+    end
+end)
+--=============================================================
+-- 如果运营商自带的DNS不好用,可以用下面的公用DNS
+-- socket.setDNS(nil,1,"223.5.5.5")
+-- socket.setDNS(nil,2,"114.114.114.114")
+
+--socket.sntp()--读取时间
+--socket.sntp("ntp.aliyun.com") --自定义sntp服务器地址
+--socket.sntp({"ntp.aliyun.com","ntp1.aliyun.com","ntp2.aliyun.com"}) --sntp自定义服务器地址
+--sys.subscribe("NTP_UPDATE", function()--订阅NTP_UPDATE这个消息,成功则打印系统时间
+--log.info("sntp", "time", os.date())
+--end)
+--sys.subscribe("NTP_ERROR", function()--订阅NTP_ERROR这个消息,失败则打印错误
+--log.info("socket", "sntp error")
+--socket.sntp()--再次获取时间
+--end)
+-- 用户代码已结束---------------------------------------------
+-- 结尾总是这一句
+sys.run()
+

+ 141 - 0
module/Air780EPM/demo/780EPM视频教程示例代码/27_I2C实战演练(SHT20数据采集)/main.lua

@@ -0,0 +1,141 @@
+-- LuaTools需要PROJECT和VERSION这两个信息
+PROJECT = "sht20demo"
+VERSION = "1.0.0"
+
+-- sys库是标配
+sys = require("sys")
+pm.ioVol(pm.IOVOL_ALL_GPIO, 3300)
+
+--[[ mcu.altfun(mcu.I2C, 0, 66, 2, nil)
+mcu.altfun(mcu.I2C, 0, 67, 2, nil) ]] 
+
+gpio.setup(2,1)--GPIO2打开给camera_3.3V供电
+-- 接线
+--[[
+SHT20 --- 模块
+SDA   -   I2C_SDA
+SCL   -   I2C_SCL
+VCC   -   VDDIO
+GND   -   GND
+]]
+
+-- 启动个task, 定时查询SHT20的数据
+sys.taskInit(function()
+
+    local tmp,hum -- 原始数据
+    local temp,hump -- 真实值
+
+    --1010 000x
+    local addr = 0x40
+    -- 按实际修改哦
+    local id = 1
+
+    log.info("i2c", "initial",i2c.setup(id))
+    --i2c.scan()
+    while true do
+        --第一种方式
+        i2c.send(id, addr, string.char(0xF3))
+        sys.wait(100)
+        tmp = i2c.recv(id, addr, 2)
+        log.info("SHT20", "read tem data", tmp:toHex())
+
+        i2c.send(id, addr, string.char(0xF5))
+        sys.wait(100)
+        hum = i2c.recv(id, addr, 2)
+        log.info("SHT20", "read hum data", hum:toHex())
+        local _,tval = pack.unpack(tmp,'>H')
+        local _,hval = pack.unpack(hum,'>H')
+        if tval and hval then
+            temp = (((17572 * tval) >> 16) - 4685)/100
+            hump = (((12500 * hval) >> 16) - 600)/100
+            log.info("SHT20", "temp,humi",temp,hump)
+        end
+        sys.wait(1000)
+    end
+end)
+-- 启动个task, 定时查询SHT40测试代码的数据
+--[[ sys.taskInit(function()
+    local tmp,hum -- 原始数据
+    local temp,hump -- 真实值
+
+    --1010 000x
+    local addr = 0x44
+    -- 按实际修改哦
+    local id = 0
+
+    log.info("i2c", "initial",i2c.setup(id))
+    --i2c.scan()
+    while true do
+        --第一种方式
+        local resalt=i2c.send(id, addr, string.char(0x89))
+        log.info("打印状态=", resalt)
+        sys.wait(100)
+        tmp = i2c.recv(id, addr, 6)
+        log.info("MT6701", "read 03 data", tmp:toHex())
+
+        i2c.send(id, addr, string.char(0x04))
+        sys.wait(100)
+        hum = i2c.recv(id, addr, 2)
+        log.info("MT6701", "read 04 data", hum:toHex())
+        local _,tval = pack.unpack(tmp,'>H')
+        local _,hval = pack.unpack(hum,'>H')
+        if tval and hval then
+            temp = (((17572 * tval) >> 16) - 4685)/100
+            hump = (((12500 * hval) >> 16) - 600)/100
+            log.info("MT6701", "03,04",temp,hump)
+        end 
+        sys.wait(1000)
+    end
+
+end) ]]
+-- 启动个task, 定时查询MT6701的数据
+--[[ sys.taskInit(function()
+    local tmp,hum -- 原始数据
+    local temp,hump -- 真实值
+
+    --1010 000x
+    local addr = 0x06
+    -- 按实际修改哦
+    local id = 1
+
+    log.info("i2c", "initial",i2c.setup(id))
+    --i2c.scan()
+    while true do
+        --第一种方式
+        local resalt=i2c.send(id, addr, string.char(0x03))
+        log.info("打印状态1=", resalt)
+        local resalt=i2c.send(id, addr, string.char(0x03))
+        log.info("打印状态2=", resalt)
+        sys.wait(100)
+        tmp = i2c.recv(id, addr, 2)--tmp是字符串
+        log.info("MT6701", "read 03 data", tmp:toHex())
+        i2c.send(id, addr, string.char(0x04))
+        sys.wait(100)
+        hum = i2c.recv(id, addr, 2)
+        log.info("MT6701", "read 04 data", hum:toHex())
+        --local raw_value =(tmp << 6) | (hum & 0x3F)
+        -- 步骤4: 转换为角度(0~360°)
+        
+        
+ 
+        local _,tval = pack.unpack(tmp,'>H')
+        log.info("MT6701", "tval=",tval)
+        local _,hval = pack.unpack(hum,'>H')
+        log.info("MT6701", "hval=",hval)
+        if tval and hval then
+            --temp = ((tval & 0x00ff) << 8) | ((hval & 0x00fc)>>2)
+            --temp = (tval << 6) | (hval & 0x3F)
+            temp = (tval >> 2)
+            log.info("MT6701", "temp=",temp)
+            local angle = (temp / 16383) * 360
+            log.info("MT6701", "angle=",angle)
+        end 
+        sys.wait(5000)
+    end
+
+end) ]]
+
+-- 用户代码已结束---------------------------------------------
+-- 结尾总是这一句
+sys.run()
+-- sys.run()之后后面不要加任何语句!!!!!

+ 52 - 0
module/Air780EPM/demo/780EPM视频教程示例代码/27_I2C实战演练(SHT20数据采集)/pins_Air780EPM.json

@@ -0,0 +1,52 @@
+{
+  "model": "Air780EPM",
+  "pins": [
+    [7, "PWR_KEY", ""],
+    [16, "GPIO27", ""],
+    [17, "UART1_RXD", ""],
+    [18, "UART1_TXD", ""],
+    [19, "GPIO22", ""],
+    [20, "PWM1", ""],
+    [22, "PWM0", ""],
+    [23, "ONEWIRE", ""],
+    [25, "CAN_TXD", ""],
+    [26, "PWM4", ""],
+    [28, "UART2_RXD", ""],
+    [29, "UART2_TXD", ""],
+    [30, "GPIO29", ""],
+    [31, "GPIO30", ""],
+    [32, "GPIO31", ""],
+    [33, "GPIO32", ""],
+    [38, "DBG_RXD", ""],
+    [39, "DBG_TXD", ""],
+    [49, "LCD_RST", ""],
+    [50, "LCD_SDA", ""],
+    [51, "LCD_RS", ""],
+    [52, "LCD_CS", ""],
+    [53, "LCD_CLK", ""],
+    [54, "CAM_MCLK", ""],
+    [55, "CAM_RX0", ""],
+    [56, "CAM_RX1", ""],
+    [57, "UART3_TXD", ""],
+    [58, "UART3_RXD", ""],
+    [61, "VBUS", ""],
+    [66, "I2C1_SDA", ""],
+    [67, "I2C1_SCL", ""],
+    [78, "GPIO28", ""],
+    [79, "USIM_DET", ""],
+    [80, "CAM_BCLK", ""],
+    [81, "CAM_CS", ""],
+    [82, "USB_BOOT", ""],
+    [83, "SPI0_CS", ""],
+    [84, "SPI0_MISO", ""],
+    [85, "SPI0_MOSI", ""],
+    [86, "SPI0_CLK", ""],
+    [97, "GPIO16", ""],
+    [99, "GPIO23", ""],
+    [100, "GPIO17", ""],
+    [101, "WAKEUP0", ""],
+    [102, "GPIO20", ""],
+    [106, "CAN_RXD", ""],
+    [107, "GPIO21", ""]
+  ]
+}

+ 150 - 0
module/Air780EPM/demo/780EPM视频教程示例代码/30_双路DS18B20数据采集/DS18B20.lua

@@ -0,0 +1,150 @@
+local DS18B20 = {}
+new_temp=-100--中间过渡数据
+gongshui_temp=-1000--供水温度/进水温度
+huishui_temp=-1000--回水温度/出水温度
+mark=0--采集成功标志
+TEMP_mark=0--温度采集成功标志
+--=============================================================
+--匹配温度ID,并发送温度转换命令并做温度转换
+local function read_ds18b20(id)
+
+    local tbuff = zbuff.create(10)
+    local succ,crc8c,range,t
+    local rbuff = zbuff.create(9)
+    --如果有多个DS18B20,需要带上ID
+    tbuff:write(0x55)
+    tbuff:copy(nil, id)
+    tbuff:write(0xb8)
+    --如果只有1个DS18B20,就用无ID方式
+    --tbuff:write(0xcc,0xb8)
+    while true do
+        tbuff[tbuff:used() - 1] = 0x44
+        succ = onewire.tx(0, tbuff, false, true, true)
+        if not succ then
+            return
+        end
+        while true do
+            succ = onewire.reset(0, true)
+            if not succ then
+                return
+            end
+            if onewire.bit(0) > 0 then
+                log.info("温度转换完成")
+                break
+            end
+            sys.wait(10)
+        end
+        tbuff[tbuff:used() - 1] = 0xbe
+        succ = onewire.tx(0, tbuff, false, true, true)
+        if not succ then
+            return
+        end
+        succ,rx_data = onewire.rx(0, 9, nil, rbuff, false, false, false)
+        crc8c = crypto.crc8(rbuff:toStr(0,8), 0x31, 0, true)
+        if crc8c == rbuff[8] then
+            range = (rbuff[4] >> 5) & 0x03
+            -- rbuff[0] = 0xF8
+            -- rbuff[1] = 0xFF
+            t = rbuff:query(0,2,false,true)
+            t = t * (5000 >> range)
+            t = t / 10000
+            new_temp=KeepDecimalPlace(t, 2)--处理数据四舍五入
+            mark=1--采集成功
+            log.info("处理后的温度=",new_temp)
+        else
+            log.info("RAM DATA CRC校验不对",  mcu.x32(crc8c), mcu.x32(rbuff[8]))
+            new_temp=-100--数据校验错误
+            mark=0--采集失败
+            return
+        end
+        sys.wait(50)
+    end
+end
+--=============================================================
+--读温度ID及判断数据
+local function test_ds18b20()
+    local succ,rx_data
+    local id = zbuff.create(8)
+
+    local crc8c
+    --onewire.init(0)
+    --onewire.timing(0, false, 0, 500, 500, 15, 240, 70, 1, 15, 10, 2)
+    --for i=1,5 do
+    while true do
+        onewire.init(0)
+        onewire.timing(0, false, 0, 500, 500, 15, 240, 70, 1, 15, 10, 2)
+        id:set() --清空id
+        succ,rx_data = onewire.rx(0, 8, 0x33, id, false, true, true)
+        if succ then
+            if id[0] == 0x28 then
+                crc8c = crypto.crc8(id:query(0,7), 0x31, 0, true)
+                if crc8c == id[7] then
+                    log.info("探测到DS18B20", id:query(0, 7):toHex())
+                    read_ds18b20(id)
+                    log.info("DS18B20离线,重新探测")
+                    new_temp=-200--异常处理
+                    mark=2--识别出,但是采集失败
+                else
+                    log.info("ROM ID CRC校验不对",  mcu.x32(crc8c), mcu.x32(id[7]))
+                    new_temp=-300--异常处理
+                    mark=3--识别出,CRC校验不对
+                end
+            else
+                log.info("ROM ID不正确", mcu.x32(id[0]))
+                new_temp=-400--异常处理
+                mark=4--识别出,D不正确不对
+            end
+        end
+        log.info("没有检测到DS18B20, 5秒后重试")
+        new_temp=-500--异常处理
+        mark=5--识别出,D不正确不对
+        sys.wait(100)
+    end
+end
+--=============================================================
+local function select_ds18b20()
+      local water_in_pin=11
+      local water_out_pin=9
+      local water_in=gpio.setup(water_in_pin, 0)--初始化状态
+      local water_out=gpio.setup(water_out_pin, 0)--初始化状态
+      while true do
+            
+            water_in(1)
+            water_out(0)
+            mark=0--重置一下标志位
+            onewire.deinit(0) -- 切换的时候一定要先关闭单总线,在读取的时候重新初始化
+            sys.wait(1000)
+            TEMP_mark=0--初始化一下 
+            log.info("进水标志位mark=",mark)
+            if mark==1 then
+                gongshui_temp=new_temp
+                log.info("采集供水/进水成功,温度=",gongshui_temp)
+            else
+                gongshui_temp=-1000
+                log.info("采集供水/进水失败,温度=",gongshui_temp)
+            end
+            water_in(0)
+            water_out(1)
+            mark=0--重置一下标志位
+            onewire.deinit(0) -- 切换的时候一定要先关闭单总线,在读取的时候重新初始化
+            sys.wait(1000)
+            log.info("回水标志位mark=",mark)
+            log.info("采集供水/进水成功,电源状态切换")
+            if mark==1 then
+                huishui_temp=new_temp
+                log.info("采集回水/出水成功,温度=",huishui_temp)
+            else
+                huishui_temp=-1000
+                log.info("采集回水/出水失败,温度=",huishui_temp)
+            end 
+            TEMP_mark=1--温度采集成功          
+      end
+end
+--=============================================================
+if onewire then
+    sys.taskInit(test_ds18b20)
+else
+    log.info("no onewire")
+end
+sys.taskInit(select_ds18b20)
+--=============================================================