Skip to content

Commit

Permalink
Merge pull request #126 from CapnBry/aat-vrx
Browse files Browse the repository at this point in the history
Add an Automatic Antenna Tracker (AAT) backpack
  • Loading branch information
CapnBry committed May 18, 2024
2 parents 5d7da05 + 10380be commit be1601d
Show file tree
Hide file tree
Showing 20 changed files with 1,616 additions and 71 deletions.
7 changes: 7 additions & 0 deletions html/elrs.css
Original file line number Diff line number Diff line change
Expand Up @@ -289,4 +289,11 @@ body, input, select, textarea {
background: #88cef7;
}

datalist {
display: flex;
flex-direction: row;
justify-content: space-between;
writing-mode: horizontal-tb;
width: 100%;
}
/*==========================*/
136 changes: 106 additions & 30 deletions html/scan.js
Original file line number Diff line number Diff line change
@@ -1,41 +1,87 @@
document.addEventListener("DOMContentLoaded", get_mode, false);
var scanTimer = undefined;
document.addEventListener("DOMContentLoaded", init, false);

function _(el) {
return document.getElementById(el);
}

function get_mode() {
var json_url = 'mode.json';
xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
var data = JSON.parse(this.responseText);
if (data.mode==="STA") {
_('stamode').style.display = 'block';
if (_('rtctab')) _('rtctab').style.display = 'block';
_('ssid').textContent = data.ssid;
} else {
_('apmode').style.display = 'block';
if (data.ssid) {
_('homenet').textContent = data.ssid;
} else {
_('connect').style.display = 'none';
}
scanTimer = setInterval(get_networks, 2000);
}
if((!data.stm32 || data.stm32==="no") && _('tx_tab')) {
mui.tabs.activate('pane-justified-2');
_('tx_tab').style.display = 'none';
}
if(data['product-name']) _('product-name').textContent = data['product-name'];
}
function init() {
initAat();

// sends XMLHttpRequest, so do it last
initOptions();
}

function initAat() {
let aatsubmit = _('aatsubmit');
if (!aatsubmit)
return;

aatsubmit.addEventListener('click', callback('Update AAT Parameters', 'An error occurred changing values', '/aatconfig',
() => { return new URLSearchParams(new FormData(_('aatconfig'))); }
));
_('azim_center').addEventListener('change', aatAzimCenterChanged);
document.querySelectorAll('.aatlive').forEach(
el => el.addEventListener('change', aatLineElementChanged)
);
}

function initOptions() {
const xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
const data = JSON.parse(this.responseText);
updateConfig(data);
setTimeout(get_networks, 2000);
}
};
xmlhttp.open("POST", json_url, true);
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlhttp.open('GET', '/config', true);
xmlhttp.send();
}

function updateConfig(data) {
let config = data.config;
if (config.mode==="STA") {
_('stamode').style.display = 'block';
if (_('rtctab')) _('rtctab').style.display = 'table-cell';
_('ssid').textContent = config.ssid;
} else {
_('apmode').style.display = 'block';
if (config.ssid) {
_('homenet').textContent = config.ssid;
} else {
_('connect').style.display = 'none';
}
}
if((!data.stm32 || data.stm32==="no") && _('tx_tab')) {
mui.tabs.activate('pane-justified-2');
_('tx_tab').style.display = 'none';
}
if(config['product_name']) _('product_name').textContent = config['product_name'];

updateAatConfig(config);
}

function updateAatConfig(config)
{
if (!config.hasOwnProperty('aat'))
return;
_('aattab').style.display = 'table-cell';

// AAT
_('servosmoo').value = config.aat.servosmoo;
_('servomode').value = config.aat.servomode;
_('azim_center').value = config.aat.azim_center;
_('azim_min').value = config.aat.azim_min;
_('azim_max').value = config.aat.azim_max;
_('elev_min').value = config.aat.elev_min;
_('elev_max').value = config.aat.elev_max;
aatAzimCenterChanged();

// VBAT
_('vbat_offset').value = config.vbat.offset;
_('vbat_scale').value = config.vbat.scale;
}

function get_networks() {
var json_url = 'networks.json';
xmlhttp = new XMLHttpRequest();
Expand All @@ -44,7 +90,6 @@ function get_networks() {
var data = JSON.parse(this.responseText);
_('loader').style.display = 'none';
autocomplete(_('network'), data);
clearInterval(scanTimer);
}
};
xmlhttp.open("POST", json_url, true);
Expand Down Expand Up @@ -340,6 +385,37 @@ function callback(title, msg, url, getdata) {
}
}

function aatAzimCenterChanged()
{
// Update the slider labels to represent the new orientation
let labels;
switch (parseInt(_('azim_center').selectedIndex))
{
default: /* fallthrough */
case 0: labels = 'SWNES'; break; // N
case 1: labels = 'WNESW'; break; // E
case 2: labels = 'NESWN'; break; // S
case 3: labels = 'ESWNE'; break; // W
}
let markers = _('bear_markers');
for (i=0; i<markers.options.length; ++i)
markers.options[i].label = labels[i];
}

function aatLineElementChanged()
{
fetch("/aatconfig", {
method: "POST",
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: new URLSearchParams({
'bear': _('bear').value,
'elev': _('elev').value,
})
});
}

_('sethome').addEventListener('submit', callback("Set Home Network", "An error occurred setting the home network", "/sethome", function() {
return new FormData(_('sethome'));
}));
Expand Down
8 changes: 3 additions & 5 deletions html/txbp_index.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,9 @@
<body>
<header class="mui-appbar mui--z1 mui--text-center elrs-header">
<img src="logo.svg" height="250" width="250" style="padding:20px;">
<h1>Welcome to your <b>ExpressLRS</b> update page<br />
</h1>
<p>From here you can update your <b><span id="product-name">TX</span>&nbsp;Backpack</b> module with <b>@PLATFORM@</b> firmware<br />
<p>
<b>Firmware Rev. </b><var>@VERSION@</var>
<h1><b>ExpressLRS</b></h1>
<span id="product_name">TX Backpack</span><br/>
<b>Firmware Rev. </b>@VERSION@ <span id="reg_domain"></span>
</header>

<br>
Expand Down
123 changes: 113 additions & 10 deletions html/vrx_index.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,22 @@
</head>

<body>
<div class="mui-appbar mui--z1 mui--text-center elrs-header">
<img src="logo.svg" height="250" width="250" style="padding:20px;"></a>
<h1>Welcome to your <b>ExpressLRS</b><br /> update page<br />
</h1>
<p>From here you can update your <b>VRx Backpack</b> module with <b>@PLATFORM@</b> firmware<br />
<p>
<b>Firmware Rev. </b><var id="FirmVersion">@VERSION@</var>
<p>
</div>
<header class="mui-appbar mui--z1 mui--text-center elrs-header">
<img src="logo.svg" height="250" width="250" style="padding:20px;">
<h1><b>ExpressLRS</b></h1>
<span id="product_name">VRx Backpack</span><br/>
<b>Firmware Rev. </b>@VERSION@ <span id="reg_domain"></span>
</header>

<br>
<br/>
<div class="mui-container-fluid">
<div class="mui-panel mui-col-sm-10 mui-col-sm-offset-1">

<ul class="mui-tabs__bar mui-tabs__bar--justified">
<li class="mui--is-active"><a data-mui-toggle="tab" data-mui-controls="pane-justified-1">Update</a></li>
<li><a data-mui-toggle="tab" data-mui-controls="pane-justified-2">Network</a></li>
<li id="rtctab" style="display:none;"><a data-mui-toggle="tab" data-mui-controls="pane-justified-3">RTC Time</a></li>
<li id="aattab" style="display:none;"><a data-mui-toggle="tab" data-mui-controls="pane-justified-4">Antenna Tracking</a></li>
</ul>

<div class="mui-tabs__pane mui--is-active" id="pane-justified-1">
Expand Down Expand Up @@ -105,6 +103,111 @@ <h2>RTC Update via NTP</h2>
</form>
</div>
</div>

<div class="mui-tabs__pane" id="pane-justified-4">
<form action="/aatconfig" id="aatconfig" method="POST" class="mui-form">
<div class="mui-panel">
<fieldset><legend>Servo maximum speed</legend>
Use the slider to limit the maximum rotational speed of the servo. Note that when the azimuth servo
must flip from one side to the other, the servo always will move at full speed.
<input type="range" id="servosmoo" name="servosmoo" list="servosmoo_markers" value="5" min="0" max="9" step="1" style="width: 100%;"/>
<datalist id="servosmoo_markers">
<option value="0" label="Fast" title="Lickedy Speed"></option>
<option value="1" label=""></option>
<option value="2" label=""></option>
<option value="3" label=""></option>
<option value="4" label=""></option>
<option value="5" label="90deg/s"></option>
<option value="6" label=""></option>
<option value="7" label=""></option>
<option value="8" label=""></option>
<option value="9" label="Slow"></option>
</datalist>
</fieldset>
</div>
<div class="mui-panel">
<fieldset><legend>Servo mode</legend>
<div>Set the mechanical servo mode to match the tracker's design.</div>
<div class="mui-select mui-col-xs-12">
<select id="servomode" name="servomode">
<option value="0">2:1 geared - Servo geared for 360 degree movement</option>
<option value="1">Clip 180 - Standard direct driven servo limited to 180 degrees</option>
</select>
</div>
</fieldset>
</div>
<div class="mui-panel">
<fieldset><legend>Azimuth servo</legend>
Enter the micrsecond (us) values for the min and max position of the horizontal servo, using the slider to test positions.
<input type="range" id="bear" name="bear" class="aatlive" list="azim_markers" value="0" min="-180" max="180" step="45" style="width: 100%;"/>
<datalist id="bear_markers">
<option value="-180"></option>
<option value="-90"></option>
<option value="0"></option>
<option value="90"></option>
<option value="180"></option>
</datalist>
<div class="mui-textfield mui-col-xs-3">
<input id="azim_min" type="number" name="azim_min" min="500" max="2500"/>
<label for="azim_min">Min</label>
</div>
<div class="mui-select mui-col-xs-6">
<select id="azim_center" name="azim_center">
<option value="0">N</option>
<option value="2">E</option>
<option value="4">S</option>
<option value="6">W</option>
</select>
<label for="azim_center">Servo center direction</label>
</div>
<div class="mui-textfield mui-col-xs-3">
<input id="azim_max" type="number" name="azim_max" min="500" max="2500"/>
<label for="azim_max">Max</label>
</div>
</fieldset>
<fieldset><legend>Elevation servo</legend>
Enter the micrsecond (us) values for the min and max position of the vertical servo, using the slider to test positions.
<input type="range" id="elev" name="elev" class="aatlive" list="elev_markers" value="45" min="0" max="90" step="15" style="width: 100%;"/>
<datalist id="elev_markers">
<option value="0" label="0"></option>
<option value="15" label=""></option>
<option value="30" label=""></option>
<option value="45" label="45"></option>
<option value="60" label=""></option>
<option value="75" label=""></option>
<option value="90" label="90"></option>
</datalist>
<div class="mui-textfield mui-col-xs-3">
<input id="elev_min" type="number" name="elev_min" min="500" max="2500"/>
<label for="elev_min">Min</label>
</div>
<div class="mui-textfield mui-col-xs-6 mui--text-center">
&nbsp;
</div>
<div class="mui-textfield mui-col-xs-3">
<input id="elev_max" type="number" name="elev_max" min="500" max="2500"/>
<label for="elev_max">Max</label>
</div>
</fieldset>
</div>
<div class="mui-panel">
<fieldset><legend>Battery voltage</legend>
Battery voltage is calculated using the formula <strong>VBAT = (ADC - offset) / scale</strong>. If voltage is reading too high, increase scale.
<div class="mui-textfield mui-col-xs-6">
<input id="vbat_scale" type="number" name="vbat_scale" min="1" max="1000"/>
<label for="vbat_scale">Scale</label>
</div>
<div class="mui-textfield mui-col-xs-6">
<input id="vbat_offset" type="number" name="vbat_offset" min="-1000" max="1000"/>
<label for="vbat_offset">Offset</label>
</div>
</fieldset>
</div>
<input type="hidden" name="commit" value="1"/>
<input type="submit" id="aatsubmit" value="Save" class="mui-btn mui-btn--primary"/>
</form>
</div>
</div>
</div>
</div>
<footer>
Expand Down
12 changes: 12 additions & 0 deletions include/devwifi_proxies.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#pragma once

#if defined(AAT_BACKPACK)

#include <cstdint>
#include <ArduinoJson.h>
#include <ESPAsyncWebServer.h>

void WebAatAppendConfig(ArduinoJson::JsonDocument &json);
void WebAatInit(AsyncWebServer &server);

#endif /* defined(AAT_BACKPACK) */
Loading

0 comments on commit be1601d

Please sign in to comment.