From 7419b8f5ed0658c370acc8c9a2121b15909949eb Mon Sep 17 00:00:00 2001 From: "Hansi, dl9rdz" Date: Thu, 9 May 2019 13:07:04 +0200 Subject: [PATCH 1/2] preparing v0.6c --- RX_FSK/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RX_FSK/version.h b/RX_FSK/version.h index ff90c12..625fa53 100644 --- a/RX_FSK/version.h +++ b/RX_FSK/version.h @@ -1,2 +1,2 @@ const char *version_name = "RDZ_TTGO_SONDE"; -const char *version_id = "master v0.6b"; +const char *version_id = "master v0.6c"; From d8ea59ecdbdd36c2b62c58c4d33dd8adecaf1507 Mon Sep 17 00:00:00 2001 From: "Hansi, dl9rdz" Date: Thu, 9 May 2019 13:07:31 +0200 Subject: [PATCH 2/2] v0.6c: Merging some minor updates - Configurable frequency error display and manual correction - Configurable RX bandwidth (for RS41), enhances sensitivity Squashed commit of the following: commit 90c117da0f8ceb3c0b061672e62a214193ac44a9 Author: Hansi, dl9rdz Date: Tue May 7 02:20:35 2019 +0200 some more configurable options commit 7012768c8ed532d756b5c46829e132fa6b8a8dbb Author: Hansi, dl9rdz Date: Tue May 7 02:17:37 2019 +0200 some more configurable options commit fdeb179a679b5a0baac3dfa6c21df11ba9d23de6 Author: Hansi, dl9rdz Date: Mon May 6 17:25:54 2019 +0200 some config options ++ commit 3549ab21cfd788126a341af3eb88b7e554582c36 Author: Hansi, dl9rdz Date: Mon May 6 01:18:41 2019 +0200 configurable RX and AFC bandwidth; configuration display of AFC value --- RX_FSK/RX_FSK.ino | 85 ++++++++++++++++++++++++++----- RX_FSK/data/index.html | 6 +++ libraries/SX1278FSK/SX1278FSK.cpp | 30 +++++++++++ libraries/SX1278FSK/SX1278FSK.h | 7 +++ libraries/SondeLib/RS41.cpp | 4 +- libraries/SondeLib/Sonde.cpp | 26 ++++++++++ libraries/SondeLib/Sonde.h | 10 ++++ 7 files changed, 154 insertions(+), 14 deletions(-) diff --git a/RX_FSK/RX_FSK.ino b/RX_FSK/RX_FSK.ino index d8a4da5..11f8c68 100644 --- a/RX_FSK/RX_FSK.ino +++ b/RX_FSK/RX_FSK.ino @@ -40,6 +40,19 @@ boolean connected = false; WiFiUDP udp; WiFiClient client; + +enum KeyPress { KP_NONE = 0, KP_SHORT, KP_DOUBLE, KP_MID, KP_LONG }; + +struct Button { + uint8_t pin; + uint32_t numberKeyPresses; + KeyPress pressed; + unsigned long press_ts; + boolean doublepress; +}; +Button button1 = {0, 0, KP_NONE, 0, false}; + + // Set LED GPIO int ledPin = 1; // Stores LED state @@ -363,6 +376,8 @@ struct st_configitems config_list[] = { {"timer", "Spectrum Timer", 0, &sonde.config.timer}, {"marker", "Spectrum MHz marker", 0, &sonde.config.marker}, {"noisefloor", "Sepctrum noisefloor", 0, &sonde.config.noisefloor}, + {"showafc", "Show AFC value", 0, &sonde.config.showafc}, + {"freqofs", "RX frequency offset (Hz)", 0, &sonde.config.freqofs}, {"---", "---", -1, NULL}, /* APRS settings */ {"call", "Call", 8, sonde.config.call}, @@ -382,6 +397,10 @@ struct st_configitems config_list[] = { {"tcp.idformat", "DFM ID Format", -2, &sonde.config.tcpfeed.idformat}, {"tcp.highrate", "Rate limit", 0, &sonde.config.tcpfeed.highrate}, {"---", "---", -1, NULL}, + /* RS41 decoder settings */ + {"rs41.agcbw", "RS41 AGC bandwidth", 0, &sonde.config.rs41.agcbw}, + {"rs41.rxbw", "RS41 RX bandwidth", 0, &sonde.config.rs41.rxbw}, + {"---", "---", -1, NULL}, /* Hardware dependeing settings */ {"oled_sda", "OLED SDA (needs reboot)", 0, &sonde.config.oled_sda}, {"oled_scl", "OLED SCL (needs reboot)", 0, &sonde.config.oled_scl}, @@ -472,6 +491,49 @@ const char *handleConfigPost(AsyncWebServerRequest *request) { setupConfigData(); } +const char *ctrlid[]={"rx","scan","spec","wifi"}; +const char *ctrllabel[]={"Receiver (short keypress)", "Scanner (double keypress)", "Spectrum (medium keypress)", "WiFi (long keypress)"}; +const char *createControlForm() { + char *ptr = message; + char tmp[4]; + strcpy(ptr, "
"); + for(int i=0; i<4; i++) { + strcat(ptr, "
"); + } + strcat(ptr, "
"); + return message; +} + + +const char *handleControlPost(AsyncWebServerRequest *request) { + Serial.println("Handling post request"); + int params = request->params(); + for (int i = 0; i < params; i++) { + String param = request->getParam(i)->name(); + Serial.println(param.c_str()); + if(param.equals("rx")) { + Serial.println("equals rx"); + button1.pressed = KP_SHORT; + } + else if(param.equals("scan")) { + Serial.println("equals scan"); + button1.pressed = KP_DOUBLE; + } + else if(param.equals("spec")) { + Serial.println("equals spec"); + button1.pressed = KP_MID; + } + else if(param.equals("wifi")) { + Serial.println("equals wifi"); + button1.pressed = KP_LONG; + } + } +} + const char *createUpdateForm(boolean run) { char *ptr = message; char tmp[4]; @@ -556,6 +618,14 @@ void SetupAsyncServer() { request->send(200, "text/html", createUpdateForm(1)); }); + server.on("/control.html", HTTP_GET, [](AsyncWebServerRequest * request) { + request->send(200, "text/html", createControlForm()); + }); + server.on("/control.html", HTTP_POST, [](AsyncWebServerRequest * request) { + handleControlPost(request); + request->send(200, "text/html", createControlForm()); + }); + // Route to load style.css file server.on("/style.css", HTTP_GET, [](AsyncWebServerRequest * request) { request->send(SPIFFS, "/style.css", "text/css"); @@ -613,17 +683,6 @@ const char *fetchWifiPw(const char *id) { } -enum KeyPress { KP_NONE = 0, KP_SHORT, KP_DOUBLE, KP_MID, KP_LONG }; - -struct Button { - uint8_t pin; - uint32_t numberKeyPresses; - KeyPress pressed; - unsigned long press_ts; - boolean doublepress; -}; -Button button1 = {0, 0, KP_NONE, 0, false}; - void IRAM_ATTR buttonISR() { if (digitalRead(button1.pin) == 0) { // Button down if (millis() - button1.press_ts < 500) { @@ -890,7 +949,9 @@ void loopSpectrum() { case KP_LONG: enterMode(ST_WIFISCAN); return; - case KP_DOUBLE: /* ignore */ break; + case KP_DOUBLE: + enterMode(ST_SCANNER); + break; default: break; } diff --git a/RX_FSK/data/index.html b/RX_FSK/data/index.html index 32990b4..b683b03 100644 --- a/RX_FSK/data/index.html +++ b/RX_FSK/data/index.html @@ -20,6 +20,7 @@ + @@ -47,6 +48,11 @@ +
+

Control

+ +
+

About

%VERSION_NAME%
diff --git a/libraries/SX1278FSK/SX1278FSK.cpp b/libraries/SX1278FSK/SX1278FSK.cpp index 058d8fc..c7b5e29 100644 --- a/libraries/SX1278FSK/SX1278FSK.cpp +++ b/libraries/SX1278FSK/SX1278FSK.cpp @@ -330,6 +330,7 @@ uint8_t SX1278FSK::setFrequency(float freq) { // set mode to FSK STANDBY writeRegister(REG_OP_MODE, FSK_STANDBY_MODE); + freq += sonde.config.freqofs; // manual frequency correction uint32_t frf = freq * 1.0 * (1<<19) / SX127X_CRYSTAL_FREQ; writeRegister(REG_FRF_MSB, (frf&0xff0000)>>16); @@ -533,6 +534,30 @@ int16_t SX1278FSK::getRSSI() return RSSI; } +/* +Function: Gets the current value of FEI (frequency error indication) +Returns: FEI value in Hz +*/ +int32_t SX1278FSK::getFEI() +{ + int32_t FEI; + int16_t regval = (readRegister(REG_FEI_MSB)<<8) | readRegister(REG_FEI_LSB); + Serial.printf("feireg: %04x\n", regval); + FEI = (int32_t)(regval * SX127X_FSTEP); + return FEI; +} +/* +Function: Gets the current value of AFC (automated frequency correction) +Returns: AFC value in Hz +*/ +int32_t SX1278FSK::getAFC() +{ + int32_t AFC; + int16_t regval = (readRegister(REG_AFC_MSB)<<8) | readRegister(REG_AFC_LSB); + Serial.printf("afcreg: %04x\n", regval); + AFC = (int32_t)(regval * SX127X_FSTEP); + return AFC; +} /* Function: Gets the current supply limit of the power amplifier, protecting battery chemistries. @@ -693,8 +718,13 @@ uint8_t SX1278FSK::receivePacketTimeout(uint32_t wait, byte *data) data[di++] = readRegister(REG_FIFO); if(di==1) { int rssi=getRSSI(); + int fei=getFEI(); + int afc=getAFC(); Serial.print("Test: RSSI="); Serial.println(rssi); + Serial.print("Test: FEI="); Serial.println(fei); + Serial.print("Test: AFC="); Serial.println(afc); sonde.si()->rssi = rssi; + sonde.si()->afc = afc; } if(di>520) { // TODO diff --git a/libraries/SX1278FSK/SX1278FSK.h b/libraries/SX1278FSK/SX1278FSK.h index 16d8dcb..3cb358a 100644 --- a/libraries/SX1278FSK/SX1278FSK.h +++ b/libraries/SX1278FSK/SX1278FSK.h @@ -31,6 +31,7 @@ *****************************************************************************/ #define SX127X_CRYSTAL_FREQ 32000000 +#define SX127X_FSTEP (SX127X_CRYSTAL_FREQ*1.0/(1<<19)) #define SX1278FSK_debug_mode 0 @@ -234,6 +235,12 @@ public: // Get current RSSI value int16_t getRSSI(); + // Get current FEI (frequency error indication) value + int32_t getFEI(); + + // Get current AFC value + int32_t getAFC(); + // Get the maximum current supply by the module. int getMaxCurrent(); diff --git a/libraries/SondeLib/RS41.cpp b/libraries/SondeLib/RS41.cpp index 586698a..233a5d9 100644 --- a/libraries/SondeLib/RS41.cpp +++ b/libraries/SondeLib/RS41.cpp @@ -98,11 +98,11 @@ int RS41::setup() Serial.println(br); #endif - if(sx1278.setAFCBandwidth(25000)!=0) { + if(sx1278.setAFCBandwidth(sonde.config.rs41.agcbw)!=0) { RS41_DBG(Serial.println("Setting AFC bandwidth 25 kHz FAILED")); return 1; } - if(sx1278.setRxBandwidth(12000)!=0) { + if(sx1278.setRxBandwidth(sonde.config.rs41.rxbw)!=0) { RS41_DBG(Serial.println("Setting RX bandwidth 12kHz FAILED")); return 1; } diff --git a/libraries/SondeLib/Sonde.cpp b/libraries/SondeLib/Sonde.cpp index c475cd0..dedeee5 100644 --- a/libraries/SondeLib/Sonde.cpp +++ b/libraries/SondeLib/Sonde.cpp @@ -4,8 +4,10 @@ #include "Sonde.h" #include "RS41.h" #include "DFM.h" +#include "SX1278FSK.h" extern U8X8_SSD1306_128X64_NONAME_SW_I2C *u8x8; +extern SX1278FSK sx1278; //SondeInfo si = { STYPE_RS41, 403.450, "P1234567", true, 48.1234, 14.9876, 543, 3.97, -0.5, true, 120 }; const char *sondeTypeStr[5] = { "DFM6", "DFM9", "RS41" }; @@ -74,6 +76,11 @@ Sonde::Sonde() { config.spectrum=10; config.timer=0; config.marker=0; + config.norx_timeout=0; + config.showafc=0; + config.freqofs=0; + config.rs41.agcbw=25; + config.rs41.rxbw=12; config.udpfeed.active = 1; config.udpfeed.type = 0; strcpy(config.udpfeed.host, "192.168.42.20"); @@ -135,6 +142,16 @@ void Sonde::setConfig(const char *cfg) { config.timer = atoi(val); } else if(strcmp(cfg,"marker")==0) { config.marker = atoi(val); + } else if(strcmp(cfg,"norx_timeout")==0) { + config.norx_timeout = atoi(val); + } else if(strcmp(cfg,"showafc")==0) { + config.showafc = atoi(val); + } else if(strcmp(cfg,"freqofs")==0) { + config.freqofs = atoi(val); + } else if(strcmp(cfg,"rs41.agcbw")==0) { + config.rs41.agcbw = atoi(val); + } else if(strcmp(cfg,"rs41.rxbw")==0) { + config.rs41.rxbw = atoi(val); } else if(strcmp(cfg,"axudp.active")==0) { config.udpfeed.active = atoi(val)>0; } else if(strcmp(cfg,"axudp.host")==0) { @@ -235,6 +252,11 @@ void Sonde::setup() { dfm.setFrequency(sondeList[currentSonde].freq * 1000000); break; } + // debug + float afcbw = sx1278.getAFCBandwidth(); + float rxbw = sx1278.getRxBandwidth(); + Serial.printf("AFC BW: %f RX BW: %f\n", afcbw, rxbw); + } int Sonde::receiveFrame() { int ret; @@ -317,6 +339,10 @@ void Sonde::updateDisplayRXConfig() { u8x8->drawString(0,0, sondeTypeStr[si()->type]); snprintf(buf, 16, "%3.3f MHz", si()->freq); u8x8->drawString(5,0, buf); + if(config.showafc) { + snprintf(buf, 15, " %+3.2fk", si()->afc*0.001); + u8x8->drawString(8,1,buf+strlen(buf)-8); + } //snprintf(buf, 8, "%s", si()->launchsite); //u8x8->drawString(0,5, buf); } diff --git a/libraries/SondeLib/Sonde.h b/libraries/SondeLib/Sonde.h index 9eaed1b..f35a8b8 100644 --- a/libraries/SondeLib/Sonde.h +++ b/libraries/SondeLib/Sonde.h @@ -12,6 +12,11 @@ enum RxResult { RX_OK, RX_TIMEOUT, RX_ERROR, RX_UNKNOWN }; enum SondeType { STYPE_DFM06, STYPE_DFM09, STYPE_RS41 }; extern const char *sondeTypeStr[5]; +struct st_rs41config { + int agcbw; + int rxbw; +}; + typedef struct st_rdzconfig { int button_pin; // PIN port number menu button (for some boards) int led_pout; // POUT port number of LED (used as serial monitor) @@ -27,9 +32,13 @@ typedef struct st_rdzconfig { int timer; // show remaining time in spectrum 0=disable int marker; // show freq marker in spectrum 0=disable int maxsonde; // number of max sonde in scan (range=1-99) + int norx_timeout; // Time after which rx mode switches to scan mode (without rx signal) int noisefloor; // for spectrum display + int showafc; // show afc value in rx screen + int freqofs; // frequency offset (tuner config = rx frequency + freqofs) in Hz char call[9]; // APRS callsign char passcode[9]; // APRS passcode + struct st_rs41config rs41; // configuration options specific for RS41 receiver // 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 @@ -54,6 +63,7 @@ typedef struct st_sondeinfo { uint8_t validPos; // bit pattern for validity of above 6 fields // RSSI from receiver int rssi; // signal strength + int32_t afc; // afc correction value uint8_t rxStat[20]; } SondeInfo; // rxState: 0=undef[empty] 1=timeout[.] 2=errro[E] 3=ok[1]