Arduinoのお勉強がてら、25Hzで打鍵する装置を作って見ることにした。それだけじゃ面白くないので、VVVも出せるように。要するに、この二つの組合せ。
アナログ入力の動作の確認として、VVVの速度は可変で。ついでに、機能切換もボリュームの位置を使ってみる。
仕様
- 打鍵機能
- OFF
- ON(連続)
- VVV連続(速度可変)
- 25Hz
- 機能切換方式
- ボリュームの位置(スイッチやジャンパは使わない)
- 出力
- フォトカプラ
- LED点滅
回路
デジタル出力を一つ、アナログ入力を一つ、という至ってシンプルなもの。
当初、打鍵出力はトランジスタのオープンコレクタで出そうかと思ったのだけど、マイコン側のノイズが(接続した無線機の)GNDに流れ込むと気持ち悪いので、フォトカプラを使って絶縁する。
LEDとフォトカプラをシリーズにしたので、フォトカプラにトラブルがあるとLEDが点灯しない(一種のデバグ機能)。抵抗も一本ですむし。ただし、この構成の場合は超高輝度タイプのLEDを使うと眩しすぎるので、昔ながらの明るくないLEDを使う。
プログラム
先の記事のプログラムを組み合せてちょっといじっただけ。微妙に長いけど、ベタで貼り付け。
/* output: VVV or 25Hz
* (C) 2020 JH4VAJ
*/
#define DOT 0
#define DASH 1
#define CODE 0
#define LETTER 1
#define LETTER_END 2
#define PHRASE 3
#define SPACE_CODE delay(cw_space_code_len);
#define SPACE_LETTER delay(cw_space_letter_len);
#define SPACE_PHRASE delay(cw_space_phrase_len);
#define MODEpin 7 // アナログ
#define OUTPUTpin 12 // デジタル
/* VRの位置 */
#define MODE_OFF 100
#define MODE_ON 200
#define MODE_VVV 900
/* VVVのスピードを変えられるように定数からグローバル変数に変更*/
int cw_dot_len; // 短点の長さ (ms) これがすべての基準
int cw_dash_len; // 長点の長さ
int cw_space_code_len; // 点間隔
int cw_space_letter_len; // 文字間隔
int cw_space_phrase_len; // 語間隔
int count_v;
void setup() {
// put your setup code here, to run once:
pinMode(OUTPUTpin, OUTPUT);
count_v = 0;
}
void loop() {
// put your main code here, to run repeatedly:
int mode_level;
mode_level = analogRead(MODEpin); /* VRの値を読む */
/*
* VRの値がMODE_OFF以下ならオフ
* VRの値がMODE_ON以下ならオン(連続)
* VRの値がMODE_VVV未満ならVVVを送出(送出速度はVRの値による)
* VRの値がMODE_VVV以上なら短点を連続送出(速度は25Hz)
*/
if (mode_level <= MODE_OFF) {
digitalWrite(OUTPUTpin, LOW);
}
else if (mode_level <= MODE_ON) {
digitalWrite(OUTPUTpin, HIGH);
}
else if (mode_level <= MODE_VVV) {
cw_dot_len = ((MODE_VVV - mode_level) >> 2) + 20; // 4で割るのはVRの変化の影響を小さくするため。20msは上限速度。
cw_dash_len = cw_dot_len * 3;
cw_space_code_len = cw_dot_len;
cw_space_letter_len = cw_dash_len; // cw_dot_len * 3;
cw_space_phrase_len = cw_dot_len * 7;
output_letter_V();
if (count_v < 2) {
SPACE_LETTER
count_v++;
}
else {
SPACE_PHRASE
count_v = 0;
}
}
else {
const int wait_time = (1.0/50.0)*1000;
digitalWrite(OUTPUTpin, HIGH);
delay(wait_time);
digitalWrite(OUTPUTpin, LOW);
delay(wait_time);
}
}
void output_LED(int dot_dash, int space) {
digitalWrite(OUTPUTpin, HIGH);
if (dot_dash == DOT) {
delay(cw_dot_len);
}
else {
delay(cw_dash_len);
}
digitalWrite(OUTPUTpin, LOW);
switch (space) {
case CODE:
SPACE_CODE
break;
case LETTER:
SPACE_LETTER
break;
case PHRASE:
SPACE_PHRASE
break;
case LETTER_END:
default:
break;
}
return;
}
void output_letter_V() {
output_LED(DOT, CODE);
output_LED(DOT, CODE);
output_LED(DOT, CODE);
output_LED(DASH, LETTER_END);
return;
}
割り込みは使っていないシンプルなもの。そのため、速度の切換は文字単位(「V」のコードを送出し終るまでは変化しない)。当初は「VVV」の単位で見ていたけど流石に長すぎるので「V」一文字に切り分けた。
連続ONからVVVに移ったときに、その二つの切れ目がないので最初の短点がないようになる(VでなくU)。判定用のフラグを設けて処理するとかも考えられるけど、その判断にも時間がかかるので見送り。ま、シンプルさを優先ということで。
動作の様子
TTCW03につないでみた。
25Hzモードの様子をオシロで観測。
あら?24Hz。ボリュームの値を読むこととその判断で時間がかかっているようだ。デューティが崩れている(49%)になっていることからも分かる(ボリューム値の読み出しと判断の間はOFFなので)。OFF時間を調整して追い込むこともできるだろうけど、でも、まぁ、これくらいは良しとしよう。
これでA1Aのスプリアス測定時の打鍵装置として使えるはず(連続ON: 帯域外領域、25Hzモード: スプリアス領域)。25Hzの打鍵をするだけならこんなことをやるまでもないのだけど、あくまでArduinoのお勉強ってことで。
コメント