M5StickC(ESP32)のフローティングピンの挙動確認

現時点の情報です。最新情報はM5StickC非公式日本語リファレンスを確認してみてください。

概要

上記ブログにて、未使用ピンの調査があったのでESP32でも実験してみました。

環境

  • M5StickC(ESP32)

USBケーブル以外未接続のM5StickC(ESP32)を使って、各Pinの状態を変化させた場合の時系列変化を調査しました。時間軸の精度は悪いので、絶対時間ではないので気をつけてください。

M5StickCは使えるPinが5つありますが、GPIO36は入力専用でプルアップできないので除外、GPIO0は外部回路でプルアップされているので除外し、GPIO26、GPIO32、GPIO33の3つのPinで実験しました。

プルアップからデジタル入力に変更

INPUT_PULLUP to INPUT
TIME   26   32   33 
   0    1    1    1 
   1    1    1    1 
   2    1    1    1 
   3    1    1    1 
   4    1    1    1 
   5    1    1    1 
   6    1    1    1 
   7    0    1    1 
   8    0    1    1 
   9    0    1    1 
  10    0    1    1 
  11    0    1    1 
  12    0    1    1 
  13    0    1    1 
  14    0    1    1 
  15    0    1    1 
  16    0    1    1 
  17    0    1    1 
  18    0    1    1 
  19    0    1    1 
  20    0    1    1 
  21    0    1    1 
  22    0    1    0 
  23    0    1    0 
  24    0    1    0 
  25    0    1    0 
  26    0    1    0 
  27    0    1    0 
  28    0    1    0 
  29    0    1    0 
  30    0    1    0 
  31    0    1    0 
  32    0    1    0 
  33    0    1    0 
  34    0    1    0 
  35    0    1    0 
  36    0    1    0 
  37    0    1    0 
  38    0    1    0 
  39    0    1    0 
  40    0    1    0 
  41    0    1    0 
  42    0    1    0 
  43    0    1    0 
  44    0    1    0 
  45    0    1    0 
  46    0    1    0 
  47    0    1    0 
  48    0    1    0 
  49    0    1    0 
  50    0    1    0 
  51    0    1    0 
  52    0    1    0 
  53    0    1    0 
  54    0    1    0 
  55    0    1    0 
  56    0    1    0 
  57    0    1    0 
  58    0    1    0 
  59    0    1    0 
  60    0    1    0 
  61    0    1    0 
  62    0    1    0 
  63    0    1    0 
  64    0    1    0 
  65    0    1    0 
  66    0    1    0 
  67    0    1    0 
  68    0    1    0 
  69    0    1    0 
  70    0    1    0 
  71    0    1    0 
  72    0    1    0 
  73    0    1    0 
  74    0    1    0 
  75    0    1    0 
  76    0    1    0 
  77    0    1    0 
  78    0    1    0 
  79    0    1    0 
  80    0    1    0 
  81    0    1    0 
  82    0    1    0 
  83    0    1    0 
  84    0    1    0 
  85    0    1    0 
  86    0    1    0 
  87    0    1    0 
  88    0    1    0 
  89    0    0    0 
  90    0    0    0 
  91    0    0    0 
  92    0    0    0 
  93    0    0    0 
  94    0    0    0 
  95    0    0    0 
  96    0    0    0 
  97    0    0    0 
  98    0    0    0 
  99    0    0    0 

一番左が経過時間で、左からGPIO26、GPIO32、GPIO33のデータが並んでいます。ざっくりいうと、未接続のPinをプルアップしてからINPUTに変更すると、プルアップしたときの電荷がPinに残っています。時間経過により徐々に減っていきますが、減っていくペースはPinによって違います。

この場合GPIO32は80ミリ秒程度、電荷が残っていました。他のM5StickCで試したところ、そっちはGPIO33の方が長く残っていました。端末によって特性は違うようです。ただしGPIO26はどっちの端末でもすぐに落ち着きましたので、全体的な傾向はあるようでした。

プルアップしてからアナログ入力

INPUT_PULLUP to ANALOG
TIME   26   32   33 
   0 2015 4083 3983 
   1  144 3687 3311 
   2  116 3375 2925 
   3   80 3141 2663 
   4   96 2939 2455 
   5  128 2787 2279 
   6   98 2650 2123 
   7  111 2519 1966 
   8   96 2401 1825 
   9   80 2295 1696 
  10   92 2191 1580 
  11   96 2097 1461 
  12   64 1991 1305 
  13    0 1894 1180 
  14   76 1806 1074 
  15   82 1722  976 
  16  136 1645  890 
  17  138 1577  812 
  18  128 1499  732 
  19  154 1422  667 
  20  128 1360  602 
  21  128 1296  549 
  22  134 1240  496 
  23    0 1169  420 
  24   10 1104  340 
  25   76 1056  312 
  26  101 1008  288 
  27  136  965  272 
  28  108  921  256 
  29  176  884  240 
  30  122  838  228 
  31  132  800  216 
  32  128  758  208 
  33   82  720  196 
  34    0  676  176 
  35   37  642  144 
  36   80  611  144 
  37  122  592  148 
  38  138  568  153 
  39  113  544  160 
  40  152  528  160 
  41  116  496  162 
  42  149  480  164 
  43  144  462  168 
  44    0  432  153 
  45   34  412  144 
  46   38  396  128 
  47   96  384  130 
  48  128  384  144 
  49   94  368  144 

デジタルよりアナログの方が数値はわかりやすいです。プルアップされている状態は4095なので、そこから徐々に電荷が減っていきます。2048前後でLOWかHIGHの判定をしていますので、デジタル入力よりアナログ入力の方が電荷の減りは大きいようです。

徐々に電荷は下がっていきますが、GPIO32とGPIO33は0にはならず数百で止まっているのがわかります。ただGPIO26は定期的に0に落ちているので、やっぱり動きがちょっと違う気がします。

LOWからアナログ入力

LOW to ANALOG
TIME   26   32   33 
   0    0    0    0 
   1  114    0    0 
   2  106    0    0 
   3   81    0    0 
   4   64    0   32 
   5   89   16   50 
   6   92   32   72 
   7   89   56   84 
   8    0   64   92 
   9    0   69   96 
  10   48   80  104 
  11   37   84  112 
  12   35  112  114 
  13   98  128  128 
  14  117  148  142 
  15   76  168  146 
  16  144  182  160 
  17  117  193  160 
  18  128  208  164 
  19  160  209  172 
  20   43  210  160 

今回は逆にLOWからアナログ入力に変更しました。最初は0ですが、徐々に電荷が溜まっているようです。

検証コード

uint8_t pinList[] = {26, 32, 33};

void printPin(int time) {
  Serial.printf("%4d ", time);
  for (int i = 0; i < sizeof(pinList); i++) {
    Serial.printf("%4d ", digitalRead(pinList[i]));
  }
  Serial.println();
}

void printAPin(int time) {
  Serial.printf("%4d ", time);
  for (int i = 0; i < sizeof(pinList); i++) {
    Serial.printf("%4d ", analogRead(pinList[i]));
  }
  Serial.println();
}

void setup() {
  Serial.begin(115200);
  delay(100);

  Serial.println("Test Start\n");

  Serial.println("INPUT_PULLUP to INPUT");
  Serial.print("TIME ");
  for (int i = 0; i < sizeof(pinList); i++) {
    Serial.printf("%4d ", pinList[i]);
  }
  Serial.println();

  // All pin pullup
  for (int i = 0; i < sizeof(pinList); i++) {
    pinMode(pinList[i], INPUT_PULLUP);
  }

  // wait
  delay(1000);

  // All pin input
  for (int i = 0; i < sizeof(pinList); i++) {
    pinMode(pinList[i], INPUT);
  }

  // print
  for (int i = 0; i < 100; i++) {
    printPin(i);
    delay(1);
  }

  Serial.println("INPUT_PULLUP to ANALOG");
  Serial.print("TIME ");
  for (int i = 0; i < sizeof(pinList); i++) {
    Serial.printf("%4d ", pinList[i]);
  }
  Serial.println();

  // All pin pullup
  for (int i = 0; i < sizeof(pinList); i++) {
    pinMode(pinList[i], INPUT_PULLUP);
  }

  // wait
  delay(1000);

  // All pin input
  for (int i = 0; i < sizeof(pinList); i++) {
    pinMode(pinList[i], ANALOG);
  }

  // print
  for (int i = 0; i < 100; i++) {
    printAPin(i);
    delay(1);
  }

  Serial.println("LOW to INPUT");
  Serial.print("TIME ");
  for (int i = 0; i < sizeof(pinList); i++) {
    Serial.printf("%4d ", pinList[i]);
  }
  Serial.println();

  // All pin low
  for (int i = 0; i < sizeof(pinList); i++) {
    pinMode(pinList[i], OUTPUT);
    digitalWrite(pinList[i], LOW);
  }

  // wait
  delay(1000);

  // All pin input
  for (int i = 0; i < sizeof(pinList); i++) {
    pinMode(pinList[i], INPUT);
  }

  // print
  for (int i = 0; i < 100; i++) {
    printPin(i);
    delay(1);
  }

  Serial.println("LOW to ANALOG");
  Serial.print("TIME ");
  for (int i = 0; i < sizeof(pinList); i++) {
    Serial.printf("%4d ", pinList[i]);
  }
  Serial.println();

  // All pin low
  for (int i = 0; i < sizeof(pinList); i++) {
    pinMode(pinList[i], OUTPUT);
    digitalWrite(pinList[i], LOW);
  }

  // wait
  delay(1000);

  // All pin input
  for (int i = 0; i < sizeof(pinList); i++) {
    pinMode(pinList[i], ANALOG);
  }

  // print
  for (int i = 0; i < 100; i++) {
    printAPin(i);
    delay(1);
  }
}

void loop() {
}

まとめ

ESP32はArduino UNOなどと違い、Pinの用途が固定されておらず、GPIOマトリクスで複数の用途に利用することができます。そのため、マトリクス部分から多少電荷が移動してきたり、インプット行為により電荷を奪ったりしているようです。

組み込みで使う場合で、自分で基板設計するのであれば未使用PinはGNDに落とす方が安全かもしれませんんが、個人ユースで開発ボード使うんだったら未使用Pinはフローティングでもいいかな。。。

コメントする

メールアドレスが公開されることはありません。

管理者承認後にページに追加されます。公開されたくない相談はその旨本文に記載するかTwitterなどでDM投げてください。またスパム対策として、日本語が含まれない投稿は無視されますのでご注意ください。