README.md
1# 一、**样例介绍**
2
3基于OpenHarmony NAPI框架和HDF框架实现控制设备端扩展板GPIO的LED灯的控制效果app
4
5## 1.1app页面效果
6
7## 1.2app演示
8<a id="demo">演示目录</a>
9
10[1.选择并实时更新](#select)
11[2.开关灯(点个与全部)](#openClose)
12[3.闪烁效果和中断](#sparkle)
13[4.射点效果](#flow1)
14[5.波动效果](#flow2)
15[6.随机效果](#random)
16
17## 1.3app功能
181.gpio开关灯
192.可选择开关灯的灯号、延时、次数
203.有特殊效果:射点、波浪、随机、闪烁
214.可随时中断效果
225.实时同步显示状态
23
24
25
26# 二、文件说明
27## hcs文件
28在\vendor\unionman\unionpi_tiger\hdf_config\khdf\device_info\device_info.hcs文件里添加下面代码,让HDF的gpio接口可以正常调用
29```
30device_gpio :: device {
31 device0 :: deviceNode {
32 policy = 2;
33 priority = 10;
34 permission = 0644;
35 moduleName = "HDF_PLATFORM_GPIO_MANAGER";
36 serviceName = "HDF_PLATFORM_GPIO_MANAGER";
37 }
38 device1 :: deviceNode {
39 policy = 0;
40 priority = 10;
41 permission = 0644;
42 moduleName = "linux_gpio_adapter";
43 deviceMatchAttr = "linux_gpio_adapter";
44 }
45 }
46```
47\vendor\unionman\unionpi_tiger\hdf_config\khdf\hdf.hcs文件里添加
48```
49#include "device_info/device_info.hcs"
50```
51## c/c++文件
52本项目使用的是unionpi_tiger\sample\napi\napisubsys\gpio_hdf目录下的c/c++文件
53主要文件包含:
54gpio_hdf.cpp ———— HDF接口处理业务逻辑和注册NPAPI驱动
55BUILD.gn ———— ohos_shared_library编译成so文件
56<br></br>
57本项目用到的HDF接口函数为
58```
59GpioSetDir(gpioNum, direction);
60GpioSetDir(gpioNum, direction);
61GpioRead(gpioNum, &getValue);
62```
63## ts文件
64本项目使用的是unionpi_tiger\sample\napi\napisubsys目录下的@ohos.gpio_hdf.d.ts文件
65编写接口定义@ohos.**nameX**.d.ts文件,放到OpenHarmony SDK目录ets\\${ets_version}\\api目录下。使用SDK 8则${ets_version}为3.1.6.6,SDK 7则为3.0.0.0。
66
67## so文件
68本地编译输出到out\\${device}\\lib.unstripped文件夹,,命名规则为lib**nameX**.z.so,**nameX**与ohos_shared_library中的命名有关
69可通过打包镜像img烧录到开发板上,若已经烧录过系统,可直接通过串口传输工具或者u盘等传输方式来发送so文件,复制so文件到系统下/system/lib/module/中
70注意@ohos.**nameX**必须和NAPI模块的BUILD.gn文件中ohos_shared_library("**nameX**")指定的动态库名一致。
71
72## 整体思路
73.png)
74
75# 四、编写app
76## 查看gpioNum
77进入到hdc_std.exe目录打开cmd
78```
79hdc_std.exe shell
80```
81若想查看gpioNum可执行下面代码进行查看
82```
83cd sys/kernel/debug
84cat gpio
85```
86
87## DevEco Studio 引用ts文件
88```
89import prompt from '@ohos.prompt';
90import gpio_hdf from '@ohos.gpio_hdf';
91```
92## 代码说明
93### 1.数据变量
94```
95data: {
96 pin: 380, //pinNum;[380,389]
97 status: [0,0,0,0,0,0,0,0,0,0], //灯号状态
98 delay: 100, //间隔
99 time: 10, //次数
100 full: false, //是否全选
101 blank: " ", //空格
102 timerID1: null, //setTimeout返回值
103 timerID2: null, //setTimeout返回值
104 type: "无", //效果运行类型
105 temp: 0, //临时变量
106 isinf: true, //是否无穷次数
107 },
108```
109### 2.开启软件执行的函数
110关闭全部灯
111```
112//初始化
113 onInit() {
114 //进入程序灭掉全部灯,保证与初始状态全为0相同
115 for(var i = 380; i <= 389; i++){
116 this.pin = i
117 this.removeLedEffect()//因IDE不能调用接口,使previewer试图变空白,注释掉即可正常预览试图
118 }
119
120 },
121```
122### 3.改变数据变量数值
123```
124
125 //改变gpio口
126 changeGpio(pinNum) {
127 this.full = false
128 this.pin = pinNum + 380
129 prompt.showToast({
130 message: "选择" + this.pin
131 })
132 },
133 //改变间隔时间
134 changeDelay(delay) {
135 this.delay = delay
136 prompt.showToast({
137 message: "选择" + this.delay + "ms"
138 })
139 },
140 //改变次数
141 changeTime(time) {
142 this.isinf = false
143 this.time = time
144 prompt.showToast({
145 message: "选择" + this.time + "次"
146 })
147 },
148 //改变是否全选
149 changeFull() {
150 this.full = true
151 prompt.showToast({
152 message: "全选"
153 })
154 },
155 //改变次数是否无穷
156 changeIsinf() {
157 this.isinf = true
158 prompt.showToast({
159 message: "选择∞"
160 })
161 },
162```
163<a id="select">选择并实时更新</a>
164
165[返回演示目录](#demo)
166### 4.开关灯函数
167#### 开灯函数接口执行流程图
168.png)
169
170```
171//开灯
172 addLedEffect() {
173 //若全选执行全开灯
174 if(this.full){
175 this.fullAddLedEffect()
176 this.full = true
177 }
178 //单个pin开灯,使用napi接口
179 gpio_hdf.setLedStatus(this.pin, gpio_hdf.LED_ON).then((result) => {
180 if (result === 0) {
181 console.info("Turned on LED." + result)
182 this.status.splice(this.pin - 380,1,1) //更新状态
183 prompt.showToast({
184 message: "pin."+this.pin+"开灯"
185 })
186 } else {
187 console.info("Turned on LED failed." + result)
188 prompt.showToast({
189 message: "pin."+this.pin+"开灯失败" + result
190 })
191 }
192 })
193
194 },
195
196 //关灯
197 removeLedEffect() {
198 //若全选执行全关灯
199 if(this.full){
200 this.fullRemoveLedEffect()
201 this.full = true
202 }
203 //单个pin关灯,使用napi接口
204 gpio_hdf.setLedStatus(this.pin, gpio_hdf.LED_OFF).then((result) => {
205 if (result === 0) {
206 console.info("Turned off LED." + result)
207 this.status.splice(this.pin - 380,1,0) //更新状态
208 prompt.showToast({
209 message: "pin."+this.pin+"关灯"
210 })
211 } else {
212 console.info("Turned off LED failed." + result)
213 prompt.showToast({
214 message: "pin."+this.pin+"关灯失败" + result
215 })
216 }
217 })
218 },
219 fullAddLedEffect() {
220 for(var i = 0; i <= 9; i++){
221 this.changeGpio(i)
222 this.addLedEffect()
223 this.status.splice(i,1,1) //更新状态;若删除则只有i = 9更新
224 }
225 },
226 fullRemoveLedEffect() {
227 for(var i = 0; i <= 9; i++){
228 this.changeGpio(i)
229 this.removeLedEffect()
230 this.status.splice(i,1,0) //更新状态;若删除则只有i = 9更新
231 }
232 },
233```
234<a id="openClose">开关灯(点个与全部)</a>
235
236[返回演示目录](#demo)
237### 5.中断
238```
239//中断
240 shutdown(){
241 this.type = "无"
242 clearInterval(this.timerID1)
243 clearInterval(this.timerID2)
244 prompt.showToast({
245 message: "关闭程序"
246 })
247 },
248```
249### 6.特殊效果
250#### 函数接口流程图
251sparkle()闪烁函数执行及shutdown()中断过程
252.png)
253#### 代码实现
254```
255//效果
256 //效果
257 sparkle(){
258 //清除setTimeout
259 clearInterval(this.timerID1)
260 clearInterval(this.timerID2)
261 /*!this.isinf表示选择的是次数有限
262 当1.次数小于0;2.次数有限;不执行函数*/
263 if(this.time <= 0 && !this.isinf){
264 this.type = "无"
265 prompt.showToast({
266 message: "次数为0"
267 })
268 return
269 }
270 //若不是无穷次数,次数减少1
271 if(!this.isinf){
272 this.time--
273 }
274 //type更新
275 this.type = "闪烁"
276 //执行开灯
277 this.addLedEffect()
278 //delay时间后执行关灯
279 this.timerID1 = setTimeout(() => {
280 this.removeLedEffect()
281 },this.delay)
282 //2 * delay时间后执行递归
283 this.timerID2 = setTimeout(() => {
284 this.sparkle()
285 },this.delay * 2)
286 },
287```
288<a id="sparkle">闪烁特效和中断</a>
289
290[返回演示目录](#demo)
291```
292 flow() {
293 //清除setTimeout
294 clearInterval(this.timerID1)
295 clearInterval(this.timerID2)
296 /*!this.isinf表示选择的是次数有限
297 当1.次数小于0;2.次数有限;不执行函数*/
298 if(this.time <= 0 && !this.isinf){
299 this.type = "无"
300 prompt.showToast({
301 message: "次数为0"
302 })
303 return
304 }
305 //若不是无穷次数,次数减少1
306 if(!this.isinf){
307 this.time--
308 }
309 //type更新
310 if(this.type != "射点") this.temp = 9
311 if(this.type == "射点" && this.temp == -1) this.temp = 9 //更新temp取代while循环,用if判断变量和递归
312 this.type = "射点"
313 if(this.temp >= 0){
314 this.changeGpio(this.temp)
315 this.addLedEffect()
316 this.timerID1 = setTimeout(() => {
317 this.removeLedEffect()
318 },this.delay)
319 this.timerID2 = setTimeout(() => {
320 this.flow()
321 },this.delay * 2)
322 this.temp--
323 }
324
325
326 },
327```
328
329<a id="flow1">射点效果</a>
330
331[返回演示目录](#demo)
332
333```
334 flow2() {
335 //清除setTimeout
336 clearInterval(this.timerID1)
337 clearInterval(this.timerID2)
338 /*!this.isinf表示选择的是次数有限
339 当1.次数小于0;2.次数有限;不执行函数*/
340 if(this.time <= 0 && !this.isinf){
341 this.type = "无"
342 prompt.showToast({
343 message: "次数为0"
344 })
345 return
346 }
347 //若不是无穷次数,次数减少1
348 if(!this.isinf){
349 this.time--
350 }
351 //type更新
352 if(this.type != "波浪") this.temp = 9
353 if(this.type == "波浪" && this.temp == -11) this.temp = 9 //更新temp取代while循环,用if判断变量和递归
354 this.type = "波浪"
355 if(this.temp >= 0){
356 this.changeGpio(this.temp)
357 this.addLedEffect()
358 this.timerID1 = setTimeout(() => {
359 this.flow2()
360 },this.delay)
361 this.temp--
362 }
363 else{
364 this.changeGpio(this.temp + 10)
365 this.removeLedEffect()
366 this.timerID1 = setTimeout(() => {
367 this.flow2()
368 },this.delay)
369 this.temp--
370 }
371
372
373 },
374```
375<a id="flow2">波动效果</a>
376
377[返回演示目录](#demo)
378```
379 random() {
380 //清除setTimeout
381 clearInterval(this.timerID1)
382 clearInterval(this.timerID2)
383 /*!this.isinf表示选择的是次数有限
384 当1.次数小于0;2.次数有限;不执行函数*/
385 if(this.time <= 0 && !this.isinf){
386 this.type = "无"
387 prompt.showToast({
388 message: "次数为0"
389 })
390 return
391 }
392 //若不是无穷次数,次数减少1
393 if(!this.isinf){
394 this.time--
395 }
396 this.type = "随机"
397 var i = Math.floor(Math.random()*10)
398 this.changeGpio(i)
399 this.addLedEffect()
400 this.timerID1 = setTimeout(() => {
401 this.removeLedEffect()
402 },this.delay)
403 this.timerID2 = setTimeout(() => {
404 this.random()
405 },this.delay * 2)
406
407 },
408```
409<a id="random">随机效果</a>
410
411[返回演示目录](#demo)