
ç«ã®äžããªãŒãããã¢ãã©ã¯ã·ã§ã³ã®åç
äžèŠãããšãããŒã¯ãŒãã«é¢ããååãªèšäºãããããã«èŠãããããããŸããïŒWeb Bluetooth ä»æ§ ã äŸä»ãã®Google Developersããã°ã®è©³çŽ°ãªèšäº ã Bluetooth Low Energyã®è©³çŽ°ãªåæ ãããŸããŸãªBLEããã€ã¹ã®ãªããŒã¹ãšã³ãžãã¢ãªã³ã°ãããã³ã«ã®äŸããããŠç¹æ» ãããã¹ããŒããã©ã€ãããã£ãããã¹ãã¬ã¹ã¬ãããããã©ãŠã¶ããçŽæ¥ããŒã¿ãåä¿¡ãã- äœãåé¡ã«ãªãå¯èœæ§ããããŸããïŒ
ã ãããèªåã®ããã€ã¹ãäœãããã©ãŠã¶ãã圌ãšãã£ããããããšãããŸã§ãç§ã¯èããã æ·±ãæãäžããããšã¯ãããå®éã®çµéšãšã³ãŒããå ±æããã ãã§ããå人çã«ã¯3é±éåã«éåžžã«åœ¹ç«ã€ã§ããã:)
ç®æ¬¡
ç®æ¬¡ãå±éãã
- ããããŒã°
- åé¡
- Bluetooth Low Energyã¢ãžã¥ãŒã«ã®æ§æ
- Webã¢ããªã±ãŒã·ã§ã³ã®äœæ
- ãšãããŒã°
åé¡
ãã®ãããããã€ã¹ãçµã¿ç«ãŠã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èŠçŽ ãžã®ãªã³ã¯ãååŸããæ¥ç¶ãã¿ã³ãšåæãã¿ã³ãã¯ãªãã¯ããŠãã©ãŒã ãéä¿¡ããããšã«ããããã³ãã©ãŒãåæããŸãã
// UI let connectButton = document.getElementById('connect'); let disconnectButton = document.getElementById('disconnect'); let terminalContainer = document.getElementById('terminal'); let sendForm = document.getElementById('send-form'); let inputField = document.getElementById('input'); // Connect connectButton.addEventListener('click', function() { connect(); }); // Disconnect disconnectButton.addEventListener('click', function() { disconnect(); }); // sendForm.addEventListener('submit', function(event) { event.preventDefault(); // send(inputField.value); // inputField.value = ''; // inputField.focus(); // }); // Bluetooth function connect() { // } // function disconnect() { // } // function send(data) { // }
ããã€ã¹æ¥ç¶
å®å šãªæ¥ç¶ã¢ã«ãŽãªãºã ã¯ãããã€ãã®æ®µéã§æ§æãããŠããŸãã
- Bluetoothããã€ã¹ã®èŠæ±ïŒãã©ãŠã¶ã¯ãæãè¿ãããã€ã¹ãæ€çŽ¢ããŠéžæããããã®ãã€ã¢ãã°ãéå§ãããŠãŒã¶ãŒãéžæãè¡ããã¢ããªã±ãŒã·ã§ã³ã³ãŒãããªããžã§ã¯ããåãåããŸãã
- ã¢ããªã±ãŒã·ã§ã³ã³ãŒãããããã€ã¹ã«æ¥ç¶ããŸãã
- äžè¬å±æ§ãããã¡ã€ã«ãµãŒããŒïŒGATTãµãŒããŒïŒãžã®æ¥ç¶ã
- é©åãªãµãŒãã¹ãååŸãã
- ææã®ç¹æ§ãååŸããŸãã
- ç¹æ§ã®å€æŽã«é¢ããéç¥ãå«ãã-ããã€ã¹ããã¡ãã»ãŒãžãåä¿¡ããå¿ èŠããããŸãã
ã³ãŒãã§å®è¡ããŠã¿ãŸãããïŒ
// let deviceCache = null; // Bluetooth function connect() { return (deviceCache ? Promise.resolve(deviceCache) : requestBluetoothDevice()). then(device => connectDeviceAndCacheCharacteristic(device)). then(characteristic => startNotifications(characteristic)). catch(error => log(error)); } // Bluetooth function requestBluetoothDevice() { // } // , function connectDeviceAndCacheCharacteristic(device) { // } // function startNotifications(characteristic) { // } // function log(data, type = '') { // }
Promiseã®
connect()
é¢æ°ã§ã¯ãæ¥ç¶ã¹ãããã«å¯Ÿå¿ãããã§ãŒã³ïŒPromiseãªããžã§ã¯ããè¿ãé¢æ°ã®ãã§ãŒã³ïŒãå®è£ ããŸããã
ãŸããå€æ°
deviceCache
å°å ¥ããŸããããã®å€æ°ã«ã¯ããŠãŒã¶ãŒãéžæããããã€ã¹ã®ãªããžã§ã¯ããåŸã§æžãçããŠãåæããå Žåã«åæ¥ç¶ãã察象ã確èªããŸãã
connect()
é¢æ°ã®æ¬æã®æåã®è¡ã§ãäžé æŒç®åã¯
deviceCache
ãªããžã§ã¯ãã§å®è¡ãããPromiseããŒãã«çãããªãå Žåã¯çŽã¡ã«äœæããããã§ãªãå Žåã¯Bluetoothããã€ã¹ãéžæããããã®èŠæ±é¢æ°ãåŒã³åºããŸãã ãããã£ãŠããŠãŒã¶ãŒãæ¢ã«ããã€ã¹ã«æ¥ç¶ããŠããå Žåã次ã«ãæ¥ç¶ããã¿ã³ãã¯ãªãã¯ãããšãããã€ã¹éžæãã€ã¢ãã°ã¯è¡šç€ºãããŸããã
ããããã®æ®µéã§ãšã©ãŒãçºçããå Žåã
log()
é¢æ°ã䜿çšããŠç«¯æ«ã«åºåããŸããããããåŸã§å®è£ ããŸãã
Bluetoothããã€ã¹ãªã¯ãšã¹ã
Bluetoothããã€ã¹ã®éžæãèŠæ±ããã«ã¯ãé¢å¿ã®ããBluetoothããã€ã¹ãèšè¿°ããå¿ é ã®åŒæ°ãšããŠæ§æãªããžã§ã¯ããæå®ããŠ
navigator.bluetooth.requestDevice()
é¢æ°ãåŒã³åºãå¿ èŠããããŸãã ååããµãŒãã¹ããšã«ãã£ã«ã¿ãŒã䜿çšã§ããŸããããã¹ãŠã®ããã€ã¹ãåãå ¥ããããšãã§ããŸããã䜿çšãããµãŒãã¹ãæå®ããå¿ èŠããããŸããããããªããšããã©ãŠã¶ãŒã¯ã¢ã¯ã»ã¹ãæäŸããŸããã
// Bluetooth function requestBluetoothDevice() { log('Requesting bluetooth device...'); return navigator.bluetooth.requestDevice({ filters: [{services: [0xFFE0]}], }). then(device => { log('"' + device.name + '" bluetooth device selected'); deviceCache = device; return deviceCache; }); }
䜿çšããBLEã¢ãžã¥ãŒã«ãæ§æãããUUID
0xFFE0
ãµãŒãã¹ãæäŸãããã¹ãŠã®ããã€ã¹ããªã¯ãšã¹ãããŸãã ãŠãŒã¶ãŒãããã€ã¹ãéžæãããšãããã€ã¹ãªããžã§ã¯ãã䜿çšããŠPromiseãå®è¡ãããåè¿°ã®ãã£ãã·ã¥ã«æžã蟌ã¿ãããã«æ»ããŸãã
ããã€ã¹ãžã®æ¥ç¶ããµãŒãã¹ãªããžã§ã¯ããšç¹æ§ã®åä¿¡
// let characteristicCache = null; // , function connectDeviceAndCacheCharacteristic(device) { if (device.gatt.connected && characteristicCache) { return Promise.resolve(characteristicCache); } log('Connecting to GATT server...'); return device.gatt.connect(). then(server => { log('GATT server connected, getting service...'); return server.getPrimaryService(0xFFE0); }). then(service => { log('Service found, getting characteristic...'); return service.getCharacteristic(0xFFE1); }). then(characteristic => { log('Characteristic found'); characteristicCache = characteristic; return characteristicCache; }); }
ç§ãã¡ã¯ãããèªäœãèªãã·ã³ãã«ãªPromiseãã§ãŒã³ãå®è¡ããŸãã
deviceCache
å€æ°ã¯ã
deviceCache
ãšåæ§ã«ãåä¿¡ããç¹æ§ãªããžã§ã¯ããä¿åããŸããããŒã¿ãæžã蟌ããã€ãŸãããã©ãŠã¶ããããã€ã¹ã«ã¡ãã»ãŒãžãéä¿¡ããå¿ èŠããããŸãã
getPrimaryService()
ããã³
getCharacteristic()
é¢æ°ã¯ãBLEã¢ãžã¥ãŒã«ãæ©èœããããã«æ§æãããŠããåŒæ°ãšããŠUUIDã䜿çšããŸãã
æ©èœå€æŽéç¥ãæå¹ã«ãã
// function startNotifications(characteristic) { log('Starting notifications...'); return characteristic.startNotifications(). then(() => { log('Notifications started'); }); }
ç¹æ§ãªããžã§ã¯ãã®
startNotifications()
ã¡ãœãããåç §ããŠãç¹æ§å€æŽã€ãã³ãã§ãã³ãã©ãŒããã³ã°ãããã ãã§ååã§ãããããã«ã€ããŠã¯åŸã§è©³ãã説æããŸãã
ã¿ãŒããã«åºå
端æ«ãžã®åºåæ©èœãå®è£ ããŠãä»ããããã€ã¹ãžã®æ¥ç¶ããã¹ãããŸãã
// function log(data, type = '') { terminalContainer.insertAdjacentHTML('beforeend', '<div' + (type ? ' class="' + type + '"' : '') + '>' + data + '</div>'); }
insertAdjacentHTML()
ã¡ãœããã䜿çšããŠãã¿ãŒããã«ã®divã³ã³ããã®æåŸã«
type
åŒæ°ã§æå®ãããã¯ã©ã¹ãæã€divãæ¿å ¥ããŸããããã¯éåžžã«ç°¡åã§ãã
ãã¹ãäž
ãã©ãŠã¶ã§ããŒãžãéãããæ¥ç¶ããã¿ã³ãã¯ãªãã¯ãããšãããã€ã¹éžæãã€ã¢ãã°ãèµ·åããŸãã ããã€ã¹ã«æ¥ç¶ãããšãæ¥ç¶ããã»ã¹ã«é¢ããã¡ãã»ãŒãžã端æ«ã«è¡šç€ºãããŸãã
ããã€ã¹ã®éžæãšæ¥ç¶ãã¯ãªãã¯å¯èœ
ãã®åŸãã©ãã«ãæžãããŠããªãèœãšãç©Žãããã€ãèŠã€ãããŸããã ãµãŒãã¹ã¡ãã»ãŒãžã®åºåã¯ãåé¡ã®èšºæãšè§£æ±ºã«åœ¹ç«ã¡ãŸããã
1ã€ç®ã¯ã Mi Bandãæ¥ç¶ãããŠããé»è©±æ©ããããã€ã¹ã«æ¥ç¶ããBLEã§åäœããè¿æ¥ããŠããå Žåãæ¥ç¶ã¯éåžžã«ãŸãã§ããããæ¥ç¶ãããå Žåãã»ãšãã©ããã«è±èœããããšã§ãã ããã¯ãã€ãã£ãã¢ããªã±ãŒã·ã§ã³ã§ãèµ·ãããŸããã ç§ã¯Mi Bandãé ãã«é£ããŠè¡ãããšããŸãã-ããã¯å©ãã«ã¯ãªããŸããã§ããã ãã¬ã¹ã¬ããã解ãã®ã§ã¯ãªããå¥ã®ã¹ããŒããã©ã³ã䜿çšããŠããŸãã åæ§ã®åé¡ãçºçããå Žåã¯ãã¹ããŒããã©ã³ãšåæã«éä¿¡ããããã€ã¹ã«æ³šæããŠãã ããã
2çªç®ã®ç³ã¯ããããç³ã§ã¯ãªããéåžžã¯æåã®æ¥ç¶äžã«çŸããæ©èœã§ãïŒæçœãªçç±ããªãæ¥ç¶ãçªç¶å€±ãããå¯èœæ§ãããããã©ãŠã¶ããµããŒããæäŸããªããããåæ¥ç¶æ©èœãç¬èªã«å®è£ ããå¿ èŠããããŸãã
èªååæ¥ç¶
åæã远跡ããããã«ãWeb Bluetoothã¯
gattserverdisconnected
ã€ãã³ããæäŸããŸãã
gattserverdisconnected
ã€ãã³ãã®ãã³ãã©ãŒã¯ããã€ã¹ãªããžã§ã¯ãã§ãã³ã°ããå¿ èŠããããŸãã æãè«ççãªå Žæã¯ãããã€ã¹éžææ©èœã§ãã
// Bluetooth function requestBluetoothDevice() { log('Requesting bluetooth device...'); return navigator.bluetooth.requestDevice({ filters: [{services: [0xFFE0]}], }). then(device => { log('"' + device.name + '" bluetooth device selected'); deviceCache = device; // deviceCache.addEventListener('gattserverdisconnected', handleDisconnection); return deviceCache; }); } // function handleDisconnection(event) { let device = event.target; log('"' + device.name + '" bluetooth device disconnected, trying to reconnect...'); connectDeviceAndCacheCharacteristic(device). then(characteristic => startNotifications(characteristic)). catch(error => log(error)); }
ããã§ãããã€ã¹ã«æ¥ç¶ããé»æºããªãã«ããŠBluetoothæ¥ç¶ã倱ãããå Žåããã©ãŠã¶ãŒã¯1ååæ¥ç¶ãè©Šã¿ãŸãã
åæ¥ç¶ãè©Šè¡ãã¯ãªãã¯å¯èœ
ããã€ã¹ããåæãã
åæããåã«ãå²ãåœãŠããããã³ãã©ãŒã
gattserverdisconnected
ã€ãã³ãããåé€ããããšãå¿ããªãããšãéèŠã§ããããããªããšããã©ãŠã¶ãŒã¯åã«åæ¥ç¶ããŸãã
// function disconnect() { if (deviceCache) { log('Disconnecting from "' + deviceCache.name + '" bluetooth device...'); deviceCache.removeEventListener('gattserverdisconnected', handleDisconnection); if (deviceCache.gatt.connected) { deviceCache.gatt.disconnect(); log('"' + deviceCache.name + '" bluetooth device disconnected'); } else { log('"' + deviceCache.name + '" bluetooth device is already disconnected'); } } characteristicCache = null; deviceCache = null; }
deviceCache
ãªã»ããããããšã¯ã§ããŸããã次ã«ãæ¥ç¶ããã¿ã³ãã¯ãªãã¯ãããšãããã€ã¹éžæãã€ã¢ãã°ã¯è¡šç€ºãããã代ããã«åã®ããã€ã¹ã«æ¥ç¶ããŸãã
ç¡å¹åãã¯ãªãã¯å¯èœ
ããŒã¿æ€çŽ¢
ããŒã¿ã¯ãBLEç¹æ§ã®å€ãå€åãããšãã«çºçããéç¥ã¡ã«ããºã ã䜿çšããŠãããã€ã¹ããéåæçã«åä¿¡ãããŸãã é¢é£ããã€ãã³ãã®
characteristicvaluechanged
ç¹æ§ã®ã¿ã賌èªããå¿ èŠããããŸãã ããã¯ãéç¥ãæå¹ã«ããåŸã«è¡ãå¿ èŠããããŸãã ãŸããããã€ã¹ããªãã«ãªã£ãŠãããšãã«ãç¹æ§ããããã»ããµãåé€ããããšãæ£ããã§ãããã
// function startNotifications(characteristic) { log('Starting notifications...'); return characteristic.startNotifications(). then(() => { log('Notifications started'); // characteristic.addEventListener('characteristicvaluechanged', handleCharacteristicValueChanged); }); } // function disconnect() { if (deviceCache) { log('Disconnecting from "' + deviceCache.name + '" bluetooth device...'); deviceCache.removeEventListener('gattserverdisconnected', handleDisconnection); if (deviceCache.gatt.connected) { deviceCache.gatt.disconnect(); log('"' + deviceCache.name + '" bluetooth device disconnected'); } else { log('"' + deviceCache.name + '" bluetooth device is already disconnected'); } } // if (characteristicCache) { characteristicCache.removeEventListener('characteristicvaluechanged', handleCharacteristicValueChanged); characteristicCache = null; } deviceCache = null; } // function handleCharacteristicValueChanged(event) { let value = new TextDecoder().decode(event.target.value); log(value, 'in'); }
event.target.value
ã¯ãããã€ã¹ããã®ã¡ãã»ãŒãžãããArrayBufferãå«ãDataViewãªããžã§ã¯ãã§ãã
TextDecoder
ïŒ MDNãè±èªã®ã¿ ïŒã䜿çšããŠããã€ãé åãããã¹ãã«ãªãŒããŒã©ã€ãããŸãã
端æ«ããããŒã¿ãéä¿¡ãããã©ãŠã¶ã§åä¿¡ãã¯ãªãã¯å¯èœ
ãã¹ãã§ã¯ãããã€ã¹ããã®ã¡ãã»ãŒãžã®åä¿¡ã¯ã
CR
ã
LF
è¡æ«ã®æç¡ã«ããããããå®å®ããŠæ©èœããããšã瀺ãããŠããŸãã é·ãã¡ãã»ãŒãžã¯å®å šã«å±ããŸããã20ãã€ãã®åæ°ã«åå²ãããŸãã
äžéãããã¡ãŒã®çŽ¹ä»
20ãã€ããè¶ ããã¡ãã»ãŒãžã®ãµããŒãã¯å¿ èŠãªããããããŸããããå®å šãæãããã«ããã®å¶éãåé¿ããŸãããã èãæ¹ã¯ç°¡åã§ããã»ãã¬ãŒã¿æåãåä¿¡ããããŸã§ãçä¿¡ãããã¡ãäžéãããã¡ã«æžã蟌ã¿ãŸãã åºåãæåãåãåã£ããã3çªç®ã®é¢æ°ãåŒã³åºããŠããããã¡ãŒããããŒã¿ãæž¡ãããã®åŸã®æžã蟌ã¿ã®ããã«ãããã¡ãŒãã¯ãªã¢ããŸãã
åºåãæåã¯ãæååïŒ
LF
ã
\n
ïŒãäŸçµŠããããã«è«ççã§ãã ãŸããã¡ãã»ãŒãžã®æåãšæåŸãã空çœãåé€ãããšäŸ¿å©ãªå ŽåããããŸãã
// let readBuffer = ''; // function handleCharacteristicValueChanged(event) { let value = new TextDecoder().decode(event.target.value); for (let c of value) { if (c === '\n') { let data = readBuffer.trim(); readBuffer = ''; if (data) { receive(data); } } else { readBuffer += c; } } } // function receive(data) { log(data, 'in'); }
ããã€ã¹åºæã®Webã¢ããªã±ãŒã·ã§ã³ãäœæããå Žåã
receive()
é¢æ°ãããŒãºã«åãããŠå€æŽããããã€ã¹ããã®ç¢ºå®ãªã¡ãã»ãŒãžã§äœæ¥ããŠããããšã確èªã§ããŸãã
äžéãããã¡ã®å°å ¥åŸã«ç«¯æ«ããããŒã¿ãéä¿¡ãããã©ãŠã¶ã§åä¿¡ãã¯ãªãã¯å¯èœ
ããŒã¿ãéä¿¡ãã
ããã€ã¹ãžã®ããŒã¿ã®éä¿¡ã¯ãç¹æ§ã«å€ãæžã蟌ãããšã«ãã£ãŠãããå ·äœçã«ã¯ãåŒæ°ãšããŠ
writeValue()
ç¹æ§ãªããžã§ã¯ãã®ã¡ãœãããåŒã³åºãããšã«ãã£ãŠå®è¡ãã
ArrayBuffer
ãŸããæååãå€æãã
ArrayBuffer
æãç°¡åãªæ¹æ³ã¯
TextEncoder
ïŒè±èªã®ã¿ã®MDNïŒã§ãã
// function send(data) { data = String(data); if (!data || !characteristicCache) { return; } writeToCharacteristic(characteristicCache, data); log(data, 'out'); } // function writeToCharacteristic(characteristic, data) { characteristic.writeValue(new TextEncoder().encode(data)); }
念ã®ãããã°ããŒãã«ãªããžã§ã¯ãã䜿çšããŠããŒã¿ãæåååã«ãã£ã¹ãããŸã
String
ã
ãã®ãããªå®è£ ã§ã¯ã20ãã€ãã®å¶éãé©çšãããŸããã¹ã³ãŒããè¶ ãããã®ã¯ãã¹ãŠåãæšãŠãããŸãããããã£ãŠãã¡ãã»ãŒãžã20ãã€ãããé·ãå Žåã¯ãã¡ãã»ãŒãžãæçã«åå²ããå°ãé ããŠé 次éä¿¡ãã䟡å€ããããŸãã
// function send(data) { data = String(data); if (!data || !characteristicCache) { return; } data += '\n'; if (data.length > 20) { let chunks = data.match(/(.|[\r\n]){1,20}/g); writeToCharacteristic(characteristicCache, chunks[0]); for (let i = 1; i < chunks.length; i++) { setTimeout(() => { writeToCharacteristic(characteristicCache, chunks[i]); }, i * 100); } } else { writeToCharacteristic(characteristicCache, data); } log(data, 'out'); }
ã³ã³ãããŒã©ãŒåŽã§ã®ã¡ãã»ãŒãžã®åŠçã容æã«ããããã«ãéä¿¡ãããã¡ãã»ãŒãžã®æåŸã«æ¹è¡æåïŒ
\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.github.io/Web-Bluetooth-Terminal-ãŸãã¯YouTubeã§ã®åäœã確èªããŸãã
ã«GitHubã§ã¯ãBLEã¢ãžã¥ãŒã«ãšã®ã·ãªã¢ã«éä¿¡çšã®ES6ã¯ã©ã¹ãšãå®éã«ã¯Webã¿ãŒããã«ãªããžããªãåå¥ã«èŠã€ããããšãã§ããŸãã
UPDïŒæ祚ãè¿œå ããŸããã