



-
- -- LuaTools需要PROJECT和VERSION这两个信息
- PROJECT = "EMQX_Plug"
- VERSION = "1.0.1"
-
- --[[
- 本demo需要mqtt库, 大部分能联网的设备都具有这个库
- mqtt也是内置库, 无需require
- ]]
-
- -- sys库是标配
- _G.sys = require("sys")
- --[[特别注意, 使用mqtt库需要下列语句]]
- _G.sysplus = require("sysplus")
-
- -- 自动低功耗, 轻休眠模式
- -- Air780E支持uart唤醒和网络数据下发唤醒, 但需要断开USB,或者pm.power(pm.USB, false) 但这样也看不到日志了
- -- pm.request(pm.LIGHT)
-
- -- 串口ID,串口读缓冲区
- local bl0942 = require "bl0942"
- local UART_ID1, UART1receQueue = 1, {}
- local uartimeout, UART1recvReady = 25,"UART_RECV_ID1"
-
-
- local RD_SPECIAL_REGISTER_FLAG=0
- local RD_DATA_REGISTER_FLAG=0
- local BAUD_CHANGED_FLAG=0
- local LED = gpio.setup(31, 1, gpio.PULLUP)
- local RELAY = gpio.setup(9, 1, gpio.PULLUP)
- LED(1)
-
-
- if wdt then
- --添加硬狗防止程序卡死,在支持的设备上启用这个功能
- wdt.init(9000)--初始化watchdog设置为9s
- sys.timerLoopStart(wdt.feed, 3000)--3s喂一次狗
- end
-
-
-
- -- 最常用115200 8N1
- local result1 = uart.setup(
- UART_ID1,--串口id
- 9600,--波特率
- 8,--数据位
- 1--停止位
- )
- print(_VERSION)
-
- sys.taskInit(function()
- log.info("初始化","bl0942软件复位")
- BL0942_Write(UART_ID1,bl0942.SOFT_RESET,0x5A,0x5A,0x5A)
- sys.wait(100)
- -- 以下代码设置防潜动阈值寄存器,保证电度数据不会累计噪声形成负值
- BL0942_Write(UART_ID1,bl0942.USR_WRPROT,0x55,0x00,0x00)
- BL0942_Write(UART_ID1,bl0942.WA_CREEP,0x33,0x00,0x00)
-
- --以下改变串口波特率
- BL0942_Write(UART_ID1,bl0942.MODE,0x87,0x03,0x00)
- BSP_FLAG=1
- uart.write(UART_ID1," ")--触发uart.on的sent事件--触发uart.on的sent事件
- print("已改变GPS串口波特率")
- end)
-
-
- uart.on(UART_ID1, "sent", function(uid)
- if BSP_FLAG==1 then
- -- uart.close(UART_ID1)--此代码注释掉也能实现波特率更改
- result1 = uart.setup(
- UART_ID1,--串口id
- 38400,--波特率
- 8,--数据位
- 1--停止位
- )
- print("已改变Air700 UART1串口波特率")
- BL0942_Write(UART_ID1,bl0942.USR_WRPROT,0xff,0x00,0x00)
- sys.publish("38400")
- BSP_FLAG=0
- BAUD_CHANGED_FLAG=1
- end
- end)
-
- sys.subscribe("38400",function()
- uart.on(UART_ID1, "receive", function(uid, length)
- local s
- while true do--保证读完不能丢包
- s = uart.read(uid, length)
- if #s == 0 then break end
- table.insert(UART1receQueue, s)
- end
- sys.timerStart(sys.publish, uartimeout, UART1recvReady)
- end)
- end)
-
- sys.subscribe(UART1recvReady, function()
-
- if (RD_SPECIAL_REGISTER_FLAG==1) then
- local m={}
- local strRe = table.concat(UART1receQueue)
- if (#strRe)>4 then --可能会有全电参数数据包的23个字节混入,必须剔除
- return --读单个寄存器一般返回3个字节
- end
- -- log.info("特殊寄存器",#strRe)
- UART1receQueue = {}
- RD_SPECIAL_REGISTER_FLAG=0
- m[1]=string.byte(strRe,1)
- m[2]=string.byte(strRe,2)
- m[3]=string.byte(strRe,3)
- -- print(m[1],m[2],m[3])
- local m_temp = string.char(m[1],m[2],m[3])
- local mode=string.unpack("i3", m_temp)
- print(string.format("MODE=%d",mode))
- end
-
- if (RD_DATA_REGISTER_FLAG==1) then
- local v,c,e={},{},{}
- local vol,cur,engerywat
- -- local w,f={},{}
- -- local freq,engery
- local strDA = table.concat(UART1receQueue)
- if (#strDA)<23 then --避免解析读寄存器数据
- return
- end
- UART1receQueue = {}
- RD_DATA_REGISTER_FLAG=0
-
- c[1]=string.byte(strDA,2)
- c[2]=string.byte(strDA,3)
- c[3]=string.byte(strDA,4)
-
- v[1]=string.byte(strDA,5)
- v[2]=string.byte(strDA,6)
- v[3]=string.byte(strDA,7)
-
- e[1]=string.byte(strDA,14)
- e[2]=string.byte(strDA,15)
- e[3]=string.byte(strDA,16)
-
- local cur_temp = string.char(c[1],c[2],c[3])
- local vol_temp = string.char(v[1],v[2],v[3])
- local ene_temp = string.char(e[1],e[2],e[3])
- -- local wat_temp = string.char(w[1],w[2],w[3])
- -- local freq_temp = string.char(f[1],f[2],f[3])
-
- local cur = string.unpack("i3", cur_temp)
- local vol = string.unpack("i3", vol_temp)
- local energy= string.unpack("i3", ene_temp)
- -- print(string.format("energy=%d",energy))
- -- local wat = string.unpack("i3", wat_temp)
- -- local freq = string.unpack("i3",freq_temp)
-
- pub_vol=(vol*V_CONSTANT)/V_DENO
- pub_cur=(cur*VREF/I_DENO)*1000
- pub_energy=(energy*E_PER_PLUSE)
-
- print(string.format("电流=%.1fmA 电压=%.1fV 电度=%0.2f度 ",pub_cur,pub_vol,pub_energy))
- -- print(string.format("电流=%0.2fA 电压=%.1fV 功率=%0.1fW 电度=%0.2f度 频率=%0.1fHz",Current,Voltage,Energy,Wat,Freq))
- end
- end)
- local cnt = 0
-
- sys.timerLoopStart(function()
- if BAUD_CHANGED_FLAG==1 then
- uartimeout=25
- BL0942_Read(UART_ID1,0xAA)--V_RMS 0xAA bl0942.V_RMS 读取全电参数数据包
- RD_DATA_REGISTER_FLAG=1
- RD_SPECIAL_REGISTER_FLAG=0
- end
- end, 1000)
-
- sys.timerLoopStart(function()
- if BAUD_CHANGED_FLAG==1 then
- uartimeout=5
- BL0942_Read(UART_ID1,bl0942.MODE) --读0x19用户模式选择寄存器
- RD_SPECIAL_REGISTER_FLAG=1
- RD_DATA_REGISTER_FLAG=0
- end
- end, 2400)
-
- -- 用户代码已结束---------------------------------------------
- -- 结尾总是这一句
- sys.run()
- -- sys.run()之后后面不要加任何语句!!!!!
- local sys = require "sys"
-
- VREF = 1.218
- V_DENO =1842052.2
- V_CONSTANT=121.8
- I_DENO =504863.7 --305978*(3.3*1000)/2000
- DOUBLE_FS =1000000.0
- POWER_COEFF=148.3524 --1.218*1.218*20*5
- P_DENO =145317.645 --3537*(3.3*1000/2000)*0.0249*1000
- E_PER_PLUSE=0.000118942
-
- bl0942= setmetatable({}, {
- __index = {
- WRITE_HEAD = 0xA8,
- READ_HEAD = 0x58,
- I_WAVE = 0x01, --电流波形寄存器,有符号
- V_WAVE = 0x02, --电压波形寄存器,有符号
- I_RMS = 0x03, --电流有效值寄存器,无符号
- V_RMS = 0x04, --电压有效值寄存器,无符号
- I_FAST_RMS = 0x05, --电流快速有效值寄存器,无符号
- WATT = 0x06, --有功功率寄存器,有符号
- CF_CNT = 0x07, --有功电能脉冲计数寄存器,无符号
- FREQ = 0x08, --线电压频率寄存器
- STATUS = 0x09, --状态寄存器
-
- ---------用户操作寄存器(读写)--------------------
- I_RMSOS = 0x12, --电流有效值小信号校正寄存器
- WA_CREEP = 0x14, --有功功率防潜寄存器
- I_FAST_RMS_TH = 0x15, --电流快速有效值阈值寄存器
- I_FAST_RMS_CYC= 0x16, --电流快速有效值刷新周期寄存器
- FREQ_CYC = 0x17, --线电压频率刷新周期寄存器
- OT_FUNX = 0x18, --输出配置寄存器
- MODE = 0x19, --用户模式选择寄存器
- GAIN_CR = 0x1A, --电流通道增益控制寄存器
- SOFT_RESET = 0x1C, --写入 0x5A5A5A 时,用户区寄存器复位
- USR_WRPROT = 0x1D --用户写保护设置寄存器。
- --写入0x55后,用户操作寄存器可以写入;
- --写入其他值,用户操作寄存器区域不可写入
- },
- __newindex = function() end
- })
-
-
- local function Check_ConStat(HEAD,address,data0_7,data8_15,data16_23)
- local sum=HEAD+address+data0_7+data8_15+data16_23
- local sumAnd=bit.band(sum,0xff)
- local checksum=bit.bnot(sumAnd)--这个输出位数大于2个字节,其十进制数位-207 十六进制:FFFF FFFF FFFF FF31
- local result=bit.band(checksum,0xff)--保证校验位1个字节,去除前面的14个FF
- return result;
- end
-
-
- function BL0942_Read(ID,address)
- uart.write(ID,string.char(bl0942.READ_HEAD,address))
- end
- --
- function BL0942_Write(ID,address,data0_7,data8_15,data16_23)
- local checksum=Check_ConStat(bl0942.WRITE_HEAD,address,data0_7,data8_15,data16_23)
- uart.write(ID,string.char(bl0942.WRITE_HEAD,address,data0_7,data8_15,data16_23,checksum))
- end
-
- return bl0942


注意:交替循环读会出现电流显示600多ma的数据,目前我还没有解决,如果单独读取全电数据包能正常准确解析数据。读特殊寄存器一般用于调试阶段。