simpleSA/data/index.html
M0WID 96a27b6005 Web Sig Gen again
Bug remains in attenuation calc
Formatting of buttons on web page to do
Add track Gen to signal generator web page if present (need to send a config state in settings)
Add track gen level control
2020-10-04 22:36:46 +01:00

1710 lines
51 KiB
HTML

<!--
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</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' id="top">
<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" style="display:none">
<!-- container for chart -->
</div>
<div class = "Grid-cell" id="sigGen" style="display:block">
<!-- container for sig gen controls -->
<br />
<div class="sigTitle">Signal Generator</div>
<br />
<div class="sigFreq">
<label for="setSigGenFreq8" class="sigFreqLabel">Frequency:</label>
<input class="sigFreqInput" id="setSigGenFreq8" name="setSigGenFreq8" type="number" min=-1 max=10 value=0>
<input class="sigFreqInput" id="setSigGenFreq7" name="setSigGenFreq7" type="number" min=-1 max=10 value=0>
<input class="sigFreqInput" id="setSigGenFreq6" name="setSigGenFreq6" type="number" min=-1 max=10 value=0>
<span class="sigFreqText">,</span>
<input class="sigFreqInput" id="setSigGenFreq5" name="setSigGenFreq5" type="number" min=-1 max=10 value=0>
<input class="sigFreqInput" id="setSigGenFreq4" name="setSigGenFreq4" type="number" min=-1 max=10 value=0>
<input class="sigFreqInput" id="setSigGenFreq3" name="setSigGenFreq3" type="number" min=-1 max=10 value=0>
<span class="sigFreqText">,</span>
<input class="sigFreqInput" id="setSigGenFreq2" name="setSigGenFreq2" type="number" min=-1 max=10 value=0>
<input class="sigFreqInput" id="setSigGenFreq1" name="setSigGenFreq1" type="number" min=-1 max=10 value=0>
<input class="sigFreqInput" id="setSigGenFreq0" name="setSigGenFreq0" type="number" min=0 max=10 value=0>
<span class="sigFreqText">Hz</span>
<button class = "set-button" id="incButton">+</button> &nbsp;
<button class = "set-button" id="decButton">-</button> &nbsp;
<button class = "set-button" id="sigOnButton">On/Off</button>
</div>
<br /><br />
<label for="setSigGenPower" class = "sigLevelLabel">Level:</label>
<input class="sigLevelInput" id="setSigGenPower" name="setSigGenPower" type="number" min=-70 max=20 value=0>
dBm
<br /><br />
<div class="slidecontainer">
<input type="range" min=-70 max=20 value=0 class="slider" id="sigLevelSlider">
</div>
</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="setStart" class="setting-label">Start:</label>
<input class="value-input" name='setStart' type="number" id="setStart" maxlength="9" min="0" max="350" required>
MHz
</div>
<div class="setting" >
<label for="setStop" class="setting-label">Stop:</label>
<input class="value-input" name='setStop' type="number" id ="setStop" maxlength="9" min="0" max="350" required>
MHz
</div>
<br />
<div class="setting" >
<label for="setCenter" class="setting-label">Centre:</label>
<input class="value-input" name='setCenter' type="number" id ="setCenter" maxlength="9" min="0" max="350" required>
MHz
</div>
<div class="setting" >
<label for="setSpan" class="setting-label">Span:</label>
<!--<select class="select-input" id="setSpan" name="setSpan">
<option class="select-option" value="250">250</option>
<option class="select-option" value="100">100</option>
<option class="select-option" value="50">50</option>
<option class="select-option" value="20">20</option>
<option class="select-option" value="10">10</option>
<option class="select-option" value="4">4</option>
<option class="select-option" value="2">2</option>
<option class="select-option" value="1">1</option>
<option class="select-option" value="0.5">0.5</option>
</select> -->
<input class="value-input" name='setSpan' type="number" id ="setSpan" maxlength="9" min="0" max="350" step="0.1" required>
MHz
</div>
<!--
<label class="setting-label">Width:</label>
<input class="value-input" name='setWidth' type="text" id ="setWidth" placeholder="width" maxlength="9" min="0" max="250" required>
MHz
</div> -->
<br />
<!-- <div style="width:180px; display: inline-block">Ext gain:<input style = "width:100px" name='setExtGain' type="text" placeholder="extGain" maxlength="9" min="-100" max="40" required></div> -->
<div id="signal_info">
<div class="setting" >
<label class="setting-label">RBW:</label>
<input class="value-display" type="text" disabled="1" id="actRBW" size="1" value="300" />
kHz
</div>
</div>
<div class="setting" >
<label for="setRBW" class="setting-label">RBW:</label>
<select class="select-input" id="setRBW" name="setRBW"></select>
kHz
</div>
<!-- <div style="width:150px; display: inline-block">
<button type="submit">Update</button>
</div> -->
<br />
<div class="setting" >
<label for="setAtten" class="setting-label">Atten:</label>
<input class="value-input" name='setAtten' type="number" step="1" id ="setAtten" maxlength=3 min=0 max=31 required>
dB
<label for="setExtern" class="setting-label">External:</label>
<input class="value-input" name='setExtern' type="number" step="1" id ="setExtern" maxlength=3 min=-60 max=60 required>
<!--<select class="select-input" id="setAtten" name="setAtten"></select> -->
dB
</div>
<br />
<div class="setting" >
<label for="setRefOut" class="setting-label">Reference:</label>
<select class="select-input" id="setRefOut" name="setRefOut">
<option class="select-option" value="-1">Off</option>
<option class="select-option" value="0">30</option>
<option class="select-option" value="1">15</option>
<option class="select-option" value="2">10</option>
<option class="select-option" value="3">4</option>
<option class="select-option" value="4">3</option>
<option class="select-option" value="5">2</option>
<option class="select-option" value="6">1</option>
</select>
MHz
</div>
<br />
<div id="spur">
<div class="setting" >
<label class="setting-widelabel">Spur Reduce:</label>
<input class="checkbox-input" type="checkbox" id="spurReduction" size="1" value="0" />
</div>
</div>
<div id="tracking">
<div class="setting" >
<label class="setting-label">TrackGen:</label>
<select class="select-input" id="trackGen" name="trackGen">
<option class="select-option" value=0>Off</option>
<option class="select-option" value=1>Track</option>
<option class="select-option" value=2>Generate</option>
</select>
<br />
<label class="setting-label">Level:</label>
<input class="value-input" type="number" id="setTrackGenPower" placeholder="setTrackGenPower" maxlength = "6" min="-60" max="20" value="0" />
dBm
</div>
<div class="setting" >
<label for="setTGFreq" class="setting-label">TG Freq:</label>
<input class="value-input" name='setTGFreq' type="number" id="setTGFreq" maxlength="9" min=0 max=350 required>
MHz
</div>
</div>
<br />
<div id="signal_info">
<div class="setting" >
<label class="setting-label">Points:</label>
<input class="value-display" type="text" disabled="1" id="sweepPoints" size="1" value="65000" />
<label class="setting-label">Time:</label>
<input class="value-display" type="text" disabled="1" id="sweepTime" size="1" value="290" />
ms
</div>
</div>
<div id="store">
<div class = "setting" >
<label class="setting-label">Store:</label>
<input class="checkbox-input" type="checkbox" id="store1" size="1" value="0" />
<input class="checkbox-input" type="checkbox" id="store2" size="1" value="0" />
<input class="checkbox-input" type="checkbox" id="store3" size="1" value="0" />
<input class="checkbox-input" type="checkbox" id="store4" size="1" value="0" />
</div>
</div>
<!-- form for device settings -->
<hr />
<h1>Settings</h1>
<div class="setting" >
<label for="levelOffset" class="setting-label">Offset:</label>
<input class="value-display" type="text" disabled="1" id="levelOffset" size="1" value="10" />
dB
</div>
<div class="setting" >
<button class = "set-button" type="submit" id="setActPower">Set Actual</button>
<input class="value-input" type="number" id="setPowerValue" placeholder="setPowerValue" 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="setPreAmp" class="setting-label">Pre-amp:</label>
<select class="select-input" id="setPreAmp" name="setPreAmp">
<option value="96">Auto</option> <!--0x60 Auto -->
<option value="0">5</option> <!--0x00 LNA Min 5dB-->
<option value="1">8</option> <!--0x01 -->
<option value="2">11</option> <!--0x02 -->
<option value="3">14</option> <!--0x03 -->
<option value="4">17</option> <!--0x04 -->
<option value="5">20</option> <!--0x05 -->
<option value="6">23</option> <!--0x06 -->
<option value="7">27</option> <!--0x07 -->
<option value="8">30</option> <!--0x08 -->
<option value="16">25</option> <!--0x10 LNA Max 25dB-->
<option value="17">28</option> <!--0x11 -->
<option value="18">31</option> <!--0x12 -->
<option value="19">34</option> <!--0x13 -->
<option value="20">37</option> <!--0x14 -->
<option value="21">40</option> <!--0x15 -->
<option value="22">43</option> <!--0x16 -->
<option value="23">46</option> <!--0x17 -->
<option value="24">49</option> <!--0x18 -->
</select>
dB
</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 class="setting" >
<label for="Average" class="setting-label">Average:</label>
<input class="value-input" type="number" id="Average" size="1" value="10" min="2" max=100 step=1 />
</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 frequency = 0;
var freqStep = 1000000;
var chartDiv = document.getElementById('chartSA');
var sigDiv = document.getElementById('sigGen');
var refreshInterval = document.getElementById('refreshInterval');
var refresh = document.getElementById('refresh');
var setMode = document.getElementById('setMode');
var sweepStart = document.getElementById('sweepStart');
var sweepStop = document.getElementById('sweepStop');
var setStart = document.getElementById('setStart');
var setStop = document.getElementById('setStop');
var setCenter = document.getElementById('setCenter');
var setSpan = document.getElementById('setSpan');
var setAtten = document.getElementById('setAtten');
var setExtern = document.getElementById('setExtern');
var setActPower = document.getElementById('setActPower');
var levelOffset = document.getElementById('levelOffset');
var setRefOut = document.getElementById('setRefOut');
var sweepPoints = document.getElementById('sweepPoints');
var sweepTime = document.getElementById('sweepTime');
var setSpur = document.getElementById('spurReduction');
var actRBW = document.getElementById('actRBW');
var setRBW = document.getElementById('setRBW');
var setDrive = document.getElementById('setLODrive');
var setIF = document.getElementById('setIF');
var setPreAmp = document.getElementById('setPreAmp');
var setAverage = document.getElementById('Average');
var setTrackGen = document.getElementById('trackGen');
var setTrackGenPower = document.getElementById('setTrackGenPower');
var setTGFreq = document.getElementById('setTGFreq');
var store1 = document.getElementById('store1');
var store2 = document.getElementById('store2');
var store3 = document.getElementById('store3');
var store4 = document.getElementById('store4');
//var messageWindow = document.getElementById('message');
var sigLevelSlider = document.getElementById('sigLevelSlider');
var setSigGenPower = document.getElementById('setSigGenPower');
var setSigGenFreq = document.getElementById('setSigGenFreq');
var sigOnButton = document.getElementById('sigOnButton');
var setSigGenFreq0 = document.getElementById('setSigGenFreq0');
var setSigGenFreq1 = document.getElementById('setSigGenFreq1');
var setSigGenFreq2 = document.getElementById('setSigGenFreq2');
var setSigGenFreq3 = document.getElementById('setSigGenFreq3');
var setSigGenFreq4 = document.getElementById('setSigGenFreq4');
var setSigGenFreq5 = document.getElementById('setSigGenFreq5');
var setSigGenFreq6 = document.getElementById('setSigGenFreq6');
var setSigGenFreq7 = document.getElementById('setSigGenFreq7');
var setSigGenFreq8 = document.getElementById('setSigGenFreq8');
var tempCenter;
// initialise these to silly values to force an update first time round
var oldSweepStart = -1;
var oldSweepStop = -1;
var oldSweepCenter = -1;
var oldSetRefOut = -2;
var oldSetRBW = -10;
var oldLevelOffset = 1000;
var oldAttenuation = 1000;
var oldExternalGain = 1000;
var oldDrive = -1;
var oldIF = 0;
var oldPreAmp = 0;
var oldSweepPoints = 0;
var oldSpur = 2;
var oldTrackGen = 2;
var oldTrackGenPower = 1000;
var oldTGFreq = -1;
var oldSigGen = -1;
var oldSigGenPower = 1000;
var oldSigGenFreq = -1;
var oldSigGenMod = -1;
var oldSigGenModFreq = -1;
var oldSigOnButton = -1;
// Chart configuration - Scope
var RSSISamples = [
{y:10},
{y:11},
{y:12},
{y:13},
{y:14},
{y:15},
{y:16},
{y:17},
{y:18},
]; // dummy for test
var dBSamples = [
{y:-10},
{y:-20},
{y:-23},
{y:-90},
{y:-120},
{y:-100},
{y:-80},
{y:-30},
{y:-40},
]; // dummy for test
var gainSamples = [
{x:0, y:42},
{x:10, y:43},
{x:20, y:44},
{x:30, y:45},
{x:40, y:46},
{x:50, y:47},
{x:80, y:48},
{x:90, y:49},
{x:100, y:40},
]; // dummy for test
var store1Samples = [
{x:0, y:42},
{x:10, y:43},
{x:20, y:44},
{x:30, y:45},
{x:40, y:46},
{x:50, y:47},
{x:80, y:48},
{x:90, y:49},
{x:100, y:40},
];
var store2Samples = [
{x:0, y:42},
{x:10, y:43},
{x:20, y:44},
{x:30, y:45},
{x:40, y:46},
{x:50, y:47},
{x:80, y:48},
{x:90, y:49},
{x:100, y:40},
];
var store3Samples = [
{x:0, y:42},
{x:10, y:43},
{x:20, y:44},
{x:30, y:45},
{x:40, y:46},
{x:50, y:47},
{x:80, y:48},
{x:90, y:49},
{x:100, y:40},
];
var store4Samples = [
{x:0, y:42},
{x:10, y:43},
{x:20, y:44},
{x:30, y:45},
{x:40, y:46},
{x:50, y:47},
{x:80, y:48},
{x:90, y:49},
{x:100, y:40},
];
var chartSA = new CanvasJS.Chart("chartSA",
{
animationEnabled: false,
zoomEnabled: true,
zoomType: "xy",
//height:800,
title: {
text: "simpleSA",
fontSize: 28
},
axisX: {
title: "Frequency (MHz)",
titleFontSize: 24,
gridThickness: 1,
gridColor: "WhiteSmoke",
stripLines:[
{
startValue:50,
thickness:1,
color:"#d8d8d8",
}
]
},
axisY:
{
title: "dB",
titleFontSize: 24,
gridThickness: 1,
gridColor: "WhiteSmoke",
minimum: -120
},
axisY2: [
{
title: "RSSI",
titleFontSize: 24,
minimum: 0,
maximum: 255
},
{
title: "Gain",
titleFontSize: 24,
minimum: 0,
maximum: 50
}],
exportEnabled: true,
legend: {
cursor: "pointer",
fontSize: 16,
itemclick: function (e) {
//console.log("legend click: " + e.dataPointIndex);
//console.log(e);
if (typeof (e.dataSeries.visible) === "undefined" || e.dataSeries.visible) {
e.dataSeries.visible = false;
} else {
e.dataSeries.visible = true;
}
e.chart.render();
}
},
data: [
{
type: "line",
name: "dB",
dataPoints : dBSamples,
showInLegend : true
},
{
type: "line",
name: "RSSI",
axisYType: "secondary",
dataPoints : RSSISamples,
showInLegend : true,
visible : false
},
{
type: "line",
name: "gain",
axisYType: "secondary",
axisYIndex: 1,
dataPoints : gainSamples,
showInLegend : true,
visible : false
},
{
type: "line",
name: "average",
dataPoints : dBSamples,
showInLegend : true,
visible : false
},
{
type: "line",
name: "min",
dataPoints : dBSamples,
showInLegend : true,
visible : false
},
{
type: "line",
name: "store1",
dataPoints : store1Samples,
showInLegend : true,
visible : false
},
{
type: "line",
name: "store2",
dataPoints : store2Samples,
showInLegend : true,
visible : false
},
{
type: "line",
name: "store3",
dataPoints : store3Samples,
showInLegend : true,
visible : false
},
{
type: "line",
name: "store4",
dataPoints : store4Samples,
showInLegend : true,
visible : false
}
]
});
renderChart();
// 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);
});
setStart.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) => {
sendValue("t", setTrackGen.value);
});
setTrackGenPower.addEventListener('change', (event) => {
sendValue("T", setTrackGenPower.value);
});
setTGFreq.addEventListener('change', (event) => {
sendValue("f", setTGFreq.value);
});
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
}
});
function changeStep(newStep) {
freqStep = newStep;
setSigGenFreq0.style.color = "black";
setSigGenFreq1.style.color = "black";
setSigGenFreq2.style.color = "black";
setSigGenFreq3.style.color = "black";
setSigGenFreq4.style.color = "black";
setSigGenFreq5.style.color = "black";
setSigGenFreq6.style.color = "black";
setSigGenFreq7.style.color = "black";
setSigGenFreq8.style.color = "black";
switch(freqStep) {
case 1:
setSigGenFreq0.style.color = "red";
break;
case 10:
setSigGenFreq1.style.color = "red";
break;
case 100:
setSigGenFreq2.style.color = "red";
break;
case 1000:
setSigGenFreq3.style.color = "red";
break;
case 10000:
setSigGenFreq4.style.color = "red";
break;
case 100000:
setSigGenFreq5.style.color = "red";
break;
case 1000000:
setSigGenFreq6.style.color = "red";
break;
case 10000000:
setSigGenFreq7.style.color = "red";
break;
case 100000000:
setSigGenFreq8.style.color = "red";
break;
}
};
changeStep(freqStep); // initial pass
function incdec(direction, factor) {
if (direction > 0) {
if ( (frequency + factor) <= 250000000)
frequency += factor;
} else {
if (frequency >= factor)
frequency -= factor;
}
if (frequency > 250000000)
frequency = 250000000;
if (frequency < 0)
frequency = 0;
console.log("incdec:", frequency);
var tempFreq = frequency;
setSigGenFreq0.value = frequency%10;
tempFreq = parseInt(tempFreq/10);
setSigGenFreq1.value = tempFreq%10;
tempFreq = parseInt(tempFreq/10);
setSigGenFreq2.value = tempFreq%10;
tempFreq = parseInt(tempFreq/10);
setSigGenFreq3.value = tempFreq%10;
tempFreq = parseInt(tempFreq/10);
setSigGenFreq4.value = tempFreq%10;
tempFreq = parseInt(tempFreq/10);
setSigGenFreq5.value = tempFreq%10;
tempFreq = parseInt(tempFreq/10);
setSigGenFreq6.value = tempFreq%10;
tempFreq = parseInt(tempFreq/10);
setSigGenFreq7.value = tempFreq%10;
tempFreq = parseInt(tempFreq/10);
setSigGenFreq8.value = tempFreq%10;
if (factor != 0)
sendValue("F", frequency);
}
incButton.onclick = function() {incdec(1, freqStep)};
decButton.onclick = function() {incdec(-1, freqStep)};
setSigGenFreq0.onfocus = function() {changeStep(1)};
setSigGenFreq1.onfocus = function() {changeStep(10)};
setSigGenFreq2.onfocus = function() {changeStep(100)};
setSigGenFreq3.onfocus = function() {changeStep(1000)};
setSigGenFreq4.onfocus = function() {changeStep(10000)};
setSigGenFreq5.onfocus = function() {changeStep(100000)};
setSigGenFreq6.onfocus = function() {changeStep(1000000)};
setSigGenFreq7.onfocus = function() {changeStep(10000000)};
setSigGenFreq8.onfocus = function() {changeStep(100000000)};
setSigGenFreq0.addEventListener('wheel', (event) => {
event.preventDefault();
changeStep(1);
incdec(-event.deltaY,1);
});
setSigGenFreq1.addEventListener('wheel', (event) => {
event.preventDefault();
changeStep(10);
incdec(-event.deltaY,10);
});
setSigGenFreq2.addEventListener('wheel', (event) => {
event.preventDefault();
changeStep(100);
incdec(-event.deltaY,100);
});
setSigGenFreq3.addEventListener('wheel', (event) => {
event.preventDefault();
changeStep(1000);
incdec(-event.deltaY,1000);
});
setSigGenFreq4.addEventListener('wheel', (event) => {
event.preventDefault();
changeStep(10000);
incdec(-event.deltaY,10000);
});
setSigGenFreq5.addEventListener('wheel', (event) => {
event.preventDefault();
changeStep(100000);
incdec(-event.deltaY,100000);
});
setSigGenFreq6.addEventListener('wheel', (event) => {
event.preventDefault();
changeStep(1000000);
incdec(-event.deltaY,1000000);
});
setSigGenFreq7.addEventListener('wheel', (event) => {
event.preventDefault();
changeStep(10000000);
incdec(-event.deltaY,10000000);
});
setSigGenFreq8.addEventListener('wheel', (event) => {
event.preventDefault();
changeStep(100000000);
incdec(-event.deltaY,100000000);
});
setSigGenPower.onchange = function() {
sendValue("L", setSigGenPower.value);
sigLevelSlider.value = this.value;
};
// Update the current level value (each time you drag the slider handle)
sigLevelSlider.oninput = function() {
setSigGenPower.value = this.value;
setSigGenPower.onchange();
}
function styleSigGenButton ( val ) {
if (sigOnButton.value == 1) {
sigOnButton.style="background-color:green";
} else {
sigOnButton.style="background-color:lightgrey";
}
}
sigOnButton.onclick = function() {
if (sigOnButton.value == 1) {
sigOnButton.value = 0;
} else {
sigOnButton.value = 1;
}
styleSigGenButton (sigOnButton.value);
sendValue("G", sigOnButton.value);
}
//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 simpleSA 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;
setStart.disabled = false;
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;
setTGFreq.disabled = true;
setTrackGenPower.disabled = true;
sigDiv.style.display = "none";
chartDiv.style.display = "block";
} else if (settings.mode == 4 ) { // IF Sweep (SAW test)
setStart.max = settings.IF;
setStop.max = 460;
setStart.min = 400;
setStop.min = settings.IF;
setStart.disabled = false;
setStop.disabled = false;
setCenter.disabled = true;
setSpan.disabled = true;
setRBW.disabled = true;
setRefOut.disabled = true;
setSpur.disabled = true;
setTrackGen.disabled = true;
setTGFreq.disabled = true;
setTrackGenPower.disabled = true;
sigDiv.style.display = "none";
chartDiv.style.display = "block";
} else if (settings.mode == 7 ) { // BANDSCOPE
setStart.max = 350;
setStop.max = 350;
setStart.min = 0;
setStop.min = 0;
setStart.disabled = false;
setStop.disabled = true;
setCenter.disabled = true;
setSpan.disabled = false;
setRBW.disabled = false;
setRefOut.disabled = true;
setSpur.disabled = true;
setTrackGen.disabled = true;
setTrackGenPower.disabled = true;
sigDiv.style.display = "none";
chartDiv.style.display = "block";
} else if (settings.mode == 2 ) { // Signal Generator
setStart.max = 350;
setStop.max = 350;
setStart.min = 0;
setStop.min = 0;
setStart.disabled = true;
setStop.disabled = true;
setCenter.disabled = true;
setSpan.disabled = true;
setRBW.disabled = true;
setRefOut.disabled = true;
setSpur.disabled = true;
setTrackGen.disabled = true;
setTGFreq.disabled = true;
setTrackGenPower.disabled = true;
sigDiv.style.display = "block";
chartDiv.style.display = "none";
} else {
setStart.max = 350;
setStop.max = 350;
setStart.min = 0;
setStop.min = 0;
setStart.disabled = false;
setStop.disabled = false;
setCenter.disabled = false;
setSpan.disabled = false;
setRBW.disabled = false;
setRefOut.disabled = false;
setSpur.disabled = false;
setTrackGen.disabled = false;
setTGFreq.disabled = false;
setTrackGenPower.disabled = false;
sigDiv.style.display = "none";
chartDiv.style.display = "block";
}
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.sg != oldSigGen) { // Sig gen on/off
sigOnButton.value = settings.sg;
oldSigGen = settings.sg;
styleSigGenButton (sigOnButton.value);
}
if (settings.sgFreq != oldSigGenFreq) { // sig gen frequency
frequency = settings.sgFreq;
oldSigGenFreq = settings.sgFreq;
incdec(0,0);
console.log("sigGenFreq=" + settings.sgFreq);
}
sigLevelSlider.max = settings.sgCal; // Limits for sig gen power
sigLevelSlider.min = settings.sgCal - settings.sgRange;
setSigGenPower.max = settings.sgCal;
setSigGenPower.min = settings.sgCal - settings.sgRange;
if (settings.sgPower != oldSigGenPower) {
setSigGenPower.value = settings.sgPower;
sigLevelSlider.value = settings.sgPower;
oldSigGenPower = settings.sgPower;
}
if (settings.tg != oldTrackGen) { // tracking generator state
setTrackGen.value = settings.tg;
oldTrackGen = settings.tg;
}
if (settings.tgFreq != oldTGFreq) { // tracking generator frequency for sig gen mode
setTGFreq.value = settings.tgFreq;
oldTGFreq = settings.tgFreq;
}
if (settings.tgPower != oldTrackGenPower) { // tracking generator output power
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;
}
var items = document.querySelectorAll(".select-button");
var i;
for (i = 0; i< items.length; i++) {
items[i].disabled = false;
}
var items = document.querySelectorAll(".checkbox-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;
}
var items = document.querySelectorAll(".select-button");
var i;
for (i = 0; i< items.length; i++) {
items[i].disabled = true;
}
var items = document.querySelectorAll(".checkbox-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)
// 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
// f trackgen signal generator frequency
// F Sig Gen frequency
// L Sig Gen level (dBm)
// G Sig Gen Off/On
// P Sig Gen set max output level (dBm)
//
//connection.send("# " + messageCounter + " " + sampleThreshold + " " + sampleSize);
if (connectionStatus.value == "Connected") {
connection.send("#" + c + " " + val);
console.log("Command:" + c + val);
} else {
console.log("No connection - 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>