VP-7720A 改造・修理 自動測定化プロジェクト その14 ― 2025/11/09
以下は歪率測定用のスケッチ(20251110版)です.まだ不安定な要素もありますが,
一応動作しています.ここまで来るのに多くのホームページ,ブログから学びました.
自動測定の前後にもリアルタイムでI/Pと歪率をデジタル表示します.
------------ 以下,スケッチ ーーーー 2025年11月10日版 ーーーー
#include <LiquidCrystal.h>
LiquidCrystal lcd(13, 8, 9, 10, 11, 12); // pin 8~13 for LCD
char InChar, dummy;
float MaxOut, MaxDist, Step;
int J, val, Nchange, dB, Ncount, Jmax;
int NStep24, NStep25; //Step number for key "24" and "25"
float InputLevel = 0, Distortion = 0;
float Fread() {
String FStr;
float F;
int line_len;
FStr = Serial.readStringUntil('\n');
line_len = FStr.length(); // 文字列の長さを取得する
if (line_len > 0) {
// 文字列を小数に変換する
F = FStr.toFloat();
return F;
}
}
int Iread() {
String IStr;
int I, line_len;
IStr = Serial.readStringUntil('\n');
line_len = IStr.length(); // 文字列の長さを取得する
if (line_len > 0) {
// 文字列を整数に変換する
I = IStr.toInt();
return I;
}
}
float IPV() {
float IPLevel = 3, IP, CoefIP;
// Level Reading for I/P Level
for (int i = 36; i <= 41; i++) {
if (digitalRead(i) == 0) { IPLevel = (40 - i) * 0.5; }
}
CoefIP = pow(10, IPLevel); //これは桁
// READING I/P LEVEL
IP = 0;
for (int i = 1; i <= 10; i++) { IP = IP + analogRead(A1); }
// 10 times average
IP = float(3.3 * 0.75457 * IP / 40950);
// "0.75457" is correction parameter for the supply voltage 3.3 V
IP = IP * CoefIP;
return IP;
}
float DistP() {
float DLevel = 3, CoefD, Dist;
// Level Reading for Distortion Level
for (int i = 42; i <= 51; i++) {
if (digitalRead(i) == 0) { DLevel = (42 - i) * 0.5; }
}
CoefD = pow(10, DLevel + 2); //これは桁
// READING Distortion LEVEL from DC OUTPUT of VP-7720A
Dist = 0;
for (int i = 1; i <= 50; i++) { Dist = Dist + analogRead(A0); }
// 50 times average
Dist = float(0.66 * 1.07097 * Dist / 40950);
// "1.07097" is correction parameter for the supply voltage 3.3 V
Dist = Dist * CoefD;
return Dist;
}
void change(int pinN, int Num) {
for (int i = 1; i <= Num; i++) {
digitalWrite(pinN, HIGH); // pinN is pin number.
delay(25);
digitalWrite(pinN, LOW);
delay(50);
}
}
void setup() {
Serial.begin(9600);
Serial.setTimeout(10000);
// VP-7720Aは遅い.従ってタイムアウトしないように設定
analogReadResolution(12);
lcd.begin(16, 2); // set up the LCD's number of columns and rows:
for (int i = 22; i <= 33; i++) { pinMode(i, OUTPUT); }
for (int i = 35; i <= 51; i++) { pinMode(i, INPUT); }
}
void loop() {
lcd.setCursor(0, 0);
lcd.print(" ");
InputLevel = IPV(); // IPV(): I/P Level}
Distortion = DistP(); // Distortion %
lcd.setCursor(0, 1);
lcd.print(InputLevel, 2);
lcd.print(" V ");
lcd.print(Distortion, 4);
lcd.print(" %");
if (Serial.available() > 0) {
InChar = Serial.read(); // VBAから命令を読む
// 'A'はAMPTD初期化の合図
if (InChar == 'A') {
lcd.setCursor(0, 1); // set the cursor to column 0, line 1
lcd.print(" ");
lcd.setCursor(0, 1);
lcd.print("A");
dummy = Serial.read(); // 受信バッファーにある変なもの
change(29, 1); // ひとつ変えると本来のモードに成る
val = digitalRead(35); // read display MODE. 1:FREQ, 0:AMPTD
if (val == 1) {
lcd.setCursor(0, 0);
lcd.print("Change MODE"); // FREQになっていたら警告
exit(1);
}
// AMPTD initialize to -75.9 dB
change(27, 9); // 27 means "2".
change(28, 10); // 28 means "3".
change(29, 10); // 29 means "4".
delay(20);
// Set AMPTD -34dB (40mV)
change(23, 4); // 23 means "B".
change(24, 2); // 24 means "C".
change(29, 1); // 29 means "4".
delay(400); //Waite due to VP-7720A auto range.
InputLevel = IPV(); // IPV(): I/P Level
Nchange = 24;
if (InputLevel > 0.25) { Nchange = 28; }
Ncount = 0;
//Set VP-7720AのINPUT~200mV〜250mVになるようにOSC/OUTPUTを調整
while ((InputLevel <= 0.2)or(InputLevel>=0.25)) {
change(Nchange, 1);
Ncount = Ncount + int((26-Nchange)/2);
//0.25以上の場合Nchange=28でNcountは-1,0.2以下の場合Ncountは+1
delay(500);
InputLevel = IPV(); // IPV(): I/P Level
}
dB = Ncount - 34;
InputLevel = IPV(); // IPV(): I/P Level
Serial.println(InputLevel, 3);
Serial.println(dB);
//送ったデータをもとにVBAがGainを計算する
lcd.setCursor(0, 0); // set the cursor to column 0, line 0
lcd.print(" ");
lcd.setCursor(0, 0);
lcd.print(InputLevel, 3);
lcd.print(" V ");
lcd.print(dB);
lcd.print(" dB");
delay(1000); //waite for stable communication
// Read data sent from PCーVBA; Maxout, MaxDist, Step,Jmax
MaxOut = Fread(); //許容最大出力電圧(V)
MaxDist = Fread(); //許容最大歪率 %)
Step = Fread(); // Step dB
Jmax = Iread(); //測定分割数
lcd.setCursor(0, 0);
lcd.print(MaxOut, 1);
lcd.print(" ");
lcd.print(MaxDist, 2);
lcd.print(" ");
lcd.print(Step, 2);
lcd.print(" ");
lcd.print(Jmax);
delay(30);
if (Step <= 0) { exit(1); }
if (Step < 0.5) { Step = 0.50; }
NStep24 = int(Step); //Step number for key "24"
NStep25 = round((Step - NStep24) * 10); //Step number for key "25"
// lcd.setCursor(0, 1);
// lcd.print(NStep24); //LCDに表示
// lcd.print(" ");
// lcd.print(NStep25);
// Main measurement loop start
J = 1;
InChar = 'D';
//'D'は歪(distortion)測定の合図
while ((InChar == 'D') and (J < Jmax + 1) and
(InputLevel <= MaxOut) and (Distortion <= MaxDist)) {
if (Serial.available() > 0) {
InChar = Serial.read(); // 受信データを読み込む
dummy = Serial.read(); // 受信バッファーにある変なもの
}
// lcd.setCursor(0, 1);
// lcd.print(J);
// lcd.print(" ");
// lcd.print(InChar);
// lcd.print(" ");
change(24, NStep24);
change(25, NStep25);
delay(500); // 電圧を安定して測る為 VBA側は600待ち
InputLevel = IPV(); // IPV(): I/P Level}
delay(5000); // 歪率を安定して測る為 VBA側は5500待ち
Distortion = DistP(); // Distortion %
Serial.println(InputLevel, 2);
Serial.println(Distortion, 4);
lcd.setCursor(0, 1);
lcd.print(InputLevel, 2);
lcd.print(" V ");
lcd.print(Distortion, 4);
lcd.print(" %");
J = J + 1;
}
change(27, 2); //測定が終わったらVBAから'E'の合図,入力を20dB下げる
}
}
}
最近のコメント