蓝牙是一种无线技术,可以在短距离内实现蓝牙设备之间的数据传输。Bluetooth ® 社区每年都在无线创新方面取得重大进展。
低功耗蓝牙
低功耗蓝牙有许多名称:BLE、蓝牙 LE 或蓝牙智能。低功耗蓝牙的优势 确实在于其非常低的能耗,具有成本效益和显着的电池寿命。BLE 技术提供了一个简单可靠的接口,深受移动应用开发商、消费电子制造商和工程师的欢迎。它是一种特定于行业的技术,已适用于物联网 (IoT),允许快速传输运动、湿度或温度等低消耗数据。
通常,蓝牙用于将移动设备与其他移动或固定设备配对。这可能是您的汽车、耳塞、智能手表或智能灯。我们已经看到很多可以与蓝牙设备交互的本地应用程序,但是使用网络浏览器连接怎么样?是的,您可以使用网站以安全且保护隐私的方式与附近的蓝牙设备进行通信。
BLE 设备可能有两个角色,中央或外围:
中央: 中央设备通过扫描和连接外围设备来管理整个过程。
外围设备: 外围设备定期提供与中央设备的连接和数据传输。
在本文中,我们将尝试使用网络浏览器连接 BLE 设备。
我们需要的东西:
谷歌浏览器
* BleuIO 是蓝牙低功耗解决方案,可用于以最快和最简单的方式创建新的 BLE 5.0 应用程序。该设备支持 Windows 10、Linux 和 macOS。
在我们开始之前
本文假设您对低功耗蓝牙 (BLE) 的工作原理有一定的了解。
由于 Google Chrome 上的 Chrome Serial 规范尚未最终确定,您必须启用突出显示的标志,然后重新启动 Chrome。
在 chrome 浏览器中打开 chrome://flags/#enable-experimental-web-platform-features 。
在此示例中,我们将使用 javascript + html(以及一些用于样式的 css)来设置 BleuIO,并只需按一个按钮即可快速开始扫描或作为 iBeacon 或 Eddystone 广告。要快速设置,请复制以下脚本并将其保存在本地目录中。您还可以从 GITHUB PAGE获取源代码。
这是最终输出的演示。 查看演示
索引.html
在这里,我们创建一个简单的 html 页面,其中包含标题、按钮和显示输出的字段。我们还添加了一个文本框,如果用户不满足 Chrome 序列号的要求,该文本框将会显示。
/> < script > // 如果请求 HTTP,则重定向到 HTTPS。如果
(window.location.protocol === "http:") {
window.location.href = "https:" + window.location.href.substring(5);
}
</ script >
< link rel="stylesheet" href="style.css" />
< link
rel="stylesheet"
href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap .min.css"
完整性="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z"
crossorigin="anonymous"
/> < script src="script.js" defer></ script >
<
class="codesection">
< div class="container">
< h1 >Web蓝牙示例</ h1 >
< main class="main">
< div id="notSupported" class="hidden">
对不起,< b >此设备不支持Chrome Serial</ b >,请确保
您运行的是 Chrome 78 或更高版本并已启用
< code >#enable-experimental-web-platform-features</ code
> 中的 < code >标志chrome://flags</代码>
</div > < br />
< button id="butConnect" type="button" class="btn btn-success">
连接
</ button >
< br />< br />
< button
id="butIbeacon"
type=" button"
disabled
class="btn btn-warning"
>
制作 iBeacon
</ button >
< button id="butEddystone" type="button"disabled class="btn btn-info">
制作 Eddystone 信标
</ button >
< button id="butScan" type="button" disabled class="btn btn-primary">
扫描BLE设备
</ button > < pre id="log" class="mt-5"></ pre >
</ main >
</ div >
</ div >
< div class="footer text-center mt-3">
Powered by < a href="https://www.bleuio.com/" target="_blank ">BleuIO </a>。 < a
的乘积
href="http://smartsensordevices.com/" target="_blank"
>智能传感器设备</a> </ div > <!-- 结束容器--> < !-- JS、Popper.js、jQuery --> <脚本 src="https://code.jquery.com/jquery-3.5.1.slim.min.js" 完整性="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous" ></ script > < script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js" 完整性="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="匿名"></ script >
< script
src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"
完整性="sha384-B4gt1jrGC7Jh4AgTPSdUtOBvfO8shuf57BaghqFfPlYxofvL8/KUEfYiJOMMV+rV"
crossorigin="anonymous"
></脚本>
</正文>
</ html >
脚本.js
我们在这里处理功能。我们将按钮与点击侦听器连接起来,并编写我们需要的功能。
通过运行:
端口 = 等待 navigator.serial.requestPort();
从串行 api 我们可以得到可用的 com 端口列表。然后我们连接到那个端口并开始监听来自加密狗的输入。
“制作信标”按钮功能是使用静态版本的 iBeacon 和 Eddystone 设置的,但您可以轻松连接输入字段并以与 iBeacon 和 Eddystone 示例。
在“readLoop()”函数中,我们只是打印从加密狗到“日志”元素的所有内容。但是您也可以在指示操作成功与否的命令(如 OK、ADVERTISING 或 ERROR 等)之后侦听响应消息,然后处理它并打印您喜欢的响应消息。
“使用严格”;让端口;
让读者;
让输入完成;
让输出完成;
让输入流;
让输出流;
让 isIbeaconAdv = false;
让 isEddystonesAdv = false;
让 isScanning = false;const log = document.getElementById("log");
const butIbeacon = document.getElementById("butIbeacon");
const butEddystone = document.getElementById("butEddystone");
const butConnect = document.getElementById("butConnect");
const butScan = document.getElementById("butScan");document.addEventListener("DOMContentLoaded", () => {
butIbeacon.addEventListener("click", clickIbeacon);
butEddystone.addEventListener("click", 点击埃迪斯通);
butScan.addEventListener("点击", clickScan);
butConnect.addEventListener("点击", clickConnect);
常量 notSupported = document.getElementById("notSupported");
notSupported.classList.toggle("disabled", "serial" in navigator);
}); /**
* @name connect
* 打开 Chrome 串行连接到串行设备(例如 Smart USB Dongle 2.0)并设置输入和
* 输出流。
*/
async function connect() {
// - 请求一个端口并打开一个连接。
端口 = 等待 navigator.serial.requestPort();
// - 等待端口打开。
等待端口.open({波特率:9600});常量编码器 = 新的 TextEncoderStream();
outputDone = encoder.readable.pipeTo(port.writable);
outputStream = 编码器.可写;让解码器 = 新的 TextDecoderStream();
inputDone = port.readable.pipeTo(decoder.writable);
inputStream = decoder.readable.pipeThrough(
new TransformStream(new LineBreakTransformer())
); 阅读器 = inputStream.getReader();
readLoop().catch((error) => {
toggleUIConnected(false);
port = null;
log.textContent = "Dongle Disconnected!";
});
} /**
* @name disconnect
* 关闭 Chrome 串行连接。
*/
async function disconnect() {
// 关闭输入流(阅读器)。
if (reader) {
等待 reader.cancel();
等待 inputDone.catch(() => {});
读者=空;
输入完成=空;
}
// 关闭输出流。
if (outputStream) {
等待 outputStream.getWriter().close();
等待输出完成;
输出流=空;
输出完成=空;
}
// 关闭端口。
等待端口.close();
端口=空;
log.textContent = "加密狗断开连接!";
} /**
* @name clickConnect
* 点击连接/断开按钮的处理程序。
* 检查端口是否!= null
* 如果为真:检查是否有任何信标正在广告或扫描正在运行,如果是,则停止广告或扫描。然后运行 disconnect() 并将 toggleUIConnected 设置为 false。
* 如果为 false:运行 connect(),然后将 toggleUIConnected 设置为 true。
*/
异步函数 clickConnect() {
log.textContent = "";
if (port) {
if (isEddystonesAdv || isIbeaconAdv) {
writeCmd("AT+ADVSTOP");
butIbeacon.textContent = "制作 iBeacon";
butEddystone.textContent = "制作埃迪斯通信标";
isIbeaconAdv = 假;
isEddystonesAdv = 假;
}
// 如果在扫描加密狗时断开连接将重新启动
if (isScanning) {
writeCmd("\x03");
butScan.textContent = "扫描 BLE 设备";
isScanning = false;
}
等待断开();
返回;
}
等待连接();
切换UIConnected(真);
} /**
* @name clickIbeacon
* iBeacon 按钮的点击处理程序。
* 通过检查布尔值 isIbeaconAdv 来检查 iBeacon 是否已经在运行。
* 如果 isIbeaconAdv = true:停止广告,更改按钮文本并显示 Eddystone 按钮。最后设置 isEddystoneAdv = false。
* 如果 isIbeaconAdv = false:设置广告数据以设置具有 UUID 的 iBeacon 并开始广告。
* 还会更改按钮文本并隐藏 Eddystone 按钮。最后设置 isIbeaconAdv = true。
*/
function clickIbeacon() {
console.log("IBEACON BUTTON PRESSED"); 如果(isIbeaconAdv){
writeCmd("AT+ADVSTOP");
但是埃迪斯通;
butIbeacon.textContent = "制作 iBeacon";
但Eddystone.removeAttribute("禁用");
butScan.removeAttribute("禁用");
isIbeaconAdv = 假;
返回;
}
writeCmd("AT+ADVDATAI=5f2dd896-b886-4549-ae01-e41acd7a354a0203010400");
setTimeout(() => {
writeCmd("AT+ADVSTART=0;200;3000;0;");
}, 500); // 等待半点以确保每个命令将分别通过。 butIbeacon.textContent = "停止信标";
但Eddystone.setAttribute(“禁用”,“真”);
butScan.setAttribute("disabled", "true");
isIbeaconAdv = 真;
} /**
* @name clickEddystone
* Eddystone Beacon 按钮的单击处理程序。
* 通过检查布尔值 isEddystoneAdv 来检查 Eddystone 信标是否已经在运行。
* 如果 isEddystoneAdv = true:停止广告,更改按钮文本并显示 iBeacon 按钮。最后设置 isEddystoneAdv = false。
* 如果 isEddystoneAdv = false:设置广告数据以设置带有指向 google.com 的链接的 Eddystone 信标并开始广告。
* 还会更改按钮文本并隐藏 iBeacon 按钮。最后设置 isEddystoneAdv = true。
*/
function clickEddystone() {
console.log("EDDYSTONE BUTTON PRESSED");
if (isEddystonesAdv) {
writeCmd("AT+ADVSTOP");
butEddystone.textContent = "制作埃迪斯通信标";
butIbeacon.removeAttribute("disabled");
butScan.removeAttribute("禁用");
isEddystonesAdv = 假;
返回;
}
writeCmd("AT+ADVDATA=03:03:aa:fe 0d:16:aa:fe:10:00:03:67:6f:6f:67:6c:65:07");
setTimeout(() => {
writeCmd("AT+ADVSTART=0;200;3000;0;");
}, 500); // 等待半点以确保每个命令将分别通过。 //butIbeacon.classList.toggle("disabled", true);
butIbeacon.setAttribute("disabled", "true");
butScan.setAttribute("disabled", "true"); //butScan.classList.toggle("
isEddystonesAdv = 真;
} /**
* @name clickScan
Prev Chapter:在 Python 中进行迭代时修改可迭代对象
Next Chapter:没有 IDE 的 C++ 调试的分步速成课程