Skip to content

Commit 729e43b

Browse files
author
Ladislav Foldyna
committed
Added Calibration utility
for more details please see README.md file
1 parent cf266c2 commit 729e43b

File tree

2 files changed

+135
-0
lines changed

2 files changed

+135
-0
lines changed

utils/calibration/README.md

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
Based on the measurement, Analyzer did not provide accurate SWR results. The raw SWR
2+
was very dependent on frequency and did not match an expected SWR.
3+
4+
The raw SWR samples are shown below:
5+
6+
Freq[Hz]/Expected SWR 1 1,5 2 3 4 7,8 20
7+
3000000 1,00517 1,14305 1,55263 2,43736 3,28571 6,40952 16,12222
8+
7000000 1,00504 1,14516 1,53968 2,38526 3,15544 5,93103 13,83333
9+
9000000 1,00482 1,15789 1,53251 2,32927 3,07463 5,6129 11,98413
10+
10500000 1,00442 1,14634 1,49639 2,24953 2,92593 5,20588 10,2755
11+
11500000 1,0042 1,13889 1,46739 2,14992 2,76547 4,77483 8,95402
12+
14000000 1,00386 1,1346 1,41396 1,97744 2,47143 3,88776 6,27692
13+
21000000 1,00377 1,1477 1,40177 1,90788 2,3211 3,41633 5,03364
14+
28000000 5,8951 1,1529 1,43052 2,02791 2,48699 3,83 5,8951
15+
16+
Therefore a calibration is highly recommended. It was tested many interpolation techniques with
17+
various results. Very negative think was a strong frequency dependence. Therefore the
18+
Antenna analyzer bandwidth (1-30MHz) was divided into the chunks - 30 chunks; 1per 1MHz
19+
20+
After bandwidth splitting, it was possible to analyze the SWR curve and find a technique
21+
for computing real (expected) SWR from raw SWR. The best interpolation result returned a polynominal
22+
function order 3
23+
24+
Folowing formula shows how the rela SWR is computed by Antenna Analyzer.
25+
26+
real SWR = coef3 * RAW_SWR^3 + coef2 * RAW_SWR^2 + coef1 * RAW_SWR + con
27+
28+
where coef3..1 and con are pre-computed values for each chunk. The coefficients are computed by calibration.py
29+
and have to be copy&pasted to arduino source code.
30+
31+
What does the utility calibration.py do:
32+
33+
1) calibration.py connects the Antenna Analyzer
34+
2) User is asked to enter a calibration Load
35+
example "500" means: user has connected 500 Ohm dummy load and calibration can start
36+
3) calibration.py receives SWR values from Antenna Analyzer for every bandwidth chunk
37+
4) User should repeat steps 2 and 3 with various dummy loads - recommended dummy load range is 50 - 1000 Ohm
38+
5) If user enters an empty string then the utility computes the coefficients.
39+
6) The coefficients are printed as C-array initialization structure.
40+
7) The C-array initialization structure has to be copy&pasted to arduino source code - initialization part
41+
8) The arduino source code has to be compiled and uploaded to Arduino.
42+

utils/calibration/calibration.py

+93
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
#!/usr/bin/env python3
2+
3+
# Setup script for calibration Antenna Analyzer project
4+
# the result should has to be inserted to Arduino source code
5+
6+
# Usage
7+
# ./calibration.py <COM_Port>
8+
#
9+
# Copyright (C) 2018 Ladislav Foldyna
10+
# Author: Ladislav Foldyna
11+
12+
# This file is part of AntennaAnalyzer.
13+
#
14+
# AntennaAnalyzer is free software: you can redistribute it and/or modify
15+
# it under the terms of either the Apache Software License, version 2, or
16+
# the GNU Lesser General Public License as published by the Free Software
17+
# Foundation, version 3 or above.
18+
#
19+
# AntennaAnalyzer is distributed in the hope that it will be useful,
20+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
21+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
22+
#
23+
# You should have received a copy of both the GNU Lesser General Public
24+
# License and the Apache Software License. If not,
25+
# see <http://www.gnu.org/licenses/> and <http://www.apache.org/licenses/>.
26+
27+
import sys
28+
import serial
29+
import numpy as np
30+
31+
def main():
32+
all_samples = [];
33+
34+
if ( len(sys.argv) < 2 ):
35+
sys.stderr.write('Usage: {} COM_PORT\n'.format(sys.argv[0]));
36+
sys.exit(1);
37+
38+
com_port = sys.argv[1]
39+
40+
try:
41+
ser = serial.Serial(com_port, 57600)
42+
except serial.SerialException as e:
43+
sys.stderr.write('Could not open serial port {}: {}\n'.format(com_port, e))
44+
sys.exit(1);
45+
46+
# when client establich an connection to arduino, arduino resets itself
47+
# we will read booting characters but they are not important for calibration
48+
49+
try:
50+
while True:
51+
arduino_answer = str(ser.readline(), 'utf-8').rstrip()
52+
print(arduino_answer)
53+
if ( arduino_answer.find('#OK#') >= 0 ):
54+
break;
55+
56+
# now calibration loop is starting
57+
while True:
58+
command = input("Enter Calibration Load: ")
59+
60+
if (len(command) == 0 ):
61+
break;
62+
63+
command = command + 'f'
64+
65+
#sending user command
66+
ser.write(command.encode())
67+
68+
run_results = []
69+
70+
#reading SWR calibration samples
71+
# format is: <expected, frequency, raw_swr>
72+
while True:
73+
arduino_answer = str(ser.readline(), 'utf-8').rstrip()
74+
print(arduino_answer)
75+
if ( arduino_answer.find('#OK#') >= 0 ):
76+
break;
77+
expected_swr, freq, swr = arduino_answer.split(',')
78+
run_results.append([float(expected_swr), int(freq), float(swr)])
79+
80+
all_samples.append(run_results)
81+
except serial.SerialException as e:
82+
sys.stderr.write('Communication error {}\n'.format(e))
83+
sys.exit(1)
84+
85+
#computing the coefficients
86+
for i in range(0,30):
87+
x = [b[2] for b in [item[i] for item in all_samples]]
88+
y = [b[0] for b in [item[i] for item in all_samples]]
89+
z = np.polyfit(x,y,3)
90+
print("{ .do_correction = 1, .coef3 = %f, .coef2 = %f, .coef1 = %f, .con = %f}," % (z[0], z[1], z[2], z[3]) )
91+
92+
if __name__ == '__main__':
93+
main()

0 commit comments

Comments
 (0)