Androidのメモとか

ポキオの日記です。今日も遅延してない。

Bootstrapでそれっぽいサイトをチョッパヤで作ってみた

それっぽさ。

Bootstrapとは

いい感じのCSSとJSが用意されたコンポーネントライブラリ。味気ない素のエレメントを、ちょっとしたコーディングで今風な感じに仕上げてくれます。

getbootstrap.com

Bootstrap is an open source toolkit for developing with HTML, CSS, and JS. Quickly prototype your ideas or build your entire app with our Sass variables and mixins, responsive grid system, extensive prebuilt components, and powerful plugins built on jQuery.

使い方は簡単で、HTMLに以下を追加。

(HEAD内に)
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
(BODY内に)
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>

あとは要素のクラス名をいじるだけでいい感じの雰囲気になります。今回は以下のサイトを参考にしながら、サイトのアップデートを行ってみました。

https://hackerthemes.com/bootstrap-cheatsheet/

実際に使ってみた

以前作ったGitHub Pagesをすべて更新してみました。

pokiiio.github.io

pokiiio.github.io

pokiiio.github.io

pokiiio.github.io

pokiiio.github.io

pokiiio.github.io

実際のイメージがこんな感じ。

bootstrap pokiiio

フォントだけでなく、NavBarもそれっぽく。

bootstrap pokiiio

ダイアログもそれっぽく。

bootstrap pokiiio

モバイルもそれっぽく。

チョッパヤでいい感じに!

micro:bitをWeb Bluetooth APIで通信するときにハマったポイント

たくさんハマりました。

micro:bit Web Bluetooth API

メモメモ

micro:bitを買ってから色々といじってましたが、色んな所でハマったのでメモしておきます。

JavaScript Block EditorでBluetoothのブロックが見つからない

デフォルトで非表示という罠。

relativelayout.hatenablog.com

Web Bluetooth APIが使えるOS/ブラウザの組み合わせが意外と少ない

Chrome on Macは優秀。Safariが対応してなくてビビる。

github.com

BLEデバイスのスキャン

Web Bluetooth

ページ上でユーザーアクションをトリガーに、ブラウザのBLEデバイスリスト画面をnavigator.bluetooth.requestDevice()で表示させることで、特定のBLEデバイスと接続し通信するわけですが。

  navigator.bluetooth.requestDevice({
    filters: [
      { services: [LED_SERVICE] },
      { namePrefix: "BBC micro:bit" }
    ]
  })

結論から言うと、こんな感じで書くとうまく動作しました。ここで、LED_SERVICEというのは、サービスのUUIDで、

// micro:bit LEDサービス
const LED_SERVICE = "e95dd91d-251d-470a-a062-fa1922dfa9a8";

こんな感じです。

例えば、servicesを指定しないと、

SecurityError: Origin is not allowed to access any service. Tip: Add the service UUID to 'optionalServices' in requestDevice() options. https://goo.gl/HxfxSQ

セキュリティ観点でブラウザに怒られてしまい、機器リストには表示されるものの、いざ接続してRead/Writeしようとすると失敗してしまいます。

  navigator.bluetooth.requestDevice({
    filters: [
      { services: [LED_SERVICE] }
    ]
  })

じゃあservicesだけならいいのかと思うと、そういうわけでなく、これだとデバイスをうまく見つけられません。

  navigator.bluetooth.requestDevice({
    services: [LED_SERVICE]
  })

むしゃくしゃしてこういう書き方をしてしまうと、

TypeError: Failed to execute 'requestDevice' on 'Bluetooth': Either 'filters' should be present or 'acceptAllDevices' should be true, but not both.

と言われてしまいます。acceptAllDevicestrueにしてもいいですが、そうすると関係ないBLEデバイスも機器リストに表示されてしまい、見づらくなってしまいます。servicesでサービスを指定しつつ、名前のprefixでフィルターするには、

  navigator.bluetooth.requestDevice({
    filters: [
      { services: [LED_SERVICE] },
      { namePrefix: "BBC micro:bit" }
    ]
  })

やっぱりこういう書き方がジャスティスっぽいです。filtersで条件をつなげていくといい感じにANDでフィルターしてくれます。

サービス、キャラクタリスティックのUUIDや仕様がわからない

ここの情報を信じて実装しました。

Bluetooth Developer Studio - Profile Report

ちなみに、先程のLEDサービスのUUIDは、プロファイルの仕様書上はE95DD91D251D470AA062FA1922DFA9A8と書かれていますが、このままJavaScriptのコードに書いてしまうとエラーになってしまいました。ちゃんとハイフンを入れてあげて、e95dd91d-251d-470a-a062-fa1922dfa9a8みたいな感じで書いてあげなければ行けません。キャラクタリスティックのUUIDも同様です。

一部未実装?だったり、セキュリティ的にアクセスできないキャラクタリスティックがある

先程のプロファイルの仕様書では、Device Informationというサービスがあり、

  • Model Number String
  • Serial Number String
  • Hardware Revision String
  • Firmware Revision String
  • Manufacturer Name String

という5つのキャラクタリスティックがあるようですが、実際にアクセスしてみると、Serial Number Stringは

SecurityError: getCharacteristic(s) called with blocklisted UUID. https://goo.gl/4NeimX

セキュリティ的にアクセスが封じられているようです。また、Hardware Revision StringとManufacturer Name Stringは、そもそもキャラクタリスティックが見つかりませんでした。

micro:bitのLEDをWeb Bluetooth APIで制御してみる

micro:bit x Web Bluetooth APIの最終章。

micro:bit web bluetooth api

最後はLED

micro:bitのBLEを色々いじってきました。

relativelayout.hatenablog.com

relativelayout.hatenablog.com

relativelayout.hatenablog.com

relativelayout.hatenablog.com

ちょっとキリがないので、今回のLED制御で一旦シメたいと思います。

micro:bit側は、BLE系のサービスを開始するだけ

相変わらず、Bluetooth系のサービスをすべて初期化するコードです。

micro:bit web bluetooth api

今回も変える必要がないので、このままの実装で進めます。

bluetooth.startAccelerometerService()
bluetooth.startButtonService()
bluetooth.startIOPinService()
bluetooth.startLEDService()
bluetooth.startTemperatureService()
bluetooth.startMagnetometerService()

IOピンサービスっていうのもあります。たまには思い出してあげてください。

HTML側のプログラミング

例によって、このプロファイル仕様書を参考にしています。

Bluetooth Developer Studio - Profile Report

LED系のサービスは少し特殊で、今表示しているLEDの状態を取得したり、任意の状態を書き込んで、好きな用に光らせることもできます(ReadもWriteもできる)。また、文字列を流し込んでスクロール表示させたり、スクロール速度も変えられます。

今回は、5x5のチェックボックスをページ上に表示して、チェックした位置に対応するLEDを光らせるというプログラミングにしました。

Octet 0 represents the first row of LEDs i.e. the top row when the micro:bit is viewed with the edge connector at the bottom and USB connector at the top.

Octet 1 represents the second row and so on.

In each octet, bit 4 corresponds to the first LED in the row, bit 3 the second and so on.

Bit values represent the state of the related LED: off (0) or on (1).

So we have:

Octet 0, LED Row 1: bit4 bit3 bit2 bit1 bit0

Octet 1, LED Row 2: bit4 bit3 bit2 bit1 bit0

Octet 2, LED Row 3: bit4 bit3 bit2 bit1 bit0

Octet 3, LED Row 4: bit4 bit3 bit2 bit1 bit0

Octet 4, LED Row 5: bit4 bit3 bit2 bit1 bit0

こんな感じで、LEDの一列をUint8で表す、Uint8Arrayデータをmicro:bitに流し込めばOKです。

github.com

pokiiio.github.io

#microbit のLEDを #webbluetooth で制御してみる。

A post shared by pokio (@pokiiiiio) on

いやー、BLEでなんでもできちゃうんですね・・・。

micro:bit、奥が深いわ・・・。

電池ボックスを改造してmicro:bitの電源をスマートな感じで供給できるようにした

なんかいい感じ!

micro:bit  battery 電池

所謂、電源どうするんだ問題

マイコンを触ってて、いつもぶち当たる問題の一つが電源。

micro:bit  battery 電池

購入したのはスターターキットだったので、電池ボックスが付属していたものの、単4電池2本ということもありバッテリー駆動時間が心配なのと、電源コードがどうもスマートではないような印象でした。

そこで電池ボックス

既存の電池ボックスを改造して、GNDと3V端子に直接電気を流してやればいいのでは?そう思ってぐぐると、すでに先人がやっていました。

qiita.com

僕は単3電池が大好きなので、単3電池3本が入るスイッチ付き電池ボックスを改造して、micro:bitに給電してみたいと思います。

いざ工作

こういう電池ボックスを買ってきまして、

micro:bit  battery 電池

電極を取り外していきます。単3電池1本分のスペースを、micro:bitの端子を接続するために使って、残りの2本分のスペースを電池用にアサインします。

micro:bit  battery 電池

micro:bitの穴と同じように、電池ボックスにも穴を開けていきます。

micro:bit  battery 電池

端子 といっても、ボルトとナットでなんとかしていきます。それぞれ2個づつつかって、3V端子とGND端子を作って、それをmicro:bitに接続します。

micro:bit  battery 電池

micro:bitに表面実装されている素子が電池ボックスと干渉するので、スペーサを噛ませて固定します。これで完成!

うーん!いい感じ!

micro:bit  battery 電池

コンパクトなmicro:bitのよさみをスポイルすることなく、低コストでコンパクトに、スマートに電源供給ができるようになりました!やったね!

以下、ごめんなさい案件です。

  • リセットボタンが押せなくなった
  • 穴を5個も開ける必要はなかった

micro:bitのボタンのステータスをWeb Bluetooth APIで読み取ってみる

第4弾!

micro:bit web bluetooth api

ボタンのステータスを読み取ります

さてさて、加速度、磁気、温度、そして今回はボタンです。

relativelayout.hatenablog.com

relativelayout.hatenablog.com

relativelayout.hatenablog.com

micro:bit、今回は百均で売ってた単三電池→USB5V出力するモバイルバッテリーで動かしてみました。いい感じ。

micro:bit側のプログラミングは全く変わりません!

相変わらず、Bluetooth系のサービスをすべて初期化するコードです。

micro:bit web bluetooth api

今回も変える必要がないので、このままの実装で進めます。

bluetooth.startAccelerometerService()
bluetooth.startButtonService()
bluetooth.startIOPinService()
bluetooth.startLEDService()
bluetooth.startTemperatureService()
bluetooth.startMagnetometerService()

残すはあとLEDとIOピンか・・・。

HTML側のプログラミング

例によって、このプロファイル仕様書を参考にしています。

Bluetooth Developer Studio - Profile Report

AボタンとBボタンにそれぞれキャラクタリスティックが割り振られていて、それぞれNotifyを受けることができます。ステータスは3種類で、押されていない/押されている/長押しされている。Androidとかの長押し判定と違って、2-3秒ボタンを押してないと長押判定されません。

早速ですが、コードはこちら。

github.com

で、サンプルページはこちら。

pokiiio.github.io

ボタンを押したり、長押しすると、表示が変わります。

#microbit のボタンのステータスを #webbluetooth で受信する。

A post shared by pokio (@pokiiiiio) on

はい。月食見忘れた!

micro:bitの温度センサーの値をWeb Bluetooth APIで読み取ってみる

夜な夜なコーディング、第3弾。

micro:bit web bluetooth api

今回は温度センサー

加速度センサー、磁気センサーとやってきました。今回は温度センサー。温度も取れちゃうんですね、早速Web Bluetoothしてしまいましょう。

relativelayout.hatenablog.com

relativelayout.hatenablog.com

micro:bit、もう一個ほしい・・・。

micro:bit側のプログラミングは全く変わりません!

相変わらず、Bluetooth系のサービスをすべて初期化するコードです。

micro:bit web bluetooth api

今回も変える必要がないので、このままの実装で進めます。

bluetooth.startAccelerometerService()
bluetooth.startButtonService()
bluetooth.startIOPinService()
bluetooth.startLEDService()
bluetooth.startTemperatureService()
bluetooth.startMagnetometerService()

JavaScriptはこんな感じ。はい。

HTML側のプログラミング

例によって、このプロファイル仕様書を参考にしています。やっぱり、これが公式資料なのかな・・・。

Bluetooth Developer Studio - Profile Report

温度センサーは、キャラクタリスティックが2つで、温度を読み取るものと、通知間隔を変えるもの。もう慣れっこですね。

github.com

pokiiio.github.io

コードはgithubをごらんください。micro:bitから温度情報を逐次読み取って、ブラウザに表示します。温度変化があれば、背景色が赤くなったり青くなったりするコードを書きました。

娘にmicro:bitを握らせて、温めて頂きました。

眠かったのか手が温かく、すぐにmicro:bitも温まりました(笑)

micro:bitの磁気センサーの値をWeb Bluetooth APIで読み取ってみる

micro:bitはBLEのインターフェイスが充実!

micro:bit web bluetooth api

今度は磁気センサー

前回は、加速度センサーの値をWeb Bluetooth APIを使ってブラウザから読み込んでみました。

relativelayout.hatenablog.com

そして、今回は磁気センサーの値を読んでみました。

micro:bit側のプログラミングは前回と同じ。

とりあえず、Bluetooth系のサービスをすべて初期化するコードです。

micro:bit web bluetooth api

前回と変える必要がないので、このままの実装で進めます。

bluetooth.startAccelerometerService()
bluetooth.startButtonService()
bluetooth.startIOPinService()
bluetooth.startLEDService()
bluetooth.startTemperatureService()
bluetooth.startMagnetometerService()

JavaScriptはこんな感じ。

HTML側のプログラミング

例によって、このプロファイル仕様書を参考にしています。

Bluetooth Developer Studio - Profile Report

磁気センサー系のサービスには、

  • x,y,zそれぞれの生値を返すサービス
  • 更新間隔の調整するサービス
  • 0-360の方角を返すサービス

この3つがありますが、今回は下の2つを使いました。

github.com

pokiiio.github.io

今回もこんな感じでGitHubにコードをアップして、Pagesで公開して見ました。

  • 更新頻度を160msecごとに変更
  • 方角の更新通知の受信を開始
  • 方角を受信したら、その角度を表示する(そのときに文字を角度分傾ける)

こんなことを実装しました。実際の動作はこんな感じ。

#microbit の磁気センサーを #webbluetooth で拾ってみた!

A post shared by pokio (@pokiiiiio) on

たーのしー。

とりあえず実装してみたけど、これを何に使おうか。

「Androidのメモとか」は、Amazon.co.jpを宣伝しリンクすることによってサイトが紹介料を獲得できる手段を提供することを目的に設定されたアフィリエイト宣伝プログラムである、Amazonアソシエイト・プログラムの参加者です。

このブログは個人的なメモ書きであったり、考えを書く場所であります。執筆者の所属する団体や企業のコメントや意向とは無関係であります。また、このブログは必ずしも正しいことが書かれているとは限らず、誤字脱字や意図せず誤った情報を載せる場合がありえます。それが原因で読者が不利益を被ったとしても、執筆者はいかなる責任も負いません。ありがとうございます。