PR

VVVと25Hzの打鍵装置 ~ Arduinoのお勉強

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のお勉強ってことで。

コメント