some web interface updates
This commit is contained in:
parent
0d64f8d05d
commit
7b58febb45
17
README.md
17
README.md
|
|
@ -43,3 +43,20 @@ A SHORT press will switch to the next channel in channels.txt
|
|||
|
||||
A medium press will active scan the whole band (400..406 MHz) and display a
|
||||
spectrum diagram (each line == 50 kHz)
|
||||
|
||||
## Setup
|
||||
|
||||
Download https://github.com/me-no-dev/ESPAsyncWebServer/archive/master.zip
|
||||
and move to your Arduino IDE's libraries directory
|
||||
Rename to (name without "-master")
|
||||
|
||||
Download https://github.com/me-no-dev/AsyncTCP/archive/master.zip
|
||||
and move to your Arduino IDE's libraries directory
|
||||
Rename to (name without "-master")
|
||||
|
||||
Install Arduino ESP32 file system uploader
|
||||
https://randomnerdtutorials.com/install-esp32-filesystem-uploader-arduino-ide/
|
||||
Download https://github.com/me-no-dev/arduino-esp32fs-plugin/releases/download/1.0/ESP32FS-1.0.zip
|
||||
Move to your Arduino IDE's tools directory
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -48,58 +48,29 @@ String processor(const String& var){
|
|||
return String();
|
||||
}
|
||||
|
||||
void SetupAsyncServer() {
|
||||
// Route for root / web page
|
||||
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||
request->send(200, "text/plain", "Hello, world");
|
||||
});
|
||||
|
||||
server.on("/index.html", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||
request->send(SPIFFS, "/index.html", String(), false, processor);
|
||||
});
|
||||
|
||||
// Route to load style.css file
|
||||
server.on("/style.css", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||
request->send(SPIFFS, "/style.css", "text/css");
|
||||
});
|
||||
#define MAX_QRG 10
|
||||
|
||||
// Route to set GPIO to HIGH
|
||||
server.on("/on", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||
digitalWrite(ledPin, HIGH);
|
||||
request->send(SPIFFS, "/index.html", String(), false, processor);
|
||||
});
|
||||
|
||||
// Route to set GPIO to LOW
|
||||
server.on("/off", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||
digitalWrite(ledPin, LOW);
|
||||
request->send(SPIFFS, "/index.html", String(), false, processor);
|
||||
});
|
||||
|
||||
// Start server
|
||||
server.begin();
|
||||
const String sondeTypeSelect(int activeType) {
|
||||
String sts = "";
|
||||
for(int i=0; i<3; i++) {
|
||||
sts += "<option value=\"";
|
||||
sts += sondeTypeStr[i];
|
||||
sts += "\"";
|
||||
if(activeType==i) { sts += " selected"; }
|
||||
sts += ">";
|
||||
sts += sondeTypeStr[i];
|
||||
sts += "</option>";
|
||||
}
|
||||
return sts;
|
||||
}
|
||||
|
||||
int nNetworks;
|
||||
struct { String id; String pw; } networks[20];
|
||||
|
||||
void setupWifiList() {
|
||||
File file = SPIFFS.open("/networks.txt", "r");
|
||||
if(!file){
|
||||
Serial.println("There was an error opening the file '/networks.txt' for reading");
|
||||
return;
|
||||
}
|
||||
int i=0;
|
||||
while(file.available()) {
|
||||
String line = file.readStringUntil('\n');
|
||||
if(!file.available()) break;
|
||||
networks[i].id = line;
|
||||
networks[i].pw = file.readStringUntil('\n');
|
||||
i++;
|
||||
}
|
||||
nNetworks = i;
|
||||
Serial.print(i); Serial.println(" networks in networks.txt\n");
|
||||
for(int j=0; j<i; j++) { Serial.print(networks[j].id); Serial.print(": "); Serial.println(networks[j].pw); }
|
||||
}
|
||||
//trying to work around
|
||||
//"assertion "heap != NULL && "free() target pointer is outside heap areas"" failed:"
|
||||
// which happens if request->send is called in createQRGForm!?!??
|
||||
char message[10240];
|
||||
|
||||
///////////////////////// Functions for Reading / Writing QRG list from/to qrg.txt
|
||||
|
||||
void setupChannelList() {
|
||||
File file = SPIFFS.open("/qrg.txt", "r");
|
||||
|
|
@ -122,16 +93,211 @@ void setupChannelList() {
|
|||
else if (space[1]=='9') { type=STYPE_DFM09; }
|
||||
else if (space[1]=='6') { type=STYPE_DFM06; }
|
||||
else continue;
|
||||
Serial.printf("Adding %f with type %d\b",freq,type);
|
||||
sonde.addSonde(freq, type);
|
||||
int active = space[3]=='+'?1:0;
|
||||
Serial.printf("Adding %f with type %d (active: %d)\n",freq,type,active);
|
||||
sonde.addSonde(freq, type, active);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
const char *createQRGForm() {
|
||||
char *ptr = message;
|
||||
strcpy(ptr,"<html><head><link rel=\"stylesheet\" type=\"text/css\" href=\"style.css\"></head><body><form action=\"qrg.html\" method=\"post\"><table><tr><th>ID</th><th>Active</th><th>Freq</th><th>Mode</th></tr>");
|
||||
for(int i=0; i<10; i++) {
|
||||
String s = sondeTypeSelect(i>=sonde.nSonde?2:sonde.sondeList[i].type);
|
||||
sprintf(ptr+strlen(ptr), "<tr><td>%d</td><td><input name=\"A%d\" type=\"checkbox\" %s/></td>"
|
||||
"<td><input name=\"F%d\" type=\"text\" value=\"%3.3f\"></td>"
|
||||
"<td><select name=\"T%d\">%s</select></td>",
|
||||
i+1,
|
||||
i+1, (i<sonde.nSonde&&sonde.sondeList[i].active)?"checked":"",
|
||||
i+1, i>=sonde.nSonde?400.000:sonde.sondeList[i].freq,
|
||||
i+1, s.c_str());
|
||||
}
|
||||
strcat(ptr,"</table><input type=\"submit\" value=\"Update\"/></form></body></html>");
|
||||
return message;
|
||||
}
|
||||
|
||||
const char *handleQRGPost(AsyncWebServerRequest *request) {
|
||||
char label[10];
|
||||
// parameters: a_i, f_1, t_i (active/frequency/type)
|
||||
#if 1
|
||||
File f = SPIFFS.open("/qrg.txt", "w");
|
||||
if(!f) {
|
||||
Serial.println("Error while opening '/qrg.txt' for writing");
|
||||
return "Error while opening '/qrg.txt' for writing";
|
||||
}
|
||||
#endif
|
||||
Serial.println("Handling post request");
|
||||
#if 0
|
||||
int params = request->params();
|
||||
for(int i=0; i<params; i++) {
|
||||
Serial.println(request->getParam(i)->name().c_str());
|
||||
}
|
||||
#endif
|
||||
for(int i=1; i<=MAX_QRG; i++) {
|
||||
snprintf(label, 10, "A%d", i);
|
||||
AsyncWebParameter *active = request->getParam(label, true);
|
||||
snprintf(label, 10, "F%d", i);
|
||||
AsyncWebParameter *freq = request->getParam(label, true);
|
||||
if(!freq) continue;
|
||||
snprintf(label, 10, "T%d", i);
|
||||
AsyncWebParameter *type = request->getParam(label, true);
|
||||
if(!type) continue;
|
||||
const char *fstr = freq->value().c_str();
|
||||
const char *tstr = type->value().c_str();
|
||||
Serial.printf("Processing a=%s, f=%s, t=%s\n", active?"YES":"NO", fstr, tstr);
|
||||
char typech = (tstr[2]=='4'?'4':tstr[3]); // Ugly TODO
|
||||
f.printf("%3.3f %c %c\n", atof(fstr), typech, active?'+':'-');
|
||||
}
|
||||
f.close();
|
||||
setupChannelList();
|
||||
}
|
||||
|
||||
|
||||
/////////////////// Functions for reading/writing Wifi networks from networks.txt
|
||||
|
||||
#define MAX_WIFI 10
|
||||
int nNetworks;
|
||||
struct { String id; String pw; } networks[MAX_WIFI];
|
||||
|
||||
// FIXME: For now, we don't uspport wifi networks that contain newline or null characters
|
||||
// ... would require a more sophisicated file format (currently one line SSID; one line Password
|
||||
void setupWifiList() {
|
||||
File file = SPIFFS.open("/networks.txt", "r");
|
||||
if(!file){
|
||||
Serial.println("There was an error opening the file '/networks.txt' for reading");
|
||||
return;
|
||||
}
|
||||
int i=0;
|
||||
|
||||
while(file.available()) {
|
||||
String line = file.readStringUntil('\n');
|
||||
if(!file.available()) break;
|
||||
networks[i].id = line;
|
||||
networks[i].pw = file.readStringUntil('\n');
|
||||
i++;
|
||||
}
|
||||
nNetworks = i;
|
||||
Serial.print(i); Serial.println(" networks in networks.txt\n");
|
||||
for(int j=0; j<i; j++) { Serial.print(networks[j].id); Serial.print(": "); Serial.println(networks[j].pw); }
|
||||
|
||||
}
|
||||
|
||||
|
||||
const char *createWIFIForm() {
|
||||
char *ptr = message;
|
||||
char tmp[4];
|
||||
strcpy(ptr,"<html><head><link rel=\"stylesheet\" type=\"text/css\" href=\"style.css\"></head><body><form action=\"wifi.html\" method=\"post\"><table><tr><th>Nr</th><th>SSID</th><th>Password</th></tr>");
|
||||
for(int i=0; i<MAX_WIFI; i++) {
|
||||
sprintf(tmp,"%d",i);
|
||||
sprintf(ptr+strlen(ptr), "<tr><td>%s</td><td><input name=\"S%d\" type=\"text\" value=\"%s\"/></td>"
|
||||
"<td><input name=\"P%d\" type=\"text\" value=\"%s\"/></td>",
|
||||
i==0?"<b>AP</b>":tmp,
|
||||
i+1, i<nNetworks?networks[i].id.c_str():"",
|
||||
i+1, i<nNetworks?networks[i].pw.c_str():"");
|
||||
}
|
||||
strcat(ptr,"</table><input type=\"submit\" value=\"Update\"></input></form></body></html>");
|
||||
return message;
|
||||
}
|
||||
|
||||
const char *handleWIFIPost(AsyncWebServerRequest *request) {
|
||||
char label[10];
|
||||
// parameters: a_i, f_1, t_i (active/frequency/type)
|
||||
#if 1
|
||||
File f = SPIFFS.open("/networks.txt", "w");
|
||||
if(!f) {
|
||||
Serial.println("Error while opening '/networks.txt' for writing");
|
||||
return "Error while opening '/networks.txt' for writing";
|
||||
}
|
||||
#endif
|
||||
Serial.println("Handling post request");
|
||||
#if 0
|
||||
int params = request->params();
|
||||
for(int i=0; i<params; i++) {
|
||||
Serial.println(request->getParam(i)->name().c_str());
|
||||
}
|
||||
#endif
|
||||
for(int i=1; i<=MAX_WIFI; i++) {
|
||||
snprintf(label, 10, "S%d", i);
|
||||
AsyncWebParameter *ssid = request->getParam(label, true);
|
||||
if(!ssid) continue;
|
||||
snprintf(label, 10, "P%d", i);
|
||||
AsyncWebParameter *pw = request->getParam(label, true);
|
||||
if(!pw) continue;
|
||||
const char *sstr = ssid->value().c_str();
|
||||
const char *pstr = pw->value().c_str();
|
||||
if(strlen(sstr)==0) continue;
|
||||
Serial.printf("Processing S=%s, P=%s\n", sstr, pstr);
|
||||
f.printf("%s\n%s\n", sstr, pstr);
|
||||
}
|
||||
f.close();
|
||||
setupWifiList();
|
||||
}
|
||||
|
||||
const char* PARAM_MESSAGE = "message";
|
||||
void SetupAsyncServer() {
|
||||
// Route for root / web page
|
||||
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||
request->send(200, "text/plain", "Hello, world");
|
||||
});
|
||||
|
||||
server.on("/index.html", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||
request->send(SPIFFS, "/index.html", String(), false, processor);
|
||||
});
|
||||
|
||||
server.on("/test.html", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||
request->send(SPIFFS, "/test.html", String(), false, processor);
|
||||
});
|
||||
|
||||
server.on("/qrg.html", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||
request->send(200, "text/html", createQRGForm());
|
||||
});
|
||||
server.on("/qrg.html", HTTP_POST, [](AsyncWebServerRequest *request){
|
||||
handleQRGPost(request);
|
||||
request->send(200, "text/html", createQRGForm());
|
||||
});
|
||||
|
||||
server.on("/wifi.html", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||
request->send(200, "text/html", createWIFIForm());
|
||||
});
|
||||
server.on("/wifi.html", HTTP_POST, [](AsyncWebServerRequest *request){
|
||||
handleWIFIPost(request);
|
||||
request->send(200, "text/html", createWIFIForm());
|
||||
});
|
||||
|
||||
// Route to load style.css file
|
||||
server.on("/style.css", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||
request->send(SPIFFS, "/style.css", "text/css");
|
||||
});
|
||||
|
||||
// Route to set GPIO to HIGH
|
||||
server.on("/on", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||
digitalWrite(ledPin, HIGH);
|
||||
request->send(SPIFFS, "/index.html", String(), false, processor);
|
||||
});
|
||||
|
||||
// Route to set GPIO to HIGH
|
||||
server.on("/test.php", HTTP_POST, [](AsyncWebServerRequest *request){
|
||||
//digitalWrite(ledPin, HIGH);
|
||||
request->send(SPIFFS, "/index.html", String(), false, processor);
|
||||
});
|
||||
|
||||
// Route to set GPIO to LOW
|
||||
server.on("/off", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||
digitalWrite(ledPin, LOW);
|
||||
request->send(SPIFFS, "/index.html", String(), false, processor);
|
||||
});
|
||||
|
||||
// Send a POST request to <IP>/post with a form field message set to <message>
|
||||
server.on("/post", HTTP_POST, [](AsyncWebServerRequest *request){
|
||||
handleQRGPost(request);
|
||||
request->send(200, "text/plain", "Hello, POST done");
|
||||
});
|
||||
|
||||
// Start server
|
||||
server.begin();
|
||||
}
|
||||
|
||||
|
||||
const char *fetchWifiPw(const char *id) {
|
||||
for(int i=0; i<nNetworks; i++) {
|
||||
Serial.print("Comparing '");
|
||||
|
|
@ -369,7 +535,7 @@ void loopWifiScan() {
|
|||
pw=fetchWifiPw(id);
|
||||
if(pw) break;
|
||||
}
|
||||
if(1||!pw) { id="test"; pw="test"; }
|
||||
if(!pw) { id="test"; pw="test"; }
|
||||
Serial.print("Connecting to: "); Serial.println(id);
|
||||
u8x8.drawString(0,6, "Conn:");
|
||||
u8x8.drawString(6,6, id);
|
||||
|
|
@ -386,11 +552,13 @@ void loopWifiScan() {
|
|||
if(cnt==10) {
|
||||
WiFi.disconnect();
|
||||
delay(1000);
|
||||
WiFi.softAP("sonde","sondesonde");
|
||||
WiFi.softAP(networks[0].id.c_str(),networks[0].pw.c_str());
|
||||
IPAddress myIP = WiFi.softAPIP();
|
||||
Serial.print("AP IP address: ");
|
||||
Serial.println(myIP);
|
||||
sonde.setIP(myIP.toString().c_str());
|
||||
u8x8.drawString(0,6, "AP: ");
|
||||
u8x8.drawString(6,6, networks[0].id.c_str());
|
||||
sonde.setIP(myIP.toString().c_str(), true);
|
||||
sonde.updateDisplayIP();
|
||||
SetupAsyncServer();
|
||||
delay(5000);
|
||||
|
|
@ -403,7 +571,7 @@ void loopWifiScan() {
|
|||
Serial.println("WiFi connected");
|
||||
Serial.println("IP address: ");
|
||||
Serial.println(WiFi.localIP());
|
||||
sonde.setIP(WiFi.localIP().toString().c_str());
|
||||
sonde.setIP(WiFi.localIP().toString().c_str(), false);
|
||||
sonde.updateDisplayIP();
|
||||
SetupAsyncServer();
|
||||
delay(5000);
|
||||
|
|
|
|||
|
|
@ -13,22 +13,44 @@
|
|||
<p><a href="/on"><button class="button">ON</button></a></p>
|
||||
<p><a href="/off"><button class="button button2">OFF</button></a></p>
|
||||
-->
|
||||
<table class="KKK">
|
||||
<tr>
|
||||
<th></th>
|
||||
<th style="width:100px">ID</th>
|
||||
<th style="width:100px">PW</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>1</td>
|
||||
<td contenteditable>DinoGast</td>
|
||||
<td contenteditable>Schokolade</td>
|
||||
<tr>
|
||||
<td>2</td>
|
||||
<td contenteditable></td>
|
||||
<td contenteditable></td>
|
||||
</tr>
|
||||
|
||||
<div class="tab">
|
||||
<button class="tablinks" onclick="selTab(event,'QRG')" id="defaultTab">QRG</button>
|
||||
<button class="tablinks" onclick="selTab(event,'WIFI')">WLAN</button>
|
||||
<button class="tablinks" onclick="selTab(event,'About')">About</button>
|
||||
</div>
|
||||
|
||||
<div id="QRG" class="tabcontent">
|
||||
<h3> QRG</h3>
|
||||
<iframe src="qrg.html" style="border:none;" width="100%%" height="100%%"></iframe>
|
||||
</div>
|
||||
|
||||
<div id="WIFI" class="tabcontent">
|
||||
<h3> WIFI</h3>
|
||||
<iframe src="wifi.html" style="border:none;" width="100%%" height="100%%"></iframe>
|
||||
</div>
|
||||
|
||||
<div id="About" class="tabcontent">
|
||||
<h3>About</h3>
|
||||
RDZSonde
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function selTab(evt, id) {
|
||||
var i, tabcontent, tablinks;
|
||||
tabcontent=document.getElementsByClassName("tabcontent");
|
||||
for(i=0; i<tabcontent.length; i++) {
|
||||
tabcontent[i].style.display = "none";
|
||||
}
|
||||
tablinks=document.getElementsByClassName("tablinks");
|
||||
for(i=0; i<tablinks.length; i++) {
|
||||
tablinks[i].className = tablinks[i].className.replace(" active", "");
|
||||
}
|
||||
document.getElementById(id).style.display = "block";
|
||||
evt.currentTarget.className += " active";
|
||||
}
|
||||
document.getElementById("defaultTab").click();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
RDZsonde
|
||||
RDZsonde
|
||||
DinoGast
|
||||
Schokolade
|
||||
AndroidDD
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
# Frequency in Mhz (format nnn.nnn)
|
||||
# Type (4=RS41, 6=DFM normal, DFM-06, 9=DFM inverted, DFM-09)
|
||||
#
|
||||
402.700 4
|
||||
402.300 4
|
||||
403.450 9
|
||||
405.100 4
|
||||
402.700 4 +
|
||||
402.300 4 +
|
||||
403.450 9 +
|
||||
405.100 4 -
|
||||
# end
|
||||
|
|
|
|||
|
|
@ -1,3 +1,40 @@
|
|||
body, html {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
font-family: Arial;
|
||||
}
|
||||
|
||||
.tab {
|
||||
overflow: hidden;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
|
||||
.tab button {
|
||||
background-color: inherit;
|
||||
float: left;
|
||||
border: none;
|
||||
outline: none;
|
||||
cursor: pointer;
|
||||
padding: 14px 16px;
|
||||
transition: 0.3s;
|
||||
}
|
||||
|
||||
.tab button:hover {
|
||||
background-color: #ddd;
|
||||
}
|
||||
|
||||
.tab button.active {
|
||||
background-color: #ccc;
|
||||
}
|
||||
|
||||
.tabcontent {
|
||||
display: none;
|
||||
padding: 6px 12px;
|
||||
border: 1px solid #ccc;
|
||||
border-top: none;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
html {
|
||||
font-family: Helvetica;
|
||||
display: inline-block;
|
||||
|
|
|
|||
|
|
@ -4,15 +4,18 @@
|
|||
|
||||
extern U8X8_SSD1306_128X64_NONAME_SW_I2C u8x8;
|
||||
|
||||
#define CHANBW 25
|
||||
#define SMOOTH 2
|
||||
#define CHANBW 10
|
||||
#define PIXSAMPL (50/CHANBW)
|
||||
#define SMOOTH 4
|
||||
#define STARTF 400000000
|
||||
#define NCHAN ((int)(6000/CHANBW))
|
||||
|
||||
int scanresult[NCHAN];
|
||||
int scandisp[NCHAN/2];
|
||||
int scandisp[NCHAN/PIXSAMPL];
|
||||
|
||||
#define PLOT_N 120
|
||||
#define TICK1 (120/6)
|
||||
#define TICK2 (TICK1/4)
|
||||
#define PLOT_MIN -220
|
||||
#define PLOT_SCALE(x) (x<PLOT_MIN?0:(x-PLOT_MIN)/2)
|
||||
|
||||
|
|
@ -37,6 +40,8 @@ void Scanner::plotResult()
|
|||
for(int i=0; i<PLOT_N; i+=8) {
|
||||
for(int j=0; j<8; j++) {
|
||||
fillTiles(row+j, PLOT_SCALE(scandisp[i+j]));
|
||||
if( ((i+j)%TICK1)==0) { row[j] |= 0x07; }
|
||||
if( ((i+j)%TICK2)==0) { row[j] |= 0x01; }
|
||||
}
|
||||
for(int y=0; y<8; y++) {
|
||||
u8x8.drawTile(i/8, y, 1, row+8*y);
|
||||
|
|
@ -59,11 +64,12 @@ void Scanner::scan()
|
|||
sx1278.writeRegister(REG_RSSI_CONFIG, SMOOTH&0x07);
|
||||
sx1278.setFrequency(STARTF);
|
||||
sx1278.writeRegister(REG_OP_MODE, FSK_RX_MODE);
|
||||
delay(5);
|
||||
delay(20);
|
||||
|
||||
unsigned long start = millis();
|
||||
uint32_t lastfrf=-1;
|
||||
for(int i=0; i<NCHAN; i++) {
|
||||
for(int iter=0; iter<2; iter++) { // two interations, to catch all RS41 transmissions
|
||||
for(int i=0; i<NCHAN; i++) {
|
||||
float freq = STARTF + 1000.0*i*CHANBW;
|
||||
uint32_t frf = freq * 1.0 * (1<<19) / SX127X_CRYSTAL_FREQ;
|
||||
if( (lastfrf>>16)!=(frf>>16) ) {
|
||||
|
|
@ -78,16 +84,24 @@ void Scanner::scan()
|
|||
int wait = 20 + 1000*(1<<(SMOOTH+1))/4/CHANBW;
|
||||
delayMicroseconds(wait);
|
||||
int rssi = -(int)sx1278.readRegister(REG_RSSI_VALUE_FSK);
|
||||
scanresult[i] = rssi;
|
||||
if(iter==0) { scanresult[i] = rssi; } else {
|
||||
if(rssi>scanresult[i]) scanresult[i]=rssi;
|
||||
}
|
||||
}
|
||||
}
|
||||
unsigned long duration = millis()-start;
|
||||
Serial.print("Scan time: ");
|
||||
Serial.println(duration);
|
||||
for(int i=0; i<NCHAN; i+=2) {
|
||||
scandisp[i/2] = scanresult[i];
|
||||
for(int j=1; j<2; j++) { if(scanresult[i+j]>scandisp[i/2]) scandisp[i/2] = scanresult[i+j]; }
|
||||
for(int i=0; i<NCHAN; i+=PIXSAMPL) {
|
||||
scandisp[i/PIXSAMPL]=scanresult[i];
|
||||
for(int j=1; j<PIXSAMPL; j++) { scandisp[i/PIXSAMPL]+=scanresult[i+j]; }
|
||||
//for(int j=1; j<PIXSAMPL; j++) { if(scanresult[i+j]>scandisp[i/PIXSAMPL]) scandisp[i/PIXSAMPL] = scanresult[i+j]; }
|
||||
Serial.print(scanresult[i]); Serial.print(", ");
|
||||
if(((i+1)%32) == 0) Serial.println();
|
||||
}
|
||||
Serial.println("\n");
|
||||
for(int i=0; i<NCHAN/PIXSAMPL; i++) {
|
||||
scandisp[i]/=PIXSAMPL;
|
||||
Serial.print(scandisp[i]); Serial.print(", ");
|
||||
}
|
||||
Serial.println("\n");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ static unsigned char stattiles[4][4] = {
|
|||
0x1F, 0x15, 0x15, 0x00 ,
|
||||
0x00, 0x1F, 0x00, 0x00 };
|
||||
|
||||
byte myIP_tiles[8*10];
|
||||
byte myIP_tiles[8*11];
|
||||
|
||||
static const uint8_t font[10][5]={
|
||||
0x3E, 0x51, 0x49, 0x45, 0x3E, // 0
|
||||
|
|
@ -37,12 +37,23 @@ static const uint8_t font[10][5]={
|
|||
0x06, 0x49, 0x39, 0x29, 0x1E }; // 9; .=0x40
|
||||
|
||||
static uint8_t halfdb_tile[8]={0x80, 0x27, 0x45, 0x45, 0x45, 0x39, 0x00, 0x00};
|
||||
|
||||
static uint8_t halfdb_tile1[8]={0x00, 0x38, 0x28, 0x28, 0x28, 0xC8, 0x00, 0x00};
|
||||
static uint8_t halfdb_tile2[8]={0x00, 0x11, 0x02, 0x02, 0x02, 0x01, 0x00, 0x00};
|
||||
|
||||
static uint8_t empty_tile[8]={0x80, 0x3E, 0x51, 0x49, 0x45, 0x3E, 0x00, 0x00};
|
||||
|
||||
static uint8_t empty_tile1[8]={0x00, 0xF0, 0x88, 0x48, 0x28, 0xF0, 0x00, 0x00};
|
||||
static uint8_t empty_tile2[8]={0x00, 0x11, 0x02, 0x02, 0x02, 0x01, 0x00, 0x00};
|
||||
static uint8_t ap_tile[8]={0x00,0x04,0x22,0x92, 0x92, 0x22, 0x04, 0x00};
|
||||
|
||||
void Sonde::setIP(const char *ip) {
|
||||
int tp = 0;
|
||||
|
||||
void Sonde::setIP(const char *ip, bool AP) {
|
||||
memset(myIP_tiles, 0, 11*8);
|
||||
int len = strlen(ip);
|
||||
int pix = (len-3)*6+6;
|
||||
int tp = 80-pix+8;
|
||||
if(AP) memcpy(myIP_tiles+(tp<16?0:8), ap_tile, 8);
|
||||
for(int i=0; i<len; i++) {
|
||||
if(ip[i]=='.') { myIP_tiles[tp++]=0x40; myIP_tiles[tp++]=0x00; }
|
||||
else {
|
||||
|
|
@ -58,18 +69,26 @@ void Sonde::setIP(const char *ip) {
|
|||
void Sonde::clearSonde() {
|
||||
nSonde = 0;
|
||||
}
|
||||
void Sonde::addSonde(float frequency, SondeType type) {
|
||||
void Sonde::addSonde(float frequency, SondeType type, int active) {
|
||||
if(nSonde>=MAXSONDE) {
|
||||
Serial.println("Cannot add another sonde, MAXSONDE reached");
|
||||
return;
|
||||
}
|
||||
sondeList[nSonde].type = type;
|
||||
sondeList[nSonde].freq = frequency;
|
||||
sondeList[nSonde].active = active;
|
||||
memcpy(sondeList[nSonde].rxStat, "\x00\x01\x2\x3\x2\x1\x1\x2\x0\x3\x0\x0\x1\x2\x3\x1\x0", 18);
|
||||
nSonde++;
|
||||
}
|
||||
void Sonde::nextConfig() {
|
||||
currentSonde++;
|
||||
// Skip non-active entries (but don't loop forever if there are no active ones
|
||||
for(int i=0; i<MAXSONDE; i++) {
|
||||
if(!sondeList[currentSonde].active) {
|
||||
currentSonde++;
|
||||
if(currentSonde>=nSonde) currentSonde=0;
|
||||
}
|
||||
}
|
||||
if(currentSonde>=nSonde) {
|
||||
currentSonde=0;
|
||||
}
|
||||
|
|
@ -160,7 +179,8 @@ void Sonde::updateDisplayRSSI() {
|
|||
int len=strlen(buf)-3;
|
||||
buf[5]=0;
|
||||
u8x8.drawString(0,6,buf);
|
||||
u8x8.drawTile(len,6,1,(sonde.si()->rssi&1)?halfdb_tile:empty_tile);
|
||||
u8x8.drawTile(len,6,1,(sonde.si()->rssi&1)?halfdb_tile1:empty_tile1);
|
||||
u8x8.drawTile(len,7,1,(sonde.si()->rssi&1)?halfdb_tile2:empty_tile2);
|
||||
}
|
||||
|
||||
void Sonde::updateStat() {
|
||||
|
|
@ -183,7 +203,7 @@ void Sonde::updateDisplayRXConfig() {
|
|||
}
|
||||
|
||||
void Sonde::updateDisplayIP() {
|
||||
u8x8.drawTile(6, 7, 10, myIP_tiles);
|
||||
u8x8.drawTile(5, 7, 11, myIP_tiles);
|
||||
}
|
||||
|
||||
// Probing RS41
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ extern const char *sondeTypeStr[5];
|
|||
|
||||
typedef struct st_sondeinfo {
|
||||
// receiver configuration
|
||||
bool active;
|
||||
SondeType type;
|
||||
float freq;
|
||||
// decoded ID
|
||||
|
|
@ -37,12 +38,13 @@ typedef struct st_sondeinfo {
|
|||
class Sonde
|
||||
{
|
||||
private:
|
||||
int nSonde;
|
||||
int currentSonde = 0;
|
||||
SondeInfo sondeList[MAXSONDE+1];
|
||||
public:
|
||||
int nSonde;
|
||||
SondeInfo sondeList[MAXSONDE+1];
|
||||
|
||||
void clearSonde();
|
||||
void addSonde(float frequency, SondeType type);
|
||||
void addSonde(float frequency, SondeType type, int active);
|
||||
void nextConfig();
|
||||
void setup();
|
||||
|
||||
|
|
@ -59,7 +61,7 @@ public:
|
|||
void updateDisplay();
|
||||
void updateDisplayScanner();
|
||||
void clearDisplay();
|
||||
void setIP(const char *ip);
|
||||
void setIP(const char *ip, bool isAP);
|
||||
};
|
||||
|
||||
extern Sonde sonde;
|
||||
|
|
|
|||
Loading…
Reference in New Issue