Androidのメモとか

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

Unity(Android)の環境をMacBook Airに構築したんだが難しかった話

UnityなAndroidアプリを作りたくて環境をセットアップしてみましたが、意外とクセモノだったのでメモしておきます。

私の環境

最新のAndroid Studioには非対応

かなり雑な言い方ですが、最新のAndroid StudioにバンドルされてるSDKをUnityで読み込ませても、UnityでAPKのビルドができませんでした。

Android Studio Unity セットアップ

SDKのパスをUnityで登録して、ビルドしようとすると、

Build failure

Unable to list target platforms. Please make sure the android sdk path is correct. See the Console for more details. See the Console for details.

Android Studio Unity セットアップ

こんな感じで怒られます。

stackoverflow.com

ここの情報を参考にさせていただきました。tools(いわゆるコマンドラインツール)のバージョンが26.x.xだとUnityに対応していない模様。25.x.xなtoolsをどこからか落として来る必要があります。

しょうがないのでイチからセットアップする

ここからMac版のtoolsを落としてきます。

http://dl-ssl.google.com/android/repository/tools_r25.2.5-macosx.zip

Android Studioが参照しているSDKディレクトリには、すでに最新のSDKが入っているので、他のディレクトリを適当に掘って解凍します。

Android Studio Unity セットアップ

この状態で、Unityでそのディレクトリを登録して、APKを作ろうとすると、別の理由で怒られます。

Android SDK is outdated

SDK Platform Tools version 0.0.0 < 23.0.0.

そりゃそうで、toolsとは別に、platforms、platform-tools、build-toolsのダウンロードが必要になります。tools/bin/sdkmanagerでそれらをコマンドラインからダウンロードしていきます。 platformsやbuild-toolsは、すべてのバージョンを落とす必要はありません。個人的にはAndroid 6.0以降の端末で動くAPKが作りたかったので、23(Android 6.0)〜25(Android 7.1)あたりのアイテムをインストールします。

Target SDK Versionは25にする

Min SDKもTarget SDKも23で良いかなと思ったんですが、Unityが生成するManifestに、25以降で対応するAttributeが存在するため、Target SDKは25にしておくと安心です。

Build failure

Failed to re-package resources. See the Console for details.

Targetが23のままだと、こんな怒られ方をされて泣きたくなります。

とりあえずAPKは作れるようになった

あとは実装するだけですね!(震え声)

今後の予定と備忘録

おかげさまで、いろんなイベントに参加させて頂ける事になったので、ご報告。

SIer主催版IoT縛りの勉強会 SIerIoTLT vol2 (vol1?)

iotlt.connpass.com

小生、SIerじゃないんですが、ちょっとだけ話してきます。一応、初心者でもとっつきやすいマイコンボードということで、Nefry BTを紹介してきます。やっぱりIoTやるなら、まずNefry BT♪。間違いないと思います。

秋のJavaScript祭 in mixi 2017

javascript-fes.doorkeeper.jp

小生、JSerでもないんですが、ちょっとだけ話してきます。Google Apps ScriptがかろうじてJSっぽいので、GASとIoTの関係性をお話する予定です。かなりこじつけかもしれませんが、JSな人たちにも是非IoTに挑戦していただきたいです。

みんなでダァシエリイェス!遅延すると光るガジェットをつくるIoTハンズオンを開催しました!

dotstud.io

先日開催したハンズオン会の記事が公開されました。私の周りの一部で非常に好評だったので、もしかしたら第2弾も開催するかも・・・?

というわけで、今後ともよろしくお願いします。 今年もあと2ヶ月。突っ走っていきます。

Nefry BTのディスプレイをサクっと触ってみる

今回はディスプレイ。

Nefry BTで強化されたディスプレイ機能を使う

Nefry BTのバージョンを1.0.8にアップデートしたら、ディスプレイ関係の関数が色々追加されてたようなので、ちょっと使ってみます。ディスプレイをコントロールするのに必要となってくるのが#include <NefryDisplay.h>。これさえ書いておけば、簡単な便利関数で好きな文字列を表示できます。

たとえば、こんな感じのコードを実行すると・・・

#include <Nefry.h>
#include <NefryDisplay.h>

void setup() {
  NefryDisplay.print("POKIO");
  NefryDisplay.print("KEIKYU");
}

void loop() {

}

Nefry BT

こんな感じで、POKIOKEIKYUと表示できました。NefryDisplay#print()という関数を使えば、簡単に好きな文字列を表示できます。ちなみに、日本語には対応していません。日本語を入力しても、何も表示されないので注意が必要。また、表示できるのは3行まで。

#include <Nefry.h>
#include <NefryDisplay.h>

void setup() {
  NefryDisplay.print("P");
  NefryDisplay.print("O");
  NefryDisplay.print("K");
  NefryDisplay.print("I");
  NefryDisplay.print("O");
}

void loop() {

}

こんな感じで4回以上NefryDisplay#print()を実行すると、最初に書き込んだ文字列は消えてしまいます。

Nefry BT

POKIOと入力しても、最後のKIOしか表示されません。ただ、1行に長文を流し込んだ場合は、文字がスクロールするので、なんとか全文読むことができます。たとえば、

#include <Nefry.h>
#include <NefryDisplay.h>

void setup() {
  NefryDisplay.print("POKIOPOKIOPOKIOPOKIO");
  NefryDisplay.print("KEIKYUKEIKYUKEIKYUKEIKYU");
}

void loop() {

}

こんな感じで、無理矢理長い文字列を入れると・・・

Nefry BT

(写真ではわかりづらいですが)文字列がスライドして、すべての文字列を表示してくれます。

Nefry BTで強化されたディスプレイ機能をもっと使う

上記の関数を使うと、簡単に文字列が表示できるものの、

  • ディスプレイ上部にNefry PrintDialogと表示される
  • 3行までしか表示できない
  • 左アライン固定、上詰め

という制限があります。そこで、NefryDisplay#drawString()NefryDisplay#drawStringWithHScroll()NefryDisplay#autoScrollFunc()を使うと、自由度高く文字列を表示できます。

#include <Nefry.h>
#include <NefryDisplay.h>

void setup() {
  NefryDisplay.setAutoScrollFlg(true);
  NefryDisplay.autoScrollFunc(pokioPrint);
}

void loop() {

}

void pokioPrint(){
  NefryDisplay.drawString(0, 0, "POKIO");
  NefryDisplay.drawString(20, 20, "POKIO");
  NefryDisplay.drawString(40, 40, "POKIO");
  NefryDisplay.drawString(60, 60, "POKIO");
}

たとえば、NefryDisplay#drawString()で関数を作って、それをNefryDisplay#autoScrollFunc()をコールするようなコードを書いてみました。NefryDisplay#drawString()では、文字を表示する位置と文字を指定できます。

Nefry BT

これを実行すると、こんな感じで好きな位置に文字列を表示できます。4行目の文字が見切れてしまっていますが、文字を縦方向に15ずつずらせば、ピッタリ4行文字列を表示できます。

#include <Nefry.h>
#include <NefryDisplay.h>

void setup() {
  NefryDisplay.setAutoScrollFlg(true);
  NefryDisplay.autoScrollFunc(pokioPrint);
}

void loop() {

}

void pokioPrint(){
  NefryDisplay.drawString(0, 0, "POKIO");
  NefryDisplay.drawString(20, 15, "POKIO");
  NefryDisplay.drawString(40, 30, "POKIO");
  NefryDisplay.drawString(60, 45, "POKIO");
}

Nefry BT

NefryDisplay#drawStringWithHScroll()を使えば、好きな位置で文字列をスクロール表示でき・・・るはずだったんですが、手元では文字が重なって表示されてしまい、上手く表示されませんでした・・・。

#include <Nefry.h>
#include <NefryDisplay.h>

void setup() {
  NefryDisplay.setAutoScrollFlg(true);
  NefryDisplay.autoScrollFunc(pokioPrint);
}

void loop() {

}

void pokioPrint(){
  NefryDisplay.drawString(0, 0, "POKIOPOKIOPOKIOPOKIOPOKIO");
  NefryDisplay.drawStringWithHScroll(0, 15, "POKIOPOKIOPOKIOPOKIOPOKIO", 10);
  NefryDisplay.drawString(40, 30, "POKIOPOKIOPOKIOPOKIOPOKIO");
  NefryDisplay.drawStringWithHScroll(40, 45, "POKIOPOKIOPOKIOPOKIOPOKIO", 10);
}

Nefry BT

何かコーディングしくじったかな・・・。

NefryDisplay#drawString()は、長い文字列だと自動で改行されるため、文字が重なっていたようです。場合によっては、改行するかしないかを気にしながらコーディングする必要がありそうです。

何はともあれ

簡単な関数でディスプレイを制御できてしまうNefry BT。使い方しだいではかなり面白いガジェットができるのではないでしょうか。

Nefry BTとIFTTTライブラリをつかってお腹が痛くなった時に押すボタンを作る

Nefry BTなら秒で作れる。

Nefry BTとIFTTTライブラリをつかってお腹が痛くなった時に押すボタンを作る

腹痛の見える化

しばしば腹痛がおこるポキオです。お腹が痛いときに、みなさんは呪文を唱えますよね。僕は唱えますよ、「#ponponpain」と。ただ本当にお腹がいたいときに、いちいち「#ponponpain」って打つのはだるいですよね。

そこでNefry BT。ワンタッチでツイッターに「#ponponpain」と宣言できます。

Nefry BT ✕ IFTTT Webhooks ✕ Twitter

Nefry BTにはIFTTTライブラリが入っていて、面倒なHTTP-POSTやらJSONなどを一切意識すること無くIFTTTのTrigger(Webhooks)を叩くことができてしまいます。さっそく、IFTTTのアプレットを作ってみます。

Nefry BTとIFTTTライブラリをつかってお腹が痛くなった時に押すボタンを作る

ここで言う、If THISはWebhooksで、Then THATはTwitterとなります。予めWebhooksとTwitterの設定は済んでいるとします。

IFTTT側の設定

まずはIf THISで、Webhooksを選びます。

Nefry BTとIFTTTライブラリをつかってお腹が痛くなった時に押すボタンを作る

イベント名を決めろと言われるので、ここは適当にponponpainとしておきます。

Nefry BTとIFTTTライブラリをつかってお腹が痛くなった時に押すボタンを作る

次に、Then THATの部分。こちらはTwitterになります。

Nefry BTとIFTTTライブラリをつかってお腹が痛くなった時に押すボタンを作る

Triggerが発火した時に「#ponponpain」とただただツイートするように設定しておきます。これで完成。

Nefry BT側の実装

今回はData Storeなどを使わずに愚直にコードを書いていきます。兎に角短いです。

#include <Nefry.h>
#include <NefryIFTTT.h>

#define EVENT "ponponpain"
#define SECRET_KEY "シークレットキーを書く"

void setup() {
  
}

void loop() {
  if(Nefry.readSW()){
    IFTTT.send(EVENT,SECRET_KEY);
  }
}

これだけ。

まずは、イベント名とシークレットキーを定数として宣言します。シークレットキーはIFTTTのWebhooksの設定画面から調べることができます。URLの後ろの部分が、シークレットキーです。

Nefry BTとIFTTTライブラリをつかってお腹が痛くなった時に押すボタンを作る

そして、ボタンの押下検知ですが、Nefry.readSW()で取得できます。これがTrueになったときはボタンが押されたときなので、IF分の条件式にしています。本当はボタンのチャタリング等の制御を入れたほうが良いかもしれませんが、面倒なので入れてません。

また、IFTTTのトリガーを発火させるのも、IFTTT.send(EVENT,SECRET_KEY);の一文でできてしまいます・・・。良い世の中になったものです。これでコーディング終了。

ponponpainと叫んでみる

あとは、Nefry BTを動作させて、ボタンを押すだけ。

Nefry BTとIFTTTライブラリをつかってお腹が痛くなった時に押すボタンを作る

ボタンを押して暫く経つと・・・

Nefry BTとIFTTTライブラリをつかってお腹が痛くなった時に押すボタンを作る

はい。ちゃんとponponpainが表示されています。ワンタッチでツイートができるようになったので、これで心置きなくトイレに行くことができます。

初めてのハンズオン会開催とNefry BTの良さみ

私事ですが。

Nefry BT ポキオ ハンズオン

初心者向けのIoTハンズオン会を開催しました

コンパスさんで募集。ショートノーティスでしたが、なんとか参加者が集まり開催しました。

dotstudio.connpass.com

togetter.com

初めてだったので色々ありました。

内容のレベルをどのくらいに設定すれば良いのか

これは悩んだ。IoTって結構フルスタック感あって、ハードの知識・ソフトの知識・あとやる気が必要。

結局ハンズオンではハードの部分は割り切りました。

  • 後述のNefry BTという開発ボードをフル活用
  • ボード単体で単体でRGBのLチカができるのでそれを利用
  • ハンズオン会でのはんだ付けやら配線やらをやるのは省略

ソフトも、さすがにその場でフルスクラッチでコードを書かせるのはアレだったので、ちょっと工夫しました。

  • 最終成果物のコードを要素ごとに分割して、1つずつ説明しながらコーディング
  • すべてコーディングするわけではなく、未完成のコードを渡して穴埋め方式にした(一部フルスクラッチでコーディング)
  • 穴埋めしてるそばで、分からない人向けにメインのスクリーンではライブコーディング

割り切る部分は割り切って、なんとか時間一杯の1.5時間に収めました。

資料をどう作れば良いのか

いままでLTというフィールドでしか戦ってこなかったので、どんなに恥をかいても5分耐えるだけでした。資料も25-30枚くらい用意して、10秒位で次のスライドへと遷移していくような、かなり忙しない感じのリズム感。そんな感じのスライドで1.5時間突っ走るのは無理なので、その辺を意識して書きました。また、途中で休憩のスライドを挟んで、想定通りの進行度合いかどうかを確かめられるようにしたり、工夫しました。

材料をどこで買えば良いのか・いつ加工すれば良いのか

そもそも、このハンズオンの出発点は、ダイソーで売ってるプチ電車シリーズのサイズ感がNefry BTにピッタリだったことから始まります。

その他の材料もダイソーとセリアで買えてしまうので、工作する人にとっていい時代になったと言わざるを得ません。ただ、大量のおもちゃをダイソーで購入するのには勇気がいるということをお伝えしておきたいです。

ただ、この大量の車両を、予め加工する必要があったのですが。流石に子どもたちが起きてる時間帯は危ないので加工はできず、結局真夜中に加工をしてました。大きな音を立てないように、静かに加工したり、音が出るようなリューターを使った加工は、風呂場にこもって加工をしました。今考えればシュールですね。

心残りなこと

兎に角、時間内に抑えるために、色々端折ってしまったので、参加者の「やった感」が少しミニマイズされてしまったのではないかと思うと、ちょっとアレです。とはいえ、あまり本質的でないことに、ハンズオンの時間を割くのも厳しいので ・・・難しいところです。

Nefry BT ポキオ ハンズオン

そういう意味では、コーディングの部分は参加者のレベルに応じて、色々なオプションをもたせたほうが良かったのかなと反省。今後のハンズオンでチューニングしていきたいです。

Nefry BTはハンズオンにもってこいのボードなのでは

今回のハンズオンではNefry BTを使いましたが、これが意外と良かったのかなと思ってます。

dotstud.io

ハンズオンのように、時間が限られているケースにおいて、

  • LEDが実装済み、ディスプレイに対応
  • 設定はWebブラウザからできる
  • 小さい
  • 複雑な処理をうまい具合にラップした関数が多く準備されている
  • Grove対応で、はんだ付けなしで拡張可能

こんな良さみがある開発ボードは、まさにうってつけ。

そして、開発者のわみさんにもハンズオンに友情出演して頂けたのも、非常に心強かった。ありがとうございました!

Nefry BT ポキオ ハンズオン

というわけで、参加していただいた方々、サポートしていただいた方々、みなさまありがとうございました。また機会があればハンズオンを開催します。IoT(というか電子工作)の楽しさをより多くの人に伝えられるように頑張ります。

Nefry BTにプログラムを書き込もうとした時に"A fatal error occurred: Failed to connect to ESP32: Timed out waiting for packet header"というエラーが出て泣きそうになった話

問題は解決しました。

Nefry BT

Nefry BTをお借りしてます

dotstud.io

初心者でも簡単に触れるIoTボード。Wi-FiとBLEが使えて夢が広がるわけなんですが、1箇所ハマったポイントがあるのでメモしておきます。

ハマったポイント

Arduino IDEでプログラムを書き込もうとしたら、

A fatal error occurred: Failed to connect to ESP32: Timed out waiting for packet header

こんなエラーが。 ぐぐってみると、プログラムを書き込むタイミングで、ボードが書き込みモードに遷移できていないことが原因っぽいです。

私の開発環境

やったこと

ターミナルで、カーネルエクステンションを確認しました。

kextstat | grep FTDI

すると、どうやらAppleの標準のFTDIのドライバしか入っていませんでした。こんな感じ。

  121    0 0xffffff7f811e7000 0x7000     0x7000     com.apple.driver.AppleUSBFTDI (1.0.1b16) <102 38 5 4 3>

そこで、FTDIのページからMac版のドライバをダウンロードして、インストール。

www.ftdichip.com

もう一度カーネルエクステンションを確認すると、ちゃんとFTDIが確認できます。(2つはいっている状態でも大丈夫なんでしょうか・・・)

  121    0 0xffffff7f811e7000 0x7000     0x7000     com.apple.driver.AppleUSBFTDI (1.0.1b16) <102 38 5 4 3>
  130    0 0xffffff7f829bf000 0x7000     0x7000     com.FTDI.driver.FTDIUSBSerialDriver (2.4.2) <102 38 5 4 3 1>

これでプログラムが書き込めるように!

準備されているライブラリのお陰で、RGB LEDの色指定も簡単だしログ出力も秒でできます。さーて、何を作ろうかな。

Amazon Dash Buttonが押されたらESP8266経由でIFTTTのWebhookを叩いて幸せになる

幸せになるんだ・・・!

Amazon Dash Button ESP8266 IFTTT Webhook

前回までの話

relativelayout.hatenablog.com

ESP8266はAP+STAモードで使えるということを確認しました。これはつまり、Amazon Dash Buttonの接続先をESP8266のAPにしてしまって、そのイベントを受けて、ESP8266(STA)が接続しているAP経由で、IFTTTを叩いて何かしてみようと思いました。

大切なことは、この辺に全部書いてあります。

qiita.com

relativelayout.hatenablog.com

まずはコーディング

基本的に、前回のコードに少し毛が生えたレベルです。ポイントは以下のとおりです。

  • Wi-Fiのイベントを受けて、ソースのデバイスMACアドレスを確認する
  • ターゲットのAmazon Dash Buttonと同じMACアドレスか比較する
  • 同じだったらWebAPIをPOSTしてIFTTTのWebhookを叩く
  • Wi-Fiのイベントは制限していないが、チャタるのでスリープを挟んでいる
  • STAの設定より前にAPの設定をすると、上手くAmazon Dash ButtonWi-Fiイベントを取得できないので、APの設定を最後に行う

こんな感じ。

#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>


extern "C" {
#include <user_interface.h>
}

#define AP_SSID "APのSSID"
#define AP_PW "APのPW"
#define SOFTAP_SSID "SOFT APのSSID"
#define SOFTAP_PW "SOFT APのPW"

// Dash ButtonのWi-Fi MACアドレス
uint8_t targetMac[6] = {255, 255, 255, 255, 255, 255};

// Dash Buttonを検知したらTrueに倒す
boolean isFound;

void ICACHE_FLASH_ATTR wifi_handle_event_cb(System_Event_t *evt) {
  uint8_t* foundMac = evt->event_info.ap_probereqrecved.mac;

  if (memcmp(foundMac, targetMac, sizeof(uint8_t) * 6) != 0) {
    return;
  }

  isFound = true;
}

void setup() {
  Serial.begin(115200);
  Serial.println("");

  // AP+STAモードの設定
  WiFi.mode(WIFI_AP_STA);

  // STAとして振る舞うための接続先APのSSIDとPW情報
  WiFi.begin(AP_SSID, AP_PW);

  // APへの接続完了待ち
  while (WiFi.status() != WL_CONNECTED) {
    delay(100);
    Serial.print(". ");
  }
  Serial.println("connected!");

  // APとして振る舞うためのSSIDとPW情報
  WiFi.softAP(SOFTAP_SSID, SOFTAP_PW);

  // Wi-Fiのイベントを受け取る
  wifi_set_event_handler_cb(wifi_handle_event_cb);
}

void loop() {
  if (isFound) {
    Serial.println("FOUND");
    doHttpPost();
    delay(3000); // チャタるので3秒位待つ
    isFound = false; // 最後にFalseに倒す
  }
}

// IFTTTにPOSTする
void doHttpPost() {
  HTTPClient http;

  // テキトーなJSON
  String json = "{\"value1\":\"" + String("test") + "\"}";

  http.begin("http://maker.ifttt.com/trigger/XXX/with/key/YYY");
  http.addHeader("Content-Type", "application/JSON");
  http.addHeader("Content-Length", String(json.length()));
  int httpCode =  http.POST(json);
  String result = http.getString();
  http.end();
  Serial.println(result);
}

Amazon Dash Buttonの設定

Amazon Dash ButtonにEPS8266のSSID/PWを覚えさせなければなりません。

皆さん御存知の通り、スマホアプリでAmazon Dash Buttonの設定を進めて、SSID/PWを設定し終わったらアプリを閉じればOK。…なんですが、ESP8266のAPはネットに接続できず、EPS8266のAPに接続しているAmazon Dash Buttonを完了させられないため、同じSSID/PWのAPを立てて設定だけさせる必要があります。

ボタンを押してみる

ボタンを押しても、たまに接続を検知できないケースもありますが、ほとんど検知出来ました。イベントは必ずしも1回とは限らず、2回呼ばれたり、もっとすごい回数呼ばれたりするので、SW的にチャタリングの制御は必要そうです。

今回は、IFTTTにHTTP-POSTしたあと、LINEにメッセージを送るように設定してみました。

Amazon Dash Button ESP8266 IFTTT Webhook

こんな感じ。ちゃんと動いてそうです。IFTTTのTriggerを叩ければ、その先はノンプログラミングで実装できるので、簡単にトリガーに対するアウトプットを変更することが出来ます。これで、かなり夢が広がりますね。

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

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