NefryBTとTouchDesignerをMQTTでつなげてみた。

![スクリーンショット 2018-08-12 21.28.53.png](https://qiita-image-store.s3.amazonaws.com/0/72479/81cf0647-9902-e2df-58d8-be8f97090323.png)

<A HREF="https://qiita.com/kitazaki/items/c298f6be83cb7bc0cc49">前回</A> は ESP8266 へボリューム抵抗を接続して AD 変換で取得した値を MQTT Broker 経由でTouchDesigner と連携させてみた。
今回はこれを拡張し、NefryBT へボリューム抵抗 x 1 (回転軸として)、スライド抵抗 x 2 (X軸、Y軸として) を接続して AD 変換で取得した値を MQTT Broker 経由で TouchDesigner と連携させてみる。

## 構成・配線図
![スクリーンショット 2018-08-12 22.20.18.png](https://qiita-image-store.s3.amazonaws.com/0/72479/336ac4e0-62dc-8fba-9f98-23e510f1805e.png)

NefryBT に搭載されている ESP32 の AD 変換機能 (ADC) は 0 〜 3.3V の電圧を 0 〜 4,095 の数値に変換する。ESP32 には 2 系統の ADC (ADC1、ADC2) があり、ADC が使用できる GPIO ピンは決まっている。また、Wi-Fi 機能を使用しているときは ADC2 を使用できないという制限がある。
したがって、今回は NefryBT (無印) を使用して、Wi-Fi へ接続して MQTT 経由で TouchDesigner と連携させるため、A2、A3、A7 が使用できることになる。
<A HREF="https://poche-magique.com/2018/05/02/nefrybt_grove_rotaryanglesensor2/">(参考: [Nefry BTとGrove接続実験] ボリューム)</A>

- 回転軸: A2 と Grove ボリューム を Grove ケーブルで接続する。
- X軸: A3 と Grove スライドボリューム を Grove - ジャンパーケーブルで接続する。
- Y軸: A7 と Grove スライドボリューム を Grove - ジャンパーケーブルで接続する。

### 配置 
![全体図.png](https://qiita-image-store.s3.amazonaws.com/0/72479/1069d097-7958-3f29-56d0-2678f5b0bbb4.png)

### MQTT Broker
<A HREF="https://qiita.com/kitazaki/items/c298f6be83cb7bc0cc49">前回</A> を参考。

### TouchDesigner
<A HREF="https://qiita.com/kitazaki/items/c298f6be83cb7bc0cc49">前回</A> を参考。入力チャネルを 3 つ (回転軸、X軸、Y軸) に拡張する。
![TouchDesigner.png](https://qiita-image-store.s3.amazonaws.com/0/72479/4060707d-0d3b-58f5-2b00-c8908d810590.png)

## ソースコード
TouchDesigner のサンプルファイルは <A HREF="https://github.com/kitazaki/TouchDesigner_MQTT_Client_DAT/blob/master/MQTT_test_02.toe">こちら</A> 。

NefryBT のサンプルコードは <A HREF"https://github.com/kitazaki/TouchDesigner_MQTT_Client_DAT/blob/master/NefryBT_Rotary_and_Slide_Volume_Resistance_MQTT_01.ino">こちら</A> 。

```c:NefryBT_Rotary_and_Slide_Volume_Resistance_MQTT_01.ino
#include <Nefry.h>
#include <NefryDisplay.h>
#include <NefrySetting.h>
#include <WiFiClient.h>
#include <PubSubClient.h>
#include <misakiUTF16.h>

void setting(){
  Nefry.disableDisplayStatus();
}

NefrySetting nefrySetting(setting);

void misakiPrint(int x, int y, char * pUTF8) {
  int n=0;
  byte buf[20][8];  //160x8ドットのバナー表示パターン
  while(*pUTF8)
    pUTF8 = getFontData(&buf[n++][0], pUTF8);  // フォントデータの取得

  // 文字の描画
  for (byte i=0; i < 8; i++) {
    for (byte j=0; j < n; j++) {
      for (byte k=0; k<8;k++) {
        if(bitRead(buf[j][i],7-k)) {
          NefryDisplay.setPixel(x + 8*j + k , y + i);
        }
      }
    }
  }
}

// MQTT settings
byte ip[] = {192, 168, 2, 1};  // MQTT IP address
const char *mqtt_topic1 = "/pishield/chan5"; // MQTT Topic (chan5 = rotation)
const char *mqtt_topic2 = "/pishield/chan6"; // MQTT Topic (chan6 = x-axis slider)
const char *mqtt_topic3 = "/pishield/chan7"; // MQTT Topic (chan6 = y-axis slider)
const char *mqtt_client = "NefryBT_MQTT_Client" "_" __DATE__ "_" __TIME__;  // MQTT ClientID

void callback(char* topic, byte* payload, unsigned int length) {
  // handle message arrived
}

WiFiClient wclient;
PubSubClient client(ip, 1883, callback, wclient);

const int PIN1 = A2;
const int PIN2 = A3;
const int PIN3 = A7;
int val1 = 0;
int val2 = 0;
int val3 = 0;
char buf[10];

void displayResistanceInfo() {
  int val;
  int f_update = 0;
  val = analogRead(PIN1);
  if (abs(val - val1) > 20) {
    val1 = val;
    // normalize: Y = (X - Xmin) / (Xmax - Xmin) => 0 - 1
    float f_val1 = float(val1) / 4096;
    char s_val1[8];
    dtostrf(f_val1, 2, 5, s_val1);
    Serial.println("Publishing: Val1: " + String(val1) + ", " + s_val1);
    client.publish(mqtt_topic1, s_val1);
    f_update++;
  }
  val = analogRead(PIN2);
  if (abs(val - val2) > 20) {
    val2 = val;
    // normalize: Y = (X - Xmin) / (Xmax - Xmin) => 0 - 1
    float f_val2 = float(val2) / 4096;
    char s_val2[8];
    dtostrf(f_val2, 2, 5, s_val2);
    Serial.println("Publishing: Val2: " + String(val2) + ", " + s_val2);
    client.publish(mqtt_topic2, s_val2);
    f_update++;
  }
  val = analogRead(PIN3);
  if (abs(val - val3) > 20) {
    val3 = val;
    // normalize: Y = (X - Xmin) / (Xmax - Xmin) => 0 - 1
    float f_val3 = float(val3) / 4096;
    char s_val3[8];
    dtostrf(f_val3, 2, 5, s_val3);
    Serial.println("Publishing: Val3: " + String(val3) + ", " + s_val3);
    client.publish(mqtt_topic3, s_val3);
    f_update++;
  }
  if (f_update) {
    NefryDisplay.clear();
    NefryDisplay.setFont(ArialMT_Plain_24);
    misakiPrint(0,0, "ロータリ:");
    misakiPrint(0,20, "スライド1:");
    misakiPrint(0,40, "スライド2:");
    sprintf(buf, "%d", val1);
    NefryDisplay.drawString(50, 0, buf);
    sprintf(buf, "%d", val2);
    NefryDisplay.drawString(50, 20, buf);
    sprintf(buf, "%d", val3);
    NefryDisplay.drawString(50, 40, buf);
    NefryDisplay.display();
    Serial.print("val1: ");
    Serial.print(val1);
    Serial.print(",val2: ");
    Serial.print(val2);
    Serial.print(",val3: ");
    Serial.println(val3);
  }
}

void setup() {
  Serial.begin(115200);
  NefryDisplay.clear();
  NefryDisplay.setFont(ArialMT_Plain_24);
  misakiPrint(0,0, "ロータリ:");
  misakiPrint(0,20, "スライド1:");
  misakiPrint(0,40, "スライド2:");
  NefryDisplay.drawString(50, 0, "0");
  NefryDisplay.drawString(50, 20, "0");
  NefryDisplay.drawString(50, 40, "0");
  NefryDisplay.display();
  pinMode(PIN1, INPUT);
  pinMode(PIN2, INPUT);
  pinMode(PIN3, INPUT);
  Serial.println("displayResistanceInfo Started");
}

void loop() {
  if (!client.connected()) {
    Serial.println("Connecting to MQTT server");
    if (client.connect(mqtt_client)) {
      Serial.println("Connected to MQTT server");
    } else {
      Serial.println("Could not connect to MQTT server");
    }
  }
  displayResistanceInfo();
  if (client.connected()) {
    client.loop();
  }
  delay(100);
}

```

## まとめ
ハンダ付け無しで簡単に Grove デバイスと TouchDesigner を組み合わさることができました。

![NefryBT_デスクトップ.png](https://qiita-image-store.s3.amazonaws.com/0/72479/deda47b2-5214-c85e-d38b-4a49cf13705c.png)