• Cordova 使用 cordova-plugin-ble-central 蓝牙插件,实现蓝牙设备持续扫描,打印RSSI等信息 RSSI三点定位 demo


    @

    前言

    算法讲解:RSSI 平面 三点定位算法(C语言、JS源码例程)
    你已经装好了cordova及其环境和插件cordova-plugin-ble-central。
    插件官网:Bluetooth Low Energy (BLE) Central Plugin for Apache Cordova
    官网自带例程,可直接参考。
    安装命令 npm i cordova-plugin-ble-central
    添加插件 cordova plugin add cordova-plugin-ble-central
    以下是我的环境
    在这里插入图片描述
    ps:如果想跑例程,我已经打好debug版apk,release中下载即可

    代码下载

    码云 GitHub

    版本更新

    V1.0 即本文演示内容版本
    V2.0 新增RSSI三点定位
    V2.1 参考点、1m时的rssi值的绝对值,环境衰减因子可配置。功能配置页可切换。
    V2.2 新增平行xy轴筛选、可用参考点全组合求平均解算法
    在这里插入图片描述
    V2.3 合并配置项,针对信标进行单一配置
    V2.4 新增“删除信标”功能,文本可以进行复制

    效果图

    都是安卓为示例

    完整演示动图

    在这里插入图片描述

    主界面

    在这里插入图片描述

    效果页

    在这里插入图片描述

    核心代码

    index.js

    // 设备列表
    var deviceList = [];
    var loopScan;
    
    // 显示设备列表于deviceListDiv
    function showDeviceList() {
        document.getElementById("deviceListDiv").innerHTML = "";
    
        /*
        	参考:http://www.elecfans.com/baike/wuxian/20171120582427.html
            公式 d=10^((ABS(RSSI)-A)/(10*n))
            其中d为距离,单位是m。
            RSSI为rssi信号强度,为负数。
            A为距离探测设备1m时的rssi值的绝对值,最佳范围在45-49之间。
            n为环境衰减因子,需要测试矫正,最佳范围在3.25-4.5之间
        */
        var d = 0;
        var A = 50;
        var n = 2.96;
    
        // 遍历deviceList
        for(var i=0; i<deviceList.length; i++){
            var msgDiv = document.createElement("div");
    
            d = Math.pow(10, (Math.abs(deviceList[i].rssi) - A) / (10 * n));
    
            msgDiv.textContent = JSON.stringify(deviceList[i]) + " RSSI算法预估距离:" + d;
            msgDiv.style.padding = "5px 0";
            msgDiv.style.borderBottom = "rgb(192,192,192) solid 1px";
            document.getElementById("deviceListDiv").appendChild(msgDiv);
        }
        //log(deviceList, "log");
        log("调用showDeviceList()", "log");
    }
    
    // 打印日志
    function log(msg, level) {
        level = level || "log";
    
        if (typeof msg === "object") {
            msg = JSON.stringify(msg, null, "  ");
        }
    
        console.log(msg);
    
        if (level === "status" || level === "error" || level === "success") {
            var msgDiv = document.createElement("div");
            msgDiv.textContent = msg;
    
            if (level === "error") {
                msgDiv.style.color = "red";
            }
            else if(level === "success") {
                msgDiv.style.color = "green";
            }
    
            msgDiv.style.padding = "5px 0";
            msgDiv.style.borderBottom = "rgb(192,192,192) solid 1px";
            document.getElementById("output").appendChild(msgDiv);
        }
        else {
            var msgDiv = document.createElement("div");
            msgDiv.textContent = msg;
            msgDiv.style.color = "#57606a";
            msgDiv.style.padding = "5px 0";
            msgDiv.style.borderBottom = "rgb(192,192,192) solid 1px";
            document.getElementById("output").appendChild(msgDiv);
        }
    }
    
    // 扫描蓝牙设备
    function scanBT() {
        var idSubstring = document.getElementById('idSubstring').value;
        ble.startScan([], function(res) {
            deviceListLen = deviceList.length;
            // 判空
            if(idSubstring.length != 0){
                // 含有子串
                if(res["id"].indexOf(idSubstring) >= 0) {
                    // deviceList为空则直接加入
                    if(0 == deviceListLen) {
                        deviceList.push(res);
                    }
                    else {
                        for(var i=0; i<deviceListLen; i++){
                            if(deviceList[i].id == res["id"]){
                                log("发现同id:" + deviceList[i].id + 
                                    "消息,进行rssi值的替换,原rssi:" +
                                    deviceList[i].rssi +
                                    ",现rssi:" +
                                    res["rssi"], "log");
                                deviceList[i].rssi = res["rssi"];
                                break;
                            }
                            if(i == (deviceListLen - 1)) deviceList.push(res);
                        }
                    }
                    // 重新显示设备列表
                    showDeviceList();
                }
            }
            else {
                if(0 == deviceListLen) {
                    deviceList.push(res);
                }
                else {
                    for(var i=0; i<deviceListLen; i++){
                        if(deviceList[i].id == res["id"]){
                            log("发现同id:" + deviceList[i].id + 
                                "消息,进行rssi值的替换,原rssi:" +
                                deviceList[i].rssi +
                                ",现rssi:" +
                                res["rssi"], "log");
                            deviceList[i].rssi = res["rssi"];
                            break;
                        }
                        if(i == (deviceListLen - 1)) deviceList.push(res);
                    }
                } 
                showDeviceList();
            }
            
            
            //log(JSON.stringify(res), "status");
                    
        }, function(res){
            log("扫描蓝牙设备失败", "error");
        });
    }
    
    document.addEventListener('deviceready', function () {
        // 停止扫描按钮
        var stopScanBtn = document.getElementById('stopScanBtn');
    	stopScanBtn.onclick = function(){
            clearInterval(loopScan);
    		ble.stopScan(function(res){
                log("停止扫描成功", "success");
    		}, function(res){
                log("停止扫描失败", "error");
    		});
    	};
    
        // 开始扫描按钮
        var startScanBtn = document.getElementById('startScanBtn');
    	startScanBtn.onclick = function() {
            loopScan = setInterval(scanBT, 3000);
    	};
    
        // 清空日志按钮
        var clearOutBtn = document.getElementById('clearOutBtn');
    	clearOutBtn.onclick = function(){
    		document.getElementById("output").innerHTML = "";
    	};
    
        // 清空设备列表按钮
        var cleardeviceListBtn = document.getElementById('cleardeviceListBtn');
    	cleardeviceListBtn.onclick = function(){
    		document.getElementById("deviceListDiv").innerHTML = "";
    	};
    });
    
    
    

    index.htnl

    <!DOCTYPE html>
    <!--
        Licensed to the Apache Software Foundation (ASF) under one
        or more contributor license agreements.  See the NOTICE file
        distributed with this work for additional information
        regarding copyright ownership.  The ASF licenses this file
        to you under the Apache License, Version 2.0 (the
        "License"); you may not use this file except in compliance
        with the License.  You may obtain a copy of the License at
        http://www.apache.org/licenses/LICENSE-2.0
        Unless required by applicable law or agreed to in writing,
        software distributed under the License is distributed on an
        "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
         KIND, either express or implied.  See the License for the
        specific language governing permissions and limitations
        under the License.
    -->
    <html>
    
    <head>
        <!--
        Customize this policy to fit your own app's needs. For more guidance, see:
            https://github.com/apache/cordova-plugin-whitelist/blob/master/README.md#content-security-policy
        Some notes:
            * gap: is required only on iOS (when using UIWebView) and is needed for JS->native communication
            * https://ssl.gstatic.com is required only on Android and is needed for TalkBack to function properly
            * Disables use of inline scripts in order to mitigate risk of XSS vulnerabilities. To change this:
                * Enable inline JS: add 'unsafe-inline' to default-src
        -->
        <meta http-equiv="Content-Security-Policy"
            content="default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *">
        <meta name="format-detection" content="telephone=no">
        <meta name="msapplication-tap-highlight" content="no">
        <meta name="viewport"
            content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width">
        <link rel="stylesheet" type="text/css" href="css/index.css">
        <title>Ble Scan</title>
    </head>
    
    <body>
        <div style="margin:10px;">
            <input type="text" id="idSubstring" placeholder="筛选id子串,例:A">
            <button class="commonBtn" id="startScanBtn" >开始扫描</button>
            <button class="commonBtn" id="stopScanBtn" >停止扫描</button>
            <button class="commonBtn" id="cleardeviceListBtn" >清空设备列表</button>
            <button class="commonBtn" id="clearOutBtn" >清空日志</button>
        </div>
        <div id="deviceListDiv" ></div>
        <div id="output" ></div>
        <script type="text/javascript" src="cordova.js"></script>
        <script type="text/javascript" src="js/index.js"></script>
    </body>
    
    </html>
    
  • 相关阅读:
    RobotFramework+Selenium2+Appium环境搭建
    spring mvc 依赖包
    linux
    清理linux 某个文件夹下面所有的log文件
    selenium grid2 使用远程机器的浏览器
    IntelliJ Idea 快捷键
    aop注解 自定义切面的注解写法
    springmvc多视图配置
    @Autowired(required = false)
    pom.xml配置详解
  • 原文地址:https://www.cnblogs.com/ikaros-521/p/15346446.html
Copyright © 2020-2023  润新知