From 994a26740d80466fac19a8978cd1fefc44c57e8b Mon Sep 17 00:00:00 2001 From: M0WID Date: Wed, 2 Sep 2020 23:22:08 +0100 Subject: [PATCH] TrackGen on/off for web Also RBW fixes - again :( Turn off track gen when going to IF/RX Sweep modes External gain/attenuation added to settings, with web/console commands. menu command still to do --- Bandscope.ino | 2 +- IFsweep.ino | 22 ++++++-------- RXsweep.ino | 14 +++++++-- SweepLo.ino | 22 +++++++------- cmd.cpp | 64 +++++++++++++++++++++++++++++++++++++++- cmd.h | 5 ++++ data/index.html | 49 ++++++++++++++++++++++++++++--- si4432.cpp | 4 +-- simpleSA.h | 1 + simpleSA.ino | 11 +++---- simpleSA_wifi.cpp | 74 +++++++++++++++++++++++++++++++++++++++++++++-- 11 files changed, 227 insertions(+), 41 deletions(-) diff --git a/Bandscope.ino b/Bandscope.ino index 5ee0bf5..7a23125 100644 --- a/Bandscope.ino +++ b/Bandscope.ino @@ -63,7 +63,7 @@ void initBandscope() old_settingMin = -1; old_startFreq = -1; old_stopFreq = -1; - old_ownrbw = -1; + old_requiredRBW10 = -1; old_vbw = -1; old_settingAverage = -1; old_settingSpur = -100; diff --git a/IFsweep.ino b/IFsweep.ino index 0aecf39..263d51c 100644 --- a/IFsweep.ino +++ b/IFsweep.ino @@ -24,6 +24,15 @@ void initIF_Sweep() tinySA_mode = IF_SWEEP; setting.Mode = tinySA_mode; +// Turn off track gen +#ifdef SI_TG_IF_CS + tg_if.RxMode(); +#endif + +#ifdef SI_TG_LO_CS + tg_lo.RxMode(); +#endif + ResetIFsweepMenuStack(); // Put menu stack back to root level } @@ -75,19 +84,6 @@ static uint16_t chunkIndex; autoSweepFreqStep = ( stopFreq_IF - startFreq_IF ) / displayPoints; vbw = autoSweepFreqStep / 1000.0; // Set the video resolution -// ownrbw = ((float) ( stopFreq_IF - startFreq_IF )) / displayPoints / 1000.0; // kHz -// -// if ( ownrbw < 2.6 ) // If it's less than 2.6KHz -// ownrbw = 2.6; // set it to 2.6KHz -// -// if ( ownrbw > 620.7 ) -// ownrbw = 620.7; -// -// if ( ownrbw != old_ownrbw ) -// { -// bandwidth = rcvr.SetRBW ( ownrbw * 10.0, &delaytime ); // Set it in the receiver Si4432 -// old_ownrbw = ownrbw; -// } bandwidth = rcvr.SetRBW ( 106.0, &delaytime ); // Set it in the receiver Si4432. delaytime is returned diff --git a/RXsweep.ino b/RXsweep.ino index 2857202..7fbd054 100644 --- a/RXsweep.ino +++ b/RXsweep.ino @@ -26,6 +26,16 @@ void initRX_Sweep() tinySA_mode = RX_SWEEP; setting.Mode = tinySA_mode; +// Turn off track gen +#ifdef SI_TG_IF_CS + tg_if.RxMode(); +#endif + +#ifdef SI_TG_LO_CS + tg_lo.RxMode(); +#endif + + ResetRXsweepMenuStack(); // Put menu stack back to root level } @@ -104,7 +114,7 @@ static uint16_t chunkIndex; wiFiPoints = displayPoints*OVERLAP; // Serial.printf("No of wifiPoints set to %i\n", wiFiPoints); - pushIFSweepSettings(); + pushRXSweepSettings(); #endif // #ifdef USE_WIFI @@ -136,7 +146,7 @@ static uint16_t chunkIndex; jsonDocument.clear (); chunkIndex = 0; - jsonDocument["PreAmp"] = setting.PreampGain; // Fixed gain + jsonDocument["PreAmp"] = setting.PreampGain; jsonDocument["mType"] = "chunkSweep"; jsonDocument["StartIndex"] = 0; jsonDocument["sweepPoints"] = sweepPoints; diff --git a/SweepLo.ino b/SweepLo.ino index cc67e7e..7d6fe7b 100644 --- a/SweepLo.ino +++ b/SweepLo.ino @@ -95,21 +95,21 @@ static uint32_t offsetIF; // IF frequency offset by half the bandwidth to pos autoSweepFreqStep = ( setting.ScanStop - setting.ScanStart ) / displayPoints; vbw = autoSweepFreqStep / 1000.0; // Set the video resolution - ownrbw = setting.Bandwidth10 / 10.0; // and the resolution bandwidth + requiredRBW10 = setting.Bandwidth10; // and the resolution bandwidth - if ( ownrbw == 0.0 ) // If the bandwidth is on "Auto" work out the required RBW - ownrbw = ((float) ( setting.ScanStop - setting.ScanStart )) / 290000.0; // 290 points on display + if ( requiredRBW10 == 0 ) // If the bandwidth is on "Auto" work out the required RBW + requiredRBW10 = (( setting.ScanStop - setting.ScanStart )) / 29000; // 290 points on display, kHz - if ( ownrbw < 2.6 ) // If it's less than 2.6KHz - ownrbw = 2.6; // set it to 2.6KHz + if ( requiredRBW10 < 26 ) // If it's less than 2.6KHz + requiredRBW10 = 26; // set it to 2.6KHz - if ( ownrbw > 620.7 ) - ownrbw = 620.7; + if ( requiredRBW10 > 6207 ) + requiredRBW10 = 6207; - if ( ownrbw != old_ownrbw ) + if ( requiredRBW10 != old_requiredRBW10 ) { - bandwidth = rcvr.SetRBW ( ownrbw * 10.0, &delaytime ); // Set it in the receiver Si4432 - old_ownrbw = ownrbw; + bandwidth = rcvr.SetRBW ( requiredRBW10, &delaytime ); // Set it in the receiver Si4432 + old_requiredRBW10 = requiredRBW10; } /* @@ -190,7 +190,7 @@ static uint32_t offsetIF; // IF frequency offset by half the bandwidth to pos * How well this works depends on how flat the SAW filter (and SI4432 filter) response is */ if (setting.Spur && spurToggle) { - uint32_t IF_Shift = ownrbw * 1000; // bandwidth in Hz + uint32_t IF_Shift = requiredRBW10 * 100; // bandwidth in Hz if (IF_Shift > MAX_IF_SHIFT) IF_Shift = MAX_IF_SHIFT; tempIF = offsetIF - IF_Shift; diff --git a/cmd.cpp b/cmd.cpp index 4f1a0f6..39d6632 100644 --- a/cmd.cpp +++ b/cmd.cpp @@ -182,6 +182,7 @@ extern uint8_t dBmToRSSI ( double dBm ); { "WFGAIN", MSG_WFGAIN }, // Gain for waterfall colours { "RXSWEEP", MSG_RX_SWEEP }, // Set RX Sweep Mode { "RXSIGNAL", MSG_RXSIGNAL }, // IF sweep signal frequency + { "EXTGAIN", MSG_EXTGAIN }, // External gain or attenuation { "", MSG_NONE } // Unrecognized command }; @@ -219,6 +220,9 @@ void ShowMenu () Serial.printf ( " ATTEN.........Set or get the attenuator setting; currently: %ddB\n", setting.Attenuate ); + Serial.printf ( " EXTGAIN.......Set or get the external gain setting; currently: %ddB\n", + setting.ExternalGain ); + Serial.printf ( " SPUR......... Turn Spur Reduction 'ON' or 'OFF'; currently: %s\n", setting.Spur ? "ON" : "OFF" ); @@ -1679,6 +1683,21 @@ uint8_t reg69; // Ditto } Serial.printf ( "RX Sweep Signal frequency: %s\n", FormatFrequency ( GetRXsweepSigFreq() )); return true; + +/* + * Set external gain or attenuation + */ + case MSG_EXTGAIN: + if ( dataLen != 0 ) // Value specified? + { + tempFloat = atof ( dataBuff ); // Yes + SetExtGain( tempFloat ); + DisplayInfo (); // Re display the scan + } + + Serial.printf ( "External gain: %4.1f\n", setting.ExternalGain ); + return true; + default: @@ -2113,6 +2132,7 @@ int oldG = setting.Generate; /* * "SetTracking" - sets the Tracking Generator Mode + * 0 = off, 1 = track, 2 = sig gen */ void SetTracking ( int8_t m ) @@ -2125,6 +2145,8 @@ int oldM = trackGenSetting.Mode; { changedSetting = true; WriteTrackGenSettings (); + pushSettings (); +// Serial.println("SetTracking - pushSettings"); } } @@ -2201,6 +2223,21 @@ int oldAtten = setting.Attenuate; } +/* + * Set the external gain value + * +ve for gain, -ve for attenuation + */ +void SetExtGain ( double a ) +{ + setting.ExternalGain = a; +} + +double GetExtGain (void ) +{ + return setting.ExternalGain; +} + + /* * "SetStorage" - Saves the results of a scan for comparison to an active one. */ @@ -2274,6 +2311,7 @@ int oldOffset = setting.LevelOffset; changedSetting = true; RedrawHisto (); // Redraw labels and restart sweep with new settings WriteSettings (); + pushSettings(); } } @@ -2297,7 +2335,7 @@ int16_t tempBw; setting.Bandwidth10 = bw; - bandwidth = rcvr.SetRBW ( tempBw, &delaytime ); +// bandwidth = rcvr.SetRBW ( tempBw, &delaytime ); // Not needed as will be done at start of sweep RedrawHisto (); // Redraw labels and restart sweep with new settings if ( setting.Bandwidth10 != oldRBW ) @@ -2385,6 +2423,7 @@ int oldLevel = setting.Drive; { changedSetting = true; WriteSettings (); + pushSettings (); } } } @@ -2525,11 +2564,34 @@ int oldLevel = trackGenSetting.IF_Drive; { changedSetting = true; WriteTrackGenSettings (); + pushSettings (); } } } #endif + +void SetTGPower ( int16_t dBm ) +{ + // Add algorithm to set attenuator and IF drive level + // initially limit to just set drive levels + // TG Output = IF output - mixer loss - attenuator pads + int16_t pathLoss = 10; //6.9 mixer + 3 pad; + int16_t maxOut = 20 - pathLoss; + int16_t minOut = 1 - pathLoss; + + if (dBm > maxOut) + dBm = maxOut; + if (dBm < minOut) + dBm = minOut; + + uint8_t level = ( dBm + pathLoss + 1 ) / 3; + Serial.printf("Set TG power - req dBm %i - level set to %i\n", dBm, level); + + trackGenSetting.Power = dBm; // saved in SetTGIFDrive + SetTGIfDrive ( level ); +} + /* * Set Tracking generator IF offset from main SA IF * Ideally TG IF should be outside bandwidth of main RX diff --git a/cmd.h b/cmd.h index 1b90a97..5b47225 100644 --- a/cmd.h +++ b/cmd.h @@ -77,6 +77,7 @@ #define MSG_WFGAIN 48 // set the gain for waterfall colouring #define MSG_RX_SWEEP 49 // Set the RX Sweep Mode #define MSG_RXSIGNAL 50 // Set frequency of injected signal for IF Sweep +#define MSG_EXTGAIN 51 // Set external gain or attenuation #define MSG_COLOURTEST 99 // test of waterfall colours - remove this when done! @@ -146,9 +147,13 @@ void SetTGLoDrive ( uint8_t level ); // set tracking generator drive void SetTGIfDrive ( uint8_t level ); bool SetTGOffset ( int32_t offset); // set tracking generator offset - returns false if invalid int32_t GetTGOffset (void ); +void SetTGPower ( int16_t dBm ); // Set TG attenuator and drive levels void SetAttenuation ( int a ); // Sets the PE4302 attenuation +void SetExtGain ( double a ); // Sets the external gain or attenuation +double GetExtGain (void ); + void SetStorage ( void ); // Saves the results of a scan void SetClearStorage ( void ); // Logically erases the saved scan void SetSubtractStorage(void); // Sets the "setting.SubtractStorage" flag diff --git a/data/index.html b/data/index.html index b408327..908d9d3 100644 --- a/data/index.html +++ b/data/index.html @@ -140,7 +140,16 @@
-
+
+
+ + + + dBm +
+
+
+
@@ -271,6 +280,9 @@ var setDrive = document.getElementById('setLODrive'); var setIF = document.getElementById('setIF'); var setPreAmp = document.getElementById('setPreAmp'); var setAverage = document.getElementById('Average'); +var setTrackGen = document.getElementById('trackGen'); +var setTrackGenPower = document.getElementById('setTrackGenPower'); + //var messageWindow = document.getElementById('message'); var tempCenter; @@ -288,6 +300,8 @@ var oldIF = 0; var oldPreAmp = 0; var oldSweepPoints = 0; var oldSpur = 2; +var oldTrackGen = 2; +var oldTrackGenPower = 1000; // Chart configuration - Scope var RSSISamples = [ @@ -479,6 +493,15 @@ setSpur.addEventListener('change', (event) => { } }); +setTrackGen.addEventListener('change', (event) => { + if (setTrackGen.checked) { + sendValue("t", 1); + } else { + sendValue("t", 0); + } +}); + + //var roundtripTime = document.getElementById('roundtripTime'); //var messageCount = document.getElementById('messageCount'); //var missedReplies = document.getElementById('missedReplies'); @@ -594,6 +617,21 @@ function handleSettings (settings) oldSpur = settings.spur; } + if (settings.tg != oldTrackGen) { + if (settings.tg) { + setTrackGen.checked = true; // Tracking Generator checkbox + } else { + setTrackGen.checked = false; // Tracking Generator checkbox + } + oldTrackGen = settings.tg; + } + + if (settings.tgPower != oldTrackGenPower) { + setTrackGenPower.value = settings.tgPower; + oldTrackGenPower = settings.tgPower; + } + + chartSA.options.axisX.minimum = setStart.value; chartSA.options.axisX.maximum = setStop.value; @@ -1012,15 +1050,18 @@ function sendValue(c, val) // a start freq (MHz) // b stop frequency // c centre frequency + // s Span // d Local Oscillator Drive // g PreAmpGain/Mode - // w sweep width (stop - start) + // p set actual power to peak value // i IF frequency - // R requested RBW // o RefOut // A internal attenuation (PE4302) // E external gain ( eg attenuator(-ve) or preamp(+ve) ) - // p set actual power to peak value + // R requested RBW + // S Spur reduction Off/On + // t trackGen Off/On/Fixed + // T trackGen output level // //connection.send("# " + messageCounter + " " + sampleThreshold + " " + sampleSize); connection.send("#" + c + " " + val); diff --git a/si4432.cpp b/si4432.cpp index 461cd29..4e640ae 100644 --- a/si4432.cpp +++ b/si4432.cpp @@ -558,7 +558,7 @@ float Si4432::SetRBW ( float reqBandwidth10, unsigned long* delaytime_p ) // "re if ( reqBandwidth10 <= _bandpassFilters[0].bandwidth10 ) { filter = 0; - Serial.print ("Minimum RBW"); +// Serial.print ("Minimum RBW"); } /* @@ -569,7 +569,7 @@ float Si4432::SetRBW ( float reqBandwidth10, unsigned long* delaytime_p ) // "re while (( _bandpassFilters[filter-1].bandwidth10 > reqBandwidth10 - 0.01 ) && ( filter > 0 )) filter--; - Serial.printf ( "Required = %f, filter = %i\n", reqBandwidth10, filter); Serial.println ( filter ); +// Serial.printf ( "Required = %f, filter = %i\n", reqBandwidth10, filter); Serial.println ( filter ); /* diff --git a/simpleSA.h b/simpleSA.h index 9dc31e0..f433b54 100644 --- a/simpleSA.h +++ b/simpleSA.h @@ -231,6 +231,7 @@ typedef struct { int16_t MaxGrid = -10; // Default dB for top line of graph (***) int16_t MinGrid = -110; // Default dB for bottom line of graph (***) int8_t Attenuate = 0; // Attenuator setting (***) + double ExternalGain = 0.0; // External gain or attenuation int8_t Generate = 0; // Signal generator mode if not zero (***) int16_t Bandwidth10 = 0; // Resolution Bandwidth setting*10; 0 = auto int16_t LevelOffset = 0; // Calibration value (move to config?) diff --git a/simpleSA.ino b/simpleSA.ino index 349cf42..fdafcc8 100644 --- a/simpleSA.ino +++ b/simpleSA.ino @@ -130,7 +130,7 @@ * renamed simpleSA. Doesn't seem that simple to me! * First go at bandscope mode * VSPI reduced to 10Mhz as some boards will not run at 16MHz - * Put onto github - lets see how it works! + * Put onto github - lets see how it works! Version numbering changed - still in beta! * */ @@ -427,6 +427,7 @@ extern void ShowSplash ( void ); // Displays the splash screen extern void pushSettings (); extern void pushIFSweepSettings (); +extern void pushRXSweepSettings (); extern void pushBandscopeSettings (); @@ -488,8 +489,8 @@ static int old_settingMax = -1; static int old_settingMin = -1; static double old_startFreq = -1; static double old_stopFreq = -1; -static int ownrbw = 0; -static int old_ownrbw = -1; +static int requiredRBW10 = 0; +static int old_requiredRBW10 = -1; static int vbw = 0; static int old_vbw = -1; static int old_settingAverage = -1; @@ -1081,7 +1082,7 @@ void init_sweep() old_settingMin = -1; old_startFreq = -1; old_stopFreq = -1; - old_ownrbw = -1; + old_requiredRBW10 = -1; old_vbw = -1; old_settingAverage = -1; old_settingSpur = -100; @@ -1495,7 +1496,7 @@ double fStop; sSprite.printf ( "Attn\n%4i", setting.Attenuate ); sSprite.setCursor ( 0, HALF_CHAR_H * 28 ); // Start at top-left corner - sSprite.printf ( "Ext\n%4.1f", 0.0 ); // Place holder for external gain/attenuation value + sSprite.printf ( "Ext\n%4.1f", setting.ExternalGain ); // Place holder for external gain/attenuation value sSprite.setTextColor ( WHITE ); if ( setting.Average ) diff --git a/simpleSA_wifi.cpp b/simpleSA_wifi.cpp index a40e13c..0a3be28 100644 --- a/simpleSA_wifi.cpp +++ b/simpleSA_wifi.cpp @@ -55,6 +55,8 @@ extern uint32_t startFreq_IF; extern uint32_t stopFreq_IF; extern uint32_t sigFreq_IF; +extern uint32_t startFreq_RX; +extern uint32_t stopFreq_RX; AsyncWebServer server ( 80 ); // Create the webserver object AsyncResponseStream *response; @@ -271,12 +273,25 @@ void webSocketEvent ( uint8_t num, WStype_t type, uint8_t* payload, size_t paylo SetAttenuation ( value ); break; + case 'E': // External Gain (+ve) or Attenuation (-ve) + SetExtGain ( value ); + break; + case 'R': // Requested RBW. 0=Auto SetRBW ( value ); + Serial.printf("Wifi RBW %f\n", value); break; case 'S': // Spur Reduction on/off - SetSpur ( value ); + SetSpur ( (int8_t)value ); + break; + + case 't': // Tracking Generator on/off + SetTracking ( (int8_t)value ); + break; + + case 'T': // Tracking Generator output power (dBm) + SetTGPower ( value ); break; default: @@ -497,6 +512,7 @@ void onGetSettings (AsyncWebServerRequest *request) root["stop"] = setting.ScanStop / 1000.0; root["IF"] = setting.IF_Freq / 1000000.0; root["attenuation"] = setting.Attenuate; + root["extGain"] = setting.ExternalGain; root["levelOffset"] = setting.LevelOffset; root["setRBW"] = setting.Bandwidth10; root["bandwidth"] = bandwidth; @@ -504,6 +520,8 @@ void onGetSettings (AsyncWebServerRequest *request) root["Drive"] = setting.Drive; root["sweepPoints"] = sweepPoints; root["spur"] = setting.Spur; + root["tg"] = trackGenSetting.Mode; + root["tgPower"] = trackGenSetting.Power; if ( AGC_On ) root["PreAmp"] = 0x60; // Auto @@ -522,8 +540,12 @@ void onGetSettings (AsyncWebServerRequest *request) */ void pushSettings () { + +if ( numberOfWebsocketClients == 0 ) + return; + size_t capacity = JSON_ARRAY_SIZE ( SCREEN_WIDTH ) - + SCREEN_WIDTH*JSON_OBJECT_SIZE ( 2 ) + JSON_OBJECT_SIZE ( 13 ); + + SCREEN_WIDTH*JSON_OBJECT_SIZE ( 2 ) + JSON_OBJECT_SIZE ( 16 ); static DynamicJsonDocument jsonDocument ( capacity ); // buffer for json data to be pushed to the web clients jsonDocument["mType"] = "Settings"; @@ -532,6 +554,7 @@ static DynamicJsonDocument jsonDocument ( capacity ); // buffer for json data to jsonDocument["stop"] = setting.ScanStop / 1000.0; jsonDocument["IF"] = setting.IF_Freq / 1000000.0; jsonDocument["attenuation"] = setting.Attenuate; + jsonDocument["extGain"] = setting.ExternalGain; jsonDocument["levelOffset"] = setting.LevelOffset; jsonDocument["setRBW"] = setting.Bandwidth10; jsonDocument["bandwidth"] = bandwidth; @@ -539,6 +562,8 @@ static DynamicJsonDocument jsonDocument ( capacity ); // buffer for json data to jsonDocument["Drive"] = setting.Drive; jsonDocument["sweepPoints"] = sweepPoints; jsonDocument["spur"] = setting.Spur; + jsonDocument["tg"] = trackGenSetting.Mode; + jsonDocument["tgPower"] = trackGenSetting.Power; if ( AGC_On ) jsonDocument["PreAmp"] = 0x60; // Auto @@ -604,6 +629,51 @@ static DynamicJsonDocument jsonDocument ( capacity ); // buffer for json data to // Serial.printf ( "Push Settings sweepPoints %u\n", sweepPoints ); } + +/* + * Push the settings data to the websocket clients + */ +void pushRXSweepSettings () +{ +size_t capacity = JSON_ARRAY_SIZE ( SCREEN_WIDTH ) + + SCREEN_WIDTH*JSON_OBJECT_SIZE ( 2 ) + JSON_OBJECT_SIZE ( 13 ); +static DynamicJsonDocument jsonDocument ( capacity ); // buffer for json data to be pushed to the web clients + + jsonDocument["mType"] = "Settings"; + jsonDocument["dispPoints"] = displayPoints; + jsonDocument["start"] = startFreq_RX / 1000.0; + jsonDocument["stop"] = stopFreq_RX / 1000.0; + jsonDocument["IF"] = setting.IF_Freq / 1000000.0; + jsonDocument["attenuation"] = setting.Attenuate; + jsonDocument["levelOffset"] = setting.LevelOffset; + jsonDocument["setRBW"] = setting.Bandwidth10; + jsonDocument["bandwidth"] = bandwidth; + jsonDocument["RefOut"] = setting.ReferenceOut; + jsonDocument["Drive"] = setting.Drive; + jsonDocument["sweepPoints"] = sweepPoints; + jsonDocument["spur"] = setting.Spur; + + if ( AGC_On ) + jsonDocument["PreAmp"] = 0x60; // Auto + + else + jsonDocument["PreAmp"] = setting.PreampGain; // Fixed gain + + String wsBuffer; + + if ( wsBuffer ) + { + serializeJson ( jsonDocument, wsBuffer ); + webSocket.broadcastTXT ( wsBuffer ); // Send to all connected websocket clients + } + + else + Serial.println ( "No buffer :("); + +// Serial.printf ( "Push Settings sweepPoints %u\n", sweepPoints ); +} + + /* * Push the settings data to the websocket clients */