I have breadboarded a AD8307 module (from SV1AFN) with an Arduino Nano to make an RF meter. The AD8307 has a 50R input impedance. I have added on the front a 40dB attenuator tap of 4x680R and 50R. Thus the divide ratio is 4x680/25. I have written the software to allow this to display the actual RF voltage at the input. Code below.
Then I have built a prototype BPF, transformer + 100p --> 8p coupling --> transformer + 100p, output tapped on primary (both type 5u3L from SPECTRUM COMMUNICATIONS). I roughly tuned this to 40m. I applied an input from my SI5351 VFO from 6000 to 8500kHz. This is what I got:
With a bit of tuning I can probably get the top a bit flatter, but I am pleased with the result.
Code
// RF_METER
#include "Oled.h" // include
#define AREF 3250 // actual value of 3V3 ref (mV)
#define AMAX 1023
#define SLOPE 25.0 // 25mV/dB
#define INTERCEPT 87.0 // -85 + 40dB
#define ATTN 40.0 // attenuation
#define IMP 50 // load ohms
float Vrms, dBm, mW; // global variable to display
void setup() {
oled.begin(); // begin OLED
analogReference(EXTERNAL); // set ADC to use external ref, Nano 3V3
}
void loop() {
int ADCin;
double mV;
ADCin = analogRead(A3); // 0-1023
delay(50);
mV = (double)(map(ADCin, 0, AMAX, 0, AREF)); // AREF in mV, calculate & convert to double
dBm = (mV / SLOPE) - INTERCEPT + ATTN; // in doubles
mW = pow(10.0, (dBm / 10.0)); // in double, out double, 0dBm = 1mW
Vrms = sqrt((mW / 1000.0) * IMP); // in double, out double
dispUpdate(); // display
}
void dispUpdate() { // display loop
oled.firstPage();
do {
if( Vrms < 1.0 ) {
dispNumL(35, 5, (Vrms * 1000.0), 0); // display mV
dispMsgL(90, 5, "mV");
}
else {
dispNumL(35, 5, Vrms, 1); // display
dispMsgL(90, 5, "V");
}
dispNumL(35, 25, dBm, 0); // display dBm
dispMsgL(90, 25, "dBm");
if ( mW > 1000.0 ) {
dispNumL(35, 45, (mW / 1000), 1); // display W
dispMsgL(90, 45, "W");
}
else {
dispNumL(35, 45, mW, 1); // display mW
dispMsgL(90, 45, "mW");
}
} while(oled.nextPage());
}
No comments:
Post a Comment