工作と競馬

電子工作、プログラミング、木工といった工作の記録記事、競馬に関する考察記事を掲載するブログ

概要

Androidで、NFCを読み取る簡単なアプリを作成し、動作を確認した。


背景と目的

AndroidのNFCを使ったアプリを作成したくなったので、手始めにタグ読み取る簡単なアプリを作成し、動作を確認してみる。


詳細

1.環境

私の環境は、

  • スマホ本体: SO-01J(当然、NFC対応)
  • OS: Android 7.0
  • 開発用PC: Windows 10、Android Studio 2.3.3
  • 読み取るタグ: 交通系カード(Suica等)

である。


2.コーディング

とりあえず、動けば何でもいいので手始めにタグのUIDを読み取るだけのアプリを作ることにする。

2.1 プロジェクト作成

新規プロジェクトHelloNFCを作成した。対応APIレベルは、以下の通りAndroid 5.0以降とした。

20170622222257

図2.1 Target Android Devices


2.2 マニュフェストファイル

次に、マニュフェストファイルを編集する。NFCを使うには、最低限、以下の記述が必要なので、追加した。

<uses-permission android:name="android.permission.NFC"/>


2.3 MainActivity

次に、MainActivityのプログラムを作成。短いのですべて載せる。

なお、すべてを理解しきれていないが、徐々に覚えればいいので、今回はメモするだけとする。

package com.example.takuya.hellonfc;

import android.app.PendingIntent;
import android.content.Intent;
import android.nfc.NfcAdapter;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;

import java.util.Arrays;

public class MainActivity extends AppCompatActivity {

    // アダプタを扱うための変数
    private NfcAdapter mNfcAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // アダプタのインスタンスを取得
        mNfcAdapter = android.nfc.NfcAdapter.getDefaultAdapter(this);

    }

    @Override
    protected void onResume(){

        super.onResume();

        // NFCがかざされたときの設定
        Intent intent = new Intent(this, this.getClass());
        intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
        // ほかのアプリを開かないようにする
        PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent, 0);
        mNfcAdapter.enableForegroundDispatch(this, pendingIntent, null, null);

    }

    @Override
    protected void onPause(){
        super.onPause();

        // Activityがバックグラウンドになったときは、受け取らない
        mNfcAdapter.disableForegroundDispatch(this);

    }

    @Override
    protected void onNewIntent(Intent intent){
        super.onNewIntent(intent);

        // NFCのUIDを取得
        byte[] uid = intent.getByteArrayExtra(NfcAdapter.EXTRA_ID);
        // 表示
        Toast.makeText(this, Arrays.toString(uid), Toast.LENGTH_SHORT).show();

    }

}


3.動作確認

以下のように、かざした結果UIDがちゃんと表示された。うまく動いたようだ。

BlogPaint

図3 動作した様子


まとめ

AndoridでNFCタグを読み取るアプリを作成できた。徐々に、役に立つアプリに仕上げていきたい。

概要

NASをラズベリーパイからアクセスできるようにするためのメモ。


背景と目的

NAS内のファイルにラズベリーパイからアクセスしたいので、設定する。


詳細

0.情報収集

手順は、以下などを参考にした。


1.マウント先ディレクトリを作成

sudo mkdir /mnt/nas


2.マウントする

次に、マウント。私の環境の場合、192.168.xxx.yyy/disk。ラズパイのrootのパスワードを聞かれるので、入力。

sudo mount -t cifs //NASのIPアドレス/ディレクトリ /mnt/nas -o iocharset=utf8

成功すれば、以下でディレクトリが列挙できる。

ls /mnt/nas


3.起動時に自動的にマウントする設定

こちらによれば、/etc/fstabは自動マウントのための設定ファイルなので、これに書き込めばよい。

sudo nano /etc/fstab

以下を書き込む。

//NASのIPアドレス/ディレクトリ /mnt/nas cifs username=xxxxx,password=xxxxx,file_mode=0755,dir_mode=0755,iocharset=utf8,uid=1000,gid=1000,forceuid,forcegid,_netdev 0 0

さらに、起動時にネットワーク接続される前にマウントしようとしても意味がないので、ネットワーク接続が完了してから起動するように、Raspberry Piの設定をする。

sudo raspi-config

で、3 Boot Options>B2 Wait for Network at Bootと進み、

BlogPaint

というように、Enableにする。

ここで、再起動して再度lsコマンドでディレクトリが列挙されれば起動時に自動マウントされている。


まとめ

NAS内のファイルにラズベリーパイからアクセスできるようになった。

概要

Switch ScienceのESP-WROOM-32ピッチ変換済みモジュールを使って、プログラムの書き込みと動作確認ができた。


背景と目的

Switch ScienceのESP-WROOM-32ピッチ変換済みモジュールを買ってみた。秋月電子が扱っている開発ボードは、すでに使用したがこちらは使用したことがないので、使い方を調べながらプログラムの書き込みと動作確認までしてみる。


詳細

1.使い方を調べる

このモジュールは、USBケーブルをつなぐだけのESP32-DevKitCとは異なり、ICのピンピッチを2.54mmに変換するだけなので、書き込みには、別途シリアル通信用の線をつないだり、電源をつなぐ必要がある。Web上でざっと調べたところ、

がとても役に立った。こちらを参考に、自分用に要点をまとめておく。


2.プログラム書き込みに必要な最低限の回路構成

接続が必要なのは、

  • 電源 = 3V3, GND
  • 書き込みモードへの切替用端子 = GPIO0, GPIO2, リセット端子EN
  • シリアル端子 RX, TX

の合計7つである。接続方法は、以下の図のとおり。

  • リセット端子は、当然スイッチを付ける。
  • GPIO0は、スイッチを付けると書き込みモードへの切り替え操作がしやすいので、つける。
  • GPIO2は、書き込み時はLOWにする必要がある。ここではあらかじめLOW固定だが、もし入力端子として使用する場合は、必要に応じてLOWにできる仕組み(スイッチやジャンパなど)をつけるとよい。
  • シリアル通信は、USBシリアル変換モジュール等への接続を想定。

回路図


3.プログラム作成

プログラムは、以前作成したArudino-espでも、esp-idfいずれでもよい。ESP32-DevKitCと同様の手順でよい。


4.プログラム書き込み

プログラムを書き込むには、書き込みモードへの切り替え操作として、

  • GPIO0ボタンを押しながら、ENボタンを押す
  • ENボタンを離してから、GPIOボタンを離す

という2手順が必要。

Arduino、ESP-IDFいずれの場合も、書き込む前に上記操作を行えばよいが、もしやらずに書き込みを実行しても、モードへの切り替え待ちになるので、そのときに実行すればよい。ただし、タイムアウトはあるようなので、先にやっておくのが無難。


5.動作確認

というわけで、上記手順により、正しく書き込みができた。


まとめ

Switch ScienceのESP-WROOM-32ピッチ変換済みモジュールを使って、プログラムの書き込みと動作確認ができた。このモジュールは、とても安く手に入り、2.54mmピッチなのでとても工作に便利。積極的に使っていきたい。

概要

ESP-WROOM-32で、AWS IoTにデータをパブリッシュしてみた。


背景と目的

ESP-IDFのサンプルには、AWS IoTとの通信プログラムがある。ESP32でセンサ等の測定値を素早くクラウド上に送信するのにちょうどよさそうだ。そこで、サンプルを使ってAWS IoTにデータ送信してみる。


詳細

1.やること

今回は、ESP-IDFのサンプルexamples/protocols/aws-iot/subscribe_publishをそのまま動かす。1秒ごとにパブリッシュするという動作をする。README.mdに一通りやり方が書いてあるのでそれを参考に進める。


2.AWS IoTでThingを作成

AWSのコンソールで、動作確認用にThingを作成。Thing名はESP32Testとした。また、Security>Create certificate ボタンにて、certificateを作成し、xxx.private.pem.keyとxxx.certificate.pem.crtをダウンロードした。また、aws-root-caファイルもダウンロードしてサンプルにあるaws-root-ca.pemと置き換えた。それと、以下の2つを忘れないようにする必要がある。

  • certificateをActivateする。
  • certificateにpolicyをアタッチする。ポリシーは、以下で十分。
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "iot:Publish",
        "iot:Subscribe",
        "iot:Connect",
        "iot:Receive"
      ],
      "Effect": "Allow",
      "Resource": [
        "*"
      ]
    }
  ]
}

これで、Thingの準備はOK。


3.Private KeyとCertificateの組み込み

組み込み方法は、ここによれば2通りがあるが、今回は、"Option 1: Embedded Key & Cert into App Binary"という方法に従う。

このサンプルのmainというフォルダの下にさらにcertsというフォルダがあるので、そこで2.でダウンロードした2つのファイルをそれぞれprivate.pem.key、certificate.pem.crtという名前に変更して配置する。

これで、必要なファイルの組み込みができた。


4.AWS IoTとの通信に必要な設定の記述

subscribe_publish_sample.cを開き、いくつか編集していく。

4.1 WiFiの設定

本筋と関係はないが、忘れないように。ESP32をWiFiに接続しないと始まらないので、56,57行目のSSIDとパスワード設定を忘れない。

#define EXAMPLE_WIFI_SSID "SSID名"
#define EXAMPLE_WIFI_PASS "パスワード"
4.2 トピックの設定

248行目のTOPICという定数を編集すればよい。ここでは、"test_topic/esp32"をそのまま使う。

4.3 送信したいデータを設定

そして、送信したいデータは、cPayloadという文字配列が用意されており258行目のsprintf文で文字を書き込んでいるので適宜編集する。ここでは、"Hello from SDK : {経過秒数}"という表記をそのまま使う。

sprintf(cPayload, "%s", "送信したい文字列など");

ここまでで、ソースコードの編集は完了。


5.ビルド設定とビルド

make menuconfigにて、AWS IoTに関わる2つの設定を行う。

  • Component config > Amazon Web Services IoT Platform > AWS IoT Endpoint Hostnameを選択し、2.で作成したThingのコンソール > Interactに表示されているHTTPS Endpoint名(xyz.iot.{リージョン名}.amazonaws.com)を書き込む。(なお、この設定はesp-idf/components/aws-iot/include/aws-iot-config.hに直接書き込んでもできるらしいが、ライブラリを直接編集するのも微妙なので、ここではやらない)
  • Example Configuration > AWS IoT Client IDに使用するThing名(ここではESP32Test)を指定する。

そして、make flashでビルド&書き込みをする。

20170516212557

図5.1 エンドポイントを設定


6.動作確認

シリアルコンソールのログは、以下の通り。1秒ごとにパブリッシュされている。

20170516220930

図6.1 パブリッシュしている様子

また、AWS IoTコンソールのTestメニューにて、"test_topic/esp32"トピックをサブスクライブしてみると、データが到着している。

20170516220923

図6.2 パブリッシュされたのが到着した様子

というわけで、正しく動作させることができた。


まとめ

ESP-WROOM-32で、AWS IoTにデータをパブリッシュできた。

概要

esp-idfのプロジェクトにarduino-esp32を組み込んで使用したところ、Wi-Fiが繋がらずハマったので注意点をメモする。


背景と目的

前回、ESP-WROOM-32からAWS IoTへパブリッシュすることができたが、同プロジェクトにarduino-esp32をコンポーネントとして組み込めば、Arduinoで作成したプログラムを、AWS IoTへの送信ができるはずである。しかし、実際にやってみたところ、Wi-Fiが繋がらず困ったので解決方法について、メモしておく。


詳細

1.症状

まず、arduino-esp32を組み込んだ場合のapp_main関数は、initArduino関数を一番初めに呼ぶ。しかし、これを入れると、Wi-Fi接続ができなくなってしまった。どうやら、initArduinoを呼ぶことで、initialize_wifi関数での処理がうまくいかなくなるようだった。

extern "C" void app_main()
{
    // Arduino初期化
    initArduino();
    
    // WiFiの初期化
    initialise_wifi();

#ifdef CONFIG_MBEDTLS_DEBUG
    const size_t stack_size = 36*1024;
#else
    const size_t stack_size = 36*1024;
#endif
    xTaskCreatePinnedToCore(&aws_iot_task, "aws_iot_task", stack_size, NULL, 5, NULL, 1);
}

2.initialze_wifi関数内で、WiFi.begin()を行えばよい

結局、試行錯誤した結果、

  • initialise_wifi関数内の4行目以降を削除し、ArduinoのWiFi.beginを呼ぶ

ことで、解決できた。

// 変更後
#include "WiFi.h" // インクルード必要

:

// 変更対象の関数
static void initialise_wifi(void)
{
    tcpip_adapter_init();
    wifi_event_group = xEventGroupCreate();
    ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) );
    WiFi.begin(ssid, password);
}


まとめ

esp-idfのプロジェクトにarduino-esp32を組み込んで使用したときにWi-Fiが繋がらない問題を解決できた。

このページのトップヘ