「君たちはどう生きるか」の自分勝手考察 【ネタバレ注意】

自分勝手考察

眞人 宮崎吾朗
アオサギ 鈴木敏夫
大叔父 宮崎駿
降ってきた塔 ジブリスタジオ
インコ/インコ王 商売のことしか頭にない広告代理店
ペリカン/老ペリカン AI処理
わらわら ジブリの新人(アニメーターの卵)
13個の積み木 宮崎駿が手がけてきた作品


若いときアニメの世界に行ったきりで戻らなくなった宮崎駿が積み木を積んで作った世界(ジブリ)。
13作目にして世界は限界に達し、息子の吾朗に跡継ぎを期待するも良い回答は得られない。
そこに現れたインコ大王「アニメなんて適当に作ればいいんだよ」と積み始め、世界ごと崩れ落ちる。


作画がAI処理に変わりゆく過程で、不要になっていくアニメーターの卵たち


ジブリが崩れ始めている暗示に感じた。

ダイソー Bluetooth モバイルシャッターに特化したライブラリ

2022/05/31 08:58
大バグを修正して再掲しました。


DaisoBleButton.hpp

#ifndef _DAISO_BLE_BUTTON_HPP_
#define _DAISO_BLE_BUTTON_HPP_

#include <NimBLEDevice.h>
#include <nvs.h>
#include <functional>
#include <map>

static const char * nvs_name = "DaisoBleButton";
static const char * allow_devices [] = {"AB Shutter3"};
static const NimBLEUUID uuid_service((uint16_t)0x1812);
static const NimBLEUUID uuid_characteristic((uint16_t)0x2a4d);

class DaisoBleButton {
  public:
    static int begin() {
      NimBLEDevice::init("");

      uint8_t devCount = 0;
      uint32_t nvs_handle;
      if(!nvs_open(nvs_name, NVS_READONLY, &nvs_handle)) {
        for(;;devCount++) {
          char key[3];  //, buf[20];
          sprintf(key, "%02u", devCount);
          uint64_t address;
          if(nvs_get_u64(nvs_handle, key, &address))
            break;
      
          auto pClient = NimBLEDevice::createClient(NimBLEAddress(address));
          if(pClient) {
            pClient->setConnectTimeout(1);
            buttons[pClient] = new DaisoBleButton(devCount, pClient);
          }
        }
      }
      nvs_close(nvs_handle);
      return devCount;
    }
    
    static int paring(const int period = 10) {
      auto pClients = NimBLEDevice::getClientList();
      for(auto pClient : *pClients)
        pClient->disconnect();
    
      auto pBLEScan = NimBLEDevice::getScan();
      pBLEScan->setActiveScan(true);
    
      Serial.println("paring mode. wait 10 secs..");
      auto pScanResults = pBLEScan->start(period);
    
      int devCount = 0;
      uint32_t nvs_handle;
      if(!nvs_open(nvs_name, NVS_READWRITE, &nvs_handle)) {
        for (int i = 0; i < pScanResults.getCount(); i++) {
          auto advertisedDevice = pScanResults.getDevice(i);
          Serial.print("Found Device ");
          Serial.println(advertisedDevice.getName().c_str());
          for(auto allow : allow_devices) {
            if (!strncmp(advertisedDevice.getName().c_str(), allow, strlen(allow)) && advertisedDevice.haveServiceUUID())  {
              auto pClient = NimBLEDevice::createClient(advertisedDevice.getAddress());
              if(pClient && pClient->connect()) {
                if(!devCount)
                  nvs_erase_all(nvs_handle);
      
                uint64_t address = advertisedDevice.getAddress();
                char key[3];
                sprintf(key, "%02d", devCount);
                nvs_set_u64(nvs_handle, key, address);
                Serial.printf("added to list[%d]: %llu %s", devCount, address, advertisedDevice.getAddress().toString().c_str());
                Serial.println();
                devCount ++;
                pClient->disconnect();
                break;
              }
            }
          }
        }
      }  
    
      nvs_close(nvs_handle);
      return devCount;
    }

    static void handle() {
      auto pClients = NimBLEDevice::getClientList();
      for (auto pClient : *pClients) {
        if(pClient && !pClient->isConnected() && pClient->connect()) {
          pClient->getServices(true);
          auto pService = pClient->getService(uuid_service);
          auto pCharacteristics = pService->getCharacteristics(true);
          for (auto pCharacteristic : *pCharacteristics) {
            if(uuid_characteristic.equals(pCharacteristic->getUUID())) {
              pCharacteristic->subscribe(false,
                [](BLERemoteCharacteristic* pRemoteCharacteristic, uint8_t* pData, size_t length, bool isNotify) {
                  buttons[pRemoteCharacteristic->getRemoteService()->getClient()]->subscribe(pRemoteCharacteristic, pData, length, isNotify);
                }
              );
            }
          }
        }
      }
    }

    static std::function<void(DaisoBleButton *)> onClick_A;
    static std::function<void(DaisoBleButton *)> onClick_B;
    
  private:
    static std::map<NimBLEClient *, DaisoBleButton *> buttons;

    
  public:
    uint8_t getId() {return id;}
    NimBLEAddress getAddress() {return bleClient->getPeerAddress();}

  private:
    DaisoBleButton(uint8_t _id, NimBLEClient * _bleClient) : id(_id), bleClient(_bleClient) {;}
    
    void subscribe(BLERemoteCharacteristic* pRemoteCharacteristic, uint8_t* pData, size_t length, bool isNotify) {
      if(length == 2 && (pData[0] || pData[1])) {
        if(pData[0] == 0x01 && pData[1] == 0x00) {
          if(last_value[0] == 0x00 && last_value[1] == 0x28) {
            if(onClick_B)
              onClick_B(this);
          }
          else {
            if(onClick_A)
              onClick_A(this);
          }
        }
        last_value[0] = pData[0];
        last_value[1] = pData[1];
      }
    }
  
  private:
    NimBLEClient * bleClient;
    uint8_t last_value[2] = {0x00, 0x00};
    uint8_t id;
};

std::function<void(DaisoBleButton *)> DaisoBleButton :: onClick_A = nullptr;
std::function<void(DaisoBleButton *)> DaisoBleButton :: onClick_B = nullptr;
std::map<NimBLEClient *, DaisoBleButton *> DaisoBleButton :: buttons;

#endif


使用例

/*
 * ダイソーモバイルシャッターリモコン
 *
 * IO0: HIGH→LOW/ペアリングモードに入り、10秒間の間に接続成功したデバイスを保存する
 */
 
#include "DaisoBleButton.hpp"

void setup() {
  Serial.begin(115200);
  pinMode(0, INPUT_PULLUP);

  DaisoBleButton::onClick_A = [] (DaisoBleButton * button) {
    Serial.println("button A");
  };

  DaisoBleButton::onClick_B = [] (DaisoBleButton * button) {
    Serial.println("button B");
  };
  
  if(!DaisoBleButton::begin()) {
    DaisoBleButton::paring();
    ESP.restart();
  }
}

void loop() {
  DaisoBleButton::handle();
  
  if(digitalRead(0) == LOW && DaisoBleButton::paring() > 0)
    ESP.restart();

  delay(1);
}

 ペアリングモード(デフォルト10秒間)の間に接続された ダイソーモバイルシャッター の情報を NVS に記録し、次回からはその接続のみを受け付けます。
 GPIO0 を押すと改めてペアリングモードに入り、ペアを登録し直すことが出来ます。
 ESP32-DevBoard 以外の、例えば M5Stack 等では GPIO0 ではなく備わってる物理スイッチに変更するといいでしょう。