16.WIFI&BT

16.1 WIFI&BT模块介绍

以SC-3568HA为例,该板卡带有WIFI&蓝牙模块,使用的是AP6275S模组(SDIO接口)

WIFIBT_0

AP6275S 是一款高集成度的无线通信芯片,主要用于 Wi-Fi 和蓝牙的连接。它支持双频 Wi-Fi(2.4GHz 和 5GHz),并具备蓝牙 5.0 功能,适用于物联网(IoT)、智能家居和其他无线应用。

16.2 WIFI连接测试

进入系统设置——>WLAN——>打开WIFI

WIFIBT_1

输入密码连接

WIFIBT_2

连接成功

WIFIBT_3

通过命令可以查询WIFI的IP地址等信息

1~# ifconfig wlan0
2wlan0     Link encap:Ethernet  HWaddr 50:41:1c:0f:1d:e6  Driver bcmsdh_sdmmc
3        inet addr:192.168.137.192  Bcast:192.168.137.255  Mask:255.255.255.0
4        inet6 addr: fe80::5241:1cff:fe0f:1de6/64 Scope: Link
5        UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
6        RX packets:106 errors:0 dropped:0 overruns:0 frame:0
7        TX packets:121 errors:0 dropped:0 overruns:0 carrier:0
8        collisions:0 txqueuelen:1000
9        RX bytes:27235 TX bytes:12641

16.3 蓝牙连接测试

进入系统设置——>蓝牙——>打开蓝牙

WIFIBT_4

选择配对的设备

WIFIBT_5

配对成功

WIFIBT_6

16.4 蓝牙API使用与实践

1.标准API使用方法

备注

本模块提供了对蓝牙操作和管理的方,首批接口从API version 10开始支持。后续版本的新增接口,采用上角标单独标记接口的起始版本。

  • 蓝牙标准接口

    @ohos.bluetooth.ble (蓝牙ble模块)

  • API使用说明

    使用蓝牙相关API开发时候,需要先了解熟悉第一个open Harmony工程的创建,相关文档 Hello World应用以及部署

    在使用一个API时,需要注意以下几点:
    • API权限说明

    • API的参数与返回值

    • API调用错误的时候,参考API错误码和通用错误码

    • API示例的正确使用

如下图所示,即为标准API文档

btIndex

2.社区Demo

  • 简介

    为了帮助开发者更快速的使用板子开发和学习,我们在gitee上提供了一个蓝牙相关的使用示例,每一个项目都是独立的DevEco Studio工程,开发者可以将工程导入到DevEco Studio中即可,通过浏览代码、编译工程、安装和运行应用示例来了解应用示例中涉及API的使用方法。

    gitee蓝牙示例

小技巧

在导入社区Demo工程的时候,需要开发者需要注意本地的开发环境是否与项目的一致,即本地SDK是否与项目SDK一致。

  • 导入模块

    在使用蓝牙标准API的时候,最重要的一步是导入蓝牙的模块,才能使用蓝牙相应的API接口。通常模块导入是在文件头导入 导入模块如下:

    import blueToothManager from '@ohos.bluetooth.ble'

  • API 介绍

    社区Demo的实现引用以下API,实现如何打开蓝牙、蓝牙扫描,以及蓝牙的连接的基本实现。

备注

以下介绍均以为简单介绍API的系统能力以及对应函数 请结合 gitee蓝牙示例蓝牙官方标准API开发文档 去熟悉开发

  • ble.createGattServer(创建GattServer实例)

    • createGattServer(): GattServer

  • ble.createGattClientDevice(创建一个可使用的GattClientDevice实例)

    • createGattClientDevice(deviceId: string): GattClientDevice

  • ble.getConnectedBLEDevices(获取和当前设备连接的BLE设备)

    • getConnectedBLEDevices(): Array<string>

    • 需要权限:ohos.permission.ACCESS_BLUETOOTH

  • ble.startBLEScan(发起BLE扫描流程)

    • startBLEScan(filters: Array<ScanFilter>, options?: ScanOptions): void

    • 需要权限:ohos.permission.ACCESS_BLUETOOTH

  • ble.stopBLEScan(停止BLE扫描流程)

    • stopBLEScan(): void

    • 需要权限:ohos.permission.ACCESS_BLUETOOTH

  • ble.startAdvertising(开始发送BLE广播)

    • startAdvertising(setting: AdvertiseSetting, advData: AdvertiseData, advResponse?: AdvertiseData): void

    • 需要权限:ohos.permission.ACCESS_BLUETOOTH

  • ble.stopAdvertising(开始发送BLE广播)
    • stopAdvertising(): void

    • 需要权限:ohos.permission.ACCESS_BLUETOOTH

  • Demo主要实现源码

  • BT.ets
      1        import ble from "@ohos.bluetooth.ble"
      2        import { BusinessError } from '@ohos.base'
      3        // import access from '@ohos.bluetooth.access';
      4
      5        const minRssi = -100
      6        @Entry
      7        @Component
      8        struct Index {
      9        @State message: string = 'Hello BLE'
     10        @State availableDevices: Array<ble.ScanResult> = [];
     11
     12        addData(data:ble.ScanResult):void {
     13           let bFind = false
     14           this.availableDevices.forEach(element => {
     15              if (!bFind && element.deviceId == data.deviceId) {
     16              console.info('BLE scan update ' + data.deviceId + ' rssi:' + element.rssi +' ==> '+ data.rssi)
     17              element.rssi = data.rssi
     18              bFind = true
     19              }
     20           })
     21           if (!bFind) {
     22              console.info('BLE scan add ' + data.deviceId + ' count:' + this.availableDevices.length)
     23              this.availableDevices.push(data)
     24              this.message='BLE count:' + this.availableDevices.length
     25           }
     26        }
     27
     28        dataToString(data:ArrayBuffer) :String {
     29           let str = ''
     30           let v = new Uint8Array(data);
     31           v.forEach(element => {
     32              let s = ''
     33              s =  element.toString(16)
     34              if (s.length == 1) {
     35              s = '0'+s
     36              }
     37              str+=s+' '
     38           });
     39           return str
     40        }
     41
     42        openBle():void {
     43           try {
     44              ble.on("BLEDeviceFind", (data:Array<ble.ScanResult>) => {
     45              // console.info('BLE scan device find result = '+ JSON.stringify(data));
     46              let i = 0
     47              data.forEach(element => {
     48                 console.info('BLE scan device[' + i + '] deviceId = '+ element["deviceId"] +
     49                    ' name = ' + element["deviceName"]  +
     50                    ' rssi = ' + element["rssi"] +
     51                    ' data['+element["data"].byteLength+'] = ' +
     52                 this.dataToString(element["data"]))
     53                 if (element.rssi > minRssi && element.deviceName != '' ) {
     54                    this.addData(element)
     55                 }
     56                 i++
     57              });
     58              });
     59
     60              ble.startBLEScan(
     61              null,
     62              {
     63                 interval: 500,
     64                 dutyMode: ble.ScanDuty.SCAN_MODE_LOW_POWER,
     65                 matchMode: ble.MatchMode.MATCH_MODE_AGGRESSIVE,
     66              }
     67              );
     68           } catch (err) {
     69              console.error("ble errCode:" + (err as BusinessError).code + ",errMessage:" + (err as BusinessError).message);
     70           }
     71
     72        }
     73
     74        //   onAccessEvent(data: access.BluetoothState):void {
     75        //   console.info('bluetooth state = '+ JSON.stringify(data));
     76        //   if (data == access.BluetoothState.STATE_ON) {
     77        //     this.openBle()
     78        //   }
     79        // }
     80
     81        build() {
     82           Row() {
     83              Column() {
     84
     85              Text(this.message)
     86                 .fontSize(30)
     87                 .fontWeight(FontWeight.Bold)
     88
     89              // 添加按钮,开启ble扫描
     90              Button() {
     91                 Text('ble start')
     92                    .fontSize(30)
     93                    .fontWeight(FontWeight.Bold)
     94              }
     95              .type(ButtonType.Capsule)
     96              .margin({
     97                 top: 20
     98              })
     99              .backgroundColor('#0D9FFB')
    100              .width('30%')
    101              .height('10%')
    102              // 跳转按钮绑定onClick事件,点击时跳转到第二页
    103              .onClick(() => {
    104                 console.info("onClick")
    105                 try {
    106                    this.openBle()
    107                    // }
    108                 } catch (err) {
    109                    console.error('ble errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
    110                 }
    111              })
    112
    113              // 添加按钮,停止ble扫描
    114              Button() {
    115                 Text('ble stop')
    116                    .fontSize(30)
    117                    .fontWeight(FontWeight.Bold)
    118              }
    119              .type(ButtonType.Capsule)
    120              .margin({
    121                 top: 20
    122              })
    123              .backgroundColor('#0D9FFB')
    124              .width('30%')
    125              .height('10%')
    126              .onClick(() => {
    127                 this.availableDevices = []
    128                 this.message = 'Hello BLE'
    129                 // AppStorage.setOrCreate('bluetoothAvailableDevices', this.availableDevices);
    130                 try {
    131                    ble.off('BLEDeviceFind')
    132                    ble.stopBLEScan();
    133                 } catch (err) {
    134                    console.error("ble errCode:" + (err as BusinessError).code + ",errMessage:" + (err as BusinessError).message);
    135                 }
    136              })
    137
    138              List({ space: "4vp", initialIndex: 0 }) {
    139                 ForEach(this.availableDevices, (item: ble.ScanResult, index: number) => {
    140                    ListItemGroup() {
    141                    ListItem() {
    142                       Text('['+index.toString(10) +"]" + item.deviceId)
    143                          .textAlign(TextAlign.Center)
    144                          .fontSize(30)
    145                          .backgroundColor(Color.Yellow)
    146                          .width('100%')
    147                    }
    148                    ListItem() {
    149                       Text('    name:' + item.deviceName)
    150                          .textAlign(TextAlign.Start)
    151                          .fontSize(30)
    152                          .backgroundColor(Color.Orange)
    153                          .width('100%')
    154                    }
    155
    156                    ListItem() {
    157                       Text('    rssi:' + item.rssi.toString(10))
    158                          .textAlign(TextAlign.Start)
    159                          .fontSize(30)
    160                          .backgroundColor(Color.Orange)
    161                          .width('100%')
    162                    }
    163
    164                    ListItem() {
    165                       Text('    connectable:' + item.connectable)
    166                          .textAlign(TextAlign.Start)
    167                          .fontSize(30)
    168                          .backgroundColor(Color.Orange)
    169                          .width('100%')
    170                    }
    171
    172                    ListItem() {
    173                       Text('    data:' + this.dataToString(item.data))
    174                          .textAlign(TextAlign.Start)
    175                          .fontSize(30)
    176                          .backgroundColor(Color.Orange)
    177                          .width('100%')
    178                    }
    179
    180
    181                    }
    182
    183
    184                 })
    185              }
    186              .layoutWeight(10)
    187              .backgroundColor(0xDCDCDC)
    188              .height('50%')
    189              .width('60%')
    190              .margin({
    191                 top: 20
    192              })
    193              }
    194              .width('100%')
    195           }
    196           .height('100%')
    197           }
    198        }
    

3.代码编译

小技巧

代码编译详细流程可见,Hello World应用以及部署 中的第二部分(构建第一个页面部分内容)

4.代码运行效果

用以上标准API接口实现蓝牙 Demo,如下图所示:

BT

16.5 WIFI API使用与实践

1.HDC相关指令

hdc指令可以用于查询WiFi的信息以及连接状态
hdc shell ifconfig

2.标准API使用方法

备注

本模块提供企业设备WiFi管理能力,包括查询WiFi开启状态等。首批接口从API version 10开始支持,接口仅可在Stage模型下使用。

  • WLAN标准接口

    @ohos.wifiManager (WLAN)

  • API使用说明

    使用WIFI相关API开发时候,需要先了解熟悉第一个open Harmony工程的创建,相关文档 Hello World应用以及部署

    在使用一个API时,需要注意以下几点:
    • API权限说明

    • API的参数与返回值

    • API调用错误的时候,参考API错误码和通用错误码

    • API示例的正确使用

如下图所示,即为标准API文档

wifiDemo

3.社区Demo

  • 简介

    为了帮助开发者更快速的使用板子开发和学习,我们在gitee上提供了一个WiFi相关的使用示例,每一个项目都是独立的DevEco Studio工程,开发者可以将工程导入到DevEco Studio中即可,通过浏览代码、编译工程、安装和运行应用示例来了解应用示例中涉及API的使用方法。

    giteeWIFI示例

小技巧

在导入社区Demo工程的时候,需要开发者需要注意本地的开发环境是否与项目的一致,即本地SDK是否与项目SDK一致。

  • 导入模块

    在使用WIFI标准API的时候,最重要的一步是导入WIFI的模块,才能使用WIFI相应的API接口。通常模块导入是在文件头导入 导入模块如下:

    import wifiManager from '@ohos.wifiManager'

  • API 介绍

    社区Demo的实现引用以下API,实现如何打开WIFI、WIFI扫描,以及WIFI的连接的基本实现。

备注

以下介绍均以为简单介绍API的系统能力以及对应函数 请结合 giteeWIFI示例WIFI官方标准API开发文档 去熟悉开发

  • wifiManager.enableWifi(使能WLAN)

    • isWifiActive(): boolean

    • 需要权限: ohos.permission.SET_WIFI_INFO 和 ohos.permission.MANAGE_WIFI_CONNECTION 仅系统应用可用。

  • wifiManager.disableWifi(去使能WLAN)

    • isWifiActive(): boolean

    • 需要权限: ohos.permission.SET_WIFI_INFO 和 ohos.permission.MANAGE_WIFI_CONNECTION 仅系统应用可用。

  • wifiManager.startScan(启动WLAN扫描)

    • startScan(): void

  • wifiManager.getScanInfoList(获取扫描结果)

    • getScanInfoList(): Array<WifiScanInfo>

    • 需要权限: ohos.permission.GET_WIFI_INFO

  • wifiManager.isWifiActive(查询WLAN是否已使能)

    • isWifiActive(): boolean

    • 需要权限: ohos.permission.GET_WIFI_INFO

  • wifiManager.connectToDevice(连接指定网络)

    • connectToDevice(config: WifiDeviceConfig): void

    • 需要权限: ohos.permission.SET_WIFI_INFO 和 ohos.permission.SET_WIFI_CONFIG 和 ohos.permission.MANAGE_WIFI_CONNECTION,仅系统应用可用。

  • Demo主要实现源码

  • wifi.ets
      1    import wifiManager from '@ohos.wifiManager';
      2    import { MyDivider } from './MyDivider';
      3
      4    @Entry
      5    @Component
      6    struct Index {
      7    @State message: string = 'WiFi示例'
      8    private TAG: string = 'ShiMetaWifi'
      9    @State wifiStatus: string = 'null'
     10    @State wifiInfoList: string = ''
     11    @State passWord: string = ''
     12    @State account: string = ''
     13
     14    build() {
     15        Row() {
     16        Column() {
     17            Text(this.message)
     18            .fontSize(50)
     19            .fontWeight(FontWeight.Bold)
     20
     21
     22            Row() {
     23            Text('WIFI开关')
     24                .fontSize(50)
     25                .fontWeight(FontWeight.Bold)
     26            Toggle({ type: ToggleType.Switch, isOn: false })
     27                .width(50)
     28                .height(50)
     29                .selectedColor('#007DFF')
     30                .switchPointColor('#FFFFFF')
     31                .onChange((isOn: boolean) => {
     32                if (isOn) {
     33                    try {
     34                    wifiManager.enableWifi();
     35                    } catch (error) {
     36                    console.error("failed:" + JSON.stringify(error));
     37                    }
     38                } else {
     39                    try {
     40                    wifiManager.disableWifi();
     41                    } catch (error) {
     42                    console.error("failed:" + JSON.stringify(error));
     43                    }
     44                }
     45                })
     46            }
     47            .width('100%')
     48            .justifyContent(FlexAlign.SpaceAround)
     49            .padding(10)
     50            MyDivider();
     51
     52
     53            Row() {
     54            Button('点击查询WIFI是否打开')
     55                .onClick(() => {
     56                let isWifiActive = wifiManager.isWifiActive();
     57                if (isWifiActive) {
     58                    this.wifiStatus = 'On'
     59                } else {
     60                    this.wifiStatus = 'Off'
     61                }
     62                console.log(this.TAG, 'isWifiActive' + isWifiActive);
     63                })
     64            Text(this.wifiStatus)
     65                .fontSize(50)
     66                .fontWeight(FontWeight.Bold)
     67            }
     68            .width('100%')
     69            .justifyContent(FlexAlign.SpaceAround)
     70            .padding(10)
     71            MyDivider();
     72
     73            Row() {
     74            Button('点击开始扫描')
     75                .onClick(() => {
     76                wifiManager.startScan()
     77                })
     78            }.padding(10)
     79
     80            Row() {
     81            Button('点击获取扫面结果')
     82                .onClick(() => {
     83                let scanInfoList = wifiManager.getScanInfoList();
     84                this.wifiInfoList = JSON.stringify(scanInfoList)
     85                console.info("scanInfoList:" + JSON.stringify(scanInfoList));
     86                })
     87            }.padding(10)
     88
     89            Row() {
     90            Button('点击清空')
     91                .onClick(() => {
     92                this.wifiInfoList = ''
     93                })
     94            }.padding(10)
     95
     96            Text(this.wifiInfoList)
     97            Column() {
     98            Row() {
     99                TextInput({ placeholder: '输入账号' })
    100                .onChange((value: string) => {
    101                    this.account = value;
    102                    console.log(this.TAG, 'account :' + this.account)
    103                })
    104            }.padding(10)
    105
    106            Row() {
    107                TextInput({ placeholder: '输入密码' })
    108                .onChange((value: string) => {
    109                    this.passWord = value;
    110                    console.log(this.TAG, 'passWord :' + this.passWord)
    111                })
    112            }.padding(10)
    113
    114            Button('连接WiFi')
    115                .onClick(() => {
    116                try {
    117                    let config: wifiManager.WifiDeviceConfig = {
    118                    ssid: this.account,
    119                    preSharedKey: this.passWord,
    120                    securityType: 3
    121                    }
    122                    wifiManager.connectToDevice(config);
    123                } catch (error) {
    124                    console.error("failed:" + JSON.stringify(error));
    125                }
    126                })
    127
    128            }.width(500)
    129        }
    130        .width('100%')
    131        }
    132        .height('100%')
    133      }
    134    }
    

4.代码编译

小技巧

代码编译详细流程可见,Hello World应用以及部署 中的第二部分(构建第一个页面部分内容)

5.代码运行效果

用以上标准API接口实现WIFI Demo,如下图所示:

wifiIndex