add: 添加新的阿里云物联网库-aliyun2库,及搭配的demo, 逐步完善中
[LuatOS.git] / script / libs / ak8963.lua
blob0862c4f95a5a3b4040041b65b77f902b1469de73
1 --[[
2 @module ak8963
3 @summary ak8963 地磁传感器
4 @version 1.0
5 @date 2023.06.07
6 @author Dozingfiretruck
7 @usage
8 --注意:因使用了sys.wait()所有api需要在协程中使用
9 -- 用法实例
10 local ak8963 = require "ak8963"
11 i2cid = 0
12 i2c_speed = i2c.FAST
13 sys.taskInit(function()
14 i2c.setup(i2cid,i2c_speed)
15 ak8963.init(i2cid)--初始化,传入i2c_id
16 while 1 do
17 sys.wait(100)
18 local mag = ak8963.get_mag()--获取地磁仪
19 log.info("ak8963 mag", "mag.x",mag.x,"mag.y",mag.y,"mag.z",mag.z)
20 end
21 end)
25 local ak8963 = {}
26 local sys = require "sys"
27 local i2cid
28 local i2cslaveaddr
29 local deviceid
31 local AK8963_ADDRESS_AD0_LOW = 0x0C
32 local AK8963_ADDRESS_AD0_HIGH = 0x0D
34 ---器件通讯地址
35 local AK8963_WHO_AM_I = 0x48 -- AK8963
37 ---AK8963所用地址
38 -- Read-only Reg
39 local AK8963_RA_WHO_AM_I = 0x00
40 local AK8963_REG_INFO = 0x01
41 local AK8963_REG_ST1 = 0x02
42 local AK8963_REG_HXL = 0x03
43 local AK8963_REG_HXH = 0x04
44 local AK8963_REG_HYL = 0x05
45 local AK8963_REG_HYH = 0x06
46 local AK8963_REG_HZL = 0x07
47 local AK8963_REG_HZH = 0x08
48 local AK8963_REG_ST2 = 0x09
49 -- Write/Read Reg
50 local AK8963_REG_CNTL1 = 0x0A
51 local AK8963_REG_CNTL2 = 0x0B
52 local AK8963_REG_ASTC = 0x0C
53 local AK8963_REG_TS1 = 0x0D
54 local AK8963_REG_TS2 = 0x0E
55 local AK8963_REG_I2CDIS = 0x0F
56 -- Read-only Reg (ROM)
57 local AK8963_REG_ASAX = 0x10
58 local AK8963_REG_ASAY = 0x11
59 local AK8963_REG_ASAZ = 0x12
60 -- Status
61 local AK8963_STATUS_DRDY = 0x01
62 local AK8963_STATUS_DOR = 0x02
63 local AK8963_STATUS_HOFL = 0x08
65 local AK8963_ASAX
66 local AK8963_ASAY
67 local AK8963_ASAZ
69 --器件ID检测
70 local function ak8963_check()
71 i2c.send(i2cid, AK8963_ADDRESS_AD0_LOW, AK8963_RA_WHO_AM_I)--读器件地址
72 sys.wait(50)
73 local revData = i2c.recv(i2cid, AK8963_ADDRESS_AD0_LOW, 1)
74 if revData:byte() ~= nil then
75 i2cslaveaddr = AK8963_ADDRESS_AD0_LOW
76 else
77 i2c.send(i2cid, AK8963_ADDRESS_AD0_HIGH, AK8963_RA_WHO_AM_I)--读器件地址
78 sys.wait(50)
79 local revData = i2c.recv(i2cid, AK8963_ADDRESS_AD0_HIGH, 1)
80 if revData:byte() ~= nil then
81 i2cslaveaddr = AK8963_ADDRESS_AD0_HIGH
82 else
83 log.info("i2c", "Can't find device")
84 return false
85 end
86 end
87 i2c.send(i2cid, i2cslaveaddr, AK8963_RA_WHO_AM_I)--读器件地址
88 sys.wait(50)
89 local revData = i2c.recv(i2cid, i2cslaveaddr, 1)
90 log.info("Device i2c address is:", revData:toHex())
91 if revData:byte() == AK8963_WHO_AM_I then
92 deviceid = AK8963_WHO_AM_I
93 log.info("Device i2c id is: AK8963")
94 else
95 log.info("i2c", "Can't find device")
96 return false
97 end
98 return true
99 end
101 --[[
102 ak8963初始化
103 @api ak8963.init(i2c_id)
104 @number 所在的i2c总线id
105 @return bool 成功返回true
106 @usage
107 ak8963.init(0)
109 function ak8963.init(i2c_id)
110 i2cid = i2c_id
111 sys.wait(20)
112 if ak8963_check() then
113 i2c.send(i2cid, i2cslaveaddr, {AK8963_REG_CNTL1, 0x0F})
114 i2c.send(i2cid, i2cslaveaddr,AK8963_REG_ASAX)
115 AK8963_ASAX = i2c.recv(i2cid, i2cslaveaddr, 1):byte()
116 i2c.send(i2cid, i2cslaveaddr,AK8963_REG_ASAY)
117 AK8963_ASAY = i2c.recv(i2cid, i2cslaveaddr, 1):byte()
118 i2c.send(i2cid, i2cslaveaddr,AK8963_REG_ASAZ)
119 AK8963_ASAZ = i2c.recv(i2cid, i2cslaveaddr, 1):byte()
120 i2c.send(i2cid, i2cslaveaddr, {AK8963_REG_CNTL1, 0x10})
121 sys.wait(10)
122 log.info("ak8963 init_ok")
123 return true
125 return false
128 --获取地磁计的原始数据
129 local function ak8963_get_mag_raw()
130 local mag={x=nil,y=nil,z=nil}
131 i2c.send(i2cid, i2cslaveaddr,AK8963_REG_HXL)
132 local x = i2c.recv(i2cid, i2cslaveaddr, 2)
133 _,mag.x = pack.unpack(x,"<h")
134 i2c.send(i2cid, i2cslaveaddr,AK8963_REG_HYL)
135 local y = i2c.recv(i2cid, i2cslaveaddr, 2)
136 _,mag.y = pack.unpack(y,"<h")
137 i2c.send(i2cid, i2cslaveaddr,AK8963_REG_HZL)
138 local z = i2c.recv(i2cid, i2cslaveaddr, 2)
139 _,mag.z = pack.unpack(z,"<h")
140 return mag or 0
144 --[[
145 获取地磁仪的数据
146 @api ak8963.get_mag()
147 @return table 地磁仪数据
148 @usage
149 local mag = ak8963.get_mag()--获取地磁仪
150 log.info("ak8963 mag", "mag.x",mag.x,"mag.y",mag.y,"mag.z",mag.z)
152 function ak8963.get_mag()
153 local mag={x=nil,y=nil,z=nil}
154 i2c.send(i2cid, i2cslaveaddr, {AK8963_REG_CNTL1, 0x11})
155 sys.wait(10)
156 local tmp = ak8963_get_mag_raw()
157 mag.x = tmp.x*((AK8963_ASAX-128)*0.5/128+1)
158 mag.y = tmp.y*((AK8963_ASAY-128)*0.5/128+1)
159 mag.z = tmp.z*((AK8963_ASAZ-128)*0.5/128+1)
160 return mag
163 return ak8963