
Still working out a good layout and method to change frequency on mobile platforms. Now works, needs some formatting and pwr control adding, then duplicate for track gen
1594 lines
48 KiB
HTML
1594 lines
48 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="setSigFreq8" class="sigFreqLabel">Frequency:</label>
|
|
<input class="sigFreqInput" id="setSigFreq8" name="setSigFreq8" type="number" min=-1 max=10 value=0>
|
|
<input class="sigFreqInput" id="setSigFreq7" name="setSigFreq7" type="number" min=-1 max=10 value=0>
|
|
<input class="sigFreqInput" id="setSigFreq6" name="setSigFreq6" type="number" min=-1 max=10 value=0>
|
|
<span class="sigFreqText">,</span>
|
|
<input class="sigFreqInput" id="setSigFreq5" name="setSigFreq5" type="number" min=-1 max=10 value=0>
|
|
<input class="sigFreqInput" id="setSigFreq4" name="setSigFreq4" type="number" min=-1 max=10 value=0>
|
|
<input class="sigFreqInput" id="setSigFreq3" name="setSigFreq3" type="number" min=-1 max=10 value=0>
|
|
<span class="sigFreqText">,</span>
|
|
<input class="sigFreqInput" id="setSigFreq2" name="setSigFreq2" type="number" min=-1 max=10 value=0>
|
|
<input class="sigFreqInput" id="setSigFreq1" name="setSigFreq1" type="number" min=-1 max=10 value=0>
|
|
<input class="sigFreqInput" id="setSigFreq0" name="setSigFreq0" type="number" min=0 max=10 value=0>
|
|
<span class="sigFreqText">Hz</span>
|
|
<button class = "set-button" id="incButton">+</button>
|
|
<button class = "set-button" id="decButton">-</button>
|
|
|
|
</div>
|
|
<br /><br />
|
|
<label for="setSigLevel" class = "sigLevelLabel">Level:</label>
|
|
<input class="sigLevelInput" id="setSigLevel" name="setSigLevel" type="number" min="-70" max="20" value="0">
|
|
dBm
|
|
<br /><br />
|
|
<div class="slidecontainer">
|
|
<input type="range" min="-70" max="20" value="10" 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-label">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>
|
|
<input class="checkbox-input" type="checkbox" id="trackGen" size="1" value="0" />
|
|
<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>
|
|
<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 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 setSigLevel = document.getElementById('setSigLevel');
|
|
|
|
var setSigFreq = document.getElementById('setSigFreq');
|
|
|
|
var setSigFreq0 = document.getElementById('setSigFreq0');
|
|
var setSigFreq1 = document.getElementById('setSigFreq1');
|
|
var setSigFreq2 = document.getElementById('setSigFreq2');
|
|
var setSigFreq3 = document.getElementById('setSigFreq3');
|
|
var setSigFreq4 = document.getElementById('setSigFreq4');
|
|
var setSigFreq5 = document.getElementById('setSigFreq5');
|
|
var setSigFreq6 = document.getElementById('setSigFreq6');
|
|
var setSigFreq7 = document.getElementById('setSigFreq7');
|
|
var setSigFreq8 = document.getElementById('setSigFreq8');
|
|
|
|
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;
|
|
|
|
// 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
|
|
},
|
|
axisY:
|
|
{
|
|
title: "dB",
|
|
titleFontSize: 24,
|
|
minimum: -120
|
|
},
|
|
axisY2: [
|
|
{
|
|
title: "RSSI",
|
|
titleFontSize: 24,
|
|
minimum: 0,
|
|
maximum: 255
|
|
},
|
|
{
|
|
title: "Gain",
|
|
titleFontSize: 24,
|
|
minimum: 0,
|
|
maximum: 50
|
|
}],
|
|
exportEnabled: true,
|
|
legend: {
|
|
cursor: "pointer",
|
|
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) => {
|
|
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
|
|
}
|
|
});
|
|
|
|
|
|
|
|
function changeStep(newStep) {
|
|
freqStep = newStep;
|
|
setSigFreq0.style.color = "black";
|
|
setSigFreq1.style.color = "black";
|
|
setSigFreq2.style.color = "black";
|
|
setSigFreq3.style.color = "black";
|
|
setSigFreq4.style.color = "black";
|
|
setSigFreq5.style.color = "black";
|
|
setSigFreq6.style.color = "black";
|
|
setSigFreq7.style.color = "black";
|
|
setSigFreq8.style.color = "black";
|
|
|
|
switch(freqStep) {
|
|
case 1:
|
|
setSigFreq0.style.color = "red";
|
|
break;
|
|
case 10:
|
|
setSigFreq1.style.color = "red";
|
|
break;
|
|
case 100:
|
|
setSigFreq2.style.color = "red";
|
|
break;
|
|
case 1000:
|
|
setSigFreq3.style.color = "red";
|
|
break;
|
|
case 10000:
|
|
setSigFreq4.style.color = "red";
|
|
break;
|
|
case 100000:
|
|
setSigFreq5.style.color = "red";
|
|
break;
|
|
case 1000000:
|
|
setSigFreq6.style.color = "red";
|
|
break;
|
|
case 10000000:
|
|
setSigFreq7.style.color = "red";
|
|
break;
|
|
case 100000000:
|
|
setSigFreq8.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;
|
|
setSigFreq0.value = frequency%10;
|
|
tempFreq = parseInt(tempFreq/10);
|
|
setSigFreq1.value = tempFreq%10;
|
|
tempFreq = parseInt(tempFreq/10);
|
|
setSigFreq2.value = tempFreq%10;
|
|
tempFreq = parseInt(tempFreq/10);
|
|
setSigFreq3.value = tempFreq%10;
|
|
tempFreq = parseInt(tempFreq/10);
|
|
setSigFreq4.value = tempFreq%10;
|
|
tempFreq = parseInt(tempFreq/10);
|
|
setSigFreq5.value = tempFreq%10;
|
|
tempFreq = parseInt(tempFreq/10);
|
|
setSigFreq6.value = tempFreq%10;
|
|
tempFreq = parseInt(tempFreq/10);
|
|
setSigFreq7.value = tempFreq%10;
|
|
tempFreq = parseInt(tempFreq/10);
|
|
setSigFreq8.value = tempFreq%10;
|
|
|
|
sendValue("F", frequency);
|
|
}
|
|
|
|
incButton.onclick = function() {incdec(1, freqStep)};
|
|
decButton.onclick = function() {incdec(-1, freqStep)};
|
|
|
|
setSigFreq0.onfocus = function() {changeStep(1)};
|
|
setSigFreq1.onfocus = function() {changeStep(10)};
|
|
setSigFreq2.onfocus = function() {changeStep(100)};
|
|
setSigFreq3.onfocus = function() {changeStep(1000)};
|
|
setSigFreq4.onfocus = function() {changeStep(10000)};
|
|
setSigFreq5.onfocus = function() {changeStep(100000)};
|
|
setSigFreq6.onfocus = function() {changeStep(1000000)};
|
|
setSigFreq7.onfocus = function() {changeStep(10000000)};
|
|
setSigFreq8.onfocus = function() {changeStep(100000000)};
|
|
|
|
|
|
setSigFreq0.addEventListener('wheel', (event) => {
|
|
event.preventDefault();
|
|
changeStep(1);
|
|
incdec(-event.deltaY,1);
|
|
});
|
|
|
|
|
|
setSigFreq1.addEventListener('wheel', (event) => {
|
|
event.preventDefault();
|
|
changeStep(10);
|
|
incdec(-event.deltaY,10);
|
|
});
|
|
|
|
setSigFreq2.addEventListener('wheel', (event) => {
|
|
event.preventDefault();
|
|
changeStep(100);
|
|
incdec(-event.deltaY,100);
|
|
});
|
|
|
|
setSigFreq3.addEventListener('wheel', (event) => {
|
|
event.preventDefault();
|
|
changeStep(1000);
|
|
incdec(-event.deltaY,1000);
|
|
});
|
|
|
|
setSigFreq4.addEventListener('wheel', (event) => {
|
|
event.preventDefault();
|
|
changeStep(10000);
|
|
incdec(-event.deltaY,10000);
|
|
});
|
|
|
|
setSigFreq5.addEventListener('wheel', (event) => {
|
|
event.preventDefault();
|
|
changeStep(100000);
|
|
incdec(-event.deltaY,100000);
|
|
});
|
|
|
|
setSigFreq6.addEventListener('wheel', (event) => {
|
|
event.preventDefault();
|
|
changeStep(1000000);
|
|
incdec(-event.deltaY,1000000);
|
|
});
|
|
|
|
setSigFreq7.addEventListener('wheel', (event) => {
|
|
event.preventDefault();
|
|
changeStep(10000000);
|
|
incdec(-event.deltaY,10000000);
|
|
});
|
|
|
|
setSigFreq8.addEventListener('wheel', (event) => {
|
|
event.preventDefault();
|
|
changeStep(100000000);
|
|
incdec(-event.deltaY,100000000);
|
|
});
|
|
|
|
|
|
setSigLevel.addEventListener('change', (event) => {
|
|
sendValue("L", setSigLevel.value);
|
|
});
|
|
|
|
// Update the current level value (each time you drag the slider handle)
|
|
sigLevelSlider.oninput = function() {
|
|
setSigLevel.value = this.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;
|
|
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;
|
|
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;
|
|
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;
|
|
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.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)
|
|
// 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);
|
|
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>
|