LuatOs changes the module serial port baud rate for reference
luatos changes the AIR530 serial port baud rate
BL0942 default serial port baud rate can be set to 9600bps by connecting the SCLK_BPS pin to a 3.3V power supply
But if you adjust to 38400bps, you need to modify the 0x19 register
Special register description of bl0942 v1.06 version, please note that there are errors in the special register description of earlier versions
Complete code
main.lua
-- LuaTools requires two pieces of information, PROJECT and VERSION PROJECT = "EMQX_Plug" VERSION = "1.0.1" --[[ This demo requires the mqtt library, which is available on most devices that can connect to the Internet. mqtt is also a built-in library, no need to require ]] -- sys library is standard _G.sys = require("sys") --[[Special note, the following statements are required to use the mqtt library]] _G.sysplus = require("sysplus") -- Automatic low power consumption, light sleep mode -- Air780E supports uart wake-up and network data wake-up, but you need to disconnect the USB, or pm.power(pm.USB, false), but you can't see the log in this way. -- pm.request(pm.LIGHT) -- Serial port ID, serial port read buffer 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 --Add a hard dog to prevent the program from freezing and enable this feature on supported devices wdt.init(9000)--Initialize watchdog set to 9s sys.timerLoopStart(wdt.feed, 3000)--feed the dog once every 3 seconds end --The most commonly used 115200 8N1 local result1 = uart.setup( UART_ID1,--serial port id 9600,--baud rate 8,--data bits 1--Stop bit ) print(_VERSION) sys.taskInit(function() log.info("Initialization","bl0942 software reset") BL0942_Write(UART_ID1,bl0942.SOFT_RESET,0x5A,0x5A,0x5A) sys.wait(100) --The following code sets the anti-creep threshold register to ensure that the electrical energy data will not accumulate noise and form negative values. BL0942_Write(UART_ID1,bl0942.USR_WRPROT,0x55,0x00,0x00) BL0942_Write(UART_ID1,bl0942.WA_CREEP,0x33,0x00,0x00) --The following changes the serial port baud rate BL0942_Write(UART_ID1,bl0942.MODE,0x87,0x03,0x00) BSP_FLAG=1 uart.write(UART_ID1," ")--trigger the sent event of uart.on--trigger the sent event of uart.on print("GPS serial port baud rate has been changed") end) uart.on(UART_ID1, "sent", function(uid) if BSP_FLAG==1 then -- uart.close(UART_ID1)--Commenting out this code can also change the baud rate result1 = uart.setup( UART_ID1,--serial port id 38400,--Baud rate 8,--data bits 1--Stop bit ) print("The Air700 UART1 serial port baud rate has been changed") 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--guarantee no packet loss after reading 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 -- There may be 23 bytes of all-electric parameter data packets mixed in, which must be eliminated return --Reading a single register generally returns 3 bytes end -- log.info("Special register",#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 --Avoid parsing and reading register data 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("Current=%.1fmA Voltage=%.1fV Electricity=%0.2f degree ",pub_cur,pub_vol,pub_energy)) -- print(string.format("Current=%0.2fA Voltage=%.1fV Power=%0.1fW Electricity=%0.2f degree Frequency=%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 Read the full electrical parameter data packet 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) --Read 0x19 user mode selection register RD_SPECIAL_REGISTER_FLAG=1 RD_DATA_REGISTER_FLAG=0 end end, 2400) --User code ended---------------------------------------------------------- - -- It always ends with this sentence sys.run() -- Do not add any statements after sys.run()!!!!!
bl0942.lua
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, --Current waveform register, signed V_WAVE = 0x02, --Voltage waveform register, signed I_RMS = 0x03, --current effective value register, unsigned V_RMS = 0x04, --voltage effective value register, unsigned I_FAST_RMS = 0x05, --current fast RMS register, unsigned WATT = 0x06, --active power register, signed CF_CNT = 0x07, --Active energy pulse count register, unsigned FREQ = 0x08, --line voltage frequency register STATUS = 0x09, --status register ----------User operation register (read and write)-------------------- I_RMSOS = 0x12, --current effective value small signal correction register WA_CREEP = 0x14, --Active power anti-subscription register I_FAST_RMS_TH = 0x15, --current fast RMS threshold register I_FAST_RMS_CYC= 0x16, --current fast effective value refresh cycle register FREQ_CYC = 0x17, --Line voltage frequency refresh cycle register OT_FUNX = 0x18, --Output configuration register MODE = 0x19, --User mode selection register GAIN_CR = 0x1A, --Current channel gain control register SOFT_RESET = 0x1C, --When writing 0x5A5A5A, the user area register is reset USR_WRPROT = 0x1D --User write protection setting register. --After writing 0x55, the user operation register can be written; --Write other values, the user operation register area cannot be written }, __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)--This output digit is greater than 2 bytes, and its decimal digit is -207 Hexadecimal: FFFF FFFF FFFF FF31 local result=bit.band(checksum,0xff)--guarantee 1 byte checksum, remove the first 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
Before modifying the special register, 0x55 must be written into the 0X1D register.
The code implements the function of reading the full power data packet and the 0x19 register. Special attention is paid to judging the length of the data when parsing the data returned by the serial port respectively, and discarding the data packets that do not meet the parsed length to ensure the accuracy of the data.
The other two read cycles are staggered in delay time to avoid simultaneous reads.
MODE=903 is 0011 1000 0111, which is [9:8]=11, and the baud rate is adjusted to 38400bps.
Note: Alternate loop reading will cause the current to display data of more than 600 mA. I have not solved it yet. If the full-power data packet is read separately, the data can be analyzed normally and accurately. Reading special registers is generally used during the debugging phase.