From 791a6bdb7568835b5df14486deaa9bc0a9ee29df Mon Sep 17 00:00:00 2001 From: "Hans P. Reiser" Date: Mon, 15 Apr 2019 21:02:50 +0200 Subject: [PATCH] v0.3: merging some changes (axupd support, partial/readonly config web page) --- RX_FSK/RX_FSK.ino | 131 +++++++++++++++++++++++++---------- RX_FSK/data/index.html | 6 ++ libraries/SondeLib/RS41.cpp | 16 ++--- libraries/SondeLib/Sonde.cpp | 23 +++++- libraries/SondeLib/Sonde.h | 14 ++++ libraries/SondeLib/aprs.cpp | 16 ++--- libraries/SondeLib/aprs.h | 14 ++-- 7 files changed, 161 insertions(+), 59 deletions(-) diff --git a/RX_FSK/RX_FSK.ino b/RX_FSK/RX_FSK.ino index f49d51c..2ba2fc0 100644 --- a/RX_FSK/RX_FSK.ino +++ b/RX_FSK/RX_FSK.ino @@ -9,8 +9,6 @@ #include #include #include -//#include -//#include #define LORA_LED 9 @@ -28,8 +26,11 @@ int e; AsyncWebServer server(80); -const char * udpAddress = "192.168.179.21"; -const int udpPort = 9002; +#define LOCALUDPPORT 9002 + +// moved to sonde.config +//const char * udpAddress = "192.168.42.20"; +//const int udpPort = 9002; boolean connected = false; WiFiUDP udp; @@ -268,11 +269,85 @@ const char *createStatusForm() { return message; } +///////////////////// Config form + +struct st_configitems { + const char *label; + int type; // 0: numeric; i>0 string of length i; -1: separator; -2: type selector + void *data; +}; +#define N_CONFIG 16 +struct st_configitems config_list[N_CONFIG] = { + {"Call", 8, sonde.config.call}, + {"Passcode", 8, sonde.config.passcode}, + {"---", -1, NULL}, + {"AXUDP active", -3, &sonde.config.udpfeed.active}, + {"AXUDP Host", 63, sonde.config.udpfeed.host}, + {"AXUDP Port", 0, &sonde.config.udpfeed.port}, + {"DFM ID Format", -2, &sonde.config.udpfeed.idformat}, + {"Rate limit", 0, &sonde.config.udpfeed.highrate}, + {"---", -1, NULL}, + {"APRS TCP active", -3, &sonde.config.tcpfeed.active}, + {"ARPS TCP Host", 63, sonde.config.tcpfeed.host}, + {"APRS TCP Port", 0, &sonde.config.tcpfeed.port}, + {"DFM ID Format", -2, &sonde.config.tcpfeed.idformat}, + {"Rate limit", 0, &sonde.config.tcpfeed.highrate}, + {"---", -1, NULL}, + {"Spectrum noise floor", 0, &sonde.config.noisefloor} +}; + +void addConfigStringEntry(char *ptr, int idx, const char *label, int len, char *field) { + sprintf(ptr+strlen(ptr), "%s\n", + label, idx, field); +} +void addConfigNumEntry(char *ptr, int idx, const char *label, int *value) { + sprintf(ptr+strlen(ptr), "%s\n", + label, idx, *value); +} +void addConfigTypeEntry(char *ptr, int idx, const char *label, int *value) { + // TODO +} +void addConfigOnOffEntry(char *ptr, int idx, const char *label, int *value) { + // TODO +} +void addConfigSeparatorEntry(char *ptr) { + strcat(ptr, "
\n"); +} + +const char *createConfigForm() { + char *ptr = message; + char tmp[4]; + strcpy(ptr,"
"); + for(int i=0; i"); + return message; +} + + + 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"); + request->send(SPIFFS, "/index.html", String(), false, processor); }); server.on("/index.html", HTTP_GET, [](AsyncWebServerRequest *request){ @@ -299,6 +374,10 @@ void SetupAsyncServer() { request->send(200, "text/html", createWIFIForm()); }); + server.on("/config.html", HTTP_GET, [](AsyncWebServerRequest *request){ + request->send(200, "text/html", createConfigForm()); + }); + server.on("/status.html", HTTP_GET, [](AsyncWebServerRequest *request){ request->send(200, "text/html", createStatusForm()); }); @@ -308,29 +387,11 @@ void SetupAsyncServer() { 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 /post with a form field message set to - server.on("/post", HTTP_POST, [](AsyncWebServerRequest *request){ - handleQRGPost(request); - request->send(200, "text/plain", "Hello, POST done"); - }); // Start server server.begin(); @@ -422,7 +483,9 @@ void setup() Serial.println(f); #endif - sx1278.setLNAGain(0); //-48); + //sx1278.setLNAGain(-48); + sx1278.setLNAGain(0); + int gain = sx1278.getLNAGain(); Serial.print("RX LNA Gain is "); Serial.println(gain); @@ -489,9 +552,9 @@ void loopDecoder() { SondeInfo *s = sonde.si(); char raw[201]; const char *str = aprs_senddata(s->lat, s->lon, s->hei, s->hs, s->dir, s->vs, sondeTypeStr[s->type], s->id, "TE0ST", "EO"); - int rawlen = aprsstr_mon2raw(str, raw, MAXLEN); + int rawlen = aprsstr_mon2raw(str, raw, APRS_MAXLEN); Serial.print("Sending: "); Serial.println(raw); - udp.beginPacket(udpAddress,udpPort); + udp.beginPacket(sonde.config.udpfeed.host,sonde.config.udpfeed.port); udp.write((const uint8_t *)raw,rawlen); udp.endPacket(); } @@ -572,7 +635,7 @@ void WiFiEvent(WiFiEvent_t event){ Serial.println(WiFi.localIP()); //initializes the UDP state //This initializes the transfer buffer - udp.begin(WiFi.localIP(),udpPort); + udp.begin(WiFi.localIP(),LOCALUDPPORT); connected = true; break; case SYSTEM_EVENT_STA_DISCONNECTED: @@ -582,6 +645,7 @@ void WiFiEvent(WiFiEvent_t event){ } } + static char* _scan[2]={"/","\\"}; void loopWifiScan() { u8x8.setFont(u8x8_font_chroma48medium8_r); @@ -623,12 +687,14 @@ void loopWifiScan() { Serial.print("."); u8x8.drawString(15,7,_scan[cnt&1]); cnt++; + #if 0 if(cnt==4) { WiFi.disconnect(true); // retry, for my buggy FritzBox WiFi.onEvent(WiFiEvent); WiFi.begin(id, pw); } - if(cnt==10) { + #endif + if(cnt==15) { WiFi.disconnect(true); delay(1000); WiFi.softAP(networks[0].id.c_str(),networks[0].pw.c_str()); @@ -666,11 +732,7 @@ void loop() { case ST_SPECTRUM: loopSpectrum(); break; case ST_WIFISCAN: loopWifiScan(); break; } -#if 0 - //wifiloop(NULL); - //e = dfm.receiveFrame(); - //e = rs41.receiveFrame(); - delay(1000); +#if 1 int rssi = sx1278.getRSSI(); Serial.print(" RSSI: "); Serial.print(rssi); @@ -678,6 +740,5 @@ void loop() { int gain = sx1278.getLNAGain(); Serial.print(" LNA Gain: "), Serial.println(gain); - #endif - +#endif } diff --git a/RX_FSK/data/index.html b/RX_FSK/data/index.html index 7e78cf1..35a3775 100644 --- a/RX_FSK/data/index.html +++ b/RX_FSK/data/index.html @@ -18,6 +18,7 @@ + @@ -36,6 +37,11 @@ +
+

Config

+ +
+

About

RDZSonde diff --git a/libraries/SondeLib/RS41.cpp b/libraries/SondeLib/RS41.cpp index 4feaa55..a3d1d72 100644 --- a/libraries/SondeLib/RS41.cpp +++ b/libraries/SondeLib/RS41.cpp @@ -357,7 +357,7 @@ static void posrs41(const byte b[], uint32_t b_len, uint32_t p) -void RS41::decode41(byte *data, int MAXLEN) +void RS41::decode41(byte *data, int maxlen) { char buf[128]; @@ -369,10 +369,10 @@ void RS41::decode41(byte *data, int MAXLEN) Serial.print(corr); Serial.println(); int p = 57; // 8 byte header, 48 byte RS - while(pMAXLEN) break; + if(p+len>maxlen) break; #if 1 // DEBUG OUTPUT @@ -459,20 +459,20 @@ static uint8_t scramble[64] = {150U,131U,62U,81U,177U,73U,8U,152U,50U,5U,89U, static byte data[800]; -#define MAXLEN (320) +#define RS41MAXLEN (320) int RS41::receiveFrame() { //sx1278.setPayloadLength(518-8); // Expect 320-8 bytes or 518-8 bytes (8 byte header) - sx1278.setPayloadLength(MAXLEN-8); // Expect 320-8 bytes or 518-8 bytes (8 byte header) + sx1278.setPayloadLength(RS41MAXLEN-8); // Expect 320-8 bytes or 518-8 bytes (8 byte header) sx1278.writeRegister(REG_OP_MODE, FSK_RX_MODE); int e = sx1278.receivePacketTimeout(1000, data+8); if(e) { Serial.println("TIMEOUT"); return RX_TIMEOUT; } //if timeout... return 1 - for(int i=0; ihei>999?"%5.0fm":"%3.1fm", si()->hei); + snprintf(buf, 16, si()->hei>999?" %5.0fm":" %3.1fm", si()->hei); u8x8.drawString((10+6-strlen(buf)),2,buf); - snprintf(buf, 16, si()->hs>99?"%3.0f":"%2.1f", si()->hs); + snprintf(buf, 16, si()->hs>99?" %3.0f":" %2.1f", si()->hs); u8x8.drawString((10+4-strlen(buf)),3,buf); - snprintf(buf, 16, "%+2.1f", si()->vs); + snprintf(buf, 16, " %+2.1f", si()->vs); u8x8.drawString((10+4-strlen(buf)),4,buf); u8x8.drawTile(14,3,2,kmh_tiles); u8x8.drawTile(14,4,2,ms_tiles); diff --git a/libraries/SondeLib/Sonde.h b/libraries/SondeLib/Sonde.h index 9b1b5e2..ee21f07 100644 --- a/libraries/SondeLib/Sonde.h +++ b/libraries/SondeLib/Sonde.h @@ -2,6 +2,8 @@ #ifndef Sonde_h #define Sonde_H +#include "aprs.h" + // RX_TIMEOUT: no header detected // RX_ERROR: header detected, but data not decoded (crc error, etc.) // RX_OK: header and data ok @@ -10,6 +12,15 @@ enum RxResult { RX_OK, RX_TIMEOUT, RX_ERROR }; enum SondeType { STYPE_DFM06, STYPE_DFM09, STYPE_RS41 }; extern const char *sondeTypeStr[5]; +typedef struct st_rdzconfig { + int noisefloor; // for spectrum display + char call[9]; + char passcode[9]; + // for now, one feed for each type is enough, but might get extended to more? + struct st_feedinfo udpfeed; // target for AXUDP messages + struct st_feedinfo tcpfeed; // target for APRS-IS TCP connections +} RDZConfig; + typedef struct st_sondeinfo { // receiver configuration bool active; @@ -39,10 +50,13 @@ class Sonde { private: public: + RDZConfig config; int currentSonde = 0; int nSonde; SondeInfo sondeList[MAXSONDE+1]; + Sonde(); + void clearSonde(); void addSonde(float frequency, SondeType type, int active); void nextConfig(); diff --git a/libraries/SondeLib/aprs.cpp b/libraries/SondeLib/aprs.cpp index 7c57310..10fc23a 100644 --- a/libraries/SondeLib/aprs.cpp +++ b/libraries/SondeLib/aprs.cpp @@ -45,7 +45,7 @@ void aprsstr_append(char *b, const char *data) { int blen=strlen(b); int len=strlen(data); - if(blen+len>MAXLEN) len=MAXLEN-blen; + if(blen+len>APRS_MAXLEN) len=APRS_MAXLEN-blen; strncat(b, data, len); } @@ -233,26 +233,26 @@ char * aprs_senddata(float lat, float lon, float hei, float speed, float dir, fl int i = strlen(b); int lati = abs((int)lat); int latm = (fabs(lat)-lati)*6000; - snprintf(b+i, MAXLEN-i, "%02d%02d.%02d%c%c", lati, latm/100, latm%100, lat<0?'S':'N', sym[0]); + snprintf(b+i, APRS_MAXLEN-i, "%02d%02d.%02d%c%c", lati, latm/100, latm%100, lat<0?'S':'N', sym[0]); i = strlen(b); int loni = abs((int)lon); int lonm = (fabs(lon)-loni)*6000; - snprintf(b+i, MAXLEN-i, "%03d%02d.%02d%c%c", loni, lonm/100, lonm%100, lon<0?'W':'E', sym[1]); + snprintf(b+i, APRS_MAXLEN-i, "%03d%02d.%02d%c%c", loni, lonm/100, lonm%100, lon<0?'W':'E', sym[1]); #if 1 if(speed>0.5) { i=strlen(b); - snprintf(b+i, MAXLEN-i, "%03d/%03d", realcard(dir+1.5), realcard(speed*1.0/KNOTS+0.5)); + snprintf(b+i, APRS_MAXLEN-i, "%03d/%03d", realcard(dir+1.5), realcard(speed*1.0/KNOTS+0.5)); } #endif if(hei>0.5) { i=strlen(b); - snprintf(b+i, MAXLEN-i, "/A=%06d", realcard(hei*FEET+0.5)); + snprintf(b+i, APRS_MAXLEN-i, "/A=%06d", realcard(hei*FEET+0.5)); } #if 0 int dao=1; if(dao) { i=strlen(b); - snprintf(b+i, MAXLEN-i, "!w%c%c!", 33+dao91(lat), 33+dao91(lon)); + snprintf(b+i, APRS_MAXLEN-i, "!w%c%c!", 33+dao91(lat), 33+dao91(lon)); } #endif const char *comm="&test"; @@ -273,11 +273,11 @@ int main(int argc, char *argv[]) float lat=48, lon=10; while(1) { const char *str = aprs_senddata(lat, lon, 543, 5, 180, 1.5, "RS41", "TE0ST", "TE1ST", "EO"); - int rawlen = aprsstr_mon2raw(str, raw, MAXLEN); + int rawlen = aprsstr_mon2raw(str, raw, APRS_MAXLEN); sendudp(fd, raw, rawlen); str = "OE3XKC>APMI06,qAR,OE3XLR:;ER-341109*111111z4803.61NE01532.39E0145.650MHz R15k OE3XPA"; - rawlen = aprsstr_mon2raw(str, raw, MAXLEN); + rawlen = aprsstr_mon2raw(str, raw, APRS_MAXLEN); sendudp(fd, &si, raw, rawlen); lat += 0.002; lon += 0.01; sleep(5); diff --git a/libraries/SondeLib/aprs.h b/libraries/SondeLib/aprs.h index 7b1f26b..90e7b97 100644 --- a/libraries/SondeLib/aprs.h +++ b/libraries/SondeLib/aprs.h @@ -2,17 +2,21 @@ #ifndef _aprs_h #define _aprs_h -enum IDTYPE { ID_DFMDXL, ID_DFMREAL, ID_DFMAUTO }; +enum IDTYPE { ID_DFMDXL, ID_DFMGRAW, ID_DFMAUTO }; typedef struct st_feedinfo { bool active; int type; // 0:UDP(axudp), 1:TCP(aprs.fi) - char *host; + char host[64]; int port; - int rate; + int lowrate; + int highrate; + int lowlimit; int idformat; // 0: dxl 1: real 2: auto -} -#define MAXLEN 201 +}; + + +#define APRS_MAXLEN 201 void aprs_gencrctab(void); int aprsstr_mon2raw(const char *mon, char raw[], int raw_len); char * aprs_senddata(float lat, float lon, float hei, float speed, float dir, float climb, const char *type, const char *objname, const char *usercall, const char *sym);
OptionValue