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); // 語句間
}
}