From 4aa452c2f2fb505a3da742fe104da2939af7a09e Mon Sep 17 00:00:00 2001 From: M0WID Date: Mon, 7 Sep 2020 19:01:14 +0100 Subject: [PATCH] RX Offset, web polling --- Bandscope.ino | 4 +-- IFsweep.ino | 4 +-- RXsweep.ino | 4 +-- SweepLo.ino | 44 ++++++++++++++++++++++++-------- data/index.html | 3 ++- my_SA.h | 3 ++- si4432.cpp | 68 ++++++++++++++++++++++++++++++++++--------------- simpleSA.h | 7 +++++ ui.cpp | 26 ++++++++++++++++--- 9 files changed, 122 insertions(+), 41 deletions(-) diff --git a/Bandscope.ino b/Bandscope.ino index 7521f93..3054841 100644 --- a/Bandscope.ino +++ b/Bandscope.ino @@ -172,7 +172,7 @@ static uint16_t chunkIndex; bandwidth = rcvr.SetRBW ( setting.BandscopeRBW10, &delaytime ); // Set it in the receiver Si4432 //Serial.printf("set rcvr Freq get:%u, tempIF:%u\n", rcvr.GetFrequency(), tempIF); - rcvr.SetFrequency ( setting.IF_Freq ); // Set the RX Si4432 to the IF frequency + rcvr.SetFrequency ( setting.IF_Freq + 1300 ); // Set the RX Si4432 to the IF frequency, offset a bit // sweepFreqStep = autoSweepFreqStep; // Step for each reading @@ -294,7 +294,7 @@ static uint16_t chunkIndex; while (( nowMicros - setFreqMicros ) < bandscopeDelay ) { - if ( ( nowMicros - setFreqMicros + delaytime > 200 ) && + if ( ( nowMicros - setFreqMicros + delaytime > MIN_DELAY_WEBSOCKETS ) && ( (nowMicros - lastWebsocketMicros > websocketInterval) || (numberOfWebsocketClients > 0) ) ) { webSocket.loop (); // Check websockets - includes Yield() to allow other tasks to run diff --git a/IFsweep.ino b/IFsweep.ino index 6a84b20..f91d843 100644 --- a/IFsweep.ino +++ b/IFsweep.ino @@ -94,7 +94,7 @@ static uint16_t chunkIndex; att.SetAtten ( 0 ); // Set the internal attenuator // pre-calculate adjustment for RSSI values - dBadjust = 120.0 + setting.LevelOffset - setting.ExternalGain; + dBadjust = -120.0 + setting.LevelOffset - setting.ExternalGain; Serial.printf("IFSweep dBadjust = %f; leveloffset = %f; attenuate = %i, ext gain = %f\n", dBadjust, setting.LevelOffset, setting.Attenuate, setting.ExternalGain); @@ -221,7 +221,7 @@ static uint16_t chunkIndex; while (( nowMicros - setFreqMicros ) < delaytime ) { - if ( ( nowMicros - setFreqMicros + delaytime > 200 ) && + if ( ( nowMicros - setFreqMicros + delaytime > MIN_DELAY_WEBSOCKETS ) && ( (nowMicros - lastWebsocketMicros > websocketInterval) || (numberOfWebsocketClients > 0) ) ) { // Serial.print("W"); diff --git a/RXsweep.ino b/RXsweep.ino index 0853cce..0116113 100644 --- a/RXsweep.ino +++ b/RXsweep.ino @@ -100,7 +100,7 @@ static uint16_t chunkIndex; att.SetAtten ( 0 ); // Set the internal attenuator // pre-calculate adjustment for RSSI values - dBadjust = 120.0 + setting.LevelOffset - setting.ExternalGain; + dBadjust = -120.0 + setting.LevelOffset - setting.ExternalGain; Serial.printf("RXSweep dBadjust = %f; leveloffset = %f; attenuate = %i, ext gain = %f\n", dBadjust, setting.LevelOffset, setting.Attenuate, setting.ExternalGain); @@ -227,7 +227,7 @@ static uint16_t chunkIndex; while (( nowMicros - setFreqMicros ) < delaytime ) { - if ( ( nowMicros - setFreqMicros + delaytime > 200 ) && + if ( ( nowMicros - setFreqMicros + delaytime > MIN_DELAY_WEBSOCKETS ) && ( (nowMicros - lastWebsocketMicros > websocketInterval) || (numberOfWebsocketClients > 0) ) ) { // Serial.print("W"); diff --git a/SweepLo.ino b/SweepLo.ino index ef9c9d9..722a72e 100644 --- a/SweepLo.ino +++ b/SweepLo.ino @@ -52,6 +52,8 @@ static uint32_t pointMaxFreq; // record frequency where maximum occurred static int16_t lastMode; // Record last operating mode (sig gen, normal) static uint32_t lastIF; static bool spurToggle; +static uint32_t actualFreq; // actual frequency +static uint32_t actualIF; // actual IF (Rx frequency) static uint16_t currentPointRSSI; static uint16_t peakRSSI; @@ -91,7 +93,7 @@ static uint32_t offsetIF; // IF frequency offset by half the bandwidth to pos { if ( initSweep || changedSetting ) // Something has changed, or a first start, so need to owrk out some basic things { - Serial.println("InitSweep or changedSetting"); + //Serial.println("InitSweep or changedSetting"); autoSweepFreqStep = ( setting.ScanStop - setting.ScanStart ) / displayPoints; vbw = autoSweepFreqStep / 1000.0; // Set the video resolution @@ -115,8 +117,10 @@ static uint32_t offsetIF; // IF frequency offset by half the bandwidth to pos /* * The FIR filters in the SI4432 are centred above the nominal IF frequency as that is where the signals are meant to be. * To make sure we are not on the edge of the filters offset the IF frequency down by half the bandwidth + * This needs to be optimised ********* */ - offsetIF = setting.IF_Freq - setting.Bandwidth10 * 50; // bW10 is in kHz * 10, so * 100-> kHz, halved +// offsetIF = setting.IF_Freq + setting.Bandwidth10 * 50; // bW10 is in kHz * 10, so * 100-> kHz, halved + offsetIF = setting.IF_Freq + RX_PASSBAND_OFFSET; // half of narrowest RBW /* * Need multiple readings for each pixel in the display to avoid missing signals. @@ -139,8 +143,8 @@ static uint32_t offsetIF; // IF frequency offset by half the bandwidth to pos // pre-calculate adjustment for RSSI values dBadjust = (double)setting.Attenuate - 120.0 + setting.LevelOffset - setting.ExternalGain; - Serial.printf("SweepLo dBadjust = %f; leveloffset = %f; attenuate = %i, ext gain = %f\n", - dBadjust, setting.LevelOffset, setting.Attenuate, setting.ExternalGain); + //Serial.printf("SweepLo dBadjust = %f; leveloffset = %f; attenuate = %i, ext gain = %f\n", + // dBadjust, setting.LevelOffset, setting.Attenuate, setting.ExternalGain); resetAverage = changedSetting; @@ -217,6 +221,7 @@ static uint32_t offsetIF; // IF frequency offset by half the bandwidth to pos //Serial.printf("set rcvr Freq get:%u, tempIF:%u\n", rcvr.GetFrequency(), tempIF); rcvr.SetFrequency ( tempIF ); // Set the RX Si4432 to the IF frequency lastIF = tempIF; + actualIF = rcvr.GetFrequency(); #ifdef SI_TG_IF_CS if (tgIF_OK && (trackGenSetting.Mode == 1) ) @@ -236,6 +241,10 @@ static uint32_t offsetIF; // IF frequency offset by half the bandwidth to pos // if (trackGenSetting.Mode == 1) // debug // Serial.printf("tglo start %i at %i\n", tg_lo.GetFrequency(), setFreqMicros); + /* + * Actual frequency in the SI4432 is rounded and is limited by the possible resolution + */ + actualFreq = xmit.GetFrequency() - actualIF + RX_PASSBAND_OFFSET; // Used for next RSSI command and JSON entry #ifdef USE_WIFI @@ -308,6 +317,8 @@ static uint32_t offsetIF; // IF frequency offset by half the bandwidth to pos lastSweepStartMicros = sweepStartMicros; // Set last time we got here sweepStartMicros = micros(); // Current time sweepMicros = sweepStartMicros - lastSweepStartMicros; // Calculate sweep time (no rollover handling) + + } // End of "if ( !sweepStartDone ) || initSweep || changedSetting )" @@ -319,18 +330,21 @@ static uint32_t offsetIF; // IF frequency offset by half the bandwidth to pos */ uint16_t oldSweepStep = autoSweepStep; - uint32_t oldSweepFreq = autoSweepFreq; + uint32_t oldSweepFreq = actualFreq; /* - * Wait until time to take the next reading. If a long wait then check the touchscreen - * and Websockets while we are waiting to improve response + * Wait until time to take the next reading. If a long enough wait left + * then check the touchscreen and Websockets while we are waiting + * to improve response */ + + nowMicros = micros(); while (( nowMicros - setFreqMicros ) < delaytime ) { - if ( ( nowMicros - setFreqMicros + delaytime > 200 ) && + if ( ( nowMicros - setFreqMicros + delaytime > MIN_DELAY_WEBSOCKETS ) && ( (nowMicros - lastWebsocketMicros > websocketInterval) || (numberOfWebsocketClients > 0) ) ) { // Serial.print("W"); @@ -360,8 +374,11 @@ static uint32_t offsetIF; // IF frequency offset by half the bandwidth to pos { // Serial.printf ( "%s\t%03d\n", // FormatFrequency ( autoSweepFreq) , rxRSSI ); // Send it to the serial output - Serial.printf ( "Freq: %s - RSSI: %03d\n", - FormatFrequency ( autoSweepFreq) , rxRSSI ); // Send it to the serial output + Serial.printf ( "Actual IF: %s", FormatFrequency ( rcvr.GetFrequency() ) ); + Serial.printf ( " LO Freq: %s", FormatFrequency ( xmit.GetFrequency() ) ); + Serial.printf ( " Sweep Freq: %s", FormatFrequency ( autoSweepFreq) ); + Serial.printf ( " Actual Freq %s - RSSI: %03d\n", + FormatFrequency ( actualFreq ), rxRSSI ); // Send it to the serial output } if ( (numberOfWebsocketClients > 0) || (setting.ShowGain) ) @@ -388,6 +405,7 @@ static uint32_t offsetIF; // IF frequency offset by half the bandwidth to pos #endif setFreqMicros = micros(); // Store the time the LO frequency was changed + #ifdef SI_TG_LO_CS // if (trackGenSetting.Mode == 1) // Serial.printf("tglo %i @ %i\n", tg_lo.GetFrequency(), setFreqMicros); @@ -442,6 +460,11 @@ static uint32_t offsetIF; // IF frequency offset by half the bandwidth to pos } } +/* + * Actual frequency in the SI4432 is rounded and is limited by the possible resolution + */ + actualFreq = xmit.GetFrequency() - actualIF + RX_PASSBAND_OFFSET; // Used for next RSSI command and JSON entry + #endif // #ifdef USE_WIFI if ( rxRSSI > pointMaxRSSI ) // RSSI > maximum value for this point so far? @@ -658,6 +681,7 @@ static uint32_t offsetIF; // IF frequency offset by half the bandwidth to pos if (( numberOfWebsocketClients > 0) && jsonDocInitialised && (chunkIndex > 0) ) { + String wsBuffer; if (wsBuffer) diff --git a/data/index.html b/data/index.html index 72a02e2..9bc51c1 100644 --- a/data/index.html +++ b/data/index.html @@ -675,8 +675,9 @@ var dateObject; */ function renderChart() { + setTimeout(function(){renderChart()}, refreshInterval.value); chartSA.render(); - setTimeout(renderChart, refreshInterval.value); + //setTimeout(renderChart, refreshInterval.value); } diff --git a/my_SA.h b/my_SA.h index 2161645..d5d28f2 100644 --- a/my_SA.h +++ b/my_SA.h @@ -30,7 +30,7 @@ #define WIFI_PASSWORD "S0ftR0ckRXTX" // Password for your WiFi - #define MAX_WIFI_POINTS 150 // Number of sample points to send to clients in each wifi chunk + #define MAX_WIFI_POINTS 75 // was 150 Number of sample points to send to clients in each wifi chunk // Some clients cannot handle too few (too frequent chart refresh) // ** IMPORTANT ** Must be less than or equal to DISPLAY_POINTS (290) @@ -218,6 +218,7 @@ #define TG_LO_CAPACITANCE 0x64 // Tracking generator LO crystal load capacitance #define TG_IF_CAPACITANCE 0x62 // Tracking generator IF crystal load capacitance + #define RX_PASSBAND_OFFSET 1300 // RX bandpass filters are offset from nominal IF by this /* * "CAL_POWER" is the calibrated power level determined when doing the calibration diff --git a/si4432.cpp b/si4432.cpp index 4e640ae..abeaf62 100644 --- a/si4432.cpp +++ b/si4432.cpp @@ -31,29 +31,57 @@ bandpassFilter_t Si4432::_bandpassFilters[] { 32, 6600, 0, 5, 4 }, // 3 "AUTO" selection possibility { 37, 6600, 0, 5, 5 }, // 4 "AUTO" selection possibility { 42, 6600, 0, 5, 6 }, // 5 "AUTO" selection possibility - { 45, 5500, 0, 5, 7 }, // 6 "AUTO" selection possibility + { 45, 6600, 0, 5, 7 }, // 6 "AUTO" selection possibility { 49, 5000, 0, 4, 1 }, // 7 "AUTO" selection possibility { 54, 4200, 0, 4, 2 }, // 8 "AUTO" selection possibility { 59, 3700, 0, 4, 3 }, // 9 "AUTO" selection possibility - { 72, 3300, 0, 4, 5 }, // 10 "AUTO" selection possibility - { 106, 2500, 0, 3, 2 }, // 11 If user selects 10KHz -> 10.6KHz actual - { 162, 2000, 0, 3, 6 }, // 12 "AUTO" selection possibility - { 210, 1600, 0, 2, 2 }, // 13 "AUTO" selection possibility - { 227, 1500, 0, 2, 3 }, // 14 "AUTO" selection possibility - { 240, 1400, 0, 2, 4 }, // 15 "AUTO" selection possibility - { 282, 1000, 0, 2, 5 }, // 16 "AUTO" selection possibility - { 322, 1000, 0, 2, 6 }, // 17 If user selects 30KHz -> 32.2KHz actual - { 377, 1000, 0, 1, 1 }, // 18 "AUTO" selection possibility - { 562, 700, 0, 1, 5 }, // 19 "AUTO" selection possibility - { 832, 600, 0, 0, 2 }, // 20 "AUTO" selection possibility - { 1121, 500, 0, 0, 5 }, // 21 If user selects 100KHz -> 112.1KHz actual - { 1811, 500, 1, 1, 9 }, // 22 "AUTO" selection possibility - { 2251, 1400, 1, 0, 1 }, // 23 "AUTO" selection possibility - { 2488, 450, 1, 0, 2 }, // 24 "AUTO" selection possibility - { 3355, 400, 1, 0, 8 }, // 25 If user selects 300KHz -> 335.5KHz actual - { 3618, 300, 1, 0, 9 }, // 26 "AUTO" selection possibility - { 4685, 300, 1, 0, 11 }, // 27 "AUTO" selection possibility - { 6207, 300, 1, 0, 14 } // 28 "AUTO" selection possibility + { 61, 3500, 0, 4, 4 }, // 10 "AUTO" selection possibility + { 72, 3300, 0, 4, 5 }, // 11 "AUTO" selection possibility + { 82, 3300, 0, 4, 6 }, // 12 "AUTO" selection possibility + { 88, 3300, 0, 4, 7 }, // 13 "AUTO" selection possibility + { 95, 3300, 0, 3, 1 }, // 14 "AUTO" selection possibility + { 106, 2500, 0, 3, 2 }, // 15 If user selects 10KHz -> 10.6KHz actual + { 115, 2500, 0, 3, 3 }, // 16 "AUTO" selection possibility + { 121, 2500, 0, 3, 4 }, // 17 "AUTO" selection possibility + { 142, 2500, 0, 3, 5 }, // 18 "AUTO" selection possibility + { 162, 2000, 0, 3, 6 }, // 19 "AUTO" selection possibility + { 175, 2000, 0, 3, 7 }, // 20 "AUTO" selection possibility + { 189, 1600, 0, 2, 1 }, // 21 "AUTO" selection possibility + { 210, 1600, 0, 2, 2 }, // 22 "AUTO" selection possibility + { 227, 1500, 0, 2, 3 }, // 23 "AUTO" selection possibility + { 240, 1400, 0, 2, 4 }, // 24 "AUTO" selection possibility + { 282, 1000, 0, 2, 5 }, // 25 "AUTO" selection possibility + { 322, 1000, 0, 2, 6 }, // 26 If user selects 30KHz -> 32.2KHz actual + { 347, 1000, 0, 2, 7 }, // 27 "AUTO" selection possibility + { 377, 1000, 0, 1, 1 }, // 28 "AUTO" selection possibility + { 417, 1000, 0, 1, 2 }, // 29 "AUTO" selection possibility + { 452, 1000, 0, 1, 3 }, // 30 "AUTO" selection possibility + { 479, 1000, 0, 1, 4 }, // 31 "AUTO" selection possibility + { 562, 700, 0, 1, 5 }, // 32 "AUTO" selection possibility + { 641, 700, 0, 1, 6 }, // 33 "AUTO" selection possibility + { 692, 700, 0, 1, 7 }, // 34 "AUTO" selection possibility + { 752, 700, 0, 0, 1 }, // 35 "AUTO" selection possibility + { 832, 600, 0, 0, 2 }, // 36 "AUTO" selection possibility + { 900, 600, 0, 0, 3 }, // 37 "AUTO" selection possibility + { 953, 600, 0, 0, 4 }, // 38 "AUTO" selection possibility + { 1121, 500, 0, 0, 5 }, // 39 If user selects 100KHz -> 112.1KHz actual + { 1279, 600, 0, 0, 6 }, // 40 "AUTO" selection possibility + { 1379, 600, 0, 0, 7 }, // 41 "AUTO" selection possibility + { 1428, 600, 1, 1, 4 }, // 42 "AUTO" selection possibility + { 1678, 600, 1, 1, 5 }, // 43 "AUTO" selection possibility + { 1811, 500, 1, 1, 9 }, // 44 "AUTO" selection possibility + { 1915, 500, 1, 1, 15 }, // 45 "AUTO" selection possibility + { 2251, 500, 1, 0, 1 }, // 46 "AUTO" selection possibility + { 2488, 450, 1, 0, 2 }, // 47 "AUTO" selection possibility + { 2693, 450, 1, 0, 3 }, // 48 "AUTO" selection possibility + { 2849, 450, 1, 0, 4 }, // 49 "AUTO" selection possibility + { 3355, 400, 1, 0, 8 }, // 50 If user selects 300KHz -> 335.5KHz actual + { 3618, 300, 1, 0, 9 }, // 51 "AUTO" selection possibility + { 4202, 300, 1, 0, 10 }, // 52 "AUTO" selection possibility + { 4684, 300, 1, 0, 11 }, // 53 "AUTO" selection possibility + { 5188, 300, 1, 0, 12 }, // 54 "AUTO" selection possibility + { 5770, 300, 1, 0, 13 }, // 55 "AUTO" selection possibility + { 6207, 300, 1, 0, 14 } // 56 "AUTO" selection possibility }; diff --git a/simpleSA.h b/simpleSA.h index 675a4e5..826ff26 100644 --- a/simpleSA.h +++ b/simpleSA.h @@ -140,6 +140,13 @@ */ #define OVERLAP 1.1 +/* + * Minimum delay left for the websockets to be checked while waiting + * for the SI4432 filters to settle + * Webocket.loop() takes around 35microseconds, varies a bit + */ + + #define MIN_DELAY_WEBSOCKETS 50 /* * These are the minimum and maximum values for the "IF Frequency". In reality, testing has diff --git a/ui.cpp b/ui.cpp index 47809e8..2f031ee 100644 --- a/ui.cpp +++ b/ui.cpp @@ -198,7 +198,8 @@ enum { KM_START, KM_STOP, KM_CENTER, KM_SPAN, KM_FOCUS, KM_REFPOS, KM_ATTENUATION, KM_ACTUALPOWER, KM_IFFREQ, KM_PREAMP, KM_TUNE, KM_SGFREQ, KM_SGLEVEL, KM_SGLEVCAL, KM_IFSTART, KM_IFSTOP, KM_IFSIG, KM_TGOFFSET, KM_TGLO_DRIVE, KM_TGIF_DRIVE, KM_BANDSCOPESTART, - KM_WFMIN, KM_WFGAIN, KM_BANDSCOPELEVEL, KM_RXSPAN, KM_RXSIG, KM_RBW }; + KM_WFMIN, KM_WFGAIN, KM_BANDSCOPELEVEL, KM_RXSPAN, KM_RXSIG, KM_RBW, + KM_EXTERN }; /* @@ -216,7 +217,8 @@ static const char * const keypad_mode_label[] = "REFPOS", "ATTEN", "POWER", "IF FREQ", "PREAMP", "XTAL CAL", "SG FREQ", "dBm", "Max dBm", "IF START", "IF STOP", "IF Sig Freq", "TG OFFSET", "TG LO Drive", "TG IF Drive", "START", - "WF MIN", "WF GAIN", "REF LEVEL", "RX SPAN", "RX Sig Freq", "RBW" + "WF MIN", "WF GAIN", "REF LEVEL", "RX SPAN", "RX Sig Freq", "RBW", + "EXTERNAL" }; @@ -306,6 +308,8 @@ static void menu_sig_levCal_cb ( int item ); // M0WID - Added in Version 3.0a static void menu_sig_level_cb ( int item ); // M0WID - Added in Version 3.0b static void menu_atten_cb ( int item ); // WA2FZW - Added in Version 2.6 static void menu_touch_cb ( int item ); // WA2FZW - Added in Version 2.6 +static void menu_extern_cb ( int item ); // M0WID - added + static void KeyNumber ( int8_t key, int x, int y ); // WA2FZW - Added in Version 2.7 static void menu_tune_cb ( int item ); // WA2FZW - Added in Version 2.7 @@ -658,6 +662,7 @@ static Menuitem menu_sweep2[] = { Menuitem ( MT_MENU, "RBW", menu_rbw ), // Set the resolution bandwidth Menuitem ( MT_FUNC, "ATTEN", menu_atten_cb ), // Set the attenuation + Menuitem ( MT_FUNC, "EXTERN", menu_extern_cb ), // Set the external gain Menuitem ( MT_MENU, "MARKERS", menu_markers ), // Marker sub menu Menuitem ( MT_BACK, "<-BACK" ), // Next level up Menuitem ( MT_END ) // End marker @@ -1800,6 +1805,12 @@ static void menu_RX_sweep_cb ( int item ) ui_process_keypad (); } +static void menu_extern_cb ( int item ) +{ + int km = KM_EXTERN; + ui_mode_keypad ( km ); + ui_process_keypad (); +} /* @@ -2129,7 +2140,8 @@ static const keypads_t * const keypads_mode_tbl[] = keypads_level, // KM_BANDSCOPELEVEL.Grid reference level keypads_freq, // KM_RXSPAN.........RX Sweep span frequency keypads_freq, // KM_RXSIG..........RX Sweep signal frequency - keypads_freq // KM_RBW............RX Sweep RBW + keypads_freq, // KM_RBW............RX Sweep RBW + keypads_level // KM_EXTERN.........External gain }; @@ -2545,6 +2557,10 @@ static void fetch_numeric_target ( void ) uistat.value = (double)setting.Bandwidth10 / 10.0; break; + case KM_EXTERN: + uistat.value = setting.ExternalGain; + break; + } uint32_t x = uistat.value; @@ -3005,6 +3021,10 @@ static int keypad_click ( int key ) SetRBW (( int32_t ) (value * 10) ); break; + case KM_EXTERN: + SetExtGain ( value ); + break; + } // End of "switch" return KP_DONE; // Indicate finished with the keypad