Created
December 9, 2013 17:36
-
-
Save jackdev23/7876502 to your computer and use it in GitHub Desktop.
Arduino: Antenna_analyzer_1.2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
///////////////////////////// | |
//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