工作と競馬

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

概要

ESP-WROOM-32で、プログラムを書き込む容量を増やす方法をまとめた。


背景と目的

ESP-WROOM-32で、あるプログラムを書き込もうとしたところ、以下のように

"最大1310720バイトのフラッシュメモリのうち、スケッチが1333771バイト(101%)を使っています。"

と表示され書き込みができなかった。そこで、容量を増やす方法について調べ、実際に増やしてみる。


詳細

0.方法を知る

Web各所で情報を探し回ったところ、

などがあったが、いろいろ試行錯誤した結果、結論から言うと、以下の2手順が必要ということがわかった。

  • tools/partitions/default.csvの編集
  • boards.txtの編集

ということで、以下順に行う。


1.tools/partitions/default.csvの編集

default.csvを開くと、以下のような記述が出てくる。

# Name,   Type, SubType, Offset,  Size, Flags
nvs,      data, nvs,     0x9000,  0x5000,
otadata,  data, ota,     0xe000,  0x2000,
app0,     app,  ota_0,   0x10000, 0x140000,
app1,     app,  ota_1,   0x150000,0x140000,
eeprom,   data, 0x99,    0x290000,0x1000,
spiffs,   data, spiffs,  0x291000,0x16F000,

app0からspiffsという4行分を編集する。プログラム書き込み領域を0x20000 = 131072byte増加させることにすると、

# Name,   Type, SubType, Offset,  Size, Flags
nvs,      data, nvs,     0x9000,  0x5000,
otadata,  data, ota,     0xe000,  0x2000,
app0,     app,  ota_0,   0x10000, 0x160000,
app1,     app,  ota_1,   0x170000,0x160000,
eeprom,   data, 0x99,    0x2D0000,0x1000,
spiffs,   data, spiffs,  0x2D1000,0x12F000,

という感じで、app0とapp1のsizeを0x20000増やし、spiffsのsizeは0x40000減らす。また、app1、eeprom、spiffsのoffsetをそれぞれ0x20000だけずらせばよい。


2.boards.txtの編集

arduino-esp32のrootにあるboards.txtを開くと、10行目くらいにある

esp32.upload.maximum_size=1310720

という記述がある。書き込み時に

"最大1310720バイトのフラッシュメモリのうち、・・・"

の数値だ。これを所望のサイズに変更する。今回は、先ほどpartitions/default.csvで0x20000 = 131072byte増加させたので、こちらも同様に1310720 + 131072となるように変更。

esp32.upload.maximum_size=1441792

3.動作確認

上記の作業をして、プログラム書き込みを行ったところ、以下のように最大サイズが変更され、以前収容できなかったプログラムを書き込むことができた。というわけで成功。

最大1441792バイトのフラッシュメモリのうち、スケッチが1333771バイト(92%)を使っています。


まとめ

ESP-WROOM-32で、プログラムを書き込む容量を増やすことができた。

概要

arduino-esp32を使って、ESP-WROOM-32でiBeaconをスキャンすることができた。


背景と目的

以前、esp-idfを使ってiBeaconをスキャンできたが、Arduino用SDKのarduino-esp32では難しかった。しかし、最新版では、BLE_scanというサンプルコードが追加されており、これを使えばiBeaconのスキャンができそうだ。なので、やってみる。


詳細

1.方針

2017/10/14時点でarduino-esp32には、どうやらNeil Kolbanさんという人が親切にも作ってくれたESP32_BLE_Arduinoというサンプルが含まれているようなので、ありがたく使用させていただく。BLE_scanというサンプルコードは、BLEデバイスをスキャンしてアドバタイジングデータを取得できるようなので、iBeaconだけを検出するようにちょっと変更してみる。


2.コーディング

2.1 iBeaconを扱うクラス

まず、iBeaconを扱うための処理をまとめておいたほうがいいと思ったので、BLEAdvertisedDeviceという型の変数を受け取って、iBeaconか判断し、iBeaconであれば、uuid、major、minor、rssiを読み取って保持するクラスを作成。細かい処理はlibraries\BLE\src\BLEAdvertisedDevice.cppあたりを参考にした。

// iBeaconを扱うクラス
class iBeacon
{
private:
  String uuid;
  uint16_t major;
  uint16_t minor;
  int rssi;
public:
  bool createByAdvertisedDevice(BLEAdvertisedDevice advertisedDevice); // BLEAdvertisedDeviceからデータを組み立てる
  String getUUID() { return uuid; }
  uint16_t getMajor() { return major; }
  uint16_t getMinor() { return minor; }
  int getRSSI() { return rssi; }
};

// BLEAdvertisedDeviceからデータを組み立てる
bool iBeacon::createByAdvertisedDevice(BLEAdvertisedDevice advertisedDevice) {

  char work[7];
  
  // 16進データをもらう
  String hexString = (String) BLEUtils::buildHexData(nullptr, (uint8_t*)advertisedDevice.getManufacturerData().data(), advertisedDevice.getManufacturerData().length());
  // iBeaconかチェック
  if (hexString.substring(0, 8).equals("4c000215")) {
    // iBeaconのとき
    uuid =  hexString.substring(8, 16) + "-" + 
            hexString.substring(16, 20) + "-" + 
            hexString.substring(20, 24) + "-" + 
            hexString.substring(24, 28) + "-" + 
            hexString.substring(28, 40);  
    ("0x" + hexString.substring(40, 44)).toCharArray(work, 7);
    major = (uint16_t) atof(work);
    ("0x" + hexString.substring(44, 48)).toCharArray(work, 7);
    minor = (uint16_t) atof(work);
    rssi = advertisedDevice.getRSSI();
    return true;
  } else {
    // iBeaconじゃないとき
    return false;
  }
}
2.2 Arduinoプログラム

次に、サンプルを上記のiBeaconクラスを使って修正。uuid、major、minor、rssiをシリアルに出力する。

#include "BLEDevice.h"
#include "BLEUtils.h"
#include "BLEScan.h"
#include "BLEAdvertisedDevice.h"

int scanTime = 2; //In seconds

/*
ここに、上記のiBeaconクラスを記述
*/

BLEScan* pBLEScan;

class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
    void onResult(BLEAdvertisedDevice advertisedDevice) {
      // アドバタイジングデータを受け取ったとき
      iBeacon ibcn;      
      if (ibcn.createByAdvertisedDevice(advertisedDevice)) {
        char uuid[37];
        ibcn.getUUID().toCharArray(uuid, 37);
        Serial.printf("UUID: %s, Major: %d, Minor: %d, RSSI: %d \n", uuid, ibcn.getMajor(), ibcn.getMinor(), ibcn.getRSSI());
      }
    }
};

void setup() {
  Serial.begin(115200);
  BLEDevice::init("");
  pBLEScan = BLEDevice::getScan(); //create new scan
  pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
  pBLEScan->setActiveScan(true); //active scan uses more power, but get results faster
}

void loop() {
  BLEScanResults foundDevices = pBLEScan->start(scanTime);
}

3.動作確認

上記のプログラムを動かしてみたところ、以下のようになった。ちゃんとiBeaconを検出できている。が、フラッシュメモリをかなり消費する。これはもともとのサンプル自体が大きいためだ。なので、メモリ不足に注意が必要。

UUID: 00000000-1ae9-1001-b000-001c4d6465e, Minor: 1, Minor: 4, RSSI: -66

まとめ

arduino-esp32を使って、ESP-WROOM-32でiBeaconをスキャンすることができた。esp-idfを使わないで済む場面がまた1つ増えてよかった。

概要

google-home-notifierというjavascriptプログラムをPC上で走らせ、同じLAN内にあるGoogle Homeにしゃべらせることができた。


背景と目的

以前、IFTTTでGoogle Homeと家電を連携させてみたのだが、今度はしゃべらせたくなった。そこで、しゃべらせてみる。


詳細

0.方法の調査

Web上で調べたところ、こちらこちらなどにあるように、google-home-notifierというjavascriptプログラムを使ってしゃべらせることができることがわかった。そこで、私の環境でもgoogle-home-notifierを使って試してみる。


1.セットアップ

1.0 方法
  • Windows10 PCを使用
  • PCにnode.js(v8.9.1)は入っている
  • PCと同じLAN内にGoogle Homeが接続されている


1.1 VCBuild.exeのインストール

まず、こちらを参考に、

npm install -g windows-build-tools

でインストール。このとき、コマンドプロンプトを管理者権限で起動することを忘れないこと。


1.2 node-gypのインストール(必要に応じて)

私の環境の場合、binding.gypがない旨のエラーが出たので、インストールした。

npm install -g node-gyp


1.3 bonjour SDKのインストール(必要に応じて)

私の環境の場合、AppleのBonjour SDKのdns_sd.hというファイルがない旨のエラーが出たので、こちらを参考に、インストールした。

具体的には、

  • Apple DeveloperサイトにApple IDでサインインし、Bonjour SDKをダウンロード。
  • インストーラを起動してインストール。
  • コントロールパネルから環境変数の編集を開き、ユーザー環境変数にBONJOUR_SDK_HOMEを追加。値は、C:\Program Files\Bonjour SDKとする。

という手順。なお、コマンドプロンプトを再起動してから1.4に進むこと。


1.4 google-home-notifierのインストール

次に、以下のコマンドでgoogle-home-notifierインストール。

npm install google-home-notifier


2.google-home-notifierを使ったプログラムを作成

こちらを参考に、こんにちはを言わせるプログラムを作成。GoogleHomeのIPアドレスは、Wi-Fiルータの管理画面等で調べておくこと。

var googlehome = require('google-home-notifier');
var language = 'ja';

// IPアドレスの設定
googlehome.device('Google Home', language).accent(language).ip('xxx.xxx.xxx.xxx');

// しゃべらせる
googlehome.notify('こんにちは', function(res) {
  console.log(res);
});

3.動作確認

上記をnodeで実行したところ、

ディロン!...こんにちは。

としゃべった。というわけで、成功だ。ただし、ディロンからは1秒くらい間が開く。

外部からのリクエストでしゃべらせるためには、こちらなどにあるとおり、ローカルHTTPサーバーを外部に公開することになるが、MQTTクライアント(AWSのAWS IoTなど)を動作させるという手もある気がする。

まとめ

Google Homeをしゃべらせることができた。

概要

Microsoft Flowを使って、JSONデータを受け取り、Excelに記録するフローを作成し、動作を確認した。


背景と目的

最近、Microsoft Flowというサービスを使い始めた。これは、IFTTTのMicrosoft版という感じだが、かなり自由度高くフローを組み立てることができそうに見える。とりあえず、お試しで、JSONデータを受け取り、記録するだけというフローを作って試してみる。


詳細

0.仕様

仕様は以下とする。

  • JSONデータをPOSTリクエストで受け取る
  • 受け取ったデータとタイムスタンプを、Excelファイルに記録


1.Microsoft Flowの設定

1.1 トリガの設定

"要求" コネクタの"HTTP要求の受信時"トリガを選択。

20171122235316

次に、要求本文の JSON スキーマとして、以下を設定。要するに、受け取ったJSONをそのまま。

{
    "type": "object"
}

そして、メソッドは、POSTとした。

設定が終わったのが、以下。

20171122235244


1.2 アクションの設定

まず、ExcelファイルとしてOneDriveの適当なフォルダに、test.xlsxというファイルを作成した。そして、Sheet1のA1:B1をテーブルとして定義した。

次に、Flowの画面にて、ExcelコネクタのInsert Rowアクションを選択。具体的には、以下のように設定。

aaaaa

ここまでで、Flowの設定はOK。

2.動作テスト用スクリプト

以下のように、POSTリクエストを送るコードをPythonにて作成した。Content-Typeヘッダとしてapplication/jsonを忘れないこと。

# coding: utf-8

import requests
import json
import pprint

if __name__ == "__main__":

    body = {
        "param1": "value1"
    }

    url = "要求トリガのHTTP POSTのURLという欄に表示されているURL"

    response = requests.post(url, data=json.dumps(body), headers={'Content-Type': 'application/json'})

    pprint.pprint(response.json())

3.動作テスト

上記スクリプトを実行したところ、正しくフローが発動し、Excelファイルに以下のように書き込まれた。成功だ。

20171123000420

まとめ

Microsoft Flowを使って、JSONデータを受け取り、Excelに記録するフローを作成し、動作を確認した。IFTTTよりもカスタマイズ性が高いので、IoT的にも重宝するのではないかと思う。

概要

Sphinxで、コードサンプルのシンタックスハイライトをさせる方法を知らべ、動作を確認した。


背景と目的

Sphinxで、コードサンプルのシンタックスハイライトがしたくなった。


詳細

0.方法の調査

こちらによれば、Pygmentsというものをインストールし、RestructuredTextのソース内にディレクティブを記述すればよいようだ。


1.Pygmentsのインストール

Pygmentsに従いインストールのつもりだったが、私の環境にはすでに入っていた。インストールする場合は、以下。

pip install Pygments


2.ディレクティブの記述

以下のように、highlightディレクティブをコードブロック(2連コロン)の行の前に書いておけばよい。言語は、ディレクティブの後ろに、"c"などと書けばOK。以下は、Arduinoの例。

.. highlight:: c

::

    // 定数
    const int GPIO_LED = 12; // LEDを接続するGPIOポート番号
    const int CYCLE_IN_MSEC = 1000; // 点滅周期

    void setup() {
        // GPIOポートの設定
        pinMode(GPIO_LED, OUTPUT); // GPIO_LED番ポートを出力に設定
    }

    void loop() {
        // 点滅
        digitalWrite(GPIO_LED, HIGH) // HIGHで点灯
        delay(CYCLE_IN_MSEC / 2); // 半周期待つ
        digitalWrite(GPIO_LED, LOW); // LOWで消灯
        delay(CYCLE_IN_MSEC / 2); // 半周期待つ
    }

なお、サポートされている言語は、こちらを参照。(HTML、javascript、C/C++、MATLAB、javaあたりがあるので個人的には十分。)


3.動作確認

実際に、記述してコンパイルしてみた結果が以下。ちゃんとハイライトされている。

  • ハイライトがある場合

20171101003749

  • ハイライトがない場合

20171101003812

まとめ

Sphinxで、コードサンプルのシンタックスハイライトをさせる方法を知らべ、動作を確認できた。

このページのトップヘ