mirror of
https://github.com/eried/portapack-mayhem.git
synced 2024-10-01 01:26:06 -04:00
New Antenna length Calculator
It reads the antennas definition from a txt file: WHIPCALC/ANTENNAS.TXT Inside the textfile you place each antenna you own with the following sintaxis: <antenna label> <elements length in mm, separated by a space> For example: ANT500 185 315 450 586 724 862 Input the required frequency, adjust the wave type (full / half / quarter, etc.) and the calculator will return the antenna length (metric and imperial) while also calculating how much you need to expand the fitting antennas you got defined on the txt. It may return up to 8 matching antennas, which is more than enough (normally you will have 2, perhaps 3 telescopic antennas around for your portapack) If by any chance your antennas txt got more than 8 antennas, and more than 8 matches the length of the freq / wave you want, it will only show the first 8 matching antennas and will warn you at the bottom that there are even more results (hidden). All calculations now are rounded into the best integer, considering first decimal, so precision is double than the original antenna calculator app.
This commit is contained in:
parent
85664c27f8
commit
8443008dfa
@ -64,22 +64,48 @@ void WhipCalcView::update_result() {
|
||||
|
||||
text_result_metric.set(m + "m " + cm + "." + mm + "cm");
|
||||
|
||||
// ANT500 elements for crude adjustment
|
||||
length /= 0.14;
|
||||
if (int(length) <= 4) {
|
||||
auto elements = to_string_dec_int((int)length, 1);
|
||||
text_result_ant500.set(elements + " " + frac_str[((int(length * 10.0) % 10) + 1) / 3] + "ANT500 elements");
|
||||
} else {
|
||||
text_result_ant500.set("-");
|
||||
}
|
||||
uint8_t ant_count = 8; //Shown antennas counter
|
||||
console.write("\f"); //Equivalent to clear console and string buffer.
|
||||
length *= 1000; //Get length in mm needed to extend the antenna
|
||||
for (antenna_entry antenna : antenna_db) { //go thru all antennas available
|
||||
if (length >= antenna.elements.front() && length <= antenna.elements.back()) //This antenna is OK
|
||||
{
|
||||
uint16_t element,refined_quarter=0;
|
||||
for(element=0; element < antenna.elements.size();element++) {
|
||||
if (length == antenna.elements[element]) //Exact element in length
|
||||
{
|
||||
element++; //Real element is +1 (zero based vector)
|
||||
break; //Done with this ant
|
||||
}
|
||||
else if (length < antenna.elements[element])
|
||||
{
|
||||
double remain, this_element, quarter = 0;
|
||||
remain = length - antenna.elements[element-1]; //mm needed from this element to reach length
|
||||
this_element=antenna.elements[element] - antenna.elements[element -1]; //total mm on this element
|
||||
quarter = (remain * 4) / this_element; //havoc & portack ended on this int(quarter) resolution.
|
||||
if (quarter - int(quarter) > 0.5) { //rounding gave a measure closer to next quarter
|
||||
refined_quarter=int(quarter) + 1;
|
||||
if(refined_quarter == 4) { //rounding gave a measure closer to next element
|
||||
refined_quarter = 0;
|
||||
element++;
|
||||
}
|
||||
} else {
|
||||
refined_quarter=int(quarter);
|
||||
}
|
||||
break; //Done with this ant
|
||||
}
|
||||
}
|
||||
if (!ant_count) {
|
||||
console.write(" and more ...");
|
||||
break;
|
||||
}
|
||||
console.write(antenna.label + " " + to_string_dec_int(element,1) + frac_str[refined_quarter] + " elements\n");
|
||||
ant_count--;
|
||||
}
|
||||
}
|
||||
|
||||
// Imperial
|
||||
calclength = (speed_of_light_fps / (double)field_frequency.value()) * divider;
|
||||
|
||||
/* auto feet = to_string_dec_int((int)length, 3);
|
||||
auto inch = to_string_dec_int(int(length * 10.0) % 12, 2);
|
||||
auto inch_c = to_string_dec_int(int(length * 100.0) % 10, 1); */
|
||||
|
||||
auto feet = to_string_dec_int(int(calclength), 3);
|
||||
calclength = get_decimals(calclength,12); //inches
|
||||
auto inch = to_string_dec_int(int(calclength), 2);
|
||||
@ -94,13 +120,38 @@ WhipCalcView::WhipCalcView(
|
||||
|
||||
add_children({
|
||||
&labels,
|
||||
&antennas_on_memory,
|
||||
&field_frequency,
|
||||
&options_type,
|
||||
&text_result_metric,
|
||||
&text_result_imperial,
|
||||
&text_result_ant500,
|
||||
&console,
|
||||
&button_exit
|
||||
});
|
||||
|
||||
File antennas_file; //LOAD /WHIPCALC/ANTENNAS.TXT from microSD
|
||||
auto result = antennas_file.open("WHIPCALC/ANTENNAS.TXT");
|
||||
antenna_db.clear(); //Start with fresh db
|
||||
if (result.is_valid()) {
|
||||
antenna_Default(); //There is no txt, store a default ant500
|
||||
} else {
|
||||
std::string line; //There is a txt file
|
||||
char one_char[1]; //Read it char by char
|
||||
for (size_t pointer=0; pointer < antennas_file.size();pointer++) {
|
||||
antennas_file.seek(pointer);
|
||||
antennas_file.read(one_char, 1);
|
||||
if ((int)one_char[0] > 31) { //ascii space upwards
|
||||
line += one_char[0]; //Add it to the textline
|
||||
}
|
||||
else if (one_char[0] == '\n') { //New Line
|
||||
txtline_process(line); //make sense of this textline
|
||||
line.clear(); //Ready for next textline
|
||||
}
|
||||
}
|
||||
if (line.length() > 0) txtline_process(line); //Last line had no newline at end ?
|
||||
if (!antenna_db.size()) antenna_Default(); //no antenna found on txt, use default
|
||||
}
|
||||
antennas_on_memory.set(to_string_dec_int(antenna_db.size(),2) + " antennas"); //tell user
|
||||
|
||||
options_type.on_change = [this](size_t, OptionsField::value_t) {
|
||||
this->update_result();
|
||||
@ -128,4 +179,32 @@ WhipCalcView::WhipCalcView(
|
||||
update_result();
|
||||
}
|
||||
|
||||
void ui::WhipCalcView::txtline_process(std::string& line) {
|
||||
if (line.find("#") != std::string::npos) return; //Line is just a comment
|
||||
size_t previous = 0;
|
||||
uint16_t value = 0;
|
||||
antenna_entry new_antenna;
|
||||
size_t current = line.find(" ");
|
||||
while (current != std::string::npos) {
|
||||
if (!previous) { //first space found
|
||||
new_antenna.label.assign(line,0,current); //antenna label
|
||||
} else {
|
||||
value = std::stoi(line.substr(previous,current - previous));
|
||||
if (!value) return; //No element length? abort antenna
|
||||
new_antenna.elements.push_back(value); //Store this new element
|
||||
}
|
||||
previous = current + 1;
|
||||
current = line.find(" ",previous); //Search for next space delimiter
|
||||
}
|
||||
if (!previous) return; //Not even a label ? drop this antenna!
|
||||
value = std::stoi(line.substr(previous,current - previous)); //Last element
|
||||
if (!value) return;
|
||||
new_antenna.elements.push_back(value);
|
||||
antenna_db.push_back(new_antenna); //Add this antenna
|
||||
}
|
||||
|
||||
void ui::WhipCalcView::antenna_Default() {
|
||||
antenna_db.push_back({"ANT500",{ 185, 315, 450, 586, 724, 862} }); //store a default ant500
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "ui_receiver.hpp"
|
||||
#include "ui_navigation.hpp"
|
||||
#include "string_format.hpp"
|
||||
#include <vector>
|
||||
|
||||
namespace ui {
|
||||
|
||||
@ -43,50 +44,67 @@ private:
|
||||
const double speed_of_light_mps = 299792458.0; // m/s
|
||||
const double speed_of_light_fps = 983571087.90472; // feet/s
|
||||
|
||||
const std::string frac_str[4] = { "", "1/4 ", "1/2 ", "3/4 " };
|
||||
const std::string frac_str[4] = { "", " 1/4", " 1/2", " 3/4" };
|
||||
|
||||
struct antenna_entry {
|
||||
std::string label { };
|
||||
std::vector <uint16_t> elements { };
|
||||
};
|
||||
|
||||
std::vector<antenna_entry> antenna_db { };
|
||||
|
||||
double get_decimals(double num, int16_t mult, bool round = false);
|
||||
void update_result();
|
||||
|
||||
uint16_t string_to_number(std::string);
|
||||
void txtline_process(std::string&);
|
||||
void antenna_Default();
|
||||
|
||||
Labels labels {
|
||||
{ { 5 * 8, 1 * 16 }, "Loaded:", Color::light_grey() },
|
||||
{ { 2 * 8, 2 * 16 }, "Frequency:", Color::light_grey() },
|
||||
{ { 2 * 8, 3 * 16 }, "Type:", Color::light_grey() }
|
||||
{ { 7 * 8, 3 * 16 }, "Wave:", Color::light_grey() },
|
||||
{ { 5 * 8, 4 * 16 }, "Metric:", Color::light_grey() },
|
||||
{ { 3 * 8, 5 * 16 }, "Imperial:", Color::light_grey() }
|
||||
};
|
||||
|
||||
Text antennas_on_memory {
|
||||
{ 13 * 8, 1 * 16, 2 * 16, 16 },
|
||||
};
|
||||
|
||||
FrequencyField field_frequency {
|
||||
{ 13 * 8, 2 * 16 },
|
||||
};
|
||||
|
||||
OptionsField options_type {
|
||||
{ 8 * 8, 3 * 16 },
|
||||
12,
|
||||
{ 13 * 8, 3 * 16 },
|
||||
7,
|
||||
{
|
||||
{ "Full wave", 8 },
|
||||
{ "Half wave", 4 },
|
||||
{ "Quarter wave", 2 },
|
||||
{ "3/4 wave", 6 },
|
||||
{ "1/8 wave", 1 },
|
||||
{ "3/8 wave", 3 },
|
||||
{ "5/8 wave", 5 },
|
||||
{ "7/8 wave", 7 }
|
||||
{ "Full", 8 },
|
||||
{ "Half", 4 },
|
||||
{ "Quarter", 2 },
|
||||
{ "3/4", 6 },
|
||||
{ "1/8", 1 },
|
||||
{ "3/8", 3 },
|
||||
{ "5/8", 5 },
|
||||
{ "7/8", 7 }
|
||||
}
|
||||
};
|
||||
|
||||
Text text_result_metric {
|
||||
{ 3 * 8, 5 * 16, 10 * 16, 16 },
|
||||
{ 13 * 8, 4 * 16, 10 * 16, 16 },
|
||||
"-"
|
||||
};
|
||||
Text text_result_imperial {
|
||||
{ 2 * 8, 6 * 16, 10 * 16, 16 },
|
||||
"-"
|
||||
};
|
||||
Text text_result_ant500 {
|
||||
{ 2 * 8, 8 * 16, 26 * 16, 16 },
|
||||
{ 13 * 8, 5 * 16, 10 * 16, 16 },
|
||||
"-"
|
||||
};
|
||||
Console console {
|
||||
{ 0, 7 * 16, 240, 144 } //Allows to show up to 8 antennas
|
||||
};
|
||||
|
||||
Button button_exit {
|
||||
{ 72, 264, 96, 32 },
|
||||
{ 72, 17 * 16, 96, 32 },
|
||||
"Exit"
|
||||
};
|
||||
};
|
||||
|
@ -595,7 +595,10 @@ void Console::write(std::string message) {
|
||||
pen_color = s.foreground;
|
||||
escape = false;
|
||||
} else {
|
||||
if (c == '\n') {
|
||||
if (c=='\f') { //Add FORM FEED (clear screen)
|
||||
clear();
|
||||
buffer.clear();
|
||||
} else if (c == '\n') {
|
||||
crlf();
|
||||
} else if (c == '\x1B') {
|
||||
escape = true;
|
||||
|
4
sdcard/WHIPCALC/ANTENNAS.TXT
Normal file
4
sdcard/WHIPCALC/ANTENNAS.TXT
Normal file
@ -0,0 +1,4 @@
|
||||
#<antenna label> <elements length in mm, separated by a space>
|
||||
ANT700 95 134 175 206 230 245
|
||||
ANT500 185 315 450 586 724 862
|
||||
CHEAPO 118 183 253 326 399 476
|
Loading…
Reference in New Issue
Block a user