æ°é±éåãæ¥œãã¿ã®ããã«ãåçŽãªããããã¢ãŒã ïŒãããã¥ã¬ãŒã¿ãŒïŒãçµã¿ç«ãŠãã¹ããŒããã©ã³ããBluetoothçµç±ã§å¶åŸ¡ããã蟌ãããšã«ããŸããã ãã€ãã£ãã¢ãã€ã«ã¢ããªã±ãŒã·ã§ã³ã®éçºçµéšã¯ãŸã ãããŸãããã
Apache Cordovaã«ã¯ãã§ã«ç²ŸéããŠã
ãŸãã ã
ããã°ã¬ãã·ãWebã¢ããªã®ãããã§å³ä»ãããã
Web Bluetooth APIã䜿çšããããšã¯è峿·±ãã§ãããã

ç«ã®äžããªãŒãããã¢ãã©ã¯ã·ã§ã³ã®åçäžèŠãããšãããŒã¯ãŒãã«é¢ããååãªèšäºãããããã«èŠãããããããŸããïŒWeb Bluetooth
仿§ ã
äŸä»ãã®Google Developersããã°ã®
詳现ãªèšäº ã Bluetooth Low Energyã®
詳现ãªåæ ãããŸããŸãªBLEããã€ã¹ã®ãªããŒã¹ãšã³ãžãã¢ãªã³ã°ãããã³ã«ã®äŸããããŠç¹æ»
ãããã¹ããŒããã©ã€ãããã£ãããã¹ãã¬ã¹ã¬ãããããã©ãŠã¶ããçŽæ¥ããŒã¿ãåä¿¡ãã-
äœãåé¡ã«ãªãå¯èœæ§ããããŸããïŒã ãããèªåã®ããã€ã¹ãäœãããã©ãŠã¶ãã圌ãšãã£ããããããšãããŸã§ãç§ã¯èããã æ·±ãæãäžããããšã¯ãããå®éã®çµéšãšã³ãŒããå
±æããã ãã§ããå人çã«ã¯3é±éåã«éåžžã«åœ¹ç«ã€ã§ããã:)
ç®æ¬¡
åé¡
ãã®ãããããã€ã¹ãçµã¿ç«ãŠãBluetoothã¢ãžã¥ãŒã«ãè£
åããŠãã©ãŠã¶ãŒããã¢ã¯ã»ã¹ããããšã«ããŸããã 以äžã§ã¯ãäŸãšããŠãBluetoothã¢ãžã¥ãŒã«ã
Arduino Unoã«æ¥ç¶ããæ§åã瀺ããŸãããã¡ãããArduinoããŒã¹ã®ããã€ã¹ããããŸããããã¡ããã
STM ã
Raspberry ã
ESP8266ãªã©ã䜿çšããŠãåºæ¬çãªéãã¯ãããŸããã éèŠãªããšã¯ãã³ã³ãããŒã©ãŒã
UARTãããã³ã«ãä»ããŠBluetoothã¢ãžã¥ãŒã«ãšé£æºããããšã§ãïŒ
GeektimesãŸãã¯
Wikipediaãåç
§ ïŒã
ç§ã®ããã«ãå€ãè¯ã
HC-05 Bluetoothã¢ãžã¥ãŒã«ãæ¢ã«ããã€ã¹ã«åºå®ãããã¡ãŒã ãŠã§ã¢ãããŠã³ããŒãããGoogleã®ãµã³ãã«ã®äžéšãèµ·åãããã©ãŠã¶ãŒãããã€ã¹ãæ€åºããªãçç±ãçè§£ã§ããªãå Žåã倱æãããŸãïŒWeb Bluetoothã¯ãBluetooth 4æšæºãã®ã¿ããµããŒãããŸãã
ãããèšäºãæžãçç±ã§ããç§ã®ããã«ãããã«BLEã¢ãžã¥ãŒã«ïŒããšãã°
HM-10ãªã©ïŒãåããæå¯ãã®ã¹ãã¢ããæºè¶³ã®ããç¶æ
ã§æ»ããšããŸã£ããç°ãªãæ¹æ³ã§åäœããæãéèŠãªããšã«ã¯ãã·ãªã¢ã«ããŒããããã¡ã€ã«ïŒ
ã·ãªã¢ã«ããŒããããã¡ã€ã« ãSPPã
Baumanã©ã€ãã©ãªã®è©³çް ïŒããµããŒãããŸããããã«ããããã€ããååŸã«äžçšæã«è¿œããããããšã«æ
£ããŠããŸãã
Bluetooth Low Energyã®æŠå¿µãç¹ã«
Generic Attribute Profile ïŒGATTïŒã«ã€ããŠã¯æ¢ã«ãåç¥ãããããŸããããããã§éèŠãªããšãç°¡åã«èª¬æããŠã¿ãŸãããã
èªäœã®ã·ãªã¢ã«ãããã³ã«ã§ã¯ãªããããã€ã¹ãã¢ããªã±ãŒã·ã§ã³ã®ã»ãããæäŸããå¿
èŠããããŸãæ¥ç¶ãããããã€ã¹ãèªã¿åãããã³/ãŸãã¯å€æŽã§ãããç¹æ§ããããšãã°ãããããã¢ãŒã ã䜿çšãããšã3ã€ã®åº§æšïŒæ°å€XãYãZïŒã§ç©ºéãç§»åããçªãéãïŒ0ïŒãŸãã¯éããïŒ1ïŒããšãã§ããŸãã ãã®ãããæ¥ç¶ãããããã€ã¹ãå¿
èŠãªå€ãèªèãèªã¿åããæžã蟌ã¿ã§ãã4ã€ã®ç¹æ§ãèªã¿æžãããããã«BLEã¢ãžã¥ãŒã«ãæ§æããå¿
èŠããããŸãã
ããã¯çŽ æŽãããããšã§ãããããã¯æªãããšã§ãããè¿é£åºããŸãã¯Aliexpressã§å
¥æã§ããéåžžã®BLEã¬ãã«ã®ãè¶£å³ãã¢ãžã¥ãŒã«ïŒHM-10ãJDY-08ãAT-09ãCC41-AããŸãã¯ãã®ä»ã®ãµãŒãã¹ãæ©èœãæ§æããæ©èœã¯ãããŸããã
代ããã«ãã·ãªã¢ã«ããŒãããšãã¥ã¬ãŒãããç¹æ§ã1ã€ã ãæäŸããããã«æžã蟌ããã¹ãŠã®ãã®ãã¢ãžã¥ãŒã«ã¯TXãä»ããŠã³ã³ãããŒã©ãŒã«éä¿¡ããã³ã³ãããŒã©ãŒããã¢ãžã¥ãŒã«ã®RXã«éä¿¡ãããã¹ãŠã¯æ¥ç¶ãããããã€ã¹ã«éä¿¡ãããŸãã ã¡ãªã¿ã«ãBLEç¹æ§ã«åºæã®20ãã€ããšããå¶éããããŸãã
ãããã£ãŠãWeb Bluetoothã¯äžè¬çãªå±æ§ã®ãããã¡ã€ã«ã®äœ¿çšã«éå®ãããŠãããšããäºå®ã«ãããããããå®éã«ã¯ãå®¶åºãã§äœ¿çšããããã«ã·ãªã¢ã«ããŒããããã¡ã€ã«ãäœæããå¿
èŠããããŸãã
Bluetooth Low Energyã¢ãžã¥ãŒã«ã®æ§æ
ãŸããBLEã¢ãžã¥ãŒã«ãæ§æããŸããäœãã©ã®ããã«ç¥ã£ãŠããã°ãããã»ã©æéã¯ããããŸããã ããŸããŸã
ãããµã¹ã€ã³ã¹ãã«ã¡ã³ãã®CC2541ãããäžã®
CC41-Aã¢ãžã¥ãŒã«ãæã«ãã
ã®ã§ ããè¿ãã®åºãã§340ã«ãŒãã«ããããŸããã ãããã£ãŠãäŸãšããŠããã®æ§æãæ£ç¢ºã«èª¬æããŸãããæ¬è³ªã¯åæ§ã®ãããã䜿çšããä»ã®ã¢ãžã¥ãŒã«ã«å
±éã§ãã
HM-10ã®äŸã®BLEã¢ãžã¥ãŒã«ã®ãã³é
åãã¯ãªãã¯å¯èœUSB-TTLã³ã³ããŒã¿ãŒããæã¡ã®å Žåã¯ãBLEã¢ãžã¥ãŒã«ãæ¥ç¶ããã ãã§ãCOMããŒããä»ããŠã³ã³ãã¥ãŒã¿ãŒããã¢ãžã¥ãŒã«ã«çŽæ¥ã¢ã¯ã»ã¹ã§ããŸãã
ã¢ãžã¥ãŒã«ã®èª¬æã«æ³šæããŠãã ããã3.3Vããžãã¯ã§åäœããå¯èœæ§ããããããTX-RXããã³RX-TXã©ã€ã³ã§ã¯ã EasyElectronicsã®å³ãšè²ã«é»å§ã¬ãã«ã·ãã¿ãŒã䜿çšããå¿
èŠããããŸãã CC41-Aã¢ãžã¥ãŒã«ã¯ããLEVELïŒ3.3Vããšè¡šç€ºãããŠããŸããã5Vããžãã¯ã«å®å
šã«å¯Ÿå¿ããŠããŸãã
BLEã¢ãžã¥ãŒã«ãUSB-TTLã³ã³ããŒã¿ãŒã«æ¥ç¶ãã¯ãªãã¯å¯èœã³ã³ããŒã¿ãŒã®ä»£ããã«ãæãåçŽãªã·ãªã¢ã«ããªããžã䜿çšããŠã³ã³ãããŒã©ãŒã䜿çšã§ããŸããã³ã³ãããŒã©ãŒã¯ãããã·ãªã¢ã«ããŒãã«éä¿¡ãããã®ããã¹ãŠå¥ã®ã·ãªã¢ã«ããŒãã«éä¿¡ããŸãã Arduino Unoã®å Žåã
SoftwareSerialã©ã€ãã©ãªã䜿çšããå¿
èŠããããŸãã
Arduino Unoã®ã¹ã±ããäŸ#include <SoftwareSerial.h> SoftwareSerial SerialBt(2, 3); void setup() { Serial.begin(9600); SerialBt.begin(9600); } void loop() { if (SerialBt.available()) { Serial.write(SerialBt.read()); } if (Serial.available()) { SerialBt.write(Serial.read()); } }
BLEã¢ãžã¥ãŒã«ãArduino Unoã«æ¥ç¶ãã¯ãªãã¯å¯èœã¿ãŒããã«ããã°ã©ã ãå®è¡ãïŒArduino IDEããã·ãªã¢ã«ã¢ãã¿ãŒã䜿çšã§ããŸããç§ã¯
Brayã®ã¿ãŒããã«ã䜿çšããŸãïŒãæšæºèšå®ã®BLEã¢ãžã¥ãŒã«ããã³ã°ããCOMããŒãã«æ¥ç¶ããŸãã
- ããŒã¬ãŒãïŒ 9600
- ããŒã¿ãããïŒ 8
- ããªãã£ïŒ ãªã
- ã¹ããããããïŒ 1
- ãã³ãã·ã§ã€ã¯ïŒ ãªã
ã¹ã¿ã³ãã€ã¢ãŒãã§ã¯ãã¢ãžã¥ãŒã«ã¯ãã£ãªããžãªã¿ãŒã³ãšã©ã€ã³ãã£ãŒãã§çµãã
ATã³ãã³ãã«å¿çã
ãŸã ïŒã·ãªã¢ã«ã¢ãã¿ãŒã®
CR+LF
ããNLãšCRã®äž¡æ¹ããªãã·ã§ã³ïŒã äžéšã®BLEã¢ãžã¥ãŒã«ã¯ããã©ã«ãã§ç°ãªãé床ã§å®è¡ãããŸãïŒããšãã°ã38400ïŒãäžéšã®ã¢ãžã¥ãŒã«ã¯ããŒãäžã®ãã¿ã³ãã¯ãªãã¯ããåŸã«æ§æã¢ãŒãã«å
¥ããŸããäžéšã®ã¢ãžã¥ãŒã«ã§ã¯ã³ãã³ãã倧æåã§ããå¿
èŠã¯ãããŸãããå
·äœçã«ã¯ã¢ãžã¥ãŒã«ã®ä»æ§ã確èªããŠãã ããã
BLEã¢ãžã¥ãŒã«ã®æ§æäžã®ç«¯æ«ããã°ã©ã ã®ãŠã£ã³ããŠã
ã¯ãªãã¯å¯èœATã³ãã³ããéä¿¡ããŠæ¥ç¶ã確èªããŸãããã ã¢ãžã¥ãŒã«ã¯ãOKããšçããã¯ãã§ã-ããã§ãã¹ãŠãæŽããŸãã å®éãã¢ãžã¥ãŒã«ãã¹ã¬ãŒãã¢ãŒãã§åäœãããã¹ã¿ãŒããã€ã¹ãæ¥ç¶ãããã®ãåŸ
æ©ãããµãŒãã¹UUIDã
0xFFE0
ã§ãç¹æ§UUIDã
0xFFE1
èšå®ãããŠããããšã確èªããã ãã§ååã§ããããã¯å°æ¥å¿
èŠã«ãªããŸãã ç§ã®ã¢ãžã¥ãŒã«ã§åäœããããã€ãã®ã³ãã³ãïŒ
AT
ãã«ã¹ãã§ãã¯ãAT+HELP
ãã¹ãŠã®ã³ãã³ãã®åºåãAT+DEFAULT
å·¥å Žåºè·æèšå®ã«ãªã»ããããŸããAT+RESET
-ãœãããªããŒããAT+ROLE
åºåã¢ãŒããAT+ROLE0
ã¹ã¬ãŒãã¢ãŒãã®èšå®ãAT+NAME
ã¢ãžã¥ãŒã«åã®åºåãAT+NAMESimon
ã¢ãžã¥ãŒã«åãSimon
èšå®ããŸããAT+PIN
ãã¢ãªã³ã°çšã®PINã³ãŒãïŒãã¹ã¯ãŒãïŒãåºåããŸããAT+PIN123456
-PINã³ãŒãã123456
èšå®ãAT+UUID
ãµãŒãã¹ã®UUIDã®åºåãAT+UUID0xFFE0
ãµãŒãã¹ã®UUIDã0xFFE0
ãšããŠ0xFFE0
ãAT+CHAR
-UUIDç¹æ§ãåºåããŸããAT+CHAR0xFFE1
-UUIDç¹æ§ã0xFFE1
ãšããŠèšå®ããŸãã
ããã§ãããšãã°ã
Characteristic Properties SampleããŒãžããããµãŒãã¹ãšããŠã0xFFE0ããæå®ãã
ç¹æ§ãšããŠã0xFFE1ããæå®ããŠãBLEã¢ãžã¥ãŒã«ãžã®æ¥ç¶ã詊ã¿ãããšãã§ã
ãŸã ã ãŸãã¯ã
éç¥ãµã³ãã«ããŒãžã§ç«¯æ«ãããã©ãŠã¶ã«äœããéä¿¡ããããšãã§ããŸãã
端æ«ããéä¿¡ãããç¹æ§ãšããŒã¿ã«é¢ããæ
å ±ã®åä¿¡ã¯ã¯ãªãã¯å¯èœã§ãWebã¢ããªã±ãŒã·ã§ã³ã®äœæ
ãŠã©ãŒã ã¢ããã¯çµäºããŸãããæãè峿·±ããã®ã«é²ã¿ãŸãïŒ
ã³ã³ã»ãã
ããã€ã¹ã®ç®¡çã®æŠå¿µãæ€èšããããšãææ¡ããŸãã ãã©ãŠã¶ãŒã®éåžžã®HTMLããŒãžã§ãããã€ã¹ãšã®å¯Ÿè©±ãå®è£
ããããŸããŸãªã³ã³ãããŒã«ã䜿çšããŠç¹å®ã®UIãäœæããŸãã
ããããã¢ãŒã ãå¶åŸ¡ããããã®UIã¢ããªã±ãŒã·ã§ã³ã®äŸã
ã¯ãªãã¯å¯èœããšãã°ã3ã€ã®åº§æšã§ç§»åããçªãééããããããã¢ãŒã ã®å Žåã3ã€ã®æ°å€ã¹ã©ã€ããŒãŸãã¯2DãµãŒãã§ã¹ã§ãããã¯ãªãã¯ãããšXããã³Yå€ãèšç®ããã1ã€ã®ã¹ã©ã€ããŒãZ軞ãšãã¿ã³ã«æ²¿ã£ãŠç§»åããŸãééçªã ãããã®å Žåã¯ãããã€ã«ããã¿ã³ãäœæã§ããŸãã ãããã©ãžã³ã³æ©ã®å Žåããã¿ã³ããé²ããããæ»ããããå·Šãããå³ããããããã©ã€ãã®ãªã³/ãªããããä¿¡å·ãéãããªã©ãè¡ãããšãã§ããŸãã
ãã³ãããã®äžã§äœãèµ·ãã£ãŠãããã®å
šäœåã¯ã¯ãªãã¯å¯èœã§ãJavaScriptã§ç¹å®ã®UIèŠçŽ ã®ç¶æ
ãæŒããã倿Žããããããšãã«ãã³ãã©ãŒããã³ã°ãããããšã«ãããWeb Bluetooth APIãä»ããŠããã€ã¹ã«éä¿¡ããã¡ãã»ãŒãžãäœæããŸãã BLEã¢ãžã¥ãŒã«ã¯ã¡ãã»ãŒãžãåä¿¡ããUARTãä»ããŠã³ã³ãããŒã©ãŒã«éä¿¡ããã³ã³ãããŒã©ãŒã¯ã¡ãã»ãŒãžãè§£æããå¿
èŠãªã¢ã¯ã·ã§ã³ãå®è¡ããåãUARTã䜿çšããŠã¡ãã»ãŒãžãŸãã¯å¿çã®åœ¢åŒã§BLEã¢ãžã¥ãŒã«ã«è¿ä¿¡ã§ããŸãããã®åŸãã¢ãžã¥ãŒã«ã¯æ¥ç¶ãããããã€ã¹ã«éä¿¡ããJSã䜿çšããŠå¿çãåä¿¡ããŸããã©ãŠã¶
ããšãã°ããã¿ã³ãã¯ãªãã¯ããŠã¯ããŒãéãããšã
onclick
ãã¿ã³ãã³ãã©ãŒãèµ·åããã¡ãã»ãŒãž
GRIPPER=CLOSE
ãéä¿¡ãããŸãã ã³ã³ãããŒã©ãŒã¯ã¡ãã»ãŒãžãåä¿¡ããå¿
èŠãªãã®ãçè§£ããã¯ããŒãéããŠã¡ãã»ãŒãž
GRIPPER=CLOSED
ãéãè¿ããŸãã ãã®ã¡ãã»ãŒãžãåŠçãããšãJSã§çªã®ç¶æ
ãèšæ¶ããããã¿ã³ã®ããã¹ãããéããã«å€æŽãããŸãã
ææŠãã
HTMLããŒãžïŒUIïŒãäœæããJavaScriptã€ãã³ããã³ãã©ãŒãåçŽã«æäœããããšã¯ããã»ã©é£ããåé¡ã§ã¯ãªããWebãã¯ãããžãŒã«é¢ããååãªåºç€ç¥èããããŸãã ãããã£ãŠãç¹å®ã®ããã€ã¹ããæœè±¡åããããã€ã¹
ã«æ¥ç¶ããŠã¡ãã»ãŒãžã亀æããã¿ãŒããã«ã¢ããªã±ãŒã·ã§ã³ãäœæããããšããå§ã
ããŸãããŸããBluetooth Low Energyããã€ã¹ã«
æ¥ç¶ãã
æ¥ç¶ã倱ãããå Žåã«
忥ç¶ãã20ãã€ãã®
BLEç¹æ§ã®é·ãã®å¶éããã€ãã¹ ããããã»ã¹ã®ãã®ã³ã°ãå®è£
ããŸãã
æåŸã«ãéåžžã®HTMLããŒãžã
ããã°ã¬ãã·ãWebã¢ããªã±ãŒã·ã§ã³ ïŒ
Google Developersã® Progressive Web Appsãè±èª
çã®Wikipedia ïŒã«å€æããŸããããã¯ãã¹ããŒããã©ã³ã®ãã¹ã¯ãããã«ã€ã³ã¹ããŒã«ããã€ã³ã¿ãŒãããããªããŠã䜿çšã§ããŸãã
HTMLããŒãžãšããã€ã¹ãå®å®ããæ¥ç¶ãã·ã³ãã«ãªAPIã®éã§ã¡ãã»ãŒãžã亀æããæ©äŒããããããŒãºã«åãããŠã¢ããªã±ãŒã·ã§ã³ã調æŽããããšã¯é£ãããããŸããã
æºåãã
ãæ°ã«å
¥ãã®
IDEã«å ããŠãåã«æ§æããäœæ¥çšã®
ãããã€ã¹ããå¿
èŠã§ããããã¯ãã³ã³ãã¥ãŒã¿ãŒã®ã¿ãŒããã«ããã°ã©ã ãä»ããŠãªã¢ã«ã¿ã€ã ã§ã¡ãã»ãŒãžãéåä¿¡ããã¢ããªã±ãŒã·ã§ã³ããã¹ãããã®ã«åœ¹ç«ã¡ãŸãã
Web Bluetooth APIã¯ã
Chrome 56以éããã³
Opera 43 以éã§ããã©ã«ãã§äœ¿çšå¯èœ
ã§ã ã ãŸããGoogle Developersã®
èšäºã§ã¯ãLinuxã§ã¯
chromeãæå¹ã«ããå¿
èŠããããšè¿°ã¹ãŠããŸã
ïŒ// flags /ïŒenable-experimental-web-platform-features flagãšãã©ãŠã¶ãåèµ·å
æåŸã®éèŠãªãã€ã³ãïŒWebã¢ããªã±ãŒã·ã§ã³ã¯ã
HTTPS ïŒ
GitHub Pagesã䜿çšã§ããŸãïŒãŸãã¯
httpïŒ// localhostã§éãå¿
èŠããã
ãŸã -ãããã¯ã»ãã¥ãªãã£èŠä»¶ã§ãã
UI
ã¢ããªã±ãŒã·ã§ã³ã¯ã1ã€ã®HTML
index.html
ããŒãžã1ã€ã®
styles.css
ãããã³1ã€ã®
main.js
ãã¡ã€ã«ã§æ§æããããã¹ãŠã®éæ³ãçºçããŸãã
ããã€ã¹ã«æ¥ç¶ããããã®ãã¿ã³ãåæãã¿ã³ãã¡ãã»ãŒãžçšã®divã³ã³ãããããã³ããã¹ããã£ãŒã«ããšãéä¿¡ããã¿ã³ã§æ§æãããéä¿¡ãã©ãŒã ãäœæããŸãã
index.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link href="styles.css" rel="stylesheet"> </head> <body> <button id="connect" type="button">Connect</button> <button id="disconnect" type="button">Disconnect</button> <div id="terminal"></div> <form id="send-form"> <input id="input" type="text"> <button type="submit">Send</button> </form> <script src="main.js"></script> </body> </html>
divã³ã³ããã§ã¯ãæ¥ç¶ãã°ãçä¿¡ããã³çºä¿¡ã¡ãã»ãŒãžã次ã®åœ¢åŒã§è¡šç€ºããŸãã
<div id="terminal"> <div> ...</div> <div class="out"> </div> <div class="in"> </div> </div>
ã©ã®ã¡ãã»ãŒãžãçºä¿¡ãããã®ããæšæž¬ããªãããã«ãã¹ã¿ã€ã«ã®è²ã§ããããåããŸãã
styles.css #terminal div { color: gray; } #terminal div.out { color: red; } #terminal div.in { color: blue; }
ã芧ã®ãšãããç¹å¥ãªãã®ã¯ãããŸããã ã€ã³ã¿ãŒãã§ã€ã¹ã®æºåãã§ããŸãã:)
ã€ãã³ããã³ãã©ãŒ
main.js
ããã«äœæ¥ãè¡ãã
main.js
UIèŠçŽ ãžã®ãªã³ã¯ãååŸããæ¥ç¶ãã¿ã³ãšåæãã¿ã³ãã¯ãªãã¯ããŠãã©ãŒã ãéä¿¡ããããšã«ããããã³ãã©ãŒãåæããŸãã
ããã€ã¹æ¥ç¶
å®å
šãªæ¥ç¶ã¢ã«ãŽãªãºã ã¯ãããã€ãã®æ®µéã§æ§æãããŠããŸãã
- Bluetoothããã€ã¹ã®èŠæ±ïŒãã©ãŠã¶ã¯ãæãè¿ãããã€ã¹ãæ€çŽ¢ããŠéžæããããã®ãã€ã¢ãã°ãéå§ãããŠãŒã¶ãŒãéžæãè¡ããã¢ããªã±ãŒã·ã§ã³ã³ãŒãããªããžã§ã¯ããåãåããŸãã
- ã¢ããªã±ãŒã·ã§ã³ã³ãŒãããããã€ã¹ã«æ¥ç¶ããŸãã
- äžè¬å±æ§ãããã¡ã€ã«ãµãŒããŒïŒGATTãµãŒããŒïŒãžã®æ¥ç¶ã
- é©åãªãµãŒãã¹ãååŸãã
- ææã®ç¹æ§ãååŸããŸãã
- ç¹æ§ã®å€æŽã«é¢ããéç¥ãå«ãã-ããã€ã¹ããã¡ãã»ãŒãžãåä¿¡ããå¿
èŠããããŸãã
ã³ãŒãã§å®è¡ããŠã¿ãŸãããïŒ
Promiseã®
connect()
颿°ã§ã¯ãæ¥ç¶ã¹ãããã«å¯Ÿå¿ãããã§ãŒã³ïŒPromiseãªããžã§ã¯ããè¿ã颿°ã®ãã§ãŒã³ïŒãå®è£
ããŸããã
ãŸãã倿°
deviceCache
å°å
¥ããŸããããã®å€æ°ã«ã¯ããŠãŒã¶ãŒãéžæããããã€ã¹ã®ãªããžã§ã¯ããåŸã§æžãçããŠãåæããå Žåã«åæ¥ç¶ãã察象ã確èªããŸãã
connect()
颿°ã®æ¬æã®æåã®è¡ã§ãäžé
æŒç®åã¯
deviceCache
ãªããžã§ã¯ãã§å®è¡ãããPromiseããŒãã«çãããªãå Žåã¯çŽã¡ã«äœæããããã§ãªãå Žåã¯Bluetoothããã€ã¹ãéžæããããã®èŠæ±é¢æ°ãåŒã³åºããŸãã ãããã£ãŠããŠãŒã¶ãŒãæ¢ã«ããã€ã¹ã«æ¥ç¶ããŠããå Žåãæ¬¡ã«ãæ¥ç¶ããã¿ã³ãã¯ãªãã¯ãããšãããã€ã¹éžæãã€ã¢ãã°ã¯è¡šç€ºãããŸããã
ããããã®æ®µéã§ãšã©ãŒãçºçããå Žåã
log()
颿°ã䜿çšããŠç«¯æ«ã«åºåããŸããããããåŸã§å®è£
ããŸãã
Bluetoothããã€ã¹ãªã¯ãšã¹ã
Bluetoothããã€ã¹ã®éžæãèŠæ±ããã«ã¯ãé¢å¿ã®ããBluetoothããã€ã¹ãèšè¿°ããå¿
é ã®åŒæ°ãšããŠæ§æãªããžã§ã¯ããæå®ããŠ
navigator.bluetooth.requestDevice()
颿°ãåŒã³åºãå¿
èŠããããŸãã ååããµãŒãã¹ããšã«ãã£ã«ã¿ãŒã䜿çšã§ããŸããããã¹ãŠã®ããã€ã¹ãåãå
¥ããããšãã§ããŸããã䜿çšãããµãŒãã¹ãæå®ããå¿
èŠããããŸããããããªããšããã©ãŠã¶ãŒã¯ã¢ã¯ã»ã¹ãæäŸããŸããã
䜿çšããBLEã¢ãžã¥ãŒã«ãæ§æãããUUID
0xFFE0
ãµãŒãã¹ãæäŸãããã¹ãŠã®ããã€ã¹ããªã¯ãšã¹ãããŸãã ãŠãŒã¶ãŒãããã€ã¹ãéžæãããšãããã€ã¹ãªããžã§ã¯ãã䜿çšããŠPromiseãå®è¡ãããåè¿°ã®ãã£ãã·ã¥ã«æžã蟌ã¿ãããã«æ»ããŸãã
ããã€ã¹ãžã®æ¥ç¶ããµãŒãã¹ãªããžã§ã¯ããšç¹æ§ã®åä¿¡
ç§ãã¡ã¯ãããèªäœãèªãã·ã³ãã«ãªPromiseãã§ãŒã³ãå®è¡ããŸãã
deviceCache
倿°ã¯ã
deviceCache
ãšåæ§ã«ãåä¿¡ããç¹æ§ãªããžã§ã¯ããä¿åããŸããããŒã¿ãæžã蟌ããã€ãŸãããã©ãŠã¶ããããã€ã¹ã«ã¡ãã»ãŒãžãéä¿¡ããå¿
èŠããããŸãã
getPrimaryService()
ããã³
getCharacteristic()
颿°ã¯ãBLEã¢ãžã¥ãŒã«ãæ©èœããããã«æ§æãããŠããåŒæ°ãšããŠUUIDã䜿çšããŸãã
æ©èœå€æŽéç¥ãæå¹ã«ãã
ç¹æ§ãªããžã§ã¯ãã®
startNotifications()
ã¡ãœãããåç
§ããŠãç¹æ§å€æŽã€ãã³ãã§ãã³ãã©ãŒããã³ã°ãããã ãã§ååã§ãããããã«ã€ããŠã¯åŸã§è©³ãã説æããŸãã
ã¿ãŒããã«åºå
端æ«ãžã®åºåæ©èœãå®è£
ããŠãä»ããããã€ã¹ãžã®æ¥ç¶ããã¹ãããŸãã
insertAdjacentHTML()
ã¡ãœããã䜿çšããŠãã¿ãŒããã«ã®divã³ã³ããã®æåŸã«
type
åŒæ°ã§æå®ãããã¯ã©ã¹ãæã€divãæ¿å
¥ããŸããããã¯éåžžã«ç°¡åã§ãã
ãã¹ãäž
ãã©ãŠã¶ã§ããŒãžãéãããæ¥ç¶ããã¿ã³ãã¯ãªãã¯ãããšãããã€ã¹éžæãã€ã¢ãã°ãèµ·åããŸãã ããã€ã¹ã«æ¥ç¶ãããšãæ¥ç¶ããã»ã¹ã«é¢ããã¡ãã»ãŒãžã端æ«ã«è¡šç€ºãããŸãã
ããã€ã¹ã®éžæãšæ¥ç¶ãã¯ãªãã¯å¯èœãã®åŸãã©ãã«ãæžãããŠããªãèœãšã穎ãããã€ãèŠã€ãããŸããã ãµãŒãã¹ã¡ãã»ãŒãžã®åºåã¯ãåé¡ã®èšºæãšè§£æ±ºã«åœ¹ç«ã¡ãŸããã
1ã€ç®ã¯ã
Mi Bandãæ¥ç¶ãããŠããé»è©±æ©ããããã€ã¹ã«æ¥ç¶ããBLEã§åäœããè¿æ¥ããŠããå Žåãæ¥ç¶ã¯éåžžã«ãŸãã§ããããæ¥ç¶ãããå Žåãã»ãšãã©ããã«è±èœããããšã§ãã ããã¯ãã€ãã£ãã¢ããªã±ãŒã·ã§ã³ã§ãèµ·ãããŸããã ç§ã¯Mi Bandãé ãã«é£ããŠè¡ãããšããŸãã-ããã¯å©ãã«ã¯ãªããŸããã§ããã ãã¬ã¹ã¬ãããè§£ãã®ã§ã¯ãªããå¥ã®ã¹ããŒããã©ã³ã䜿çšããŠããŸãã åæ§ã®åé¡ãçºçããå Žåã¯ãã¹ããŒããã©ã³ãšåæã«éä¿¡ããããã€ã¹ã«æ³šæããŠãã ããã
2çªç®ã®ç³ã¯ããããç³ã§ã¯ãªããéåžžã¯æåã®æ¥ç¶äžã«çŸããæ©èœã§ãïŒæçœãªçç±ããªãæ¥ç¶ãçªç¶å€±ãããå¯èœæ§ãããããã©ãŠã¶ããµããŒããæäŸããªããããåæ¥ç¶æ©èœãç¬èªã«å®è£
ããå¿
èŠããããŸãã
èªå忥ç¶
åæã远跡ããããã«ãWeb Bluetoothã¯
gattserverdisconnected
ã€ãã³ããæäŸããŸãã
gattserverdisconnected
ã€ãã³ãã®ãã³ãã©ãŒã¯ããã€ã¹ãªããžã§ã¯ãã§ãã³ã°ããå¿
èŠããããŸãã æãè«ççãªå Žæã¯ãããã€ã¹éžææ©èœã§ãã
ããã§ãããã€ã¹ã«æ¥ç¶ãã黿ºããªãã«ããŠBluetoothæ¥ç¶ã倱ãããå Žåããã©ãŠã¶ãŒã¯1å忥ç¶ã詊ã¿ãŸãã
忥ç¶ã詊è¡ãã¯ãªãã¯å¯èœããã€ã¹ããåæãã
åæããåã«ãå²ãåœãŠããããã³ãã©ãŒã
gattserverdisconnected
ã€ãã³ãããåé€ããããšãå¿ããªãããšãéèŠã§ããããããªããšããã©ãŠã¶ãŒã¯åã«åæ¥ç¶ããŸãã
deviceCache
ãªã»ããããããšã¯ã§ããŸãããæ¬¡ã«ãæ¥ç¶ããã¿ã³ãã¯ãªãã¯ãããšãããã€ã¹éžæãã€ã¢ãã°ã¯è¡šç€ºãããã代ããã«åã®ããã€ã¹ã«æ¥ç¶ããŸãã
ç¡å¹åãã¯ãªãã¯å¯èœããŒã¿æ€çŽ¢
ããŒã¿ã¯ãBLEç¹æ§ã®å€ãå€åãããšãã«çºçããéç¥ã¡ã«ããºã ã䜿çšããŠãããã€ã¹ããéåæçã«åä¿¡ãããŸãã é¢é£ããã€ãã³ãã®
characteristicvaluechanged
ç¹æ§ã®ã¿ã賌èªããå¿
èŠããããŸãã ããã¯ãéç¥ãæå¹ã«ããåŸã«è¡ãå¿
èŠããããŸãã ãŸããããã€ã¹ããªãã«ãªã£ãŠãããšãã«ãç¹æ§ããããã»ããµãåé€ããããšãæ£ããã§ãããã
event.target.value
ã¯ãããã€ã¹ããã®ã¡ãã»ãŒãžããã
ArrayBufferãå«ã
DataViewãªããžã§ã¯ãã§ãã
TextDecoder
ïŒ
MDNãè±èªã®ã¿ ïŒã䜿çšããŠããã€ãé
åãããã¹ãã«ãªãŒããŒã©ã€ãããŸãã
端æ«ããããŒã¿ãéä¿¡ãããã©ãŠã¶ã§åä¿¡ãã¯ãªãã¯å¯èœãã¹ãã§ã¯ãããã€ã¹ããã®ã¡ãã»ãŒãžã®åä¿¡ã¯ã
CR
ã
LF
è¡æ«ã®æç¡ã«ããããããå®å®ããŠæ©èœããããšã瀺ãããŠããŸãã é·ãã¡ãã»ãŒãžã¯å®å
šã«å±ããŸããã20ãã€ãã®åæ°ã«åå²ãããŸãã
äžéãããã¡ãŒã®ç޹ä»
20ãã€ããè¶
ããã¡ãã»ãŒãžã®ãµããŒãã¯å¿
èŠãªããããããŸããããå®å
šãæãããã«ããã®å¶éãåé¿ããŸãããã èãæ¹ã¯ç°¡åã§ããã»ãã¬ãŒã¿æåãåä¿¡ããããŸã§ãçä¿¡ãããã¡ãäžéãããã¡ã«æžã蟌ã¿ãŸãã åºåãæåãåãåã£ããã3çªç®ã®é¢æ°ãåŒã³åºããŠããããã¡ãŒããããŒã¿ãæž¡ãããã®åŸã®æžã蟌ã¿ã®ããã«ãããã¡ãŒãã¯ãªã¢ããŸãã
åºåãæåã¯ãæååïŒ
LF
ã
\n
ïŒãäŸçµŠããããã«è«ççã§ãã ãŸããã¡ãã»ãŒãžã®æåãšæåŸãã空çœãåé€ãããšäŸ¿å©ãªå ŽåããããŸãã
ããã€ã¹åºæã®Webã¢ããªã±ãŒã·ã§ã³ãäœæããå Žåã
receive()
颿°ãããŒãºã«åãããŠå€æŽããããã€ã¹ããã®ç¢ºå®ãªã¡ãã»ãŒãžã§äœæ¥ããŠããããšã確èªã§ããŸãã
äžéãããã¡ã®å°å
¥åŸã«ç«¯æ«ããããŒã¿ãéä¿¡ãããã©ãŠã¶ã§åä¿¡ãã¯ãªãã¯å¯èœããŒã¿ãéä¿¡ãã
ããã€ã¹ãžã®ããŒã¿ã®éä¿¡ã¯ãç¹æ§ã«å€ãæžã蟌ãããšã«ãã£ãŠãããå
·äœçã«ã¯ãåŒæ°ãšããŠwriteValue()
ç¹æ§ãªããžã§ã¯ãã®ã¡ãœãããåŒã³åºãããšã«ãã£ãŠå®è¡ããArrayBuffer
ãŸããæååã倿ããArrayBuffer
æãç°¡åãªæ¹æ³ã¯TextEncoder
ïŒè±èªã®ã¿ã®MDNïŒã§ãã
念ã®ãããã°ããŒãã«ãªããžã§ã¯ãã䜿çšããŠããŒã¿ãæåååã«ãã£ã¹ãããŸãString
ããã®ãããªå®è£
ã§ã¯ã20ãã€ãã®å¶éãé©çšãããŸããã¹ã³ãŒããè¶
ãããã®ã¯ãã¹ãŠåãæšãŠãããŸãããããã£ãŠãã¡ãã»ãŒãžã20ãã€ãããé·ãå Žåã¯ãã¡ãã»ãŒãžãæçã«åå²ããå°ãé
ããŠé 次éä¿¡ãã䟡å€ããããŸãã
ã³ã³ãããŒã©ãŒåŽã§ã®ã¡ãã»ãŒãžã®åŠçã容æã«ããããã«ãéä¿¡ãããã¡ãã»ãŒãžã®æåŸã«æ¹è¡æåïŒ\n
ïŒã远å ããŸããæ¬¡ã«ãã¡ãã»ãŒãžã¯ããã£ãªããžãªã¿ãŒã³ïŒCR
ã\r
ïŒããã³ã©ã€ã³ãã£ãŒãïŒLF
ã\n
ïŒãæ£ããåŠçããæ£èŠè¡šçŸã䜿çšããŠæçã«åå²ããããã®åŸãæåã®éšåãããã«éä¿¡ããã100ããªç§ã®åæ°ã®é
å»¶ãæã€ã¿ã€ããŒãä»ãéä¿¡ããããã«èšå®ãããŸã
端æ«ãšãã©ãŠã¶éã®ããŒã¿äº€æãã¯ãªãã¯å¯èœããŸãããïŒ
ããã€ã¹ãšã®å®å
šã«æ©èœããåæ¹åã®ããŒã¿äº€æãååŸããŸããããããã¯ãã¹ãŠJSã§ããããã°ã¬ãã·ãWebã¢ããª
ããã€ã¹ãã©ã®ãããªç¶æ
ã«ãªãããäºåã«ç¥ãããšã¯ã§ããŸããããã®ãããã€ã³ã¿ãŒããããªãã§äœæãããWebã¢ããªã±ãŒã·ã§ã³ãæäœã§ãããšäŸ¿å©ã§ãããããŠãããã§ããã°ã¬ãã·ãWebã¢ããªã®æŠå¿µã圹ç«ã¡ãŸãïŒè±èªã§Google DevelopersãŸãã¯Wikipediaã®è©³çްãåç
§ïŒãç°¡åã«èšãã°ããããã¯ãŠãŒã¶ãŒã«ãšã£ãŠéåžžãŸãã¯ã¢ãã€ã«ã¢ããªã±ãŒã·ã§ã³ã®ããã«èŠããWebãµã€ãã§ããPWAãã¯ãããžãŒã䜿çšãããšãæåã«Webãµã€ãã«ã¢ã¯ã»ã¹ãããšãã«ãã¹ããŒããã©ã³ã®ãã¹ã¯ãããã«ã¢ããªã±ãŒã·ã§ã³ãšããŠã€ã³ã¹ããŒã«ãããªãã©ã€ã³ã§äœæ¥ã§ããŸããã¢ã€ã³ã³
ã¢ã€ã³ã³ã¯ããã¹ã¯ãããã«ã¢ããªã±ãŒã·ã§ã³ãã€ã³ã¹ããŒã«ããããã«å¿
èŠã§ããå人çã«ãç§ã¯realfavicongenerator.netã䜿çšããŸã -é©åãªç»åãã¢ããããŒããããšããžã§ãã¬ãŒã¿ãŒã¯ããŸããŸãªããã€ã¹ã®ã¢ã€ã³ã³ã調æŽããããã«æäŸããŸãããAndroid Chromeã®ãã¡ãã³ã³ãã»ã¯ã·ã§ã³ã§ããã¢ã»ãããã¿ãã«åãæ¿ããŠãææžåããããã¹ãŠã®ã¢ã€ã³ã³ãäœæããéžæããããšããå§ãããŸããããããªããšãChromeã¯ããã€ã¹ã«æãè¿ããµã€ãºã®ãã¹ã¯ãããã¢ã€ã³ã³ãçæããŸããã»ããã¢ãããå®äºãããããçæããã¿ã³ãã¯ãªãã¯ãããFaviconããã±ãŒãžããããŠã³ããŒãããŠãWebããŒãžã®æšªã«è§£åããŸãããŸãããžã§ãã¬ãŒã¿ã«ãã£ãŠææ¡ãããã³ãŒããã«ã³ããŒããŸã<head>
ããããã§ã¹ã
ã¢ã€ã³ã³ãšäžç·ã«ããžã§ãã¬ãŒã¿ãŒã¯ãããã§ã¹ãã®ãã©ããã芪åã«æäŸããŠãããŸãã- manifest.json
ïŒ { "name": "", "icons": [ ... ], "theme_color": "#ffffff", "background_color": "#ffffff", "display": "standalone" }
ããããã£ã§ã¢ããªã±ãŒã·ã§ã³ã®ååãæå®ãã12æå以å
ã®ççž®åãå«ãããããã£name
ã远å ããŸãshort_name
ãé
åã«ã¯icons
ãã§ã«çæããããã¹ãŠã®ã¢ã€ã³ã³ããªã¹ããããŠãããããããã£display
ã«ã¯ã¢ããªã±ãŒã·ã§ã³ã®è¡šç€ºã¢ãŒããå«ãŸããŠããŸããstandalone
ããã¯ããã€ãã£ãã¢ããªã±ãŒã·ã§ã³ãšå¯èœãªéãé¡äŒŒããããã©ãŠã¶UIèŠçŽ ãªãã§Webã¢ããªã±ãŒã·ã§ã³ãèµ·åããããšãæå³ããŸã-ãããå¿
èŠãªããšã§ãããã©ãŠã¶ã¯ããŒã«ããŒãcolorã§è²ä»ããtheme_color
ãã¢ããªã±ãŒã·ã§ã³ãããŒããããšãã«ã¹ãã©ãã·ã¥ç»é¢ã®background_color
èæ¯ãšããŠäœ¿çšãããŸãããããã§ã¹ãã倿Žãããšãã¯ãå¿
ãmetaã¿ã°ã倿ŽããŠãã ããããŸããããããã£ã远å ãã䟡å€ããããšçããã§ãtheme_color
<meta name="theme-color" content="#ffffff">
start_url
scope
./
ãã®ãããæåã«ã¢ããªã±ãŒã·ã§ã³ãèµ·åãããšãã¡ã€ã³ããŒãžã§éããæ¬¡ã«Webã¢ããªã±ãŒã·ã§ã³ã®ããã²ãŒã·ã§ã³é åãçŸåšã®ããŒãžãšãµãããŒãžã«å¶éããŸããããã¯ãã¢ããªã±ãŒã·ã§ã³ãã¡ã€ã«ãWebãµã€ãã®ã«ãŒããã£ã¬ã¯ããªã«ãªãå Žåã«åœ¹ç«ã¡ãŸãããµãŒãã¹ã¯ãŒã«ãŒ
Service Workerã䜿çšãããšãã¢ããªã±ãŒã·ã§ã³ã«å¿
èŠãªãã¡ã€ã«ããã£ãã·ã¥ããã€ã³ã¿ãŒãããããªãå Žåã«ãããã䜿çšã§ããŸããService Worker Toolboxã¯ãsw-toolbox.jsãšcompanion.jsãããŠã³ããŒãããããããæšªã«é
眮ãindex.html
ãŠæåŸã«è¿œå ããã ãã§ãService Workerããã°ããäœæããã®ã«åœ¹ç«ã¡ãŸã<body>
ã <script src="companion.js" data-service-worker="sw.js"></script>
ãã®åŸãsw.js
次ã®ã¹ã¯ãªããã远å ããã ãã§index.html
ãå¿
èŠãªãã¡ã€ã«ããã£ãã·ã¥ã§ããŸãã importScripts('sw-toolbox.js'); toolbox.precache([ 'companion.js', 'index.html', 'main.js', 'styles.css', ]);
ããã§ãããŒãžã ãã§ãªããå®éã®ããã°ã¬ãã·ãWebã¢ããªã±ãŒã·ã§ã³ãã§ããŸããã
ãã¹ã¯ããããžã®ã¢ããªã±ãŒã·ã§ã³ã®è¿œå ãšèµ·åãã¯ãªãã¯å¯èœ
æçµãã¹ããã¯ãªãã¯å¯èœãšãããŒã°
ããã€ã¹ãšãã©ãŠã¶éã®åæ¹åéä¿¡ãã£ãã«ã䜿çšããŠãäºç®ã¢ãžã¥ãŒã«ãšã¯ãã¹ãã©ãããã©ãŒã Webã¢ããªã±ãŒã·ã§ã³ãåããç¬èªã®Bluetooth Low Energyããã€ã¹ã®éçºãéå§ããã®ã¯ãšãŠãç°¡åã§ç°¡åã§ããããã§ãããã€ã¹ã®UIãç¹å®ã®UIã«å€æŽããå¿
èŠãªãã³ãã©ãŒã远å ããããã€ã¹ã«éä¿¡ãããã³ã«ãå®è£
ãã...ã¹ããŒããã©ã³ã®ã¢ããªã±ãŒã·ã§ã³ã®ãã¿ã³ãæŒããªã©ããŠãããã³ã®ãããããªã³ã«ããããšãã§ããŸããæçµçãªã³ãŒãã¯ããã¡ã€ã«index.html
ãstyles.css
ãmain.js
ããã³sw.js
å©çšå¯èœã§ããããããã§ã倿ŽãããWebã¿ãŒããã«ã¢ããªã±ãŒã·ã§ã³ãå®è¡ã§ããŸãïŒloginov-rocks.imtqy.com/Web-Bluetooth-Terminal-ãŸãã¯YouTubeã§ã®åäœã確èªããŸããã«GitHubã§ã¯ãBLEã¢ãžã¥ãŒã«ãšã®ã·ãªã¢ã«éä¿¡çšã®ES6ã¯ã©ã¹ãšãå®éã«ã¯Webã¿ãŒããã«ãªããžããªãåå¥ã«èŠã€ããããšãã§ããŸããUPDïŒæç¥šã远å ããŸããã