ArduinoでAGCが可能か検討⑩
- 2016/12/20
- 20:32
その後、さらに減衰幅を広げるために、欲を出してプリアンプ後にもPINダイオードを入れてみました。
強力な信号がANTから入ってきた際に、プリアンプ前後で信号をGNDに落とし信号を減衰する仕組みです。
制御は、既存のMCP4725の出力を分岐して行っております。。


結果は良好です。 気にしていた受信過度の低下なども無く、減衰幅はより広がりました。
簡易的に測定したところでは、約40dB程度の減衰が得れておりました。
もう少し減衰できている気がしていましたが、こんなものなのでしょうか。
本来100dB程度あったほうが良いらしいです。
アタックタイム:アタックタイムをなるべく短くするために、収束させたい信号強度より大幅に差がある場合には,PINダイオードの電流制御幅を大きく変化させております。※ソフト制御の難点であるアタックタイムが短くできない問題点は残っています。頭の部分が大きく聞こえてしまいます。
ホールド&リリースタイム: SSBの受信音がおかしくならないように、一定時間ホールドしてからリリースするようにしました。
これを言ってしまうとアレですが、
AGC制御を色々変えて試しているのですが、AGC無しが一番自然な感じ良い気がするのは気のせいだろうか。
強い局が突然出てきてビックリしてしまうという点はよくないけど、それ以外は、AGC無しが良い気がしてきた。
その後、色々試していますが、信号に比例して単純にPINダイオードのATTを可変するのが良い感じになっています。
後日行った、コーディングの最適化で、アタックタイムが遅れて先頭の音が大音量になることもなくなりました。
試行錯誤は続きます・・・
備忘録、バックアップ、最新プログラム
強力な信号がANTから入ってきた際に、プリアンプ前後で信号をGNDに落とし信号を減衰する仕組みです。
制御は、既存のMCP4725の出力を分岐して行っております。。


結果は良好です。 気にしていた受信過度の低下なども無く、減衰幅はより広がりました。
簡易的に測定したところでは、約40dB程度の減衰が得れておりました。
もう少し減衰できている気がしていましたが、こんなものなのでしょうか。
本来100dB程度あったほうが良いらしいです。
アタックタイム:アタックタイムをなるべく短くするために、収束させたい信号強度より大幅に差がある場合には,PINダイオードの電流制御幅を大きく変化させております。※ソフト制御の難点であるアタックタイムが短くできない問題点は残っています。頭の部分が大きく聞こえてしまいます。
ホールド&リリースタイム: SSBの受信音がおかしくならないように、一定時間ホールドしてからリリースするようにしました。
これを言ってしまうとアレですが、
AGC制御を色々変えて試しているのですが、AGC無しが一番自然な感じ良い気がするのは気のせいだろうか。
強い局が突然出てきてビックリしてしまうという点はよくないけど、それ以外は、AGC無しが良い気がしてきた。
その後、色々試していますが、信号に比例して単純にPINダイオードのATTを可変するのが良い感じになっています。
後日行った、コーディングの最適化で、アタックタイムが遅れて先頭の音が大音量になることもなくなりました。
試行錯誤は続きます・・・
備忘録、バックアップ、最新プログラム
/*自作機2号機用コントロールプログラムJQ1SRN本プログラムの多くはネットで見つけた情報を参考にしております。コードの最適化などは考えていないため、効率が悪いコーディングになっていると思われます。ご注意ください。使用IOポート0: CAT TX1: CAT RX2: ロータリーエンコーダーA(基板1)3: ロータリーエンコーダーB(基板2) (基板3:GND)4: LCD , Refer to P186 Arduinoを始めよう5: LCD , Refer to P186 Arduinoを始めよう6: LCD , Refer to P186 Arduinoを始めよう7: LCD , Refer to P186 Arduinoを始めよう8: AD9850 DATA9: AD9850 RESET10: LCD , Refer to P186 Arduinoを始めよう11: LCD , Refer to P186 Arduinoを始めよう12: LCD , Refer to P186 Arduinoを始めよう13:周波数ステップ切替スイッチ(ロータリエンコーダスイッチ利用) ロータリー側コネクター6、5はGへ(基板4)14: F_LOCK周波数ロック、Mega以降追加 ★試にプルアップしてみた。外付け抵抗不要でよさそう。15:Freq Lock16:AD9850 FQ_UD17:AD9850 CLK22: INPUT: PTT from MIC, BUT, KEY24: OUTPUT: RELAY (with delay)26: MUTE54: A0(14) (Mega 54)スキャン開始、停止用押しボタンスイッチ55: A1(15) (Mega 55)VFO A/B切替スイッチ56: A2(16)(Mega 56) RIT ONスイッチ57: A3 (17)(Mega 57)TX検出、受信時にのみRIT-ON58: A4 (18)(Mega 58) HIGHを検出するとCW表示、LOW検出時はSSB表示59: A5(19)(Mega 59)電圧検出60: A8 RSSI read from IF44: 44 Gain Controle to change PIN Di*/
// ヘッダー関連 -----------------------------------
#include <LiquidCrystal.h> /// LCD表示用
#include <EF_AD9850.h> //AD9850を使うためのライブラリ
#define BEAT 300 // 音の長さを指定
#define PINNO 15 // 圧電スピーカを接続したピン番号
#include <Wire.h>
#include <Adafruit_MCP4725.h>
#include <Rotary.h>
Adafruit_MCP4725 dac;
// 初期設定関連 -----------------------------------
// 初期周波数設定
volatile long X = 35840000; ///液晶に表示する数字、周波数Hz
volatile long Y = 35840000; /// RIT時のテンポラリー
volatile long TEMP_DELTA_FREQ; /// CW時の周波数ズラシ用
volatile long DISP_FREQ = 50150000; /// LCD表示周波数
volatile long DELTA_FREQ = DISP_FREQ - X; ///差分記憶
volatile long RIT_FREQ = 0; ///RIT用周波数
volatile long OLD_RIT_FREQ; ///RIT変化チェック用
volatile long XA; ///VFOテンポラリーメモリー
volatile long XB = 36177830; ///VFOテンポラリーメモリー ★電源ON時、VFO-Bにビーコン周波数がデフォルト設定が便利
volatile long OLD_X = 35840000;
//RotayEncorder
Rotary r = Rotary(2, 3);
long OLD_MILLIS;
long ROTARY_SPEED;
long ROTARLY_MAX = 20;
// LCDのポート設定
LiquidCrystal lcd(12, 11, 10, 7, 6, 5, 4); // デジタルポート番号、本参照
// 周波数ステップの切替ボタン設定
const int BUTTON = 13; /// ボタン、ステップ切替用
int val = 0; /// 状態変数、0か1、1の場合は10ステップ、0時は100ステップ
int old_val = 0; /// 前の状態を記憶
int state = 1; /// 現在のステート
int state_a = 0; /// VFO A 時のステップ
int state_b = 0; /// VFO B 時のステップ
int freq_step = 10; /// 周波数ステップ
// 周波数に小数点を入れる計算をするためのテンポラリメモリ
String TMP; //周波数表示に小数点入れるためのテンポラリ計算用
String TMP1; //周波数表示に小数点入れるためのテンポラリ計算用
String TMP2; //周波数表示に小数点入れるためのテンポラリ計算用
String TMP3; //周波数表示に小数点入れるためのテンポラリ計算用
///スキャン用ボタン設定
const int SCAN_BUTTON = 54; ///スキャンON/OFF用ボタン
int val2 = 0; /// 仮ステータス
int old_val2 = 0; /// 仮ステータス
int state2 = 0; /// 仮ステータス
int scan_pose = 0;
long pose_start_time = 0;
int SCAN_LCD_HOLI = 4;
int INI_SCAN = 1;
int SCAN_THL_LEVEL = 130; //Scan停止のRSSIスレッショルド
int AVG_RSSI = 0;
int SCAN_Calibration = 1;
///RIT用ボタン設定
const int RIT_BUTTON = 55; ///スキャンON/OFF用ボタン 16pin
int val3 = 0; /// 仮ステータス
int old_val3 = 0; /// 仮ステータス
int state3 = 0; /// 仮ステータス
///TX検出用ボタン設定
const int TX_DETECT = 57; ///TX
int val4 = 0; /// 仮ステータス
int old_val4 = 0; /// 仮ステータス
int state4 = 0; /// 仮ステータス
// モード検出用設定、リグのHWスイッチから電圧を検出する
const int MODE_DETECT = 58; ///検出ピン18番、A4
int val5 = 0; /// 仮ステータス
int old_val5 = 0; /// 仮ステータス
int state5 = 0; /// 仮ステータス
///VFO-AB 用ボタン設定
const int VFO_BUTTON = 56; ///VFO A B ボタン 15Pin
int val6 = 0; /// 仮ステータス
int old_val6 = 0; /// 仮ステータス
int state6 = 0; /// 仮ステータス
//周波数ロック機能
const int FREQ_LOCK = 14; ///スキャンON/OFF用ボタン
int val7 = 0; /// 仮ステータス
int old_val7 = 0; /// 仮ステータス
int state7 = 0; /// 仮ステータス
// 電圧測定用変数
const int VOLT = 5; /// ピン定義A5を使う
double volt_val = 0; /// 電圧入れる変数
char volt_1[2]; /// LCD電圧表示用変数 小数点より前
char volt_2[1]; /// LCD電圧表示用変数 小数点後
int DISP_VOLT = 200;
//AD9850 DDSモジュールとArduinnoの接続
int clock = 17;//W_CLK original 1
int fqup = 16;//FQ_UD , original 0
int data = 8;//DATA
int ddsreset = 9;//RESET
EF_AD9850 AD9850(clock, fqup, ddsreset, data);
/// CAT送信間隔用
volatile long SEND_CAT = 1;
/// RSSI
long RSSI_VAL = 0;
long RSSI_PIN = 8; // A8 pin
/// AGC
long AGC_VAL = 600;
long AGC_PIN = 44; // 44 pin
long OLD_AGC_VAL1 = 600;
long OLD_AGC_VAL2 = 600;
long AGC_TARGET = 200;
int REFRESH_RSSI_ON_LCD = 100;
int DISP_AGC_ON_LCD = 1;
int DELTA_FOR_S;
int DELTA_FOR_S1;
int DELTA_FOR_S2;
int DELTA_FOR_S3;
int DELTA_FOR_S4;
int DELTA_FOR_S5;
int DELTA_FOR_S6;
int DELTA_FOR_S7;
int DELTA_FOR_S8;
int DELTA_FOR_S9;
int DELTA_FOR_S10;
int DELTA_FOR_S11;
//PTT RELATED
int PTT_PIN = 22;
int PTT_STAT = 1;
int OLD_PTT_STAT = 1;
int PTT_RELAY = 24;
int PTT_MUTE = 26;
long MUTE_COUNT = 0;
long MUTE_COUNT_RX = 0;
long MAX_MUTE_COUNT = 10;
long MAX_MUTE_COUNT_RX = 7;
int MUTE_STAT = 0;
//カスタム文字 バー表示
byte METER1[8] = {
B10000,
B10000,
B10000,
B10000,
B10000,
B10000,
B10000,
};
byte METER2[8] = {
B10100,
B10100,
B10100,
B10100,
B10100,
B10100,
B10100,
};
byte METER3[8] = {
B10101,
B10101,
B10101,
B10101,
B10101,
B10101,
B10101,
};
byte METER4[8] = { // スキャン記録バーグラフ用
B00000,
B00000,
B00000,
B00000,
B00000,
B00000,
B11111,
};
byte METER5[8] = { // スキャン記録バーグラフ用
B00000,
B00000,
B00000,
B00000,
B11111,
B11111,
B11111,
};
byte METER6[8] = { // スキャン記録バーグラフ用
B00000,
B00000,
B11111,
B11111,
B11111,
B11111,
B11111,
};
byte METER7[8] = { // スキャン記録バーグラフ用
B11111,
B11111,
B11111,
B11111,
B11111,
B11111,
B11111,
};
//ループ時間計測用、ループの最後のコメントを外すとシリアルに結果が出る
long TEST1 = millis();
long TEST0 = 0;
// セットアップ、初回のみ実行 ----------------------------
void setup(void) {
//分周比を標準の128から16に下げて、AD高速化
// http://ameblo.jp/aretaumitohirunosunahama/entry-12014713486.html
ADCSRA = ADCSRA & 0xf8;
//ADCSRA = ADCSRA | 0x04; //16分周 精度悪い、電圧表示に影響あり
ADCSRA = ADCSRA | 0x05; //64分周
Serial.begin(115200); /// CAT用
pinMode(2, INPUT); // ロータリーエンコーダーA デジポート2
digitalWrite(2, HIGH); // プルアップ
pinMode(3, INPUT); // ロータリーエンコーダーB デジポート3、Cはグラウンドへ!
digitalWrite(3, HIGH); // プルアップ
pinMode(BUTTON, INPUT); // ボタン、ステップ切替用
pinMode(SCAN_BUTTON, INPUT); /// スキャン用のボタン、トグル化する
pinMode(RIT_BUTTON, INPUT); /// RIT ON用
pinMode(TX_DETECT, INPUT); /// TX検出用
pinMode(MODE_DETECT, INPUT); /// MODE検出用
pinMode(FREQ_LOCK, INPUT); /// プルアップしてみる。
digitalWrite(FREQ_LOCK, HIGH); ///プルアップ設定はこれ。
pinMode(PTT_PIN, INPUT_PULLUP); /// PTT端子、検出
pinMode(PTT_RELAY, OUTPUT); /// 2SC1815経由でリレー制御
pinMode(PTT_MUTE, OUTPUT); /// LM386ミュート
// LCDのセットアップ
// 16文字×2行のLCDを使用します
lcd.begin(16, 2);
attachInterrupt(digitalPinToInterrupt(2), interrupt, CHANGE);
attachInterrupt(digitalPinToInterrupt(3), interrupt, CHANGE);
// AD9850セットアップ関連
AD9850.init();//AD9850の初期化
AD9850.reset();//AD9850リセット
AD9850.wr_serial(0x00, X); //周波数データを送る、初期周波数Xを設定
//MUTE 初期設定
digitalWrite(PTT_MUTE, HIGH);
/// スタートアップ画面 電源ONしたときに遊びで表示
lcd.home();
lcd.print("SRN-02 BY JQ1SRN");
lcd.setCursor(0, 1); // 横に14、下に1、の位置にカーソル移動
lcd.print("Starting........");
/////////////////////////// 液晶表示文字数定規
delay(2000);
lcd.clear();
//DAC設定
dac.begin(0x60); // MCP4725 DAモジュールのI2Cアドレス
dac.setVoltage(0, false);// DA制御
//SCAN_Thre_auto_calibration キャリブレーション
if (SCAN_Calibration == 1) {
for (int i = 0; i < 10; i++) {
RSSI_VAL = analogRead(RSSI_PIN); /// 電圧読み出し
lcd.setCursor(0, 0);
lcd.print("Calibrating now!");
lcd.setCursor(0, 1);
lcd.print(" ");
lcd.setCursor(0, 1);
lcd.print("RSSI("); lcd.print(i); lcd.print("/10):");
lcd.print(RSSI_VAL);
AVG_RSSI = AVG_RSSI + RSSI_VAL;
delay(500);
}
lcd.setCursor(0, 0);
lcd.print(" ");
lcd.setCursor(0, 0);
lcd.print("Calibration:Done");
lcd.setCursor(0, 1);
SCAN_THL_LEVEL = (AVG_RSSI / 10) + 20; //平均値+20を設定
lcd.print("ScanThrVal: "); lcd.print(SCAN_THL_LEVEL); // 表示、後でモードや他の情報表示に使う
delay(2000);
lcd.setCursor(0, 0);
lcd.print(" ");
lcd.setCursor(0, 1);
lcd.print(" ");
// Sメーター表示部分の計算負荷を減らすためあらかじめ計算しておく
DELTA_FOR_S = SCAN_THL_LEVEL / 11;
DELTA_FOR_S1 = SCAN_THL_LEVEL + DELTA_FOR_S * 1;
DELTA_FOR_S2 = SCAN_THL_LEVEL + DELTA_FOR_S * 2;
DELTA_FOR_S3 = SCAN_THL_LEVEL + DELTA_FOR_S * 3;
DELTA_FOR_S4 = SCAN_THL_LEVEL + DELTA_FOR_S * 4;
DELTA_FOR_S5 = SCAN_THL_LEVEL + DELTA_FOR_S * 5;
DELTA_FOR_S6 = SCAN_THL_LEVEL + DELTA_FOR_S * 6;
DELTA_FOR_S7 = SCAN_THL_LEVEL + DELTA_FOR_S * 7;
DELTA_FOR_S8 = SCAN_THL_LEVEL + DELTA_FOR_S * 8;
DELTA_FOR_S9 = SCAN_THL_LEVEL + DELTA_FOR_S * 9;
DELTA_FOR_S10 = SCAN_THL_LEVEL + DELTA_FOR_S * 10;
DELTA_FOR_S11 = SCAN_THL_LEVEL + DELTA_FOR_S * 11;
/* Serial.print("DELTA_FOR_S "); Serial.println(DELTA_FOR_S); Serial.print("DELTA_FOR_S1 "); Serial.println(DELTA_FOR_S1); Serial.print("DELTA_FOR_S2 "); Serial.println(DELTA_FOR_S2); Serial.print("DELTA_FOR_S3 "); Serial.println(DELTA_FOR_S3); Serial.print("DELTA_FOR_S4 "); Serial.println(DELTA_FOR_S4); Serial.print("DELTA_FOR_S5 "); Serial.println(DELTA_FOR_S5); Serial.print("DELTA_FOR_S6 "); Serial.println(DELTA_FOR_S6); Serial.print("DELTA_FOR_S7 "); Serial.println(DELTA_FOR_S7); Serial.print("DELTA_FOR_S8 "); Serial.println(DELTA_FOR_S8); Serial.print("DELTA_FOR_S9 "); Serial.println(DELTA_FOR_S9); Serial.print("DELTA_FOR_S10 "); Serial.println(DELTA_FOR_S10); Serial.print("DELTA_FOR_S11 "); Serial.println(DELTA_FOR_S11); */
}
//立ち上げ時設定モードへ移行 --------------
val2 = digitalRead(SCAN_BUTTON); /// スキャンボタンで移行
if (digitalRead(SCAN_BUTTON)) {
lcd.setCursor(0, 0);
lcd.print("< Setting Mode >"); lcd.print(SCAN_THL_LEVEL);
tone(PINNO, 100, 500) ; //スキャン停止時にビープ
delay(2000);
//手動設定の場合
for (;;) { // SCAN_THL_Lev -------------- Change SCAN_THL_LEVEL
lcd.setCursor(0, 0);
lcd.print("< Setting Mode >"); lcd.print(SCAN_THL_LEVEL);
lcd.setCursor(0, 1);
lcd.print("SCAN_THL_Lev:"); lcd.print(SCAN_THL_LEVEL);
if (digitalRead(VFO_BUTTON)) {
SCAN_THL_LEVEL = SCAN_THL_LEVEL + 5;
tone(PINNO, 100, 150) ; //スキャン停止時にビープ
delay(500);
}
if (digitalRead(SCAN_BUTTON)) {
tone(PINNO, 100, 500) ; //スキャン停止時にビープ
delay(1000);
lcd.setCursor(0, 0);
lcd.print(" ");
lcd.setCursor(0, 1);
lcd.print(" ");
break;
}
}
for (;;) { // DISP AGC -------------- Change DISP_AGC_ON_LCD
lcd.setCursor(0, 1);
if (DISP_AGC_ON_LCD == 1) {
lcd.setCursor(0, 0);
lcd.print("< Setting Mode >");
lcd.setCursor(0, 1);
lcd.print("Disp AGC number ");
}
if (DISP_AGC_ON_LCD == 0) {
lcd.setCursor(0, 0);
lcd.print("< Setting Mode >");
lcd.setCursor(0, 1);
lcd.print("Disp RSSI Meter ");
}
if (digitalRead(VFO_BUTTON)) {
if (DISP_AGC_ON_LCD == 1) {
DISP_AGC_ON_LCD = 0;
} else {
DISP_AGC_ON_LCD = 1;
}
tone(PINNO, 100, 150) ; //スキャン停止時にビープ
delay(500);
}
if (digitalRead(SCAN_BUTTON)) {
tone(PINNO, 100, 500) ; //スキャン停止時にビープ
delay(1000);
break;
}
}
lcd.setCursor(0, 0);
lcd.print(" ");
lcd.setCursor(0, 1);
lcd.print(" ");
}
//初回表示
DISP_FREQ = DELTA_FREQ + X; // DDSと表示周波数の差分を計算している
TMP = String(DISP_FREQ, DEC); /// 数値→テキスト変換
lcd.setCursor(6, 0); // 横に4、下に0、の位置にカーソル移動
TMP1 = TMP.substring(0, 2); // MHz部分表示VFOして、ピリオド
lcd.print(TMP1);
lcd.print(".");
TMP2 = TMP.substring(2, 5); // その後のKHZ表示
lcd.print(TMP2);
lcd.print(".");
TMP3 = TMP.substring(5, 9); // その後のHz表示
lcd.print(TMP3);
lcd.setCursor(0, 1); // 横に0、下に1、の位置にカーソル移動
// VFO Initial 表示
lcd.setCursor(4, 0); // 横に0、下に1、の位置にカーソル移動
lcd.print("A"); // 表示、後でモードや他の情報表示に使う
}
// ループ、実行部分 --------------------------------ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー-
void loop(void) {
// LCDに文字を表示するための処理ーーーーーーーーーーーーーーーーーーーーーーーーーーーー
if (X != OLD_X) { //周波数が変化したときだけ書き換えする
DISP_FREQ = DELTA_FREQ + X; // DDSと表示周波数の差分を計算している
TMP = String(DISP_FREQ, DEC); /// 数値→テキスト変換
lcd.setCursor(6, 0); // 横に4、下に0、の位置にカーソル移動
TMP1 = TMP.substring(0, 2); // MHz部分表示VFOして、ピリオド
lcd.print(TMP1);
lcd.print(".");
TMP2 = TMP.substring(2, 5); // その後のKHZ表示
lcd.print(TMP2);
lcd.print(".");
TMP3 = TMP.substring(5, 9); // その後のHz表示
lcd.print(TMP3);
lcd.setCursor(0, 1); // 横に0、下に1、の位置にカーソル移動
OLD_X = X;
}
// AGC 処理 ---------------------------------
AGC();
// 周波数ステップ切替ボタン -------------------------
/* 途中でSW無しロータリーエンコーダーに切り替えたので不要になった val = digitalRead(BUTTON); /// ステップ切替ボタン用シーケンス if ((val == HIGH) && (old_val == LOW)) { /// ボタンが押されたの検出 state = 1 - state; /// 前とステート変更 } old_val = val; if (state == 1) { /// ステート1ならば、、、 ステップ10 暫定として freq_step = 10; } else { /// ステート0ならば、、、 ステップ100 暫定として // X = X / 100; // 100ステップ時に10の桁をゼロにリセットして見た目をよくする // X = X * 100; // 100ステップ時に10の桁をゼロにリセットして見た目をよくする freq_step = 300; } */
// スキャン開始終了ボタン ---------------------------------
val2 = digitalRead(SCAN_BUTTON); /// スキャン切替ボタン用シーケンス
if ((val2 == HIGH) && (old_val2 == LOW) ) { /// ボタンが押されたの検出
SCAN_LCD_HOLI = 5;
if (scan_pose == 1) {
state2 = 0;
scan_pose = 0;
lcd.setCursor(5, 0);
lcd.print(" "); // LCDの★マーク消す
} else {
state2 = 1 - state2; /// 前とステート変更
scan_pose = 0;
lcd.setCursor(5, 0);
lcd.print(" "); // LCDの★マーク消す
}
}
old_val2 = val2;
if (state2 == 1) { /// ステート1ならばスキャンスタート、、、 周波数を上に変化させる
if (INI_SCAN) {
lcd.setCursor(4, 1); // LCD VOL表示エリア
lcd.print(" --- --- ---");
SCAN_LCD_HOLI = 4;
INI_SCAN = 0;
}
X = X + 500;
AD9850.wr_serial(0x00, X); //周波数データを送る アップ
if (X > 36090000) { /// 35990000=50.300MHzでスキャンを50.150から再スキャン
X = 35840000; /// 35840000=50.150から再スキャン
}
} else { /// ステート0ならば、、、 周波数変化させない
/// digitalWrite(LED,LOW);
/// スキャンスイッチをもう一度押すと、なにもしない、スキャン停止する
}
if (RSSI_VAL > SCAN_THL_LEVEL && state2 == 1 && scan_pose == 0) { // RSSIが閾値以上 & スキャン中 & スキャンポーズしてない場合 → 一時ストップ
tone(PINNO, 50, 75) ; //スキャン停止時にビープ
delay(BEAT) ;
state2 = 0;
scan_pose = 1;
pose_start_time = millis();
if (SCAN_LCD_HOLI >= 16) {
SCAN_LCD_HOLI = 4;
}
lcd.setCursor(SCAN_LCD_HOLI, 1);
//Scan時の信号レベルメーター
lcd.createChar(4, METER4);
lcd.createChar(5, METER5);
lcd.createChar(6, METER6);
lcd.createChar(7, METER7);
if (RSSI_VAL > SCAN_THL_LEVEL) { // スキャン履歴棒グラフRSSI表示
lcd.setCursor(SCAN_LCD_HOLI, 1);
lcd.write(4);
}
if (RSSI_VAL > SCAN_THL_LEVEL + 10) {
lcd.setCursor(SCAN_LCD_HOLI, 1);
lcd.write(5);
}
if (RSSI_VAL > SCAN_THL_LEVEL + 25) {
lcd.setCursor(SCAN_LCD_HOLI, 1);
lcd.write(6);
}
if (RSSI_VAL > SCAN_THL_LEVEL + 50) {
lcd.setCursor(SCAN_LCD_HOLI, 1);
lcd.write(7);
}
lcd.print(TMP2); // 周波数をバーグラフの次に表示
SCAN_LCD_HOLI = SCAN_LCD_HOLI + 4;
}
if ( state2 == 0 & scan_pose == 1) {// スキャンポーズ中 & 周波数移動停止中の場合、★を点滅
if (millis() - pose_start_time > 5000) { // 5秒超えたら
tone(PINNO, 100, 75) ; //スキャン停止再開時にビープ
delay(BEAT) ;
state2 = 1;
scan_pose = 0;
X = X + 10000;
AD9850.wr_serial(0x00, X); //周波数データを送る アップ
delay(500); // RSSI整流電圧がコンデンサから放電され下がるまで待つ
lcd.setCursor(5, 0);
lcd.print(" "); // LCDの★マーク消す
} else { //5秒までの間
if (millis() % 1000 > 500 ) {
lcd.setCursor(5, 0);
lcd.print("*"); // LCDにロック時★マーク表示
if (RSSI_VAL > SCAN_THL_LEVEL) { // スキャン履歴棒グラフRSSI表示
lcd.setCursor(SCAN_LCD_HOLI - 4, 1);
lcd.write(4);
}
if (RSSI_VAL > SCAN_THL_LEVEL + 10) {
lcd.setCursor(SCAN_LCD_HOLI - 4, 1);
lcd.write(5);
}
if (RSSI_VAL > SCAN_THL_LEVEL + 25) {
lcd.setCursor(SCAN_LCD_HOLI - 4, 1);
lcd.write(6);
}
if (RSSI_VAL > SCAN_THL_LEVEL + 50) {
lcd.setCursor(SCAN_LCD_HOLI - 4, 1);
lcd.write(7);
}
} else {
lcd.setCursor(5, 0);
lcd.print(" "); // LCDの★マーク消す
if (RSSI_VAL > SCAN_THL_LEVEL) { // スキャン履歴棒グラフRSSI表示
lcd.setCursor(SCAN_LCD_HOLI - 4, 1);
lcd.write(4);
}
if (RSSI_VAL > SCAN_THL_LEVEL + 10) {
lcd.setCursor(SCAN_LCD_HOLI - 4, 1);
lcd.write(5);
}
if (RSSI_VAL > SCAN_THL_LEVEL + 25) {
lcd.setCursor(SCAN_LCD_HOLI - 4, 1);
lcd.write(6);
}
if (RSSI_VAL > SCAN_THL_LEVEL + 50) {
lcd.setCursor(SCAN_LCD_HOLI - 4, 1);
lcd.write(7);
}
}
}
}
// RITボタン ---------------------------------
val3 = digitalRead(RIT_BUTTON); /// ステップ切替ボタン用シーケンス
if ((val3 == HIGH) && (old_val3 == LOW)) { /// ボタンが押されたの検出
state3 = 1 - state3; /// 前とステート変更、RITがONの時State3は1となる
if (state3 == 1) {
lcd.setCursor(5, 1); // 横に0、下に1、の位置にカーソル移動
lcd.print("R "); // 表示、後でモードや他の情報表示に使う
lcd.setCursor(8, 1); // 横に0、下に1、の位置にカーソル移動
lcd.print(RIT_FREQ); // 表示、後でモードや他の情報表示に使う
lcd.print("Hz "); // 表示、後でモードや他の情報表示に使う
}
}
old_val3 = val3;
if (state3 == 1) { /// RITがONであれば
lcd.setCursor(5, 1); // 横に0、下に1、の位置にカーソル移動
lcd.print("R "); // RIT ON表示
if (RIT_FREQ != OLD_RIT_FREQ) { /// ロータリーエンコーダーが回って周波数が変わったら
lcd.print(" "); // 表示、後でモードや他の情報表示に使う
lcd.setCursor(7, 1); // 横に0、下に1、の位置にカーソル移動
lcd.print(RIT_FREQ); // 表示、後でモードや他の情報表示に使う
lcd.print("Hz"); // 表示、後でモードや他の情報表示に使う
OLD_RIT_FREQ = RIT_FREQ;
}
} else { /// /// RITがOFFであれば
++DISP_VOLT;
if (DISP_VOLT > 100) { // 頻繁にLCD書き換えしない
if ( scan_pose + state2 == 0) { // Scan中のSTOP履歴を表示するためVoltを表示しない
lcd.setCursor(4, 1); // 横に0、下に1、の位置にカーソル移動
lcd.print(" "); // 表示、後でモードや他の情報表示に使う
Y = X;
RIT_FREQ = 0;
// RITがOFFの時だけ電圧表示する
volt_val = analogRead(VOLT); /// 電圧読み出し
volt_val *= 5; ///変換
volt_val /= 1024; ///変換
volt_val /= 30.2; /// 変換 元々30で、微調整で+0.2電圧微調整
volt_val *= 130;
dtostrf(volt_val, 2, 1, volt_1); //変換する値 ,変換後の総文字数,小数点以下の桁数(13.82->13.8),変換後格納する変数
lcd.print(volt_1); // 電圧をLCDに表示
lcd.print("V "); // 電圧をLCDに表示
if (atoi(volt_1) < 10.0 && atoi(volt_1) > 1.0 ) { // 電圧が10v以下になったらアラートを出す!
tone(PINNO, 262, BEAT) ; // ド
delay(BEAT) ;
tone(PINNO, 294, BEAT) ; // レ
delay(BEAT) ;
}
DISP_VOLT = 1;
INI_SCAN = 1; // SCAN終了時に1、次回1だと、初回だけ --- --- ---を表示する。
}
}
}
// Serial.print(" scan_pose="); Serial.print(scan_pose); Serial.print(" state2="); Serial.println(state2);
// PTT制御 ---------------------------------
PTT_STAT = digitalRead(PTT_PIN); /// 結果0=送信
//Serial.print("PTT---------------");
//Serial.println(PTT_STAT);
if (PTT_STAT == 0 && OLD_PTT_STAT == 1) { // 初回送信時実行 ★
digitalWrite(PTT_MUTE, LOW); // MUTEするーー>MUTE解除まで
MUTE_COUNT = 0;
digitalWrite(PTT_RELAY, HIGH);
OLD_PTT_STAT = PTT_STAT;
MUTE_STAT = 1;
}
if (PTT_STAT == 0 && OLD_PTT_STAT == 0 && MUTE_STAT == 1) { // MUTE解除までの時間
MUTE_COUNT = MUTE_COUNT + 1;
if (MUTE_COUNT == MAX_MUTE_COUNT)
{
digitalWrite(PTT_MUTE, HIGH);
MUTE_STAT = 0;
}
if (MUTE_COUNT > MAX_MUTE_COUNT) {
MAX_MUTE_COUNT = 50;
}
}
if (PTT_STAT == 1 && OLD_PTT_STAT == 0) { // 受信に切り替わり ★
digitalWrite(PTT_MUTE, LOW); // MUTEするーー>MUTE解除まで
MUTE_COUNT_RX = 0;
digitalWrite(PTT_RELAY, LOW);
OLD_PTT_STAT = PTT_STAT;
}
if (PTT_STAT == 1 && OLD_PTT_STAT == 1) { // MUTE解除までの時間
MUTE_COUNT_RX = MUTE_COUNT_RX + 1;
if (MUTE_COUNT_RX == MAX_MUTE_COUNT_RX)
{
digitalWrite(PTT_MUTE, HIGH);
}
if ( MAX_MUTE_COUNT_RX > MAX_MUTE_COUNT_RX) {
MAX_MUTE_COUNT_RX = 50;
}
}
// TX検出 ---------------------------------
val4 = digitalRead(TX_DETECT); ///送信検出
if (val4 == HIGH) { /// ボタンが押されたの検出 val4は送信時「1」となる
if (old_val4 != HIGH) { //LCD表示が点滅するのを防ぐ、RXからTXになった際だけ、このIF分入
lcd.setCursor(14, 1); // 横に14、下に1、の位置にカーソル移動
lcd.print("TX"); // 送信時にLCDにTXと表示
AD9850.wr_serial(0x00, X); //周波数データを送る アップ
old_val4 = val4;
if (state2 == 1) { /// スキャン中なら、PTTでスキャン停止
state2 = 0;
}
if (scan_pose == 1) { /// スキャン中でキャリア検出してPOSE中の場合も停止
scan_pose = 0;
lcd.setCursor(5, 0);
lcd.print(" "); // LCDの★マーク消す
}
}
} else { /// 受信時 val4がLOWである時
lcd.setCursor(14, 1); // 横に14、下に1、の位置にカーソル移動
if ( scan_pose + state2 == 0) { // Scan中のSTOP履歴を表示するためVoltを表示しない
lcd.print("RX"); // 受信時にLCDにRXと表示
}
if (state3 == HIGH) { /// RITスイッチをチェックする、RITがONの時はこちら
//AD9850.wr_serial(0x00, Y); /// バックアップ:RIT補正の周波数データを送る アップ
/// CW時でかつ、RXの時だけ、受信周波数を800Hz下げる
if (val5 == HIGH) { /// CWモードと判断
TEMP_DELTA_FREQ = Y - 800;
AD9850.wr_serial(0x00, TEMP_DELTA_FREQ); //送信波を800HzだけUP
} else { // SSBモードの場合通常にY周波数を送る
AD9850.wr_serial(0x00, Y); //周波数データを送る アップ
old_val4 = val4;
}
} else { /// RIT が OFFの時はこちら
//AD9850.wr_serial(0x00, X); //周波数データを送る アップ
/// CW時でかつ、RXの時だけ、受信周波数を800Hz下げる
if (val5 == HIGH) { /// CWモードと判断
TEMP_DELTA_FREQ = X - 800;
AD9850.wr_serial(0x00, TEMP_DELTA_FREQ); //送信波を800HzだけUP
} else { // SSBモードの場合通常にY周波数を送る
AD9850.wr_serial(0x00, X); //周波数データを送る アップ
old_val4 = val4;
}
}
old_val4 = val4;
}
// MODE検出 ---------------------------------
val5 = digitalRead(MODE_DETECT); /// モード検出ピンをチェック
if (val5 == HIGH) { /// ボタンが押されたの検出 val5は送信時「1」となる
if (old_val5 != HIGH) { //LCD表示が連続上書きされ点滅するのを防ぐ
lcd.setCursor(0, 0); // 左上座標
lcd.print("CW "); // CW表示
}
// delay(10);
} else {
if (old_val5 != HIGH) { //LCD表示が連続上書きされ点滅するのを防ぐ
lcd.setCursor(0, 0); // 左上座標
lcd.print("SSB"); // SSB表示
}
old_val5 = val5;
}
// VFO ABボタン処理 ---------------------------------
val6 = digitalRead(VFO_BUTTON); /// VFOボタン定義
if ((val6 == HIGH) && (old_val6 == LOW)) { /// ボタンが押されたの検出
state6 = 1 - state6; /// 前とステート変更、ボタンONの時Stateは1となる
if (state6 == 1) { /// VFO B-> A
XA = X;
X = XB;
state_a = state;
state = state_b;
} else { /// VFO A - > B
XB = X;
X = XA;
state_b = state;
state = state_a;
}
if (state6 == 1) { ///
lcd.setCursor(4, 0); // 横に0、下に1、の位置にカーソル移動
lcd.print("B"); // 表示、後でモードや他の情報表示に使う
} else { /// ///
lcd.setCursor(4, 0); // 横に0、下に1、の位置にカーソル移動
lcd.print("A"); // 表示、後でモードや他の情報表示に使う
}
}
old_val6 = val6;
// 周波数ロック ボタン処理 ---------------------------------
val7 = digitalRead(FREQ_LOCK); /// VFOボタン定義
if ((val7 == LOW) && (old_val7 == HIGH)) { /// ボタンが押されたの検出
state7 = 1 - state7; /// 前とステート変更、ボタンONの時Stateは1となる
if (state7 == 1) { ///LOCKボタン押されて、LOCKステートに入っている
lcd.setCursor(3, 0);
lcd.print("*"); // LCDにロック時★マーク表示
} else { /// ///
lcd.setCursor(3, 0);
lcd.print(" "); // LCDの★マーク消す
}
}
old_val7 = val7;
// CAT出力 ---------------------------------
++SEND_CAT;
if (SEND_CAT > 300) {
Serial.print("FA000"); ///周波数
Serial.print(DISP_FREQ); ///周波数
Serial.println(";"); ///周波数
if (val5 == HIGH) { /// ボタンが押されたの検出 val5は送信時「1」となる
Serial.println("MD3;"); ///モード
} else {
Serial.println("MD2;"); ///モード
}
SEND_CAT = 1;
}
// AGC 処理 ---------------------------------
AGC();
/* ループ時間計測用 if (TEST0 > 100) { Serial.println(millis() - TEST1); TEST0 = 0; TEST1 = millis(); } else { TEST0 = TEST0 + 1; } */
} /// ←Loop閉じるカッコなので注意、if文の終わりではない
// 割り込み時に実行されるプログラム ロータリー処理、周波数変更、AD9850アップデート --ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
void interrupt() {
if (state7 == 1) { /// F_LOCKされている
return;
}
unsigned char result = r.process();
if (result == DIR_NONE) {
// do nothing
}
else if (result == DIR_CW) { // 右回転
ROTARY_SPEED = millis() - OLD_MILLIS;
if (ROTARY_SPEED > ROTARLY_MAX) {
ROTARY_SPEED = ROTARLY_MAX;
}
ROTARY_SPEED = (ROTARY_SPEED - ROTARLY_MAX - 1);
if ((state3 == HIGH) && (val4 == LOW)) { /// RITモードがONでRX状態ならば
RIT_FREQ = RIT_FREQ + 10;
Y = X + RIT_FREQ;
// AD9850.wr_serial(0x00, Y); /// 周波数データを送る アップ
delay(10);
} else { /// RITモードでない場合
//Serial.print("CounterClockWise ");
//Serial.println(ROTARY_SPEED);
X = X + ROTARY_SPEED;
}
OLD_MILLIS = millis();
}
else if (result == DIR_CCW) { // 右回転
ROTARY_SPEED = millis() - OLD_MILLIS;
if (ROTARY_SPEED > ROTARLY_MAX) {
ROTARY_SPEED = ROTARLY_MAX;
}
ROTARY_SPEED = (ROTARY_SPEED - ROTARLY_MAX - 1);
if ((state3 == HIGH) && (val4 == LOW)) { /// RITモードがONでRX状態ならば
RIT_FREQ = RIT_FREQ - 10;
Y = X + RIT_FREQ;
delay(10);
} else { /// RITモードでない場合
//Serial.print("ClockWise ");
//Serial.println(ROTARY_SPEED);
X = X - ROTARY_SPEED;
}
OLD_MILLIS = millis();
}
}
// AGCサブルーチン------------------------------------------
void AGC() {
RSSI_VAL = analogRead(RSSI_PIN); /// 電圧読み出し
//①RSSI LCD表示
if (DISP_AGC_ON_LCD == 1) {// LCDにSメーターかAGC数値かを表示させる
++REFRESH_RSSI_ON_LCD;
if (REFRESH_RSSI_ON_LCD > 100) {
lcd.setCursor(0, 1);
lcd.write(" ");
lcd.setCursor(0, 1);
lcd.print(RSSI_VAL);
REFRESH_RSSI_ON_LCD = 1;
}
}
// RSSIバー表示
if (DISP_AGC_ON_LCD == 0) { // LCDにSメーターかAGC数値かを表示させる
++REFRESH_RSSI_ON_LCD;
if (REFRESH_RSSI_ON_LCD > 100) {
lcd.createChar(1, METER1);
lcd.createChar(2, METER2);
lcd.createChar(3, METER3);
/* Sメーター表示旧バージョン if (RSSI_VAL < 121) { lcd.setCursor(0, 1); lcd.write(1); lcd.write(" "); } if (RSSI_VAL > 120 && RSSI_VAL < 141) { lcd.setCursor(0, 1); lcd.write(2); lcd.write(" "); } if (RSSI_VAL > 140 && RSSI_VAL < 183) { lcd.setCursor(0, 1); lcd.write(3); lcd.write(" "); } if (RSSI_VAL > 182 && RSSI_VAL < 225) { lcd.setCursor(0, 1); lcd.write(3); lcd.write(1); lcd.write(" "); } if (RSSI_VAL > 224 && RSSI_VAL < 266) { lcd.setCursor(0, 1); lcd.write(3); lcd.write(2); lcd.write(" "); } if (RSSI_VAL > 265 && RSSI_VAL < 308) { lcd.setCursor(0, 1); lcd.write(3); lcd.write(3); lcd.write(" "); } if (RSSI_VAL > 307 && RSSI_VAL < 350) { lcd.setCursor(0, 1); lcd.write(3); lcd.write(3); lcd.write(1); lcd.write(" "); } if (RSSI_VAL > 349 && RSSI_VAL < 391) { lcd.setCursor(0, 1); lcd.write(3); lcd.write(3); lcd.write(2); lcd.write(" "); } if (RSSI_VAL > 390 && RSSI_VAL < 433) { lcd.setCursor(0, 1); lcd.write(3); lcd.write(3); lcd.write(3); lcd.write(" "); } if (RSSI_VAL > 432 && RSSI_VAL < 475) { lcd.setCursor(0, 1); lcd.write(3); lcd.write(3); lcd.write(3); lcd.write(1); } if (RSSI_VAL > 474 && RSSI_VAL < 516) { lcd.setCursor(0, 1); lcd.write(3); lcd.write(3); lcd.write(3); lcd.write(2); } if (RSSI_VAL > 515 && RSSI_VAL < 558) { lcd.setCursor(0, 1); lcd.write(3); lcd.write(3); lcd.write(3); lcd.write(3); } if (RSSI_VAL > 557) { lcd.setCursor(0, 1); lcd.write(3); lcd.write(3); lcd.write(3); lcd.write(3); } */
//Sメーター表示2
if (RSSI_VAL < SCAN_THL_LEVEL) {
lcd.setCursor(0, 1);
lcd.write(1); lcd.write(" ");
goto complete_s;
}
if (RSSI_VAL >= SCAN_THL_LEVEL && RSSI_VAL < DELTA_FOR_S1) { //S1
lcd.setCursor(0, 1);
lcd.write(2); lcd.write(" ");
goto complete_s;
}
if (RSSI_VAL >= DELTA_FOR_S1 && RSSI_VAL < DELTA_FOR_S2) { //S2
lcd.setCursor(0, 1);
lcd.write(3); lcd.write(" ");
goto complete_s;
}
if (RSSI_VAL >= DELTA_FOR_S2 && RSSI_VAL < DELTA_FOR_S3) { //S3
lcd.setCursor(0, 1);
lcd.write(3); lcd.write(1); lcd.write(" ");
goto complete_s;
}
if (RSSI_VAL >= DELTA_FOR_S3 && RSSI_VAL < DELTA_FOR_S4) { //S4
lcd.setCursor(0, 1);
lcd.write(3); lcd.write(2); lcd.write(" ");
goto complete_s;
}
if (RSSI_VAL >= DELTA_FOR_S4 && RSSI_VAL < DELTA_FOR_S5) { //S5
lcd.setCursor(0, 1);
lcd.write(3); lcd.write(3); lcd.write(" ");
goto complete_s;
}
if (RSSI_VAL >= DELTA_FOR_S5 && RSSI_VAL < DELTA_FOR_S6) { //S6
lcd.setCursor(0, 1);
lcd.write(3); lcd.write(3); lcd.write(1); lcd.write(" ");
goto complete_s;
}
if (RSSI_VAL >= DELTA_FOR_S6 && RSSI_VAL < DELTA_FOR_S7) { //S7
lcd.setCursor(0, 1);
lcd.write(3); lcd.write(3); lcd.write(2); lcd.write(" ");
goto complete_s;
}
if (RSSI_VAL >= DELTA_FOR_S7 && RSSI_VAL < DELTA_FOR_S8) { //S8
lcd.setCursor(0, 1);
lcd.write(3); lcd.write(3); lcd.write(3); lcd.write(" ");
goto complete_s;
}
if (RSSI_VAL >= DELTA_FOR_S8 && RSSI_VAL < DELTA_FOR_S9) { //S9
lcd.setCursor(0, 1);
lcd.write(3); lcd.write(3); lcd.write(3); lcd.write(1);
goto complete_s;
}
if (RSSI_VAL >= DELTA_FOR_S9 && RSSI_VAL < DELTA_FOR_S10) { //S10
lcd.setCursor(0, 1);
lcd.write(3); lcd.write(3); lcd.write(3); lcd.write(2);
goto complete_s;
}
if (RSSI_VAL >= DELTA_FOR_S10 && RSSI_VAL < DELTA_FOR_S11) { //S11
lcd.setCursor(0, 1);
lcd.write(3); lcd.write(3); lcd.write(3); lcd.write(3);
goto complete_s;
}
REFRESH_RSSI_ON_LCD = 1;
}
}
complete_s:
//②デバッグ用RSSIシリアル出力
//Serial.print("RSSI_VAL: "); ///周波数
//Serial.print(RSSI_VAL); ///周波数
//Serial.print(" "); ///周波数
//①単純にATTをRSSIに比例しONにする、アタックタイムが早いが、ホールド・リリース調整ができない
//デバイスによって異なる、カットアンドトライが必須
//AGC_VAL = RSSI_VAL * 32 / 10;
//AGC_VAL = (RSSI_VAL * 6 ) -520 ;
//AGC_VAL = (RSSI_VAL * 4 ) -200 ;
//AGC_VAL = (RSSI_VAL * 9 ) - 1800 ;
AGC_VAL = (RSSI_VAL * RSSI_VAL ) / 38 ;
//②Target値に収束させるアルゴリズムを使う場合
/* if (RSSI_VAL < AGC_TARGET) { // ホールド&リリースタイム、550以下の場合(弱電界)、Gへの抵抗上げる、オープン方向 if (AGC_TARGET - RSSI_VAL > 100) { AGC_VAL = AGC_VAL - 400; } if (AGC_TARGET - RSSI_VAL <= 100 && AGC_TARGET - RSSI_VAL > 50 ) { AGC_VAL = AGC_VAL - 100; } if (AGC_TARGET - RSSI_VAL <= 50 && AGC_TARGET - RSSI_VAL > 25 ) { AGC_VAL = AGC_VAL - 50; } if (AGC_TARGET - RSSI_VAL <= 25 && AGC_TARGET - RSSI_VAL > 10 ) { AGC_VAL = AGC_VAL - 10; } if (AGC_TARGET - RSSI_VAL <= 10 ) { AGC_VAL = AGC_VAL - 1; } } if (RSSI_VAL > AGC_TARGET) { // アタックタイム、550以上の場合(強電界)、Gへの抵抗下げる、ショート方向 if ( RSSI_VAL - AGC_TARGET > 100) { AGC_VAL = AGC_VAL + 400;//50 } if (RSSI_VAL - AGC_TARGET <= 100 && RSSI_VAL - AGC_TARGET > 50 ) { AGC_VAL = AGC_VAL + 50;//25 } if (RSSI_VAL - AGC_TARGET <= 50 && RSSI_VAL - AGC_TARGET > 25 ) { AGC_VAL = AGC_VAL + 10;//13 } if (RSSI_VAL - AGC_TARGET <= 25 && RSSI_VAL - AGC_TARGET > 10 ) { AGC_VAL = AGC_VAL + 5;//5 } if (RSSI_VAL - AGC_TARGET <= 10 ) { AGC_VAL = AGC_VAL + 1; } } */
if (AGC_VAL > 4095) { //上限
AGC_VAL = 4095;
}
if (AGC_VAL <= 600) { //下限
AGC_VAL = 600;
}
AGC_VAL = (OLD_AGC_VAL1 + OLD_AGC_VAL2 + AGC_VAL) / 3; //平均化で急激すぎる変化を回避
if (state7 == 1) { ///LOCKボタン押されて、LOCKステートに入っている★暫定 後で削除
AGC_VAL = 0; //0でPINダイオード電流最小、Gへはオープン、ATTとなっていない状態、スルー
}
dac.setVoltage(AGC_VAL, false);// DA制御
OLD_AGC_VAL2 = OLD_AGC_VAL1;
OLD_AGC_VAL1 = AGC_VAL;
//①LCDにAGC値を表示、デバッグ用
//lcd.setCursor(0, 1);
//lcd.write(" ");
//lcd.setCursor(0, 1);
//lcd.print(AGC_VAL);
//②AGCシリアルデバッグ出力
//Serial.print("AGC_VAL: ");
//Serial.print(AGC_VAL);
//for (int i = 0; i <= AGC_VAL / 50; i++) {
// Serial.print("*");
//}
//Serial.println(" ");
}
// ----------------------------------------------------------------------------------------------