02.ATOM LiteのAD値をLEDでモールス


02.ATOM LiteのAD値をLEDでモールス

前回にLED表示を追加します。ATOM LiteでADC2を使う場合、無線が使えず、ブザーも無いため、LEDにて測定値を表示します。その表示はモールス符号とします。
例) ch1が1.579Vの時、LEDが赤色で、モールス符号で158と3桁表示します。

モールス符号

モールス符号は、線と点からなり、符号の長さと間隔は、
1点: 1点の長さ、1符号の線又は点の間隔
3点: 1線の長さ、2符号の間隔
7点: 2語の間隔
と決まっています。(総務省令無線局運用規則別表第1号注1
https://elaws.e-gov.go.jp/data/325M50080000017_20200622_502M60000008061/pict/S25F30901000017-001.pdf )

数字
1 ・----
2 ・・---
3 ・・・--
4 ・・・・-
5 ・・・・・
6 -・・・・
7 --・・・
8 ---・・
9 ----・
0 -----
数字の1符号はどれも点と線で5つの組合わせです。点から始まり点の数により1~5、線から始まり線の数により6~9,0です。簡単です。

数字の略体もありますが、これは使用しません。
1:・-
2:・・-
3:・・・-
4:・・・・-
5:・・・・・
6:-・・・・
7:-・・・
8:-・・
9:-・
0:-

動作

数値は、100倍して整数を表示します。
例)1.234V→123
LED色は認識しやすい色、ch1:赤、ch2:緑、ch3:青、ch4:紫、ch5:白にしました。
例)ch1:0.67V, ch2:1.23V, ch3:1.78V, ch4:2.34V, ch5:2.89Vの測定値の場合は、 (赤色)067(緑色)123(青色)178(紫色)234(白色)289と表示され、これを繰返します。
シリアルモニタには、5chの電圧値とモールス符号の値を表示しています。

スケッチ


// ATOM Lite アナログ5ch入力 モールス符号LED表示
// ADC1_6のG34は、測定pinのG23と100Ωで接続
#include <M5Atom.h>           // ATOMを使用
int chpin[5] = {25, 32, 26, 33, 34}; // ch1~5のpin番号
int AD[5] = {0, 0, 0, 0, 0};  // AD読取初期値
int ADmax = 4095;             // ADの最大値 12bit 2^12-1
float V[5] = {0, 0, 0, 0, 0}; // 電圧算出初期値(V)
float Vmax = 3.3;       // 電圧最大値 3300mV/4095=0.8mVきざみ
int i, iM;              // chのループ用,モールスループ用
int timeS = 200;        //1点の長さ,1符号内の線・点間隔(mS)
int timeL = timeS * 3;  // 1線の長さ,2符号の間隔
int timeLL = timeS * 7; // 2語の間隔
CRGB LEDColor[5] = {0x00ff00, 0x800000, 0x0000ff, 0x008080, 0x707070};
                         // {赤, 緑, 青, 紫, 白} GRB 1-5ch
CRGB LEDoff = 0x000000;  // 黒 GRB
int V1, Vm[3];           // モールス符号用電圧 3桁,1桁

void onS() {             // モールス符号の点
  M5.dis.drawpix(0, LEDColor[i]); // 点灯
  delay(timeS);                   // 待つ
  M5.dis.drawpix(0, LEDoff);      // 消灯
  delay(timeS);                   // 待つ
}
void onL() {          // モールス符号の線
  M5.dis.drawpix(0, LEDColor[i]); // 点灯
  delay(timeL);                   // 待つ
  M5.dis.drawpix(0, LEDoff);      // 消灯
  delay(timeS);                   // 待つ
}

void setup() {
  M5.begin(true, false, true);//(LCD,PowerEnable=true,Serial)
  delay(500);                 // 0.5秒待つ
  pinMode(23, INPUT); // G34は測定pinG23と100Ωで接続のためopen
  for (i = 0; i < 5; i++) {   // ch1-5
    pinMode(chpin[i], ANALOG); // アナログpinとする
  }
}
void loop() {
  Serial.println("");              // シリアルモニタ改行
  for (i = 0; i < 5; i++) {        // ch1~5
    AD[i] = analogRead(chpin[i]);  // アナログ入力

    if (AD[i] < 10) {  // 0.11V以下で0V近辺より
      V[i] = 0.0;                  // 0Vとする
    } else if (AD[i] <= 1084) {    // 1V以下の場合
      V[i] = float(AD[i]) * 0.89 / 1084.0 + 0.11;//電圧に変換
    } else if (AD[i] <= 2303) {    // 2V以下の場合
      V[i] = float(AD[i] - 1084) / 1219.0 + 1.0;
    } else if (AD[i] <= 3179) {    // 2.7V以下の場合
      V[i] = float(AD[i] - 2303) * 0.7 / 876.0 + 2.0;
    } else if (AD[i] <= 3659) {    // 3V以下の場合
      V[i] =  float(AD[i] - 3179) * 0.3 / 480.0 + 2.7;
    } else if (AD[i] <= 4071) {    // 3.2V以下の場合
      V[i] = float(AD[i] - 3659) * 0.2 / 412.0 + 3.0;
    } else {                       // 3.2Vを超える場合
      V[i] = float(AD[i] - 4071) * 0.1 / 24.0 + 3.2;
    }
    //V[i] = float(AD[i]) / float(ADmax) * Vmax; // 補正無しの場合
    //Serial.printf("%1d:%5.3fV(%04d) ", i + 1, V[i], AD[i]);//電圧,AD値表示
    V1 = (int)(V[i] * 100 + 0.5);           // 100倍して四捨五入整数化
    Vm[0] = (int)(V1 / 100); // 1Vの位(切捨て) V[i]<10Vの時
    Vm[1] = (int)((V1 - Vm[0] * 100) / 10); // 100mVの位
    Vm[2] = V1 - Vm[0] * 100 - Vm[1] * 10;  // 10mVの位
    Serial.printf("%1d:%5.3fV(%01d%01d%01d) ", i + 1, V[i], Vm[0], Vm[1], Vm[2]);//電圧,モールス
    for (int iM = 0; iM <= 2; iM++) {      // モールス3桁
      if (Vm[iM] == 1) {                   // 1
        onS(); onL(); onL(); onL(); onL(); // ・----
      } else if (Vm[iM] == 2) {            // 2
        onS(); onS(); onL(); onL(); onL(); // ・・---
      } else if (Vm[iM] == 3) {            // 3
        onS(); onS(); onS(); onL(); onL(); // ・・・--
      } else if (Vm[iM] == 4) {            // 4
        onS(); onS(); onS(); onS(); onL(); // ・・・・-
      } else if (Vm[iM] == 5) {            // 5
        onS(); onS(); onS(); onS(); onS(); // ・・・・・
      } else if (Vm[iM] == 6) {            // 6
        onL(); onS(); onS(); onS(); onS(); // -・・・・
      } else if (Vm[iM] == 7) {            // 7
        onL(); onL(); onS(); onS(); onS(); // --・・・
      } else if (Vm[iM] == 8) {            // 8
        onL(); onL(); onL(); onS(); onS(); // ---・・
      } else if (Vm[iM] == 9) {            // 9
        onL(); onL(); onL(); onL(); onS(); // ----・
      } else if (Vm[iM] == 0) {            // 0
        onL(); onL(); onL(); onL(); onL(); // -----
      }
      delay(timeL - timeS);                // 符号間
    }
    delay(timeLL - timeL);                 // 語句間
  }
}