Commands via terminal

Enabled console commands via normal terminal emulator
Added menu for calibration of filters
This commit is contained in:
M0WID 2020-10-19 23:25:56 +01:00
parent 7fe1a17a2d
commit 0ce1ca00f8
10 changed files with 135 additions and 1424 deletions

View File

@ -54,6 +54,7 @@ static int16_t lastMode; // Record last operating mode (sig gen, normal)
static uint16_t currentPointRSSI;
static uint16_t peakRSSI;
static uint16_t centreRSSI; // RSSI at centre of sweep (ie at IF)
static uint16_t prevPointRSSI;
static uint32_t peakFreq;
static uint16_t peakIndex;
@ -81,11 +82,16 @@ static uint16_t bpfCalFirstSweepDone;
if (bpfCalibrate)
{
setting.LevelOffset = 0;
if (bpfCalFirstSweepDone)
{
// max value for this bpFilter index (pervious sweep) is in peaks[0].Level
bpfCalibrations[bpFilterIndex] = CAL_POWER - rssiTodBm ( peaks[0].Level);
Serial.printf("bpfCalibration: filter: %i, rbw10=%i , cal=%f \n", bpFilterIndex, currentRBW10, bpfCalibrations[bpFilterIndex]);
// max value for this bpFilter index (previous sweep) is in peaks[0].Level
// value at the IF is in myActual[displayPoints/2]
// use the average of the two values
uint16_t rssi_average = ( peaks[0].Level + myActual[displayPoints/2] ) / 2;
bpfCalibrations[bpFilterIndex] = CAL_POWER - rssiTodBm( rssi_average );
Serial.printf("bpfCalibration: filter: %i, rbw10=%i , cal=%f, rssi av = %i\n",
bpFilterIndex, currentRBW10, bpfCalibrations[bpFilterIndex], rssi_average);
bpFilterIndex ++;
if (bpFilterIndex >= bpfCount) // end of calibration
@ -93,6 +99,7 @@ static uint16_t bpfCalFirstSweepDone;
bpfCalibrate = false;
currentRBW10 = setting.Bandwidth10;
SaveBpfCalibration();
WriteSettings();
Serial.println("bpfCalibration done");
}
else // not reached end of filters
@ -132,7 +139,7 @@ static uint16_t bpfCalFirstSweepDone;
att.SetAtten ( 0 ); // Set the internal attenuator
// pre-calculate adjustment for RSSI values
dBadjust = -120.0 - setting.ExternalGain; // No correction applied for this mode
dBadjust = -120.0 - setting.ExternalGain; // No Level Offset correction applied for this mode
//Serial.printf("RXSweep dBadjust = %f; ext gain = %f\n", dBadjust, setting.ExternalGain);
xmit.SetPowerReference ( setting.ReferenceOut ); // Set the GPIO reference output

View File

@ -144,8 +144,8 @@ static uint32_t tgIF; // Track gen IF - SA IF plus any offset if both SI4432
// pre-calculate adjustment for RSSI values
dBadjust = (double)setting.Attenuate - 120.0 + setting.LevelOffset - setting.ExternalGain + bpfCalibrations[bpfIndex];
Serial.printf("SweepLo dBadjust = %f; leveloffset = %f; attenuate = %i, ext gain = %f\n",
dBadjust, setting.LevelOffset, setting.Attenuate, setting.ExternalGain);
Serial.printf("SweepLo dBadjust = %f; leveloffset = %f; attenuate = %i, ext gain = %f, bpfCal = %f\n",
dBadjust, setting.LevelOffset, setting.Attenuate, setting.ExternalGain, bpfCalibrations[bpfIndex]);
resetAverage = changedSetting;

72
cmd.cpp
View File

@ -194,6 +194,8 @@ extern uint8_t dBmToRSSI ( double dBm );
{ "TRACKSIG", MSG_TGSIG }, // turn off tracking generator output
{ "TGFREQ", MSG_TGFREQ }, // Set Track gen freq for sig gen mode
{ "BPFCAL", MSG_BPFCAL }, // Start bandpass filter calibration
{ "OTA", MSG_OTA }, // Select OTA Update Mode
{ "", MSG_NONE } // Unrecognized command
};
@ -239,16 +241,20 @@ void ShowMenu ()
Serial.println ( " PAUSE.........Pause or resume the sweep" );
Serial.println ( "\nDisplay Options:\n" );
Serial.println ( "\nMode selection:\n" );
Serial.println ( " SALO..........Set to analyse mode low frequency range" );
Serial.println ( " SGLO..........Set to signal generator mode low frequency range" );
Serial.println ( " IFSWEEP.......Set to IF Sweep mode to analyse the TinySA SAW filters" );
Serial.println ( " RXSWEEP.......Set to RX Sweep mode to analyse the TinySA FIR filters" );
Serial.println ( " BANDSCOPE.....Set to BANDSCOPE mode" );
Serial.println ( " OTA...........Set to OTA update mode to download firmware or SPIFFS over wifi" );
Serial.println ( "\nDisplay Options:\n" );
Serial.println ( " TRACES........Turn display traces on or off ['GAIN' or 'dB']" );
Serial.printf ( " PREAMP/GAIN...Set or get the receiver preamp gain\n" );
Serial.println ( " See documentation for allowed values" );
@ -386,9 +392,9 @@ void ShowMenu ()
bool CheckCommand ()
{
char inBuff[80]; // Input buffer
char c = 0; // Just one character
int16_t index = 0; // Index to the buffer
static char inBuff[80]; // Input buffer
char c = 0; // Just one character
static int16_t index = 0; // Index to the buffer
if ( !Serial.available() ) // Any input?
return false; // Nope!
@ -397,18 +403,28 @@ int16_t index = 0; // Index to the buffer
{
c = toupper ( Serial.read () ); // Get next character
Serial.print(c); // Echo
Serial.printf("(%02X)", c); // debug
//Serial.printf("(%02X)", c); // debug
if (( c == '\r' ) || ( c == '\n' )) // End of the line?
if ( ( c == '\r' ) || ( c == '\n' ) ) // End of the line?
{
Serial.println();
inBuff[index++] = '\0'; // Replace with a null
Serial.println("EOL"); // debug
return ParseCommand ( inBuff ); // Process the command and return result
//Serial.printf("EOL = %s \n", inBuff); // debug
boolean result = ParseCommand ( inBuff ); // Process the command and return result
index = 0;
return result;
}
else // Not the end of the line
{
inBuff[index++] = c; // Save the character
inBuff[index] = '\0'; // Make next character a null
inBuff[index+1] = '\0'; // Make next character a null
}
if (index >= 78)
{
Serial.println("Serial Buffer Overun");
index = 0;
break;
}
}
return false;
@ -1657,6 +1673,10 @@ uint8_t reg69; // Ditto
setMode(RX_SWEEP);
return true;
case MSG_OTA:
setMode(OTA_UPDATE);
return true;
case MSG_TGOFFSET:
if ( dataLen != 0 ) // Frequency specified?
{
@ -1798,17 +1818,7 @@ uint8_t reg69; // Ditto
* Valid only if already in RX Sweep mode
*/
case MSG_BPFCAL:
if ( setting.Mode == RX_SWEEP )
{
bpfCalibrate = true;
Serial.println("Starting bpf calibration");
return true;
}
else
{
Serial.println("bpfCal only works in RX_SWEEP (RBW test) mode");
}
return false;
return StartBpfCal ();
default:
@ -3173,6 +3183,24 @@ uint32_t GetRXsweepSigFreq ( void )
}
/*
* start the bandpass filter calibration sequence
* must be in RX_Sweep mode
*/
boolean StartBpfCal ( void )
{
if ( setting.Mode == RX_SWEEP )
{
bpfCalibrate = true;
Serial.println("Starting bpf calibration");
return true;
}
else
{
Serial.println("bpfCal only works in RX_SWEEP (RBW test) mode");
return false;
}
}
/*
* Specific start/stop frequency setting for Bandscope mode

3
cmd.h
View File

@ -86,6 +86,7 @@
#define MSG_TGFREQ 57 // Set Track Gen frequency for sig gen mode
#define MSG_TGSIG 58 // Set Track Gen sig gen mode
#define MSG_BPFCAL 59 // Start bandpass filter calibration
#define MSG_OTA 60 // OTA Update mode
#define MSG_COLOURTEST 99 // test of waterfall colours - remove this when done!
@ -219,6 +220,8 @@ uint32_t GetRXsweepSpan ( void );
void SetRXsweepSigFreq ( uint32_t freq );
uint32_t GetRXsweepSigFreq ( void );
boolean StartBpfCal ( void );
void SetSweepCenter ( uint32_t freq, uint8_t span );
uint32_t GetSweepCenter ( void );

View File

@ -47,7 +47,7 @@
<p style="max-width:700px;">
This simpleSA running on an ESP32 has been adapted by Dave M0WID and John WA2FZW.<br />
It was based on an early prototype design of the TinySA by Erik PD0EK.<br />
It was based on an early arduino prototype of the TinySA by Erik PD0EK.<br />
Information can be found at <a href = "https://groups.io/g/HBTE">https://groups.io/g/HBTE</a>
</p>

View File

@ -1039,12 +1039,13 @@ var dateObject;
*/
function renderChart()
{
setTimeout(function(){renderChart()}, refreshInterval.value);
chartSA.render();
//setTimeout(renderChart, refreshInterval.value);
setTimeout(function(){renderChart()}, refreshInterval.value);
}
//messageCount.value = messageCounter;
//missedReplies.value = missedMessageCounter;
hostName.value = "ws://" + location.host + ":81";

View File

@ -1,976 +0,0 @@
<!--
This application is loosly based on the code found here:
Repository: https://github.com/krzychb/EspScopeA0
Version: Delta
Flie: index.htm
Revision: 0.1.0
Date: 10-Jul-2016
Author: krzychb at gazeta.pl
Copyright (c) 2016 Krzysztof Budzynski. All rights reserved.
This modified version takes the samples from the TinySA
spectrum analyser and displays in a web page.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-->
<!DOCTYPE html>
<html>
<head>
<title>simpleSA-ESP</title>
<link rel="stylesheet" type="text/css" href="styles.css">
<!-- get file below from http://canvasjs.com/ -->
<script type="text/javascript" src="canvasjs.min.js"></script>
<script type="text/javascript" src="jquery-3.2.1.min.js"></script>
<script type="text/javascript" src="support.js"></script>
</head>
<body style="min-width:100vw">
<div class='norm'>
<button id="homeButton" onclick="window.location.href='index.html';">Home</button>
<!-- <button id="settingsButton" onclick="window.location.href='settings.html';">Settings</button>
<button id="backupRestoreButton" onclick="window.location.href='backupRestore.html';">Backup/Restore</button>
// <button id="helpButton" onclick="window.location.href='help.html';">Help</button> -->
<button id="aboutButton" onclick="window.location.href='about.html';">About</button>
</div>
<div class ="Grid">
<div class = "Grid-cell" id="chartSA" ></div>
<br />
<div class = "Grid-cell-side" id="postSweepSettings" >
<!--<form style="width: 90vw; margin-left: 80px" action="doSetSweep" method="get"> -->
<div class="setting" >
<select class="Sweep-select" id="setMode" name="setMode">
<option class="sweep-option" value="0">Sweep Low</option>
<!-- <option class="sweep-option" value="1">Sweep High</option> -->
<option class="sweep-option" value="2">Sig Gen</option>
<!-- <option class="sweep-option" value="3">Sig Gen High</option> -->
<option class="sweep-option" value="4">SAW Test</option>
<!-- <option class="sweep-option" value="5">Zero Span</option> -->
<!-- <option class="sweep-option" value="6">Zero Span High</option> -->
<option class="sweep-option" value="7">Bandscope</option>
<option class="sweep-option" value="8">RBW Test</option>
</select>
<img src="refresh.png" id="refresh" name = "refresh" height = "18">
</div>
<div class="setting" >
<label for="setFreq" class="setting-label">Frequency:</label>
<input class="value-input" name='setFreq' type="number" id="setFreq" maxlength="9" min="0" max="350" required>
MHz
</div>
<br />
<div class="setting" >
<label for="setLevel" class="setting-label">Level:</label>
<input class="value-input" name='setLevel' type="number" step="1" id ="setLevel" maxlength="4" min="-31" max="0" required>
dBm
</div>
<hr />
<h1>Settings</h1>
<div class="setting" >
<label for="calLevel" class="setting-label">Max Level:</label>
<input class="value-display" type="text" disabled="1" id="calLevel" size="1" value="0" />
dB
</div>
<div class="setting" >
<button class = "set-button" type="submit" id="setActPower">Set Max</button>
<input class="value-input" type="number" id="setMaxPower" placeholder="setMaxPower" maxlength = "9" min="-60" max="20" value="0" />
dBm
</div>
<br />
<div class="setting" >
<label for="setLODrive" class="setting-label">LO Drive:</label>
<select class="select-input" id="setLODrive" name="setLODrive">
<option class="select-option" value="0">-1</option>
<option class="select-option" value="1">2</option>
<option class="select-option" value="2">5</option>
<option class="select-option" value="3">8</option>
<option class="select-option" value="4">11</option>
<option class="select-option" value="5">14</option>
<option class="select-option" value="6">17</option>
<option class="select-option" value="7">20</option>
</select>
dBm
</div>
<div class="setting" >
<label for="setIF" class="setting-label">IF:</label>
<input class="value-input" type="number" id="setIF" size="1" value="433.92" min="433" max=435 step=0.01 />
MHz
</div>
</div>
<!--</form> -->
</div>
<!-- Below chart (hopefully!) -->
<div class = "Grid">
<div class = "Grid-cell-connection" id="status" >
<hr />
<div id="connection-status">
<form onsubmit="return false;">
<div style="width: 400px; display: inline-block">Host:
<input type="text" id="hostName" value="ws://hostName:81" style="width:160px;"/>
<input type="button" value="Connect" onclick="connect(hostName.value)" />
<input type="button" value="Disconnect" onclick="disconnect()" />
</div>
<div style="width: 250px; display: inline-block">Status:
<input type="text" id="connectionStatus" value="Idle" style="border: 0" />
</div>
<div style="width: 100px; display: inline-block">Pings:
<input type="text" id="connectionPings" size="3" value="-" style="border: 0" />
</div>
<div style="width: 100px; display: inline-block">Refresh Interval:
<input class="value-input" type="number" id="refreshInterval" size="3" min="100" max="3000" value="500" />
</div>
</form>
</div>
<!-- <input class="message-display" type="text" disabled="1" id="message" size="1" value="json message" /> -->
</div>
</div>
<script type="text/javascript">
var refreshInterval = document.getElementById('refreshInterval');
var refresh = document.getElementById('refresh');
var setMode = document.getElementById('setMode');
var setFreq = document.getElementById('setFreq');
var setLevel = document.getElementById('setLevel');
var calLevel = document.getElementByID('calLevel');
var setActPower = document.getElementById('setActPower');
var setMaxPower = document.getElementByID('setMaxPower');
var setLODrive = document.getElementById('setLODrive');
var setIF = document.getElementById('setIF');
//var messageWindow = document.getElementById('message');
// initialise these to silly values to force an update first time round
var oldFreq = 0
var oldSetLevel = 100;
var oldCalLevel = 100;
var oldMaxPower = 100;
var oldLODrive = -1;
var oldIF = 0;
// Add handlers for the change events in the input fields
refresh.addEventListener('click', (event) => {
sendValue("r", 0);
});
setMode.addEventListener('change', (event) => {
sendValue("m", setMode.value);
});
setFreq.addEventListener('change', (event) => {
sendValue("a", setStart.value);
});
setStop.addEventListener('change', (event) => {
sendValue("b", setStop.value);
});
setCenter.addEventListener('change', (event) => {
sendValue("c", setCenter.value);
});
setLODrive.addEventListener('change', (event) => {
if ((setLODrive.value >=0) && (setLODrive.value <= 7))
sendValue("d", setLODrive.value);
});
setIF.addEventListener('change', (event) => {
sendValue("i", setIF.value);
});
setRefOut.addEventListener('change', (event) => {
sendValue("o", setRefOut.value);
});
setActPower.addEventListener('click', (event) => {
sendValue("p", setPowerValue.value);
});
setSpan.addEventListener('change', (event) => {
sendValue("s", setSpan.value);
});
setAtten.addEventListener('change', (event) => {
sendValue("A", setAtten.value);
});
setExtern.addEventListener('change', (event) => {
sendValue("E", setExtern.value);
});
setRBW.addEventListener('change', (event) => {
sendValue("R", setRBW.value);
});
setPreAmp.addEventListener('change', (event) => {
if (setPreAmp.value == "96") {
sendValue("g", setPreAmp.value);
} else {
sendValue("g", setPreAmp.selectedOptions[0].text);
}
});
setSpur.addEventListener('change', (event) => {
if (setSpur.checked) {
sendValue("S", 1);
} else {
sendValue("S", 0);
}
});
setTrackGen.addEventListener('change', (event) => {
if (setTrackGen.checked) {
sendValue("t", 1);
} else {
sendValue("t", 0);
}
});
store1.addEventListener('change', (event) => {
if (store1.checked) {
var b = parseFloat(levelOffset.value) + parseFloat(setAtten.value) - 120 - parseFloat(setExtern.value);
chartSA.options.data[5].dataPoints = chartSA.options.data[1].dataPoints.map(obj => {
let rObj = {}
rObj.x = obj.x
rObj.y = obj.y/2+b
return rObj
})
} else {
chartSA.options.data[5].dataPoints.length = 2; // reset
}
});
store2.addEventListener('change', (event) => {
if (store2.checked) {
var b = parseInt(levelOffset.value) + parseInt(setAtten.value) - 120 - parseFloat(setExtern.value);
chartSA.options.data[6].dataPoints = chartSA.options.data[1].dataPoints.map(obj => {
let rObj = {}
rObj.x = obj.x
rObj.y = obj.y/2+b
return rObj
})
} else {
chartSA.options.data[6].dataPoints.length = 2; // reset
}
});
store3.addEventListener('change', (event) => {
if (store3.checked) {
var b = parseInt(levelOffset.value) + parseInt(setAtten.value) - 120 - parseFloat(setExtern.value);
chartSA.options.data[7].dataPoints = chartSA.options.data[1].dataPoints.map(obj => {
let rObj = {}
rObj.x = obj.x
rObj.y = obj.y/2+b
return rObj
})
} else {
chartSA.options.data[7].dataPoints.length = 2; // reset
}
});
store4.addEventListener('change', (event) => {
if (store4.checked) {
var b = parseInt(levelOffset.value) + parseInt(setAtten.value) - 120 - parseFloat(setExtern.value);
chartSA.options.data[8].dataPoints = chartSA.options.data[1].dataPoints.map(obj => {
let rObj = {}
rObj.x = obj.x
rObj.y = obj.y/2+b
return rObj
})
} else {
chartSA.options.data[8].dataPoints.length = 2; // reset
}
});
//var roundtripTime = document.getElementById('roundtripTime');
//var messageCount = document.getElementById('messageCount');
//var missedReplies = document.getElementById('missedReplies');
var messageCounter = 0;
var missedMessageCounter = 0;
var messageSendMilis;
var connection;
var connectionStatus = document.getElementById('connectionStatus');
var hostName = document.getElementById('hostName');
var pingCounter = 0;
var sendPingVar;
var dateObject;
/*
* Timed update of chart render to reduce load on slow smartphones or tablets
*/
function renderChart()
{
setTimeout(function(){renderChart()}, refreshInterval.value);
chartSA.render();
//setTimeout(renderChart, refreshInterval.value);
}
//messageCount.value = messageCounter;
//missedReplies.value = missedMessageCounter;
hostName.value = "ws://" + location.host + ":81";
// connect to TinySA server
connect(hostName.value);
// At this point the page is running
$(document).ready(function () {
update();
var chartUpdateVar;
// chartUpdateVar = setInterval(renderChart, 500);
});
var initDone = false;
var indexUpdateMilliSeconds = 1 * 1000;
function handleSettings (settings)
{
setMode.value = settings.mode;
if (setMode.value == 8) { // RX Sweep (RBW test)
setStart.max = settings.IF;
setStop.max = 600;
setStart.min = 350;
setStop.min = settings.IF;
setStop.disabled = false;
setCenter.disabled = true;
setSpan.disabled = true;
setRBW.disabled = false;
setRefOut.disabled = true;
setSpur.disabled = true;
setTrackgen.disabled = true;
setTrackGenPower.disabled = true;
} else if (settings.mode == 4 ) { // IF Sweep (SAW test)
setStart.max = settings.IF;
setStop.max = 460;
setStart.min = 400;
setStop.min = settings.IF;
setStop.disabled = false;
setCenter.disabled = true;
setSpan.disabled = true;
setRBW.disabled = true;
setRefOut.disabled = true;
setSpur.disabled = true;
setTrackgen.disabled = true;
setTrackGenPower.disabled = true;
} else if (settings.mode == 7 ) { // BANDSCOPE
setStart.max = 350;
setStop.max = 350;
setStart.min = 0;
setStop.min = 0;
setStop.disabled = true;
setCenter.disabled = true;
setSpan.disabled = false;
setRBW.disabled = false;
setRefOut.disabled = true;
setSpur.disabled = true;
setTrackgen.disabled = true;
setTrackGenPower.disabled = true;
} else {
setStart.max = 350;
setStop.max = 350;
setStart.min = 0;
setStop.min = 0;
setStop.disabled = false;
setCenter.disabled = false;
setSpan.disabled = false;
setRBW.disabled = false;
setRefOut.disabled = false;
setSpur.disabled = false;
setTrackgen.disabled = false;
setTrackGenPower.disabled = false;
}
actRBW.value = settings.bandwidth;
levelOffset.value = settings.levelOffset;
// console.log("levelOffset=" + settings.levelOffset);
if (settings.start/1000 != oldSweepStart) {
//console.log("Start:" + settings.start + " Stop:" + settings.stop + " oldStart:" + oldSweepStart);
//sweepStart.value = settings.start/1000;
setStart.value = settings.start/1000; // change default if changed
oldSweepStart = setStart.value;
setSpan.value = (settings.stop - settings.start)/1000;
}
if (settings.stop/1000 != oldSweepStop) {
//sweepStop.value = settings.stop/1000;
setStop.value = settings.stop/1000; // change default if changed
oldSweepStop = setStop.value;
setSpan.value = (settings.stop - settings.start)/1000;
}
tempCenter = ( (parseFloat(settings.stop) - parseFloat(settings.start) )/2 + parseFloat(settings.start) ) / 1000; // calculate center
if (tempCenter != oldSweepCenter) {
setCenter.value = tempCenter;
oldSweepCenter = tempCenter;
}
if (settings.attenuation != oldAttenuation) {
setAtten.value = settings.attenuation;
oldAttenuation = settings.attenuation;
}
if (settings.extGain != oldExternalGain) {
setExtern.value = settings.extGain;
oldExternalGain = settings.extGain;
}
if (settings.setRBW != oldSetRBW) {
setRBW.value = settings.setRBW;
oldSetRBW = settings.setRBW;
}
if (settings.RefOut != oldSetRefOut) {
setRefOut.value = settings.RefOut; // reference output dropdown
oldSetRefOut = settings.RefOut;
}
if (settings.Drive != oldDrive) {
setLODrive.value = settings.Drive; // LO Drive dropdown
oldDrive = settings.Drive;
}
if (settings.IF != oldIF) {
setIF.value = settings.IF; // IF value
oldIF = settings.IF;
}
if (settings.PreAmp != oldPreAmp) {
setPreAmp.value = settings.PreAmp; // PreAmp Gain value
oldPreAmp = settings.PreAmp;
}
if (settings.spur != oldSpur) {
if (settings.spur) {
spurReduction.checked = true; // Spur reduction checkbox
} else {
spurReduction.checked = false; // Spur reduction checkbox
}
oldSpur = settings.spur;
}
if (settings.tg != oldTrackGen) {
if (settings.tg) {
setTrackGen.checked = true; // Tracking Generator checkbox
} else {
setTrackGen.checked = false; // Tracking Generator checkbox
}
oldTrackGen = settings.tg;
}
if (settings.tgPower != oldTrackGenPower) {
setTrackGenPower.value = settings.tgPower;
oldTrackGenPower = settings.tgPower;
}
chartSA.options.axisX.minimum = setStart.value;
chartSA.options.axisX.maximum = setStop.value;
initDone = false;
}
function handleData (data) // rarely used! see handleChunkData for most sweeps
{
if (data.sweepPoints != sweepPoints.value) {
// reset chart data
chartSA.options.data[0].dataPoints.length = 2;
chartSA.options.data[1].dataPoints.length = 2;
chartSA.options.data[3].dataPoints.length = 2;
sweepPoints.value = data.sweepPoints;
}
var b = parseFloat(levelOffset.value) + parseFloat(setAtten.value) - 120 - parseFloat(setExtern.value);
//chartSA.options.data[0].dataPoints = data.Points; // First series dB
chartSA.options.data[0].dataPoints = data.Points.map(obj => {
let rObj = {}
rObj.x = obj.x
rObj.y = obj.y/2+b
return rObj
})
chartSA.options.data[1].dataPoints = data.Points; // RSSI trace
chartSA.options.data[1].axisYType = "secondary";
if ((initDone == 0) || (oldSweepPoints != data.sweepPoints) || (oldDataPointCount != data.Points.length)) {
chartSA.options.data[3].dataPoints = chartSA.options.data[0].dataPoints // first run
initDone = 1;
oldSweepPoints = data.Points.length;
oldDataPointCount = data.Points.length;
}
chartSA.options.data[3].dataPoints = chartSA.options.data[0].dataPoints.map((obj, index) => { // average trace
let rObj = {}
rObj.x = obj.x
rObj.y = chartSA.options.data[3].dataPoints[index].y*(1-1/setAverage) + obj.y*1/setAverage;
return rObj
})
chartSA.options.axisX.minimum = setStart.value;
chartSA.options.axisX.maximum = setStop.value;
// chartSA.options.axisY.minimum = -120;
// chartSA.options.axisY.maximum = 0;
chartSA.options.axisY2.minimum = 0;
chartSA.options.axisY2.maximum = 255;
// RSSISamples.from(data.Points); // moves data
//console.log(RSSISamples[10].y);
// update the chart
chartSA.render();
}
function handleChunkData (data)
{
var init = false;
var n = data.sweepPoints;
if (n != oldSweepPoints) {
// reset chart data
chartSA.options.data[0].dataPoints.length = 0;
chartSA.options.data[1].dataPoints.length = 0;
chartSA.options.data[2].dataPoints.length = 0;
chartSA.options.data[3].dataPoints.length = 0;
chartSA.options.data[4].dataPoints.length = 0;
// add dummy data points
var i;
for (i=0; i<n; i++) {
var p = {x:250, y:-120};
var q = {x:250, y:0};
var r = {x:250, y:49};
var s = {x:250, y:-120};
var m = {x:250, y:10};
chartSA.options.data[0].dataPoints.push(p); // dB
chartSA.options.data[1].dataPoints.push(q); // RSSI
chartSA.options.data[2].dataPoints.push(r); // gain
chartSA.options.data[3].dataPoints.push(s); // average
chartSA.options.data[4].dataPoints.push(m); // min - initialise to high value
}
//chartSA.options.data[0].dataPoints.length = n; // reduces size if > no of data points
//chartSA.options.data[1].dataPoints.length = n;
//chartSA.options.data[2].dataPoints.length = n;
//chartSA.options.data[3].dataPoints.length = n;
sweepPoints.value = data.sweepPoints;
init = true;
initDone = false;
oldSweepPoints = n;
//chartSA.render();
}
var dataStart = data.StartIndex;
var b = parseInt(levelOffset.value) + parseInt(setAtten.value) - 120 - parseFloat(setExtern.value);
var a = 1/setAverage.value;
data.Points.forEach (function (point, index) { // copy data into the chart data series
var p = {};
p = point; // create a copy not a reference ??
var f = {};
f = point.x;
chartSA.options.data[1].dataPoints[dataStart + index] = p; // RSSI
chartSA.options.data[0].dataPoints[dataStart + index].x = f * 1;
var dB = p.y/2+b;
chartSA.options.data[0].dataPoints[dataStart + index].y = dB * 1;
//chartSA.options.data[3].dataPoints[dataStart + index] = point;
//try {
//chartSA.options.data[3].dataPoints[dataStart + index].x = f * 1;
// if (initDone) {
// var av = chartSA.options.data[3].dataPoints[dataStart + index].y*(1-a) + dB*a;
// chartSA.options.data[3].dataPoints[dataStart + index].y = av * 1;
// } else {
// chartSA.options.data[3].dataPoints[dataStart + index].y = dB * 1;
// }
//}
//catch {
// chartSA.options.data[3].dataPoints[dataStart + index].y = point.y/2+b;
//}
})
// If end of sweep update the average and min data sets
if (dataStart + data.Points.length >= data.sweepPoints) {
if (!initDone) { // If first time then set the values to current dB series
initDone = true;
chartSA.options.data[3].dataPoints = chartSA.options.data[0].dataPoints.map((obj, index) => { // average trace
let rObj = {}
rObj.x = obj.x;
rObj.y = obj.y*1;
return rObj
})
chartSA.options.data[4].dataPoints = chartSA.options.data[0].dataPoints.map((obj, index) => { // average trace
let rObj = {}
rObj.x = obj.x;
rObj.y = obj.y*1;
return rObj
})
} else {
chartSA.options.data[3].dataPoints = chartSA.options.data[0].dataPoints.map((obj, index) => { // average trace
let rObj = {}
rObj.x = obj.x;
rObj.y = chartSA.options.data[3].dataPoints[index].y*(1-a) + obj.y*a;
return rObj
})
chartSA.options.data[4].dataPoints = chartSA.options.data[0].dataPoints.map((obj, index) => { // average trace
let rObj = {}
rObj.x = obj.x;
rObj.y = Math.min(chartSA.options.data[4].dataPoints[index].y, obj.y);
return rObj
})
}
if (chartSA.options.data[2].visible) {
$.getJSON( "getGainSweep") // proper line
// $.getJSON( "getGainSweep.json") // for local test
.done(function (data) {
// We have the data, process it.
chartSA.options.data[2].dataPoints = data.gainPoints; // Gain trace
});
}
}
//chartSA.render();
// dataPoints.value = chartSA.options.data[0].dataPoints.length;
sweepTime.value = data.sweepTime;
}
function update()
{
// Get the settings
$.getJSON( "getSettings")
.done(function (settings) {
handleSettings(settings);
})
.fail(function(jqxhr, textStatus, error) {
var err = textStatus +", " + error;
console.log("Settings Request Failed: " + err);
});
// Get the sweep data
$.getJSON( "getSweep") // proper line
// $.getJSON( "getSweep.json") // for local test
.done(function (data) {
// We have the data, process it.
handleData(data);
//setTimeout(update, indexUpdateMilliSeconds);
})
.fail(function(jqxhr, textStatus, error) {
var err = textStatus +", " + error;
console.log("Sweep Request Failed: " + err);
});
if (chartSA.options.data[2].visible) {
$.getJSON( "getGainSweep") // proper line
// $.getJSON( "getGainSweep.json") // for local test
.done(function (data) {
// We have the data, process it.
chartSA.options.data[2].dataPoints = data.gainPoints; // Gain trace
});
}
}
/*
// This method is called to add all necessary options to a
// select representing the available resolution bandwidths(RBW).
// default is auto
*/
function buildRBWSelect()
{
let dropdown = $('#setRBW');
dropdown.empty();
// Populate dropdown with list of RBW
$.getJSON("getRbwList", function (data) {
dropdown.append($('<option class="select-option" ></option>').attr('value', 0).text("Auto"));
$.each(data, function (key, bpf) {
dropdown.append($('<option class="select-option" ></option>').attr('value', bpf.bw10).text(bpf.bw));
})
});
//dropdown.prop('selectedIndex', 0);
}
buildRBWSelect();
/*
// This method is called to add all necessary options to a
// select representing the available attenuations.
// default is auto
*/
function buildAttenSelect()
{
let dropdown = $('#setAtten');
dropdown.empty();
// Populate dropdown with list of RBW
$.getJSON("getAttenList", function (data) {
$.each(data, function (key, att) {
dropdown.append($('<option class="select-option" ></option>').attr('value', att.dB).text(att.dB));
})
});
//dropdown.prop('selectedIndex', 0);
}
//buildAttenSelect();
function connect(host)
{
if(connection)
{
//connection.close(); // restart
return; // already connected
}
connectionStatus.value = "Connecting...";
connection = new WebSocket(host, ['arduino']);
connection.onopen = function()
{
connectionStatus.value = "Connected";
connectionStatus.style = "background-color:lightgreen";
connection.send('Hello from Browser :-) ' + new Date());
sendMessage();
sendPingVar = setInterval(function(){ sendPing() }, 30000);
sendValue("r",0); // request settings
// Get the settings to make sure current
//$.getJSON( "getSettings")
// .done(function (settings) {
// handleSettings(settings);
// })
//
// .fail(function(jqxhr, textStatus, error) {
// var err = textStatus +", " + error;
// console.log("Settings Request Failed: " + err);
// });
var items = document.querySelectorAll(".value-input");
var i;
for (i = 0; i< items.length; i++) {
items[i].disabled = false;
}
var items = document.querySelectorAll(".select-input");
var i;
for (i = 0; i< items.length; i++) {
items[i].disabled = false;
}
};
connection.onclose = function(event)
{
clearInterval(sendPingVar);
connectionStatus.value = "Disconnected";
connectionStatus.style = "background-color:red";
//connection.removeEventListeners();
connection = null;
// Disable user input
var items = document.querySelectorAll(".value-input");
var i;
for (i = 0; i< items.length; i++) {
items[i].disabled = true;
}
var items = document.querySelectorAll(".select-input");
var i;
for (i = 0; i< items.length; i++) {
items[i].disabled = true;
}
};
connection.onerror = function(error)
{
console.log("WebSocket Error ", error);
};
connection.onmessage = function(message) // to be used later when we send data at each sweep
{
//console.log("Websocket message received");
// show message
//messageWindow.value = message.data;
//messageSize.value = message.data.length;
// check only messages begining with '{'
if(message.data[0] == "{")
{
// //console.log("Parsing message");
myObject = JSON.parse(message.data);
//console.log("message type " + myObject.mType);
if (myObject.mType == "Settings")
{
pointsCount = myObject.dispPoints;
// sweepSamples = myObject.Points;
//console.log("handle settings");
handleSettings(myObject);
}
else if (myObject.mType == "fullSweep")
{
//console.log("handle full Sweep");
handleData(myObject);
}
else if (myObject.mType == "chunkSweep")
{
//console.log("handle chunk Sweep:" + myObject.StartIndex);
handleChunkData(myObject);
}
else
{
console.log("Invalid json message type");
}
}
};
}
function disconnect()
{
if(connection)
{
connection.close();
}
else
{
connectionStatus.value = "Not connected yet";
}
}
function sendValue(c, val)
{
//
// Message format
// #(code) value where code is a single char. Case is important
// a start freq (MHz) - sig gen freq if in sig gen mode
// b stop frequency
// c centre frequency
// s Span
// d Local Oscillator Drive
// g PreAmpGain/Mode
// i IF frequency
// m mode
// p set actual power to peak value
// o RefOut
// r request Settings are pushed
// A internal attenuation (PE4302)
// E external gain ( eg attenuator(-ve) or preamp(+ve) )
// R requested RBW
// S Spur reduction Off/On
// t trackGen Off/On/Fixed
// T trackGen output level
// L Sig Gen level (dBm)
// G Sig Gen Off/On
// P Sig Gen set max output level (dBm)
//
//connection.send("# " + messageCounter + " " + sampleThreshold + " " + sampleSize);
connection.send("#" + c + " " + val);
console.log("Command:" + c + val);
}
function sendMessage()
{
messageCounter++;
//messageCount.value = messageCounter;
dateObject = new Date();
messageSendMilis = dateObject.getTime();
//
// Message format
// # MESSAGE_NUMBER SAMPLE_THRESHOLD NUMBER_OF_SAMPLES
//
//connection.send("# " + messageCounter + " " + sampleThreshold + " " + sampleSize);
connection.send("# " + messageCounter + " " + sweepStart + " " + sweepStop);
}
function sendPing()
{
connection.send('ping');
pingCounter++;
connectionPings.value = pingCounter;
}
</script>
</body>
</html>

View File

@ -847,7 +847,7 @@ bool fsStatus = false; // True if SPIFFS loads ok
tft.setTextColor(WHITE);
tft.setFreeFont ( &FreeSansBold9pt7b ); // Select Free Serif 9 point font
tft.print( "Progress:");
tft.fillRect(120, 180, 100, 20, SIG_BACKGROUND_COLOR); // x, y, w, h, color
tft.fillRect(120, 182, 100, 20, SIG_BACKGROUND_COLOR); // x, y, w, h, color
tft.setCursor (120, 200);
tft.printf("%u%%", (progress / (total / 100)));
@ -1208,7 +1208,7 @@ void init_sweep()
void initChunkSweepDoc (uint32_t startIndex)
{
jsonDocument.clear ();
jsonDocument["PreAmp"] = setting.PreampGain; // Fixed gain
jsonDocument["PreAmp"] = setting.PreampGain;
jsonDocument["mType"] = "chunkSweep";
jsonDocument["StartIndex"] = startIndex;
jsonDocument["sweepPoints"] = sweepPoints;
@ -1911,7 +1911,7 @@ double rssiTodBm ( uint8_t rSSI )
/*
* Function to convert rSSi to dBm
* Function to convert dBm to RSSI
*/
uint8_t dBmToRSSI ( double dBm )

View File

@ -163,12 +163,9 @@ boolean connectWiFi() // Connect to Wifi using SSID (ie via Router)
/*
* Apply any hostname that we may have
* Apply hostname
*/
// if ( strlen ( (char *) &configuration.Hostname[0]) > 0 )
// WiFi.setHostname ( (char *) &configuration.Hostname[0] );
// else
WiFi.setHostname ( PROGRAM_NAME );
int maxTry = 10; // Wait for the connection to be made.
@ -505,167 +502,49 @@ void addTagNameValue ( char *b, char *_name, char *value )
/*
* On request from web page convert the data from a scan into XML and send
*
* Ideally we would push the data to the web page at the end of a scan,
* or perhaps just create the xml at the end of each scan - investigate later
* Handle settings that are common to all modes
*/
//void onGetScan ( AsyncWebServerRequest *request )
//{
// response = request->beginResponseStream ( "text/xml" );
//// Serial.println ( "onGetScan" );
//
// response->print ( "<?xml version=\"1.0\" encoding=\"utf-16\"?>" );
// response->println ( "<Points>" );
//
// for( int i = 0; i < displayPoints-1; i++ ) // For each data point
// {
//// Serial.printf ( "<Point F=\"%i\" RSSI=\"%i\"/> %i\n",myFreq[i], myData[i], i );
// response->printf ( "<P F=\"%i\" R=\"%i\"/>\n", myFreq[i], myData[i] );
// }
//
// response->print ( "</Points>" );
// request->send ( response );
//}
/*
* On request from web page convert the gain data from a sweep into JSON and send
* Ideally we would push the data to the web page at the end of a scan,
*/
//void onGetGainSweep ( AsyncWebServerRequest *request )
//{
// size_t bufferSize = JSON_ARRAY_SIZE ( SCREEN_WIDTH )
// + JSON_OBJECT_SIZE ( 1 ) + SCREEN_WIDTH * JSON_OBJECT_SIZE ( 2 );
//
// AsyncJsonResponse * response = new AsyncJsonResponse ( false, bufferSize );
//// response->addHeader ( "Server","ESP Async Web Server" );
//
// JsonObject root = response->getRoot();
// JsonArray gainPoints = root.createNestedArray ( "gainPoints" ); // Add gainPoints array
//
///*
// * Add the objects to the array
// */
//
// for ( int i = 0; i < displayPoints; i++ ) // For each data point
// {
// JsonObject dataPoint = gainPoints.createNestedObject(); // Add an object to the array
// dataPoint["x"] = myFreq[i]/1000000.0; // set the x(frequency) value
// dataPoint["y"] = myGain[i]; // set the y (gain) value
// }
//
// response->setLength();
// request->send ( response );
//}
/*
* On request from web page convert the data from a sweep into JSON and send.
* Ideally we would push the data to the web page at the end of a scan.
*/
//void onGetSweep ( AsyncWebServerRequest *request )
//{
// size_t bufferSize = JSON_ARRAY_SIZE ( SCREEN_WIDTH )
// + JSON_OBJECT_SIZE ( 14 ) + SCREEN_WIDTH * JSON_OBJECT_SIZE ( 2 );
//
// AsyncJsonResponse * response = new AsyncJsonResponse ( false, bufferSize );
//
// JsonObject root = response->getRoot();
//
// root["dispPoints"] = displayPoints;
// root["start"] = setting.ScanStart / 1000.0;
// root["stop"] = setting.ScanStop / 1000.0;
// root["IF"] = setting.IF_Freq / 1000000.0;
// root["attenuation"] = setting.Attenuate;
// root["extGain"] = setting.ExternalGain;
// root["levelOffset"] = setting.LevelOffset;
// root["filterCal"] = bpfCalibrations[bpfIndex];
// root["setRBW"] = setting.Bandwidth10;
// root["bandwidth"] = bandwidth;
// root["RefOut"] = setting.ReferenceOut;
// root["Drive"] = setting.Drive;
// root["sweepPoints"] = sweepPoints;
//
// if ( AGC_On )
// root["PreAmp"] = 0x60; // Auto
//
// else
// root["PreAmp"] = setting.PreampGain; // Fixed gain
//
// JsonArray Points = root.createNestedArray ( "Points" ); // Add Points array
//
//
// for ( int i = 0; i < displayPoints; i++ ) //For each data point
// {
// JsonObject dataPoint = Points.createNestedObject(); // add an object to the array
// dataPoint["x"] = myFreq[i]/1000000.0; // set the x(frequency) value
// dataPoint["y"] = myData[i]; // set the y (RSSI) value
// }
//
//
// response->setLength();
// request->send ( response );
//}
/*
* On request from web page send the settings as JSON
*/
//void onGetSettings (AsyncWebServerRequest *request)
//{
// AsyncJsonResponse * response = new AsyncJsonResponse(false) ;
//
// JsonObject root = response->getRoot();
//
// root["mType"] = "Settings";
// root["mode"] = setting.Mode;
// root["dispPoints"] = displayPoints;
// root["start"] = setting.ScanStart / 1000.0;
// root["stop"] = setting.ScanStop / 1000.0;
// root["IF"] = setting.IF_Freq / 1000000.0;
// root["attenuation"] = setting.Attenuate;
// root["extGain"] = setting.ExternalGain;
// root["levelOffset"] = setting.LevelOffset;
// root["filterCal"] = bpfCalibrations[bpfIndex];
// root["setRBW"] = setting.Bandwidth10;
// root["bandwidth"] = bandwidth;
// root["RefOut"] = setting.ReferenceOut;
// root["Drive"] = setting.Drive;
// root["sweepPoints"] = sweepPoints;
// root["spur"] = setting.Spur;
// root["tg"] = trackGenSetting.Mode;
// root["tgPower"] = trackGenSetting.Power;
// root["tgFreq"] = trackGenSetting.Frequency;
// root["tgMod"] = trackGenSetting.ModulationType;
// root["tgModFreq"] = trackGenSetting.ModFrequency;
// root["sg"] = sigGenOutputOn; //
// root["sgPower"] = sigGenSetting.Power;
// root["sgMod"] = sigGenSetting.ModulationType;
// root["sgModFreq"] = sigGenSetting.ModFrequency;
// root["sgFreq"] = sigGenSetting.Frequency;
// root["sgCal"] = sigGenSetting.Calibration;
// root["sgRange"] = ATTENUATOR_RANGE + 11; // SI4432 output can be adjusted over 21dBm but max to SAW filter is 10dBm
// root["tgCal"] = trackGenSetting.Calibration;
// root["tgRange"] = ATTENUATOR_RANGE + 21; // no SAW filter so 20dBm output is possible.
//
// if ( AGC_On )
// root["PreAmp"] = 0x60; // Auto
//
// else
// root["PreAmp"] = setting.PreampGain; // Fixed gain
//
// response->setLength();
// request->send ( response );
//// Serial.printf ( "Get Settings sweepPoints %u\n", sweepPoints );
//}
void addCommonSettings ( JsonDocument& jDoc )
{
jDoc["mType"] = "Settings";
jDoc["mode"] = setting.Mode;
jDoc["IF"] = setting.IF_Freq / 1000000.0;
jDoc["attenuation"] = setting.Attenuate;
jDoc["extGain"] = setting.ExternalGain;
jDoc["filterCal"] = bpfCalibrations[bpfIndex];
jDoc["setRBW"] = setting.Bandwidth10;
jDoc["bandwidth"] = bandwidth;
jDoc["RefOut"] = setting.ReferenceOut;
jDoc["Drive"] = setting.Drive;
jDoc["sweepPoints"] = sweepPoints;
jDoc["spur"] = setting.Spur;
jDoc["tg"] = trackGenSetting.Mode;
jDoc["tgPower"] = trackGenSetting.Power;
jDoc["tgFreq"] = trackGenSetting.Frequency;
jDoc["tgMod"] = trackGenSetting.ModulationType;
jDoc["tgModFreq"] = trackGenSetting.ModFrequency;
jDoc["sg"] = sigGenOutputOn; //
jDoc["sgPower"] = sigGenSetting.Power;
jDoc["sgMod"] = sigGenSetting.ModulationType;
jDoc["sgModFreq"] = sigGenSetting.ModFrequency;
jDoc["sgFreq"] = sigGenSetting.Frequency;
jDoc["sgCal"] = sigGenSetting.Calibration;
jDoc["sgRange"] = ATTENUATOR_RANGE + 11; // SI4432 output can be adjusted over 21dBm but max to SAW filter is 10dBm
jDoc["tgCal"] = trackGenSetting.Calibration;
jDoc["tgRange"] = ATTENUATOR_RANGE + 21; // no SAW filter so 20dBm output is possible.
if ( AGC_On )
jDoc["PreAmp"] = 0x60; // Auto
else
jDoc["PreAmp"] = setting.PreampGain; // Fixed gain
}
/*
* Push the settings data to the websocket clients
* Slightly different for each mode
*
* Could economise by splitting so common fields are in one function
*/
void pushSettings ()
{
@ -677,41 +556,12 @@ size_t capacity = JSON_ARRAY_SIZE ( SCREEN_WIDTH )
+ SCREEN_WIDTH*JSON_OBJECT_SIZE ( 2 ) + JSON_OBJECT_SIZE ( 17 );
static DynamicJsonDocument jsonDocument ( capacity ); // buffer for json data to be pushed to the web clients
jsonDocument["mType"] = "Settings";
jsonDocument["mode"] = setting.Mode;
addCommonSettings(jsonDocument);
jsonDocument["dispPoints"] = displayPoints;
jsonDocument["start"] = setting.ScanStart / 1000.0;
jsonDocument["stop"] = setting.ScanStop / 1000.0;
jsonDocument["IF"] = setting.IF_Freq / 1000000.0;
jsonDocument["attenuation"] = setting.Attenuate;
jsonDocument["extGain"] = setting.ExternalGain;
jsonDocument["levelOffset"] = setting.LevelOffset;
jsonDocument["filterCal"] = bpfCalibrations[bpfIndex];
jsonDocument["setRBW"] = setting.Bandwidth10;
jsonDocument["bandwidth"] = bandwidth;
jsonDocument["RefOut"] = setting.ReferenceOut;
jsonDocument["Drive"] = setting.Drive;
jsonDocument["sweepPoints"] = sweepPoints;
jsonDocument["spur"] = setting.Spur;
jsonDocument["tg"] = trackGenSetting.Mode;
jsonDocument["tgPower"] = trackGenSetting.Power;
jsonDocument["tgFreq"] = trackGenSetting.Frequency;
jsonDocument["tgMod"] = trackGenSetting.ModulationType;
jsonDocument["tgModFreq"] = trackGenSetting.ModFrequency;
jsonDocument["sg"] = sigGenOutputOn; //
jsonDocument["sgPower"] = sigGenSetting.Power;
jsonDocument["sgMod"] = sigGenSetting.ModulationType;
jsonDocument["sgModFreq"] = sigGenSetting.ModFrequency;
jsonDocument["sgFreq"] = sigGenSetting.Frequency;
jsonDocument["sgCal"] = sigGenSetting.Calibration;
jsonDocument["sgRange"] = ATTENUATOR_RANGE + 11; // SI4432 output can be adjusted over 21dBm but max to SAW filter is 10dBm
jsonDocument["tgCal"] = trackGenSetting.Calibration;
jsonDocument["tgRange"] = ATTENUATOR_RANGE + 21; // no SAW filter so 20dBm output is possible.
if ( AGC_On )
jsonDocument["PreAmp"] = 0x60; // Auto
else
jsonDocument["PreAmp"] = setting.PreampGain; // Fixed gain
String wsBuffer;
@ -727,6 +577,7 @@ static DynamicJsonDocument jsonDocument ( capacity ); // buffer for json data to
}
/*
* Push the settings data to the websocket clients
*/
@ -736,39 +587,12 @@ size_t capacity = JSON_ARRAY_SIZE ( SCREEN_WIDTH )
+ SCREEN_WIDTH*JSON_OBJECT_SIZE ( 2 ) + JSON_OBJECT_SIZE ( 17 );
static DynamicJsonDocument jsonDocument ( capacity ); // buffer for json data to be pushed to the web clients
jsonDocument["mType"] = "Settings";
jsonDocument["mode"] = setting.Mode;
addCommonSettings(jsonDocument);
jsonDocument["dispPoints"] = displayPoints;
jsonDocument["start"] = startFreq_IF / 1000.0;
jsonDocument["stop"] = stopFreq_IF / 1000.0;
jsonDocument["IF"] = setting.IF_Freq / 1000000.0;
jsonDocument["attenuation"] = setting.Attenuate;
jsonDocument["extGain"] = setting.ExternalGain;
jsonDocument["levelOffset"] = setting.LevelOffset;
jsonDocument["filterCal"] = bpfCalibrations[bpfIndex];
jsonDocument["setRBW"] = setting.Bandwidth10;
jsonDocument["bandwidth"] = bandwidth;
jsonDocument["RefOut"] = setting.ReferenceOut;
jsonDocument["Drive"] = setting.Drive;
jsonDocument["sweepPoints"] = sweepPoints;
jsonDocument["spur"] = setting.Spur;
jsonDocument["tg"] = trackGenSetting.Mode;
jsonDocument["tgPower"] = trackGenSetting.Power;
jsonDocument["tgFreq"] = trackGenSetting.Frequency;
jsonDocument["sg"] = sigGenOutputOn; //
jsonDocument["sgPower"] = sigGenSetting.Power;
jsonDocument["sgMod"] = sigGenSetting.ModulationType;
jsonDocument["sgModFreq"] = sigGenSetting.ModFrequency;
jsonDocument["sgFreq"] = sigGenSetting.Frequency;
jsonDocument["sgCal"] = sigGenSetting.Calibration;
jsonDocument["sgRange"] = ATTENUATOR_RANGE + 11; // SI4432 output can be adjusted over 21dBm but max to SAW filter is 10dBm
jsonDocument["tgCal"] = trackGenSetting.Calibration;
jsonDocument["tgRange"] = ATTENUATOR_RANGE + 21; // no SAW filter so 20dBm output is possible.
if ( AGC_On )
jsonDocument["PreAmp"] = 0x60; // Auto
else
jsonDocument["PreAmp"] = setting.PreampGain; // Fixed gain
String wsBuffer;
@ -779,8 +603,6 @@ static DynamicJsonDocument jsonDocument ( capacity ); // buffer for json data to
}
else
Serial.println ( "No buffer :(");
// Serial.printf ( "Push Settings sweepPoints %u\n", sweepPoints );
}
@ -793,39 +615,12 @@ size_t capacity = JSON_ARRAY_SIZE ( SCREEN_WIDTH )
+ SCREEN_WIDTH*JSON_OBJECT_SIZE ( 2 ) + JSON_OBJECT_SIZE ( 17 );
static DynamicJsonDocument jsonDocument ( capacity ); // buffer for json data to be pushed to the web clients
jsonDocument["mType"] = "Settings";
jsonDocument["mode"] = setting.Mode;
addCommonSettings(jsonDocument);
jsonDocument["dispPoints"] = displayPoints;
jsonDocument["start"] = startFreq_RX / 1000.0;
jsonDocument["stop"] = stopFreq_RX / 1000.0;
jsonDocument["IF"] = setting.IF_Freq / 1000000.0;
jsonDocument["attenuation"] = setting.Attenuate;
jsonDocument["extGain"] = setting.ExternalGain;
jsonDocument["levelOffset"] = 0;
jsonDocument["filterCal"] = bpfCalibrations[bpfIndex];
jsonDocument["setRBW"] = setting.Bandwidth10;
jsonDocument["bandwidth"] = bandwidth;
jsonDocument["RefOut"] = setting.ReferenceOut;
jsonDocument["Drive"] = setting.Drive;
jsonDocument["sweepPoints"] = sweepPoints;
jsonDocument["spur"] = setting.Spur;
jsonDocument["tg"] = trackGenSetting.Mode;
jsonDocument["tgPower"] = trackGenSetting.Power;
jsonDocument["tgFreq"] = trackGenSetting.Frequency;
jsonDocument["sg"] = sigGenOutputOn; //
jsonDocument["sgPower"] = sigGenSetting.Power;
jsonDocument["sgMod"] = sigGenSetting.ModulationType;
jsonDocument["sgModFreq"] = sigGenSetting.ModFrequency;
jsonDocument["sgFreq"] = sigGenSetting.Frequency;
jsonDocument["sgCal"] = sigGenSetting.Calibration;
jsonDocument["sgRange"] = ATTENUATOR_RANGE + 11; // SI4432 output can be adjusted over 21dBm but max to SAW filter is 10dBm
jsonDocument["tgCal"] = trackGenSetting.Calibration;
jsonDocument["tgRange"] = ATTENUATOR_RANGE + 21; // no SAW filter so 20dBm output is possible.
if ( AGC_On )
jsonDocument["PreAmp"] = 0x60; // Auto
else
jsonDocument["PreAmp"] = setting.PreampGain; // Fixed gain
String wsBuffer;
@ -836,8 +631,6 @@ static DynamicJsonDocument jsonDocument ( capacity ); // buffer for json data to
}
else
Serial.println ( "No buffer :(");
// Serial.printf ( "Push Settings sweepPoints %u\n", sweepPoints );
}
@ -850,39 +643,12 @@ size_t capacity = JSON_ARRAY_SIZE ( SCREEN_WIDTH )
+ SCREEN_WIDTH*JSON_OBJECT_SIZE ( 2 ) + JSON_OBJECT_SIZE ( 17 );
static DynamicJsonDocument jsonDocument ( capacity ); // buffer for json data to be pushed to the web clients
jsonDocument["mType"] = "Settings";
jsonDocument["mode"] = setting.Mode;
addCommonSettings(jsonDocument);
jsonDocument["dispPoints"] = setting.BandscopePoints;
jsonDocument["start"] = setting.BandscopeStart / 1000.0;
jsonDocument["stop"] = ( setting.BandscopeStart + setting.BandscopeSpan ) / 1000.0;
jsonDocument["IF"] = setting.IF_Freq / 1000000.0;
jsonDocument["attenuation"] = setting.Attenuate;
jsonDocument["extGain"] = setting.ExternalGain;
jsonDocument["levelOffset"] = setting.LevelOffset;
jsonDocument["filterCal"] = bpfCalibrations[bpfIndex];
jsonDocument["setRBW"] = setting.Bandwidth10;
jsonDocument["bandwidth"] = bandwidth;
jsonDocument["RefOut"] = setting.ReferenceOut;
jsonDocument["Drive"] = setting.Drive;
jsonDocument["sweepPoints"] = sweepPoints;
jsonDocument["spur"] = setting.Spur;
jsonDocument["tg"] = trackGenSetting.Mode;
jsonDocument["tgPower"] = trackGenSetting.Power;
jsonDocument["tgFreq"] = trackGenSetting.Frequency;
jsonDocument["sg"] = sigGenOutputOn; //
jsonDocument["sgPower"] = sigGenSetting.Power;
jsonDocument["sgMod"] = sigGenSetting.ModulationType;
jsonDocument["sgModFreq"] = sigGenSetting.ModFrequency;
jsonDocument["sgFreq"] = sigGenSetting.Frequency;
jsonDocument["sgCal"] = sigGenSetting.Calibration;
jsonDocument["sgRange"] = ATTENUATOR_RANGE + 11; // SI4432 output can be adjusted over 21dBm but max to SAW filter is 10dBm
jsonDocument["tgCal"] = trackGenSetting.Calibration;
jsonDocument["tgRange"] = ATTENUATOR_RANGE + 21; // no SAW filter so 20dBm output is possible.
if ( AGC_On )
jsonDocument["PreAmp"] = 0x60; // Auto
else
jsonDocument["PreAmp"] = setting.PreampGain; // Fixed gain
String wsBuffer;
@ -893,8 +659,6 @@ static DynamicJsonDocument jsonDocument ( capacity ); // buffer for json data to
}
else
Serial.println ( "No buffer :(");
// Serial.printf ( "Push Settings sweepPoints %u\n", sweepPoints );
}
@ -908,41 +672,12 @@ size_t capacity = JSON_ARRAY_SIZE ( SCREEN_WIDTH )
+ SCREEN_WIDTH*JSON_OBJECT_SIZE ( 2 ) + JSON_OBJECT_SIZE ( 17 );
static DynamicJsonDocument jsonDocument ( capacity ); // buffer for json data to be pushed to the web clients
jsonDocument["mType"] = "Settings";
jsonDocument["mode"] = setting.Mode;
addCommonSettings(jsonDocument);
jsonDocument["dispPoints"] = displayPoints;
jsonDocument["start"] = startFreq_IF / 1000.0;
jsonDocument["stop"] = stopFreq_IF / 1000.0;
jsonDocument["IF"] = setting.IF_Freq / 1000000.0;
jsonDocument["attenuation"] = setting.Attenuate;
jsonDocument["extGain"] = setting.ExternalGain;
jsonDocument["levelOffset"] = setting.LevelOffset;
jsonDocument["filterCal"] = bpfCalibrations[bpfIndex];
jsonDocument["setRBW"] = setting.Bandwidth10;
jsonDocument["bandwidth"] = bandwidth;
jsonDocument["RefOut"] = setting.ReferenceOut;
jsonDocument["Drive"] = setting.Drive;
jsonDocument["sweepPoints"] = sweepPoints;
jsonDocument["spur"] = setting.Spur;
jsonDocument["tg"] = trackGenSetting.Mode;
jsonDocument["tgPower"] = trackGenSetting.Power;
jsonDocument["tgMod"] = trackGenSetting.ModulationType;
jsonDocument["tgModFreq"] = trackGenSetting.ModFrequency;
jsonDocument["tgFreq"] = trackGenSetting.Frequency;
jsonDocument["sg"] = sigGenOutputOn; //
jsonDocument["sgPower"] = sigGenSetting.Power;
jsonDocument["sgMod"] = sigGenSetting.ModulationType;
jsonDocument["sgModFreq"] = sigGenSetting.ModFrequency;
jsonDocument["sgFreq"] = sigGenSetting.Frequency;
jsonDocument["sgCal"] = sigGenSetting.Calibration;
jsonDocument["sgRange"] = (ATTENUATOR_RANGE + RX_SI4432_MAX_DRIVE * 3); // SI4432 output can be adjusted over 21dBm but max to SAW filter is 10dBm
jsonDocument["tgCal"] = trackGenSetting.Calibration;
jsonDocument["tgRange"] = ATTENUATOR_RANGE + 21; // no SAW filter so full 20dBm output is possible.
if ( AGC_On )
jsonDocument["PreAmp"] = 0x60; // Auto
else
jsonDocument["PreAmp"] = setting.PreampGain; // Fixed gain
String wsBuffer;
@ -953,8 +688,6 @@ static DynamicJsonDocument jsonDocument ( capacity ); // buffer for json data to
}
else
Serial.println ( "No buffer :(");
// Serial.printf ( "Push Settings sweepPoints %u\n", sweepPoints );
}
@ -1027,93 +760,6 @@ void onDoReboot ( AsyncWebServerRequest *request )
}
/*
* Function sets the sweep parameters based on the data in the form posted by the web page
* No longer used
*/
// doSetSweep ? setStart = 10 & setStop = 20 & setExtGain = 0 & setRBW = 26
//void onSetSweep ( AsyncWebServerRequest *request )
//{
//
// Serial.print ( request->url ()); // Get the paramaters passed from the
// Serial.print ( ":-" ); // web page, checking they exist
//
// if ( request->hasParam ( "setStart" ))
// {
// Serial.print ( "setStart;" );
// AsyncWebParameter* startInput = request->getParam ( "setStart" );
// SetSweepStart ( atof ( startInput->value().c_str()) * 1000000.0 );
// }
//
// if ( request->hasParam ( "setStop" ))
// {
// Serial.print ( "setStop;" );
// AsyncWebParameter* stopInput = request->getParam ( "setStop" );
// SetSweepStop( atof ( stopInput->value().c_str()) * 1000000.0 );
// }
//
// if ( request->hasParam ( "setExtGain" ))
// {
// Serial.print ( "setExtGain;" );
// AsyncWebParameter* extGainInput = request->getParam ( "setExtGain" );
//// Need to add function later
// }
//
// if ( request->hasParam ( "refOut" ))
// {
// Serial.print ( "refOut;" );
// AsyncWebParameter* setRefOut = request->getParam ( "setRefOut" );
// setting.ReferenceOut = atoi ( setRefOut->value().c_str() );
// xmit.SetPowerReference ( setting.ReferenceOut );
// }
//
// if ( request->hasParam ( "setAtten" ))
// {
// Serial.print ( "setAtten:" );
// AsyncWebParameter* setAtten = request->getParam ( "setAtten");
// SetAttenuation ( atoi ( setAtten->value().c_str() ));
// Serial.print ( atoi ( setAtten->value().c_str() ));
// Serial.print ( "; " );
// }
//
// if ( request->hasParam ( "setRBW" ))
// {
// Serial.print ( "setRBW ");
// AsyncWebParameter* rbwInput = request->getParam ( "setRBW" );
// SetRBW ( atoi ( rbwInput->value().c_str() ));
// Serial.printf ( "setting.bandwidth = %i, input = %i;", setting.Bandwidth10, atoi ( rbwInput->value().c_str() ));
// }
//
// Serial.println ();
// request->redirect ( "index.html" ); // redirect to the index page
//}
//
//
///*
// * Function sets the sweep parameters based on the data in the form posted by the web page
// * No longer used
// */
//
//// doSetSweep ? setStart = 10 &setStop = 20 & setExtGain = 0 & setRBW = 26
//
//void onSettings ( AsyncWebServerRequest *request )
//{
// Serial.print ( request->url() ); // Get the paramaters passed from the web
// Serial.print ( ":-" ); // page, checking they exist
//
// if ( request->hasParam ( "setActPower" ))
// {
// Serial.print ( "setActPower;" );
// AsyncWebParameter* setLevelInput = request->getParam ( "setActPower" );
// SetPowerLevel ( atof ( setLevelInput->value().c_str()) );
// }
//
// Serial.println();
// request->redirect ( "index.html"); // Redirect to the index page
//}
void onGetNameVersion ( AsyncWebServerRequest *request )
{
@ -1123,8 +769,8 @@ void onGetNameVersion ( AsyncWebServerRequest *request )
response->printf ( "<IndexNameVersion " );
response->printf ( "Name=\"%s\" ",PROGRAM_NAME );
response->printf ( "Version=\"V%s\" ",PROGRAM_VERSION );
response->printf ( "Copyright=\"PD0EK\"" );
response->printf ( "Version=\"%s\" ",PROGRAM_VERSION );
response->printf ( "Copyright=\"M0WID\"" );
response->printf ( "/>" );
@ -1176,17 +822,11 @@ void buildServer () // We can now configure and start the server
{
Serial.println ( "Building Server.." );
server.reset (); // Clear any existing settings and events
// server.on ( "/getSweep", HTTP_GET, onGetSweep ); // Set event to return sweep data as JSON array
// server.on ( "/getGainSweep", HTTP_GET, onGetGainSweep ); // Set event to return sweep gain data as JSON array
// server.on ( "/getSettings", HTTP_GET, onGetSettings ); // Set event to return settings data as JSON array
// server.on ( "/doSetSweep", HTTP_POST, onSetSweep ); // Set event to set sweep values received from client
server.on ( "/doReboot", HTTP_GET, onDoReboot ); // Set event to reboot the ESP32
server.on ( "/getNameVersion", HTTP_GET, onGetNameVersion );// Set event to return name and version
// server.on ( "/getScan", HTTP_GET, onGetScan ); // Set event to return sweep data as XML
server.on ( "/getRbwList", HTTP_GET, onGetRbwList ); // Set event to return RBW options as JSON array
server.on ( "/getAttenList", HTTP_GET, onGetAttenList ); // Set event to return attenuator options as JSON array
server.on ( "/getSSIDs", HTTP_GET, onGetSIDDs ); // Set event to return list of SSID as XML
// server.on ( "/doSettings", HTTP_POST, onSettings ); // Set event to set setting values received from client
server.on ( "/getNameVersion", HTTP_GET, onGetNameVersion );// Set event to return name and version
server.on ( "/doReboot", HTTP_GET, onDoReboot ); // Set event to reboot the ESP32
server.serveStatic ( "/", SPIFFS, "/" ).setDefaultFile ( "index.html" );

10
ui.cpp
View File

@ -277,6 +277,7 @@ static void menu_scale_cb ( int item );
static void menu_sweep_cb ( int item );
static void menu_IF_sweep_cb ( int item ); // M0WID added 3.0c
static void menu_RX_sweep_cb ( int item );
static void menu_bpfCal_cb ( int item );
static void menu_recall_cb ( int item );
static void menu_version_cb (int item );
static void menu_generate_cb(int item); // WA2FZW - Added in M0WID's Version 05
@ -757,6 +758,7 @@ static Menuitem menu_RXsweep_top[] = // This is the main "IF_SWEEP" menu
Menuitem ( MT_FUNC, "\2SWEEP\0SIG", menu_RX_sweep_cb ),
Menuitem ( MT_FUNC, "RBW", menu_RX_sweep_cb ),
Menuitem ( MT_MENU, "REFERENCE", menu_refer ), // Select GPIO2 reference frequency
Menuitem ( MT_FUNC, "\2BPF\0CAL", menu_bpfCal_cb ),
Menuitem ( MT_END ) // End marker
};
@ -1493,7 +1495,6 @@ static void menu_autosettings_cb ( int item )
SetRefLevel ( AUTO_REF_LEVEL );
SetRefOutput ( AUTO_REF_OUTPUT );
SetAttenuation ( AUTO_ATTEN );
// SetPowerLevel ( 100 ); // Removed - Screws up calibration
SetRBW ( AUTO_RBW ); // Auto mode
SetRX ( 0 );
setting.ShowGain = 1; // Gain trace on
@ -1827,6 +1828,13 @@ static void menu_RX_sweep_cb ( int item )
ui_process_keypad ();
}
static void menu_bpfCal_cb ( int item )
{
StartBpfCal ();
ui_mode_normal();
}
static void menu_extern_cb ( int item )
{
int km = KM_EXTERN;