我们使用Web Bluetooth API和Arduino控制LED



-水壶,体重秤,玩具,灯泡,咖啡机……这些设备和其他设备中内置了蓝牙模块。
-为什么?
-让用户通过该应用程序管理其设备。 例如,控制房间的照明。
-噢,可以组装自己的一些简单设备并直接通过浏览器进行管理吗?
-是的! 而这篇文章就是这样。


一点理论


在这里,我将提供一些基本术语,这些术语是我们生活中实现任务所需要的(稍后再讨论)。


蓝牙功能


一种无线标准,可在短距离内连接各种类型的设备。 要通过Web蓝牙API控制腺体,我们需要蓝牙v4.0。


加特


通用属性是蓝牙设备功能的不断广播的树。


服务项目


蓝牙设备内部有服务。 服务本身是功能和与其他服​​务的关系的集合。 每个服务都有其自己的UID和名称。 通常,会出现“未知服务”。 这是由于设备及其使用案例的数量很大。


特点


每个服务中都有一些特征,您可以在其中编写,读取它们以及订阅它们。 该功能还具有自己的UID。


挑战赛


作为一项任务,我选择了一个网站实现,它可以:


  • 用不同的颜色点亮LED并关闭它们。
  • 使LED闪烁不同的颜色。

并且,从问题的陈述中您可以理解,您需要学习如何与蓝牙设备连接和断开连接。


组成部分


为了完成任务,我选择了以下必要列表:


  • Arduino的
  • 蓝牙模块v4.0(在我的情况下为HM-10)。
  • 两个三色LED。
  • 面包板。
  • 连接电线。
  • 电阻器

该列表对于执行并不严格。 我确信您可以用其他东西代替Arduino并选择其他蓝牙模块。 但是本文将考虑与这些组件的交互。


它应该如何工作


简而言之,本质是这样的:我们连接到蓝牙模块并传输一定的代码(包括1到4)。 如果代码有效,则三种颜色之一会亮起,或者LED会以所有可能的颜色(红色,绿色,蓝色)闪烁一段时间。


做饭


首先,您需要收集工作图并加载Arduino草图。 下面我给出电路(图1)和我得到的草图代码。



1(组装图)


#include <SoftwareSerial.h> int green_pin = 2; int red_pin = 3; int blue_pin = 4; int BLINK_STEPS = 3; int BLINK_DELAY = 100; SoftwareSerial mySerial(7, 8); // RX, TX void setup() { Serial.begin(9600); mySerial.begin(9600); pinMode(green_pin, OUTPUT); pinMode(red_pin, OUTPUT); pinMode(blue_pin, OUTPUT); } int code; void loop() { if (mySerial.available()) { code = mySerial.read(); shutDownAll(); if (code > 0 && code < 5) { analogWrite(code, 200); } if (code == 1) { blinked(); } } } void shutDownAll() { analogWrite(green_pin, 0); analogWrite(red_pin, 0); analogWrite(blue_pin, 0); } void blinked() { int steps = 0; while(steps <= BLINK_STEPS) { analogWrite(green_pin, 200); delay(BLINK_DELAY); analogWrite(green_pin, 0); delay(BLINK_DELAY); analogWrite(red_pin, 200); delay(BLINK_DELAY); analogWrite(red_pin, 0); delay(BLINK_DELAY); analogWrite(blue_pin, 200); delay(BLINK_DELAY); analogWrite(blue_pin, 0); delay(BLINK_DELAY); steps += 1; } } 

最后做饭


因此,我们下载了草图,将电路连接到电源。 接下来是什么? 要使用Web Bluetooth API,我们需要知道设备的名称以及我们要访问的服务。 您可以为此使用“ nRF Connect”应用程序。


我们打开该应用程序,然后查看附近的蓝牙设备列表(图2)。



2(应用程序找到的设备列表)

名为“ CC41-A”的设备使我感兴趣,但没有白费。


连接到设备后,我们可以使用其服务列表(图3)。 我们不太可能在“设备信息”中找到有趣的内容,因此我们大胆地单击“未知服务”。



3(设备服务列表)

在下面的屏幕截图(图4)中,您可以注意到对我们来说最重要的事情:写特征并阅读它。


解决上述问题后,我尝试将值“ 2”发送到特征。 结果,我的一对LED开始变绿。 几乎成功了。 现在,我们需要做同样的事情,而不是通过移动应用程序,而是通过浏览器。



4(未知特征)

这是我们从应用程序收到的继续执行任务的数据列表:


  1. 设备的名称。
  2. 服务的UID。
  3. UID特征。

网络实施


在开始编写JavaScript代码之前,需要注意以下几点:


  1. 该API是实验性的。
  2. 适用于Chrome和Samsung Internet。
  3. 需要通过HTTPS连接。
  4. 我不会提供HTML和CSS代码的示例,因为在本文的框架内没有有趣的内容,但是在本文结尾处,我将保留指向存储库和网站的链接。

Java脚本


使用Web蓝牙API是基于Promise的。 下面,我将给出分阶段的代码示例。 完整的源代码可以在链接所在的存储库中找到。


首先,我们需要连接到设备。 我们请求设备,并在过滤器中传输将使用的设备名称和服务UID。 如果您未预先指定服务,则将来将无法与其进行交互。


 navigator.bluetooth.requestDevice({ filters: [ { name: MY_BLUETOOTH_NAME }, { services: [SEND_SERVICE] }, ] }) 

单击“连接”按钮后,将打开一个窗口(图5),您需要在其中选择设备并单击“连接”按钮。



5(带有可访问设备的窗口)

连接后,将返回一个包含“设备”的Promise,您可以连接到该设备。 好的,让我们将其写入变量并创建连接。


 .then(device => { myDevice = device; return device.gatt.connect(); }) 

之后,包含“服务器”的Promise将退还给我们。 然后,我们从“服务器”请求“服务”,并向其中传递服务UID(我们通过应用程序对其进行监视)。 然后,我们得到一个包含“服务”的Promise,从中我们请求“特征”,并向其传递UID(我们也通过应用程序进行了窥视)。


 .then(server => server.getPrimaryService(SEND_SERVICE)) .then(service => service.getCharacteristic(SEND_SERVICE_CHARACTERISTIC)) 

只有现在,我们才可以开始做某事。 例如,我将特征存储在变量中并挂断按钮单击处理程序。 在其数据属性中,它们包含一个代码,单击该代码将被写入特性。


按钮单击处理程序包含以下代码:


 const code = Number(event.target.dataset.code); if (code === 1) { toggleLigthCharacteristic.writeValue(Uint8Array.of(code)); return; } toggleLigthCharacteristic.readValue() .then(currentCode => { const convertedCode = currentCode.getUint8(0); toggleLigthCharacteristic.writeValue( Uint8Array.of(convertedCode === code ? 0 : code) ); }); 

必须将uint8数组传递给特征,因此,要转换将传递给它的代码,必须使用Uint8Array。


按照计划,代码1使LED闪烁三种颜色,然后熄灭。 但是,如果已向其发送代码3并且LED仍然亮着,该如何关闭LED? 或打开其他颜色?


我读取了特征中的值,使用getUint8对其进行了转换,如果代码匹配,则发送任何无效值(例如0)。 如果该值有效,则将其转换为数组unit8并将其写入特性。


对于该任务的最终解决方案,您只需要学习如何与设备断开连接。 我们已经在“ Disconnect”按钮上有一个eventListener,其中设备与蓝牙设备断开连接,eventListener被删除,控制按钮被隐藏,并且undefined被写入变量。


 myDevice.gatt.disconnect(); toggleItemsEventListeners('removeEventListener'); toggleButtonsVisible(); toggleLigthCharacteristic = undefined; myDevice = undefined; 

总结


我们创建了一个简单的网页,您可以通过该网页连接并控制蓝牙设备。 如您所见,这非常简单。 您可以通过这种方式组装和管理的设备仅受您的想象力限制!


有用的链接


Source: https://habr.com/ru/post/zh-CN416579/


All Articles