Arduino: Antenna_analyzer_1.2
///////////////////////////// | |
//Antenna analyzer KL V1.2 // | |
///////////////////////////// | |
/** Copyright 2013 Luca Facchinetti, IW2NDH | |
All trademarks referred to in source code and documentation are copyright their respective owners. | |
This program is free software: you can redistribute it and/or modify | |
it under the terms of the GNU General Public License as published by | |
the Free Software Foundation, either version 3 of the License, or | |
(at your option) any later version. | |
This program is distributed in the hope that it will be useful, | |
but WITHOUT ANY WARRANTY; without even the implied warranty of | |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
GNU General Public License for more details. | |
You should have received a copy of the GNU General Public License | |
along with this program. If not, see <http://www.gnu.org/licenses/>. | |
If you offer a hardware kit using this software, show your appreciation by sending the author | |
a complimentary kit or a donation to a cats refuge ;-) | |
*/ | |
#include "U8glib.h" | |
#include "M2tk.h" | |
#include "utility/m2ghu8g.h" | |
#include <AH_AD9850.h> | |
U8GLIB_PCD8544 u8g(8, 9, 11, 10, 13); | |
AH_AD9850 AD9850(5, 6, 7, 4); //AH_AD9850(int CLK, int FQUP, int BitData, int RESET); | |
float freqCenter; | |
float stepSpan; | |
float bandSwr[5]; | |
float freqBand[5] = {3650000.0, 7100000.0, 14175000.0, 21225000.0, 28850000.0}; | |
byte SWR[84]; | |
//byte Z[84]; | |
float minSwr; | |
float maxSwr; | |
uint32_t next_state_sweep = 0; | |
byte select_display = 0; | |
uint32_t center_value = 0; | |
uint32_t span_value = 0; | |
//from radians to degrees | |
const float R2d = 57.296; | |
//Standard characteristic impedance | |
const float Z0 = 50.0; | |
float Angle ; | |
float Mag ; | |
float Ximp ; | |
float Rimp ; | |
float Zimpl ; | |
float Swr ; | |
void Docalcswr(){ | |
float Tmpsa ; | |
float Tmpsb ; | |
float Tmpsc ; | |
//adc variables | |
float Adcphase; | |
float Adcmagnitude; | |
float Returnloss; | |
float refer = 5.0*analogRead(A1)/1023; | |
Adcphase = 5.0*analogRead(A2)/1023; | |
Adcmagnitude = 5.0*analogRead(A0)/1023; | |
Returnloss = (60.0 * Adcmagnitude /refer); | |
Returnloss = Returnloss - 30.0 + 7.7656 ; | |
Angle = (180.0 * Adcphase /refer)- 90; | |
Tmpsa = Returnloss / 20.0; | |
Tmpsb = 10.0; | |
Mag = pow(Tmpsb , Tmpsa); | |
Mag = 1.0 / Mag; | |
Tmpsa = 1.0 + Mag; | |
Tmpsb = 1.0 - Mag; | |
Tmpsc = Tmpsa / Tmpsb; | |
Swr = abs(Tmpsc); | |
} | |
void Docalcall(){ | |
Docalcswr(); | |
float Tmpsa ; | |
float Tmpsb ; | |
float Tmpsc ; | |
float Rrsqrtmp ; | |
float Sssqrtmp ; | |
float F ; | |
float G ; | |
float Rr ; | |
float Ss ; | |
Tmpsa = Angle / R2d; | |
F = cos(Tmpsa); | |
G = sin(Tmpsa); | |
Rr = F * Mag; | |
Ss = G * Mag; | |
Tmpsa = 1.0 - Rr; | |
Rrsqrtmp = Tmpsa * Tmpsa; | |
Sssqrtmp = Ss * Ss; | |
Tmpsa = Rrsqrtmp + Sssqrtmp; | |
Tmpsb = 2.0 * Ss; | |
Tmpsc = Tmpsb / Tmpsa; | |
Tmpsa = Tmpsc * Z0; | |
Ximp = abs(Tmpsa); | |
Tmpsa = Rr * Rr; | |
Tmpsb = 1.0 - Tmpsa; | |
Tmpsa = Tmpsb - Sssqrtmp; | |
Tmpsb = Rrsqrtmp + Sssqrtmp; | |
Tmpsc = Tmpsa / Tmpsb; | |
Tmpsa = Tmpsc * Z0; | |
Rimp = abs(Tmpsa); | |
Tmpsa = Rimp * Rimp; | |
Tmpsb = Ximp * Ximp; | |
Tmpsc = Tmpsa + Tmpsb; | |
Zimpl = sqrt(Tmpsc); | |
} | |
void calcParameters(int k){ | |
float freq; | |
freq = freqCenter + (k-42)* stepSpan; | |
AD9850.set_frequency(freq); | |
delay(10); | |
Docalcswr(); | |
if (Swr < 1.1) Swr = 1.1; | |
if (Swr > 3.0) Swr = 3.0; | |
SWR[k] = 54 -(18*Swr); //MAX SWR = 3.0 | |
if (minSwr > Swr) minSwr = Swr; | |
if (maxSwr < Swr) maxSwr = Swr; | |
// Z[k] = 36 -(0.24* min(Zimpl,150)); | |
} | |
void creaGrid(){ | |
u8g.setFont(u8g_font_u8glib_4); | |
for (int i = 1 ;i < 3; i++){ | |
u8g.drawHLine(0,i*12,83); | |
} | |
for (int i = 1 ;i < 7; i++){ | |
u8g.drawVLine(i*12,0,36); | |
} | |
u8g.setPrintPos(0, 42); | |
u8g.print((freqCenter - 42*stepSpan)/1000000,3); | |
u8g.setPrintPos(30, 42); | |
u8g.print(freqCenter/1000000,3); | |
u8g.setPrintPos(60, 42); | |
u8g.print((freqCenter + 42*stepSpan)/1000000,3); | |
u8g.setPrintPos(0, 48); | |
u8g.print("SWR"); | |
u8g.setPrintPos(30, 48); | |
u8g.print(minSwr, 2); | |
u8g.setPrintPos(60, 48); | |
u8g.print(maxSwr, 2); | |
u8g.drawRFrame(0,0,84,36, 1); | |
} | |
void printSwr(){ | |
for (int k = 0;k < 83; k++){ | |
u8g.drawLine(k,SWR[k],k+1,SWR[k+1]); | |
// u8g.drawCircle(k,Z[k], 1, U8G_DRAW_ALL) ; | |
} | |
} | |
void swrFrame(u8g_uint_t pos, float swrVal){ | |
u8g.drawBox(30, 10+pos, 53*((min(swrVal,2.5)-1.0)/1.5), 5); | |
u8g.drawFrame(30, 10+pos, 53, 5); | |
u8g.drawVLine(48, 10+pos,4); | |
u8g.drawVLine(65, 10+pos,4); | |
} | |
void creaBand(){ | |
u8g.setPrintPos(45,8); | |
u8g.print(1.5,1); | |
u8g.setPrintPos(62,8); | |
u8g.print(2.0,1); | |
for (int i = 0 ;i < 5; i++){ | |
u8g_uint_t pos = 8*i; | |
u8g.setPrintPos(0, 15+pos); | |
u8g.print(freqBand[i]/1000000,3); | |
swrFrame(pos,bandSwr[i]); | |
} | |
} | |
void barraZ(u8g_uint_t pos, float val){ | |
u8g.drawBox(30 , pos, 53*((min(val,100))/100), 5); | |
u8g.drawFrame(30 , pos, 53, 5); | |
u8g.drawVLine(56,pos,4); | |
u8g.setPrintPos(10,pos+7); | |
u8g.print(val,1); | |
} | |
void creaZimp(){ | |
u8g.setPrintPos(0,8); | |
u8g.print("freq:"); | |
u8g.setPrintPos(30,8); | |
u8g.print(freqCenter,0); | |
u8g.setPrintPos(0,17); | |
u8g.print("SWR"); | |
swrFrame(0,Swr); | |
u8g.setPrintPos(0,27); | |
u8g.print("R"); | |
barraZ(20,Rimp); | |
u8g.setPrintPos(0,37); | |
u8g.print("X"); | |
barraZ(30,Ximp); | |
u8g.setPrintPos(0,47); | |
u8g.print("Z"); | |
barraZ(40,Zimpl); | |
} | |
uint8_t uiKeyUpPin = 2; | |
uint8_t uiKeyDownPin = 3; | |
uint8_t uiKeySelectPin = 12; | |
M2_EXTERN_ALIGN(el_top); | |
M2tk m2(&el_top, m2_es_arduino_rotary_encoder, m2_eh_4bs, m2_gh_u8g_ffs); | |
uint32_t u32_freq(m2_rom_void_p element, uint8_t msg, uint32_t val) | |
{ | |
if ( msg == M2_U32_MSG_SET_VALUE ){ | |
center_value = val; | |
freqCenter = (float)center_value; | |
} | |
return center_value; | |
} | |
uint32_t u32_span(m2_rom_void_p element, uint8_t msg, uint32_t val) | |
{ | |
if ( msg == M2_U32_MSG_SET_VALUE ){ | |
span_value = val; | |
} | |
if ( msg == M2_U32_MSG_GET_VALUE ){ | |
if (span_value > 2*center_value) | |
span_value = 0; | |
} | |
stepSpan = (float)(span_value/84); | |
return span_value; | |
} | |
M2_LABEL(el_label1, NULL, "freq:"); | |
M2_U32NUMFN(el_u8_cb, "a1.6c8", u32_freq); | |
M2_LABEL(el_label2, NULL, "span: "); | |
M2_U32NUMFN(el_span, "a1.6c8", u32_span); | |
void fn_details(m2_el_fnarg_p fnarg) { | |
select_display = 2; | |
m2.setRoot(&m2_null_element); // selecting this, will remove all menues | |
} | |
void fn_5_band(m2_el_fnarg_p fnarg) { | |
select_display = 1; | |
m2.setRoot(&m2_null_element); // selecting this, will remove all menues | |
} | |
void fn_ok(m2_el_fnarg_p fnarg) { | |
select_display = 0; | |
m2.setRoot(&m2_null_element); // selecting this, will remove all menues | |
} | |
void fn_reset(m2_el_fnarg_p fnarg) { | |
center_value = 7100000; | |
freqCenter = 7100000.0; | |
span_value = 1000000; | |
stepSpan = 1000000.0; | |
} | |
M2_BUTTON(el_details, "f4", "R-X-Z", fn_details); | |
M2_BUTTON(el_5_band, "f4", "5-Band", fn_5_band); | |
M2_BUTTON(el_ok, "f4", "Ok", fn_ok); | |
M2_BUTTON(el_reset, "f4", "Reset", fn_reset); | |
M2_LIST(list) = { | |
&el_label1, &el_u8_cb, | |
&el_label2, &el_span, | |
&el_details,&el_5_band, | |
&el_reset,&el_ok | |
}; | |
M2_GRIDLIST(el_top_grid, "c2",list); | |
M2_ALIGN(el_top, "-1|1W64H64", &el_top_grid); | |
uint8_t update_graph_Zimp(void) { | |
if ( next_state_sweep < 2) { | |
Docalcall(); | |
next_state_sweep++; | |
return 0; | |
}else{ | |
next_state_sweep = 0; | |
return 1; | |
} | |
} | |
uint8_t update_graph_band(void) { | |
if ( next_state_sweep < 5) { | |
AD9850.set_frequency(freqBand[next_state_sweep]); | |
delay(10); | |
Docalcswr(); | |
bandSwr[next_state_sweep] = Swr; | |
next_state_sweep++; | |
return 0; | |
}else{ | |
next_state_sweep = 0; | |
return 1; | |
} | |
} | |
uint8_t update_graph(void) { | |
if ( next_state_sweep < 84) { | |
if(next_state_sweep == 0){ | |
minSwr = 10.0; | |
maxSwr = 1.0; | |
} | |
calcParameters(next_state_sweep); | |
next_state_sweep++; | |
return 0; | |
}else{ | |
next_state_sweep = 0; | |
return 1; | |
} | |
} | |
// update graphics, will return none-zero if an update is required | |
uint8_t update_graphics(void) { | |
if ( m2.getRoot() == &m2_null_element ) { | |
// check for any keys and assign a suitable menu again | |
if ( m2.getKey() != M2_KEY_NONE ) { | |
m2.setRoot(&el_top); | |
select_display = 0; | |
} | |
switch (select_display){ | |
case 1: return update_graph_band(); | |
break; | |
case 2: { | |
AD9850.set_frequency(freqCenter); | |
return update_graph_Zimp(); | |
} | |
break; | |
default: return update_graph(); | |
} | |
} | |
// no update for the graphics required | |
return 0; | |
} | |
//================================================================ | |
// overall draw procedure for u8glib | |
void draw(void) { | |
if ( m2.getRoot() == &m2_null_element ) { | |
u8g.setDefaultForegroundColor(); | |
switch (select_display){ | |
case 1: creaBand(); | |
break; | |
case 2: creaZimp(); | |
break; | |
default: | |
{ creaGrid(); | |
printSwr(); | |
} | |
} | |
} | |
m2.draw(); | |
} | |
//================================================================ | |
// Arduino setup and loop | |
void setup(void) { | |
// initialize serial communication at 9600 bits per second: | |
Serial.begin(9600); | |
// Connect u8glib with m2tklib | |
m2_SetU8g(u8g.getU8g(), m2_u8g_box_icon); | |
m2.setFont(0, u8g_font_04b_03); | |
u8g.setFont(u8g_font_04b_03); | |
// define button for the select message | |
m2.setPin(M2_KEY_SELECT, 12); // dogm128 shield, 2nd from top | |
// The incremental rotary encoder is conected to these two pins | |
m2.setPin(M2_KEY_ROT_ENC_A, 3); | |
m2.setPin(M2_KEY_ROT_ENC_B, 2); | |
AD9850.reset(); //reset module | |
delay(1000); | |
AD9850.powerDown(); //set signal output to LOW | |
center_value = 7100000; | |
freqCenter = 7100000.0; | |
// freqCenter = (float)(readEEprom(0) * 100); | |
span_value = 1000000; | |
stepSpan = 1000000.0; | |
// stepSpan = (float)(100*readEEprom(4)/84); | |
AD9850.set_frequency(0,0,freqCenter); | |
} | |
void loop() { | |
m2.checkKey(); | |
if ( m2.handleKey() != 0 || update_graphics() != 0 ) { | |
u8g.firstPage(); | |
do { | |
m2.checkKey(); | |
draw(); | |
} while( u8g.nextPage() ); | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment