DG7EAOサイトの説明は断片的で,単純に真似してもIO割り付けに整合性がなく、動作しない。そのため、回路図、PCB、スケッチに矛盾が無く動作する様、纏めた。
実装基板は、秋月電子のアクリルケースに収納できるサイズとした。
部品実装基板。
TFTは、高さ8.5のピンソケット。DDSとnanoは、高さ3.5のピンソケットを使った。
抵抗0Ω(4本)は、ジャンパー。
回路図。
ダイオードは、1N60を使用。入手困難な部品がないので、簡単に作れる筈。
基板サイズ 80x112
Program
コメントに字下げなどの工夫がなくて読みづらく、一部書換を行ったが、プログラム変更は3点である。/***************************************************************************\
* Name : DDS_Sweeper.BAS *
* Author : Beric Dunn (K6BEZ) *
* Notice : Copyright (c) 2013 CC-BY-SA *
* : Creative Commons Attribution-ShareAlike 3.0 Unported License *
* Date : 9/26/2013 *
* Version : 1.0 *
* Notes : Written using for the Arduino Micro *
* : Pins: *
* : A0 - Reverse Detector Analog in *
* : A1 - Forward Detector Analog in *
* : Modified by Norbert Redeker (DG7EAO) 07/2014 *
* : TFT Display mit ILI9341 Chip, SPI, 240 x 320 *
* : usglib Grafik Bibliothek https://code.google.com/p/ucglib/ *
*---------------------------------------------------------------------------*
* Modification: 2015/11/26 JA2GQP *
* A1)DDS Pin Assign *
* A2)Ucglib_ILI9341_18x240x320_SWSPI Parameters *
* A3)DDS Reset Sequence *
\***************************************************************************/
#include <SPI.h>
#include "Ucglib.h"
// Define Pins used to control AD9850 DDS
//const int FQ_UD=10; // N6BEZ
//const int SDAT=11;
//const int SCLK=9;
//const int RESET=12;
//const int FQ_UD=9; // DG7EAO
//const int SDAT=11;
//const int SCLK=10;
//const int RESET=12;
const int FQ_UD=11; //A1)DDS Pin Assign JA2GQP
const int SDAT=10; //
const int SCLK=12; //
const int RESET=9; //
// Variablen für Display
double vswrArray[110]; //Array für SWR
int z = 0; // Index für Array
double SwrFreq = 14; // Variable für Freq. mit SWR Min.
double SwrMin = 100; // Variable für SWR Min.
double Freq1 = 1; // Freq. Links unterste Zeile Display
double Freq2 = 15; // Freq. Mitte unterste Zeile Display
double Freq3 = 30; // Freq. Mitte unterste Zeile Display
unsigned long milliold = 0; //Millisekunden für Entprellung Interrupt
unsigned long millinew = 0; //Millisekunden für Entprellung Interrupt
int flag = 0; // wir auf 1 gesetzt bei Interrupt, in void Loop perform_sweep
double counter = 0; // Zähler um erste Interrupts zu ignorieren
// Variablen für Messung
double Fstart_MHz = 1; // Start Frequency for sweep
//double Fstop_MHz = 10; // Stop Frequency for sweep
double Fstop_MHz = 30; // Stop Frequency for sweep
double current_freq_MHz; // Temp variable used during sweep
long serial_input_number; // Used to build number from serial stream
int num_steps = 100; // Number of steps to use in the sweep
char incoming_char; // Character read from serial stream
//Konstruktor für Display
//Ucglib_ILI9341_18x240x320_SWSPI ucg(/*sclk=*/ 10, /*data=*/ 11, /*cd=*/ 6 , /*cs=*/ 5, /*reset=*/ 4); // DG7EAO
Ucglib_ILI9341_18x240x320_SWSPI ucg(/*sclk=*/ 8, /*data=*/ 7, /*cd=*/ 6 , /*cs=*/ 5, /*reset=*/ 4); //A2) JA2GQP
// the setup routine runs once when you press reset:----------------------------------
void setup() {
// Schreibe Info Text auf Display
//ucg.begin(UCG_FONT_MODE_TRANSPARENT);
ucg.begin(UCG_FONT_MODE_SOLID);
ucg.clearScreen();
ucg.setRotate90();
ucg.setFont(ucg_font_ncenR14r);
//ucg.setColor(255, 255, 255); //weiss
//ucg.setColor(255, 0, 0); //rot
ucg.setColor(0, 255, 0); //grün
//ucg.setColor(1, 255, 0,0); // rot, Index1
ucg.setPrintPos(0,75);
ucg.print("Arduino");
ucg.setPrintPos(10,100);
ucg.print("Antennen");
ucg.setPrintPos(20,125);
ucg.print("Analyzer");
ucg.setPrintPos(30,150);
ucg.print("DG7EAO");
// Configiure DDS control pins for digital output
pinMode(FQ_UD,OUTPUT);
pinMode(SCLK,OUTPUT);
pinMode(SDAT,OUTPUT);
pinMode(RESET,OUTPUT);
//Tasten Interrupt an PIN 2
pinMode(2,OUTPUT);
digitalWrite(2, HIGH);
attachInterrupt(0, key2, FALLING);
unsigned long milliold = millis();
//Tasten Interrupt an PIN 3
pinMode(3,OUTPUT);
digitalWrite(3, HIGH);
attachInterrupt(1, key3, FALLING);
//milliold = millis();
// Configure LED pin for digital output
pinMode(13,OUTPUT);
pinMode(A0,INPUT); // Set up analog inputs on A0 and A1
pinMode(A1,INPUT);
analogReference(INTERNAL); //internal reference voltage
Serial.begin(57600); // initialize serial communication at 57600 baud
// Reset the DDS
//digitalWrite(RESET,HIGH); // N6BEZ
//digitalWrite(RESET,LOW);
digitalWrite(RESET,HIGH); //A3)DDS Reset Sequence JA2GQP
delay(1); //
digitalWrite(RESET,LOW); //
//
digitalWrite(SCLK,HIGH); //
digitalWrite(SCLK,LOW); //
digitalWrite(FQ_UD,HIGH); //
digitalWrite(FQ_UD,LOW); //
serial_input_number=0; //Initialise the incoming serial number to zero
}
// the loop routine runs over and over again forever:----------------------------------
void loop() {
//Check for character
if(Serial.available()>0){
incoming_char = Serial.read();
switch(incoming_char){
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
serial_input_number=serial_input_number*10+(incoming_char-'0');
break;
case 'A': //Turn frequency into FStart
Fstart_MHz = ((double)serial_input_number)/1000000;
serial_input_number=0;
break;
case 'B': //Turn frequency into FStop
Fstop_MHz = ((double)serial_input_number)/1000000;
serial_input_number=0;
break;
case 'C': //Turn frequency into FStart and set
// DDS output to single frequency
Fstart_MHz = ((double)serial_input_number)/1000000;
SetDDSFreq(Fstart_MHz * 1000000);//SetDDSFreq(Fstart_MHz);
delay(100);
SetDDSFreq(Fstart_MHz * 1000000);
serial_input_number=0;
break;
case 'N': // Set number of steps in the sweep
num_steps = serial_input_number;
serial_input_number=0;
break;
case 'S':
case 's':
Perform_sweep();
break;
case '?': // Report current configuration to PC
Serial.print("Start Freq:");
Serial.println(Fstart_MHz*1000000);
Serial.print("Stop Freq:");
Serial.println(Fstop_MHz*1000000);
Serial.print("Num Steps:");
Serial.println(num_steps);
break;
}
Serial.flush();
}
if (flag == 1 && counter >2) //Perform Sweep nach Interrupt PIN2 oder 3
{ // ingnoriere Startup Interrupts durch counter
flag = 0;
Perform_sweep();
}
}
void Perform_sweep(){
double FWD=0;
double REV=0;
double VSWR;
double Fstep_MHz = (Fstop_MHz-Fstart_MHz)/num_steps;
z = 0;
SwrMin = 100;
ucg.setPrintPos(220,150);
ucg.print("... Starte");
ucg.clearScreen();
for(int i=0;i<=num_steps;i++){ // Start loop
current_freq_MHz = Fstart_MHz + i*Fstep_MHz;// Calculate current frequency
SetDDSFreq(current_freq_MHz*1000000); // Set DDS to current frequency
//delay(10); // Wait a little for settling
delay(100);
REV = analogRead(A0); // Read the reverse voltages
FWD = analogRead(A1); // forward voltages
REV = REV-5; //Offset Correction
if(REV>=FWD){REV = FWD-1;}
if (REV <1) {REV = 1;}
VSWR = (FWD+REV)/(FWD-REV);
VSWR = VSWR * 1000; //Scale Output
Serial.print(current_freq_MHz*1000000); // Send current line back to PC over serial bus
Serial.print(",0,");
Serial.print(VSWR);
Serial.print(",");
Serial.print(FWD);
Serial.print(",");
Serial.println(REV);
vswrArray[z] = VSWR/1000; //Submitter SWR to Array
if (vswrArray[z] > 10) vswrArray[z] = 10; //Max SWR
if (vswrArray[z] < SwrMin && vswrArray[z] > 1){ //Minimum SWR
SwrMin = vswrArray[z]; //Minimum SWR and frequency store
SwrFreq = current_freq_MHz;
}
z = z + 1;
}
// Send "End" to PC to indicate end of sweep
Serial.println("End");
Serial.flush();
//Zeichne Grid
CreateGrid();
//Linienfarbe = rot
ucg.setColor(255, 0, 0); //rot
// Draw Line
// 30 = swr 10 210 = swr 0
// Diff swr 10 = 180
// swr 2 = 18 * 2
double last = 10;
double xx = 6;
int j = 1;
for (int i = 1 ;i < 103; i++){
xx = vswrArray[i];
ucg.drawLine(j,210-last*18, j+1, 210-xx*18);
ucg.drawLine(j+1,210-last*18, j+2, 210-xx*18);
j = j + 3;
last = xx;
}
}
// Setze DDS Frequenz-----------------------------------------------------------------
void SetDDSFreq(double Freq_Hz){
int32_t f = Freq_Hz * 4294967295/125000000; // Calculate the DDS word - from AD9850 Datasheet
for (int b=0;b<4;b++,f>>=8){ // Send one byte at a time
send_byte(f & 0xFF);
}
send_byte(0); // 5th byte needs to be zeros(AD9850 Command Parameters)
digitalWrite(FQ_UD,HIGH); // Strobe the Update pin to tell DDS to use values
digitalWrite(FQ_UD,LOW);
}
// Sende Daten an DDS-----------------------------------------------------------------
void send_byte(byte data_to_send){
for (int i=0; i<8; i++,data_to_send>>=1){ // Bit bang the byte over the SPI bus
digitalWrite(SDAT,data_to_send & 0x01); // Set Data bit on output pin
digitalWrite(SCLK,HIGH); // Strobe the clock pin
digitalWrite(SCLK,LOW);
}
}
//Zeichne Grid auf TFT Display--------------------------------------------------------
void CreateGrid(){
//ucg.clearScreen();
double maxSwr = 10;
ucg.drawHLine(0,120,310);
ucg.drawHLine(0,196,310);
ucg.drawVLine(78,30,180);
ucg.drawVLine(155,30,180);
ucg.drawVLine(233,30,180);
ucg.setPrintPos(0, 235);
ucg.print(Freq1,3);
ucg.setPrintPos(130, 235);
ucg.print(Freq2,3);
ucg.setPrintPos(260, 235);
ucg.print(Freq3,3);
ucg.setPrintPos(10, 15);
ucg.print("SWR");
ucg.setPrintPos(70, 15);
ucg.print(SwrMin,2);
ucg.setPrintPos(115, 15);
ucg.print(">");
ucg.setPrintPos(130, 15);
ucg.print(maxSwr,2);
ucg.setPrintPos(250, 15);
//ucg.print((freqCenter/1000000*1.05),3);
ucg.print(SwrFreq,3);
ucg.drawRFrame(0,30,310,180, 1);
}
// Interrupt Service Routine----------------------------------------------------------
// Abfrage Low an Pin 2
void key2(){
counter = counter + 1; //ignoriere Startup Interrupts > counter
//Entprellen mit millis()
millinew = millis();
if (millinew - milliold < 1000){
milliold = millinew;
return;
}
milliold = millinew;
Fstart_MHz = 1; // Start Frequency for sweep
Fstop_MHz = 30; // Stop Frequency for sweep
num_steps = 102; // Steps
Freq1 = 1; // Unterste Zeile Display Freq. Links
Freq2 = 15; // Unterste Zeile Display Freq. Mitte
Freq3 = 30; // Unterste Zeile Display Freq. Recht
//Perform_sweep();
flag = 1;
}
// Interrupt Service Routine----------------------------------------------------------
// Abfrage Low an Pin 3
void key3()
{
counter = counter + 1; //ignoriere Startup Interrupts > counter
millinew = millis(); //Entprellen mit millis()
if (millinew - milliold < 1000){
milliold = millinew;
return;
}
milliold = millinew;
int x = SwrFreq + 0.5; //Runde auf Mhz
Fstart_MHz = x-1; // Start Frequency for sweep
Fstop_MHz = x+1; // Stop Frequency for sweep
num_steps = 102; // Steps
Freq1 = x-1; // Unterste Zeile Display Freq. Links
Freq2 = x; // Unterste Zeile Display Freq. Mitte
Freq3 = x+1; // Unterste Zeile Display Freq. Rechts
//Perform_sweep();
flag = 1;
}
thank you. 73 9w2nfe
返信削除Sure.
削除Hello. Make you this PCB board on Eagle software?
返信削除I would like to know if he did.
削除The CAD I am using is not Eagle. It is a popular pcbe in Japan.
削除Hello,
返信削除Will it be possible to modify the sketch to use 1.8" TFT display ST7735S as 2.2" display is not readily available
Please use 2.4 "or 2.8" using ili 9341 for the controller.
削除Thank you
削除Can you please share the PCB in PDF format as getting the JPG on size is a problem
Hi, gaurav
削除The necessary information should be on the download site.
https://sites.google.com/site/ja2gqp/
How about using the Nextion Displays...... I guess they have a waveform widget also.
返信削除In the Nexion Editor, make screen, touch. Arduino will only process data with Nexion.
削除For this level of display, touch can be easily done with Nextion. Unfortunately it's a novice in Nextion, so I can not make it.
Hi,
返信削除i am getting a lot of errors during compilation. i have ili9341 2.2 TFT display!
sp3nyrのアナライザは、ファームを改造して校正機能を付加したものと思われます。改造したファームと校正機能をセットで使わなければ、機能しないと思います。
返信削除sp3nytに問い合わせたら如何ですか。
削除Hello.
返信削除I have a problem about the program. You have to programs, one on Your download side, and one In the top of his artikel. Non of then will run, with out a error with the Arduino Nano.
Is it possible to send the program, that works with the Nano?
Vy 73 de
oZ2ADU René
Hi,René
削除Please download the hex file from the antenna analyzer folder.
https://sites.google.com/site/ja2gqp/
When trying to upload the code to the Arduino Nano, it tells me that the file exceeds the capacity. How can I solve this problem? Thank you LU1VFP Edgardo. Patagonia Argentina
返信削除
返信削除Hi Edgardo.
This is probably due to a different version of Ucglib.
A library is also included so that it can be compiled.
Unzip the zip file and compile it.
Please download from here.
https://sites.google.com/site/ja2gqp/
Download the zip file dated 2021/4/13 in the Antenna Analyzer folder.
It seems that the device settings of Arduino IDE are inappropriate.
返信削除If it is Arduino Nano ATmega328P (Old Bootloader), there can be no memory shortage.
error: 'ucg_font_ncenR14r' was not declared in this scope
返信削除Please download from here
返信削除https://sites.google.com/view/ja2gqp
Download DDS_sweeper1_TFT.zip from the Antenna Analyzer folder.
You can unzip the zip file and compile it as it is.
Is possible SI5351 as rf source, because ad9850 is hard to find and expensive.?
返信削除