Androidのメモとか

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

京急の運行情報ページのレイアウトが更新されました(涙)

やばいよやばいよ。

ポキオ 京急 運行情報

突然のレイアウト変更

我らが京急のHPのデザインが刷新されました。それに伴って、運行情報ページもおしゃれになっています。

unkou.keikyu.co.jp

ただし以前から危惧していた問題が発生してしまいました。いままで個人的に開発をしてきた「運行情報パースロジック」はすべて使えなくなっています・・・。もう一度、イチから考え直します。

下記のコードは現在動作しません

そのため、下記のリポジトリで公開しているコードは一部正常に動作しません。おいおい修正を行いますので、ご了承くださいませ。

結構多いぞ・・・。

京急とファン大研究読本 赤い電車に魅せられて

京急とファン大研究読本 赤い電車に魅せられて

  • 作者:久野知美
  • 発売日: 2019/11/05
  • メディア: 単行本(ソフトカバー)

台風の接近と同時に設置した気圧センサーの結果と反省

気づき。

ポキオ ESP32 BMP280 ambient

前回は気圧センサーを設置しました

これこれ。

relativelayout.hatenablog.com

その後の様子をメモしておきます。

気圧はセンシングできたの?

できましたー。

ポキオ ESP32 BMP280 ambient

午後8時22分頃に968ヘクトパスカルを記録し、その後はV字回復。すごいですねぇ、自然現象って。こりゃ頭も痛くなるわけです。

一方で、BMP280では気圧の他に気温も測定できるので、そちらも併せてセンシングしていたんですが・・・

ポキオ ESP32 BMP280 ambient

こんな感じで30度近傍を推移。室内はそんなに暑くないはずなので、センサーがダメだったのかなと思ったのですが・・・。

どうやら、マイコンが発する熱が影響していた模様(笑)BMP280とESP32を近づけ過ぎたようです。失敗は成功のもと、今度は対策を打ちたいです。

というわけで、サマリ

  • BMP280はI2Cで接続できるしライブラリも豊富なのでかんたん
  • Ambientさんの可視化の容易さは本当に神がかってる
  • センサーの設置場所は結果に影響を与えることがある
  • 台風怖い

明日は買いすぎたカップラーメンでも食べようと思います。

Raspberry Piからmicro:bitにBLEで接続して加速度センサーの情報を読み取る

とりあえず読むだけ。

ポキオ Raspberry Pi BLE Central noble

前回やってたこと

とりあえず、Raspberry Piからmicro:bitをスキャンしたりしていました。

relativelayout.hatenablog.com

今回は、実際に接続して、データを取得してみます。

とりあえずやってみる

startScanning()で見つかったペリフェラルに対して以下の処理をします。

  • 所望のサービス(今回は加速度センサーサービス)を探す
  • そのサービスの所望のキャラクタリスティック(今回は加速度センサーの通知)を探す
  • そのキャラクタリスティックに対してRead/Writeや通知の設定などをする

こんな感じです。加速度センサーのサービスのUUIDはe95d0753251d470aa062fa1922dfa9a8、加速度の変化があるたびに情報を通知してくれるキャラクタリスティックはe95dca4b251d470aa062fa1922dfa9a8なので、これを探してみます。

var noble = require('noble')

function scanPeripheral() {
    noble.on('discover', peripheral => {
        var localName = peripheral.advertisement.localName

        if (localName && localName.startsWith('BBC micro:bit')) {
            console.log(peripheral)
            noble.stopScanning()

            setTimeout(() => {
                connectPeripheral(peripheral)
            }, 500) // wait 500msec to avoid disconnection.
        }
    })

    noble.startScanning()
}

function connectPeripheral(peripheral) {
    peripheral.on('connect', () => {
        console.log('connected')
        peripheral.discoverServices()
    })

    peripheral.on('disconnect', () => {
        console.log('disconnected')
        process.exit(1)
    })

    peripheral.on('servicesDiscover', services => {
        console.log(services)
        services.forEach(service => {
            if (service.uuid && service.uuid === 'e95d0753251d470aa062fa1922dfa9a8') {
                searchCharacteristic(service)
            }
        });
    })

    peripheral.connect()
}

function searchCharacteristic(service) {
    service.on('characteristicsDiscover', characteristics => {
        console.log(characteristics)
        characteristics.forEach(characteristic => {
            if (characteristic.uuid && characteristic.uuid === 'e95dca4b251d470aa062fa1922dfa9a8') {
                subscribeChatacteristic(characteristic)
            }
        })
    })

    service.discoverCharacteristics()
}

function subscribeChatacteristic(characteristic) {
    characteristic.on('data', (data, isNotification) => {
        console.log('x : ' + data.readInt16LE(0) + ' / y : ' + data.readInt16LE(2) + ' / z : ' + data.readInt16LE(4))
    })

    characteristic.subscribe()
}

scanPeripheral()

今回ハマったのは、

  • スキャンで発見から接続までを間髪をいれずに処理してしまうと、なぜか切断してしまうケースがあったので、不本意ながらSleepを入れています。
  • micro:bitから通知される情報はバイト列のBufferで来るが、X/Y/Z軸の情報がInt16でそれぞれ詰まってるので変換する必要がある。

このあたりでした。

いざ実行

Node.js上で上記コードを実行すると・・・

ポキオ Raspberry Pi BLE Central noble

かなり短い間隔で加速度センサー情報が送られてきます。

今回、micro:bitのLEDマトリックスがある側を上にして測定してましたが、Z軸の加速度が負の値だったので、もしかしたらLEDマトリックスは裏側なのかもしれません。。。

台風が来るし気圧センサー「BMP280」をESP32につなげて測定してみる

そんなことしてて大丈夫?

ポキオ ESP32 BMP280 ambient

台風怖いんですけど

すごそうですよね。

スーパーに行ったら、水とかパンとか全然なくてビビりました。備えあれば憂いなしって言いますしね。私もなんとか食料を確保できました。

ただ、台風の準備はそれだけで良いのでしょうか?だめです。気圧を測りましょう。

気圧を測るには?

台風は低気圧なわけで、台風が近づけば気圧も下がるはず。それをセンシングして可視化してみようと思います。気圧をセンシングするにはBMP280というものを使います。Amazonなら安いもので300円くらいで買えます。

こやつをESP32ボードにつないで制御してみようと思います。今回は、この前掃除してたら出てきたESP32 DevKitCを使います。

また、データの可視化には、Wi-Fi経由でAmbientさんに接続しデータを送り続け、Ambientさんのページ上で気圧の推移を見てみようと思います。(Ambientさん、いつもお世話になっています。多謝多謝。)

つくってみる

BMP280はI2C接続が可能なので、非常にシンプルな配線で組み立てることができます。

BMP280側 ESP32 DevKitC側
VCC 3.3V
GND GND
SCL 22pin
SDA 21pin

この4本だけ接続すればOKなはず。

コーディングもAdafruitのライブラリが使えたので、超簡単です。

github.com

#include <WiFi.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP280.h>
#include "Ambient.h"

#define SSID "xxxxx"
#define PASSWORD "xxxxx"
#define INTERVAL 5 * 60 * 1000 // 5分毎にAmbientさんにデーターを送る
#define CHANNEL_ID xxxxx
#define WRITE_KEY "xxxxx"

Adafruit_BMP280 bme;
WiFiClient client;
Ambient ambient;
float temperature;
float pressure;

void setup() {
  Serial.begin(9600);
  Serial.println(F("BMP280 test"));

  if (!bme.begin(0x76)) {
    Serial.println("Could not find a valid BMP280 sensor, check wiring!");
    while (1);
  }
}

void loop() {
  connectWifi();
  readData();
  sendData();
  disconnectWifi();
  delay(INTERVAL);
}

void connectWifi() {
  WiFi.mode(WIFI_STA);
  WiFi.begin(SSID, PASSWORD);

  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(100);
  }

  Serial.println("connected!");
}

void disconnectWifi() {
  WiFi.disconnect();
  Serial.println("disconnected!");
}

void readData() {
  temperature = bme.readTemperature();
  pressure = bme.readPressure();

  Serial.print("Temperature = ");
  Serial.print(temperature);
  Serial.println(" *C");

  Serial.print("Pressure = ");
  Serial.print(pressure);
  Serial.println(" Pa");

  Serial.println();
}

void sendData() {
  ambient.begin(CHANNEL_ID, WRITE_KEY, &client);
  ambient.set(1, temperature);
  ambient.set(2, pressure);
  ambient.send();
}

ちなみに、気温も測れるので、ついでに送ってみます。

ポキオ ESP32 BMP280 ambient

とりあえず、嫁の許可が降りたので、キッチンで使っていないコンセントに直差ししておきます。

データは可視化できたの?

じゃーん。

ポキオ ESP32 BMP280 ambient

それっぽい値が取れてますねぇ。これから台風が接近するにあたり、値がどう変化するか気になりますねぇ。

小説 天気の子 (角川文庫)

小説 天気の子 (角川文庫)

  • 作者:新海 誠
  • 発売日: 2019/07/18
  • メディア: 文庫

Raspberry PiのBLEをNode.jsのnobleから叩いてmicro:bitを見つけてみる

ちょっと癖があるね。

ポキオ Raspberry Pi BLE Central noble

前回まで

RPiのBLEをnobleから叩いてました。

relativelayout.hatenablog.com

今回は、micro:bitのBLE機能を有効にして、RPiからmicro:bitをスキャンしてみようと思います。

relativelayout.hatenablog.com

ちなみに、micro:bitは電池ケースにくっつけて給電できるようにしています。

とりあえずスキャン

フツーにScanすれば良いんですが。

var noble = require('noble')

noble.on('discover', function(peripheral){
    console.log(peripheral)
})

noble.startScanning()

startScanning()のオプションでGATTのサービスのUUIDを指定することができ、これによってスキャン結果をそのサービスがあるペリフェラルにフィルタできるようで。試しにmicro:bitのサービスを指定してスキャンをしてみました。

たとえば、加速度サービスのUUIDはe95d0753-251d-470a-a062-fa1922dfa9a8なので、

noble.startScanning(['e95d0753251d470aa062fa1922dfa9a8'], false)

みたいに叩けばよいはず。これで叩いてみると・・・なぜかmicro:bitが見つかりません・・・。

接続しないとサービスがわからない?

そんなのもんなのかなぁ思い、改めてオプション無しでstartScanning()して、見つかったmicro:bitのプロパティを見てみると・・・。

Peripheral {
  _noble: 
   Noble {
    (中略)
 },
  id: 'xxxxxxxxxxxx',
  uuid: 'xxxxxxxxxxxx',
  address: 'xx:xx:xx:xx:xx:xx',
  addressType: 'random',
  connectable: true,
  advertisement: 
   { localName: 'BBC micro:bit [xxxxx]',
     txPowerLevel: undefined,
     manufacturerData: undefined,
     serviceData: [],
     serviceUuids: [],
     solicitationServiceUuids: [],
     serviceSolicitationUuids: [] },
  rssi: -33,
  services: null,
  state: 'disconnected' }

serviceUuidsが空っぽですねぇ。これが空なのでUUIDでフィルタができなかったのでしょうか・・・。とはいえ、localNameにはちゃんとmicro:bitと入っているので、とりあえずワークアラウンドとしてlocalNameでフィルタするしかないんですかね・・・。たとえばこんな感じ。

var noble = require('noble')

noble.on('discover', function (peripheral) {
    var localName = peripheral.advertisement.localName

    if (localName && localName.startsWith('BBC micro:bit')) {
        console.log('micro:bit found!')
    }
})

noble.startScanning()

うーん、ちょっとダサいけど、動いてそうだしこれで行くか・・・。

Raspberry PiのBLEをNode.jsから叩いてチョッパヤでスキャンする

うわーかんたん。

ポキオ Raspberry Pi BLE Central noble

noble導入して速攻Scan余裕でした

RPi上のBLEを叩いてみようと、ふと思ったんですが、ちょっと面倒なのかなと思ってやってみたところ、意外と簡単だったのでメモ。

github.com

nobleを入れるだけでした。

BLEデバイスのスキャンができるまで

Raspberry PiでNode.jsのセットアップが整っている状態で、まずは必要な要素をapt installする。

$ sudo apt-get install bluetooth bluez libbluetooth-dev libudev-dev

なにか聞かれてもYしとく。これだけ。

あとは、よしななディレクトリをつくって、

$ npm init -y
$ npm install noble

nobleをインストール。index.jsみたいなテキトーなJSファイル作って、

var noble = require('noble')

noble.on('discover', function(peripheral){
    console.log(peripheral)
})

noble.startScanning()

こんな感じでScanして、その結果をconsole出力するだけのコードを書く。あとは、node index.jsすると、周辺にあるBLEデバイスのScan結果が、バァーっとターミナルに表示されます。これでおしまい。

本当に簡単でした

あとは、テキトーにPeripheralに接続して、ReadなりWriteなりすればOK。Androidとは違ってPromiseとか駆使すれば、コールバックの嵐にはならなそう。これは使えるぞ・・・!

[asin:B07446WLQV:detail]

「かぶれる京急」がIoT感を手に入れました

#がんばれ京急 #ありがとう京急

pokiiio keikyu-unko-to-image

MFT2019で展示した「かぶれる京急

relativelayout.hatenablog.com

会場でのインターネット接続性の確保が難しかったのと、工数不足諸般の事情から、MFT2019ではスタンドアローンで動く実装にしていました。

pokiiio keikyu-unko-to-image

HUB75規格のインターフェースでRaspberry Piと接続されたRGB LEDパネルモジュールに、予め作成した画像ファイルをNode-REDでランダムに選択してPythonで書いたスクリプトでモジュールに流し込んでいました。

今回のアップデートは?

Pythonスクリプトのなかで、京急の運行情報ページにアクセスをして運行情報をパースし、それを画像化してモジュールに流し込む実装を追加(笑)

pokiiio keikyu-unko-to-image

github.com

今回利用したパネルに限らず、良心的なパネルであれば画像を焼べれば表示されるようなライブラリをついているとおもうので、今回画像化に使ったスクリプトGithubで公開しています。誰も使わないと思いますが、ご査収ください。

pokiiio keikyu-unko-to-image

こんな画像をスクリプトで作成し、RGB LEDパネルに流し込みます。

pokiiio keikyu-unko-to-image

こんな感じ。

動作してる様子がこちら

こちらも併せてご査収ください。

View this post on Instagram

進捗出した。

A post shared by pokio (@pokiiiiio) on

というわけで

京急の運行情報はおいておいて、とりあえずRGB LEDパネルは画像さえ生成できてしまえばあとは楽勝ということがわかります。楽勝で画像を生成するにはやっぱりPythonのPILですね。間違いないです。

そして、このRGB LEDパネルの話とか、光り物の話がいっぱい詰まった本が、なんと技術書典7で売りますよ!

techbookfest.org

場所はけ27Dですよ!買ってね!

Adafruit 64x32 RGB LED Matrix Panel - 5mm pitch

Adafruit 64x32 RGB LED Matrix Panel - 5mm pitch

  • メディア: エレクトロニクス

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

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