2020-08-16 02:03:43 +08:00
/*
* Initialise variables and SI4432 for the low frequency sweep
*/
void initSweepLow ( )
{
2020-08-17 05:24:08 +08:00
// set up checkerboard sizes
gridHeight = GRID_HEIGHT ;
gridWidth = DISPLAY_POINTS ;
yGrid = Y_GRID ; // no of grid divisions
yDelta = gridHeight / yGrid ; // no of points/division
xGrid = X_GRID ;
xOrigin = X_ORIGIN ;
yOrigin = Y_ORIGIN ;
displayPoints = DISPLAY_POINTS ;
xDelta = displayPoints / xGrid ;
2020-08-16 02:03:43 +08:00
init_sweep ( ) ;
tinySA_mode = SA_LOW_RANGE ;
setting . Mode = tinySA_mode ;
ResetSAMenuStack ( ) ; // Put menu stack back to root level
}
/*
* This function section handles the low freq range sweep
*/
void doSweepLow ( )
{
static uint32_t autoSweepStep = 0 ;
static uint32_t autoSweepFreq = 0 ;
static uint32_t autoSweepFreqStep = 0 ;
static uint32_t nextPointFreq = 0 ; // Frequency for the next display point. Used for substeps
static unsigned long setFreqMicros ;
static unsigned long nowMicros ;
static uint32_t sweepStep ; // Step count
static uint32_t sweepFreqStep ;
static int16_t pointMinGain ; // to record minimum gain for the current display point
static int16_t pointMaxRSSI ; // to record max RSSI of the samples in the current display point
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 ;
2020-09-08 02:01:14 +08:00
static uint32_t actualFreq ; // actual frequency
static uint32_t actualIF ; // actual IF (Rx frequency)
2020-08-16 02:03:43 +08:00
static uint16_t currentPointRSSI ;
static uint16_t peakRSSI ;
static uint16_t prevPointRSSI ;
static uint32_t peakFreq ;
static uint16_t peakIndex ;
2020-08-21 05:27:55 +08:00
static uint16_t maxRSSI ;
static uint32_t maxFreq ;
static uint16_t maxIndex ;
2020-08-16 02:03:43 +08:00
static uint16_t pointsPastPeak ;
static uint16_t pointsPastDip ;
static uint16_t minRSSI ; // Minimum level for the sweep
static uint16_t lastMinRSSI ; // Minimum level for the previous sweep
static bool resetAverage ; // Flag to indicate a setting has changed and average valuesneeds to be reset
static bool jsonDocInitialised = false ;
static uint16_t chunkIndex ;
2020-08-22 05:02:22 +08:00
static uint32_t offsetIF ; // IF frequency offset by half the bandwidth to position in the centre of the filter
2020-09-29 05:44:47 +08:00
static uint32_t tgIF ; // Track gen IF - SA IF plus any offset if both SI4432 defined
2020-08-16 02:03:43 +08:00
/*
* If paused and at the start of a sweep then do nothing
*/
if ( ! sweepStartDone & & paused )
return ;
/*
* If the " sweepStartDone " flag is false or if the " initSweep " flag is true , we need
* to set things up for the sweep .
*/
if ( ( ! sweepStartDone | | initSweep | | changedSetting ) )
{
if ( initSweep | | changedSetting ) // Something has changed, or a first start, so need to owrk out some basic things
{
2020-09-08 02:01:14 +08:00
//Serial.println("InitSweep or changedSetting");
2020-08-17 05:24:08 +08:00
autoSweepFreqStep = ( setting . ScanStop - setting . ScanStart ) / displayPoints ;
2020-08-16 02:03:43 +08:00
vbw = autoSweepFreqStep / 1000.0 ; // Set the video resolution
2020-09-03 06:22:08 +08:00
requiredRBW10 = setting . Bandwidth10 ; // and the resolution bandwidth
2020-08-16 02:03:43 +08:00
2020-09-03 06:22:08 +08:00
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
2020-08-16 02:03:43 +08:00
2020-09-03 06:22:08 +08:00
if ( requiredRBW10 < 26 ) // If it's less than 2.6KHz
requiredRBW10 = 26 ; // set it to 2.6KHz
2020-08-16 02:03:43 +08:00
2020-09-03 06:22:08 +08:00
if ( requiredRBW10 > 6207 )
requiredRBW10 = 6207 ;
2020-08-16 02:03:43 +08:00
2020-09-03 06:22:08 +08:00
if ( requiredRBW10 ! = old_requiredRBW10 )
2020-08-16 02:03:43 +08:00
{
2020-09-03 06:22:08 +08:00
bandwidth = rcvr . SetRBW ( requiredRBW10 , & delaytime ) ; // Set it in the receiver Si4432
old_requiredRBW10 = requiredRBW10 ;
2020-08-16 02:03:43 +08:00
}
2020-08-22 05:02:22 +08:00
/*
* 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
2020-09-08 02:01:14 +08:00
* This needs to be optimised * * * * * * * * *
2020-08-22 05:02:22 +08:00
*/
2020-09-08 02:01:14 +08:00
// 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
2020-08-22 05:02:22 +08:00
2020-08-16 02:03:43 +08:00
/*
* Need multiple readings for each pixel in the display to avoid missing signals .
* Work out how many points needed for the whole sweep :
*/
sweepPoints = ( uint32_t ) ( ( setting . ScanStop - setting . ScanStart ) / bandwidth / 1000.0 * OVERLAP + 0.5 ) ; // allow for some overlap (filters will have 3dB roll off at edge) and round up
2020-08-17 05:24:08 +08:00
if ( sweepPoints < displayPoints )
sweepPoints = displayPoints ; // At least the right number of points for the display
2020-08-16 02:03:43 +08:00
sweepFreqStep = ( setting . ScanStop - setting . ScanStart ) / sweepPoints ; // Step for each reading
if ( setting . Attenuate ! = old_settingAttenuate )
{
if ( ! att . SetAtten ( setting . Attenuate ) ) // Set the internal attenuator
setting . Attenuate = att . GetAtten ( ) ; // Read back if limited (setting.Attenuate was outside range)
old_settingAttenuate = setting . Attenuate ;
}
2020-09-05 06:54:52 +08:00
// pre-calculate adjustment for RSSI values
dBadjust = ( double ) setting . Attenuate - 120.0 + setting . LevelOffset - setting . ExternalGain ;
2020-09-08 02:01:14 +08:00
//Serial.printf("SweepLo dBadjust = %f; leveloffset = %f; attenuate = %i, ext gain = %f\n",
// dBadjust, setting.LevelOffset, setting.Attenuate, setting.ExternalGain);
2020-09-05 06:54:52 +08:00
2020-08-16 02:03:43 +08:00
resetAverage = changedSetting ;
xmit . SetPowerReference ( setting . ReferenceOut ) ; // Set the GPIO reference output if wanted
2020-08-21 05:27:55 +08:00
maxGrid = setting . MaxGrid ;
minGrid = setting . MinGrid ;
2020-08-16 02:03:43 +08:00
# ifdef USE_WIFI
// Vary number of points to send in each chunk depending on delaytime
// A chunk is sent at the end of each sweep regardless
wiFiPoints = wiFiTargetTime / delaytime ;
if ( wiFiPoints > MAX_WIFI_POINTS )
wiFiPoints = MAX_WIFI_POINTS ;
2020-08-17 05:24:08 +08:00
if ( wiFiPoints > displayPoints * OVERLAP )
wiFiPoints = displayPoints * OVERLAP ;
2020-08-16 02:03:43 +08:00
//Serial.printf("No of wifiPoints set to %i\n", wiFiPoints);
if ( numberOfWebsocketClients > 0 )
pushSettings ( ) ;
# endif // #ifdef USE_WIFI
2020-10-13 06:35:14 +08:00
# if defined( TG_IF_INSTALLED ) && !defined( TG_LO_INSTALLED )
2020-08-16 02:03:43 +08:00
if ( tgIF_OK & & ( trackGenSetting . Mode = = 1 ) )
2020-10-13 06:35:14 +08:00
{
2020-08-16 02:03:43 +08:00
tg_if . TxMode ( trackGenSetting . IF_Drive ) ; // Set tracking generator IF on
2020-10-13 06:35:14 +08:00
Serial . println ( " tgif turned on " ) ;
delayMicroseconds ( 300 ) ;
}
2020-08-16 02:03:43 +08:00
else
tg_if . RxMode ( ) ;
# endif
2020-10-10 04:14:58 +08:00
# if defined(TG_IF_INSTALLED) && defined(TG_LO_INSTALLED)
2020-10-13 06:35:14 +08:00
if ( tgLO_OK & & tgIF_OK )
2020-09-29 05:44:47 +08:00
{
2020-10-13 06:35:14 +08:00
switch ( trackGenSetting . Mode )
{
case 0 : // off
tg_if . RxMode ( ) ;
tg_lo . RxMode ( ) ;
break ;
case 1 : // tracking
tg_if . TxMode ( trackGenSetting . IF_Drive ) ; // Set tracking generator IF on
tg_lo . TxMode ( trackGenSetting . LO_Drive ) ; // Set tracking generator LO on
break ;
case 2 : // generator mode
tg_lo . TxMode ( trackGenSetting . LO_Drive ) ; // Set tracking generator LO on
tg_if . TxMode ( trackGenSetting . IF_Drive ) ; // Set tracking generator IF on
tg_lo . SetFrequency ( setting . IF_Freq + trackGenSetting . Offset + trackGenSetting . Frequency ) ;
break ;
default :
Serial . println ( " Invalid track gen mode in Sweeplo " ) ;
}
2020-09-29 05:44:47 +08:00
}
2020-10-13 06:35:14 +08:00
2020-09-29 05:44:47 +08:00
# endif
2020-08-16 02:03:43 +08:00
} // initSweep || changedSetting
autoSweepStep = 0 ; // Set the step counter to zero
2020-09-15 04:49:22 +08:00
sweepStep = 0 ;
2020-08-16 02:03:43 +08:00
autoSweepFreq = setting . ScanStart ; // Set the start frequency.
nextPointFreq = autoSweepFreq + autoSweepFreqStep ;
/* Spur reduction offsets the IF from its normal value. LO also has to be offset same amount
* Offset should be more than half the RX bandwidth to ensure spur is still not in the RX filter passband
* but not so big that the frequencies fall outside the SAW filter passband .
* Use the average trace set to minimum to see the result . Spurs if any will be visible
* at different frequencies .
* Real signals will be present at the same frequency , so a min trace will show only real signals
* How well this works depends on how flat the SAW filter ( and SI4432 filter ) response is
*/
if ( setting . Spur & & spurToggle ) {
2020-09-03 06:22:08 +08:00
uint32_t IF_Shift = requiredRBW10 * 100 ; // bandwidth in Hz
2020-08-16 02:03:43 +08:00
if ( IF_Shift > MAX_IF_SHIFT )
IF_Shift = MAX_IF_SHIFT ;
2020-08-22 05:02:22 +08:00
tempIF = offsetIF - IF_Shift ;
2020-08-16 02:03:43 +08:00
} else {
2020-08-22 05:02:22 +08:00
tempIF = offsetIF ;
2020-08-16 02:03:43 +08:00
}
2020-08-22 05:02:22 +08:00
2020-09-29 05:44:47 +08:00
// track gen IF follows LO if only one SI4432, otherwise its offset by an amount to reduce blow by
if ( tgLO_OK )
tgIF = tempIF + trackGenSetting . Offset ;
else
tgIF = tempIF ;
2020-08-16 02:03:43 +08:00
2020-08-22 05:02:22 +08:00
2020-08-16 02:03:43 +08:00
spurToggle = ! spurToggle ;
//Serial.printf("tempIF %u, spurOffset=%i, spur:%i, Toggle:%i\n", tempIF, tempIF - setting.IF_Freq, setting.Spur, spurToggle);
while ( ( micros ( ) - setFreqMicros ) < delaytime ) // Make sure enough time has elasped since previous frequency write
{
}
if ( ( lastIF ! = tempIF ) | | initSweep | | changedSetting )
{
//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 ;
2020-09-08 02:01:14 +08:00
actualIF = rcvr . GetFrequency ( ) ;
2020-08-16 02:03:43 +08:00
2020-10-10 04:14:58 +08:00
# ifdef TG_IF_INSTALLED
2020-08-16 02:03:43 +08:00
if ( tgIF_OK & & ( trackGenSetting . Mode = = 1 ) )
2020-10-13 06:35:14 +08:00
{
2020-09-29 05:44:47 +08:00
tg_if . SetFrequency ( tgIF ) ; // Set tracking generator IF for the sweep
2020-10-13 06:35:14 +08:00
//Serial.printf("tgif set to %i Hz\n", tgIF);
}
2020-08-16 02:03:43 +08:00
# endif
}
xmit . SetFrequency ( tempIF + autoSweepFreq ) ; // set the LO frequency, tempIF is offset if spur reduction on
2020-10-10 04:14:58 +08:00
# ifdef TG_LO_INSTALLED
2020-08-16 02:03:43 +08:00
if ( tgLO_OK & & ( trackGenSetting . Mode = = 1 ) )
2020-10-13 06:35:14 +08:00
{
2020-09-29 05:44:47 +08:00
tg_lo . SetFrequency ( tgIF + autoSweepFreq ) ; // Set tracking generator LO
2020-10-13 06:35:14 +08:00
//Serial.printf("tglo set to %i Hz at start of sweep\n", tgIF + autoSweepFreq);
}
2020-08-16 02:03:43 +08:00
# endif
setFreqMicros = micros ( ) ; // Store the time the frequency was changed
2020-09-08 02:01:14 +08:00
/*
* 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
2020-08-16 02:03:43 +08:00
# ifdef USE_WIFI
if ( numberOfWebsocketClients > 0 ) // Start off the json document for the scan
{
jsonDocument . clear ( ) ;
chunkIndex = 0 ;
2020-09-15 04:49:22 +08:00
initChunkSweepDoc ( sweepStep ) ;
2020-08-16 02:03:43 +08:00
Points = jsonDocument . createNestedArray ( " Points " ) ; // Add Points array
jsonDocInitialised = true ;
}
else
jsonDocInitialised = false ;
# endif // #ifdef USE_WIFI
startFreq = setting . ScanStart + tempIF ; // Start freq for the LO
stopFreq = setting . ScanStop + tempIF ; // Stop freq for the LO
pointMinGain = 100 ; // Reset min/max values
pointMaxRSSI = 0 ;
/*
* Copy the values for the peaks ( marker positions ) to the old versions . No need to
* reset the indicies or frequencies ; just the " Level " .
*/
for ( int i = 0 ; i < MARKER_COUNT ; i + + )
{
oldPeaks [ i ] . Level = peaks [ i ] . Level ;
oldPeaks [ i ] . Index = peaks [ i ] . Index ;
oldPeaks [ i ] . Freq = peaks [ i ] . Freq ;
peaks [ i ] . Level = 0 ;
}
DisplayInfo ( ) ; // Display axis, top and side bar text
peakLevel = 0 ; // Reset the peak values for the sweep
peakFreq = 0.0 ;
peakGain = 100 ; // Set to higher than gain can ever be
lastMinRSSI = minRSSI ;
minRSSI = 300 ; // Higher than it can be
pointsPastPeak = 0 ; // Avoid possible peak detection at start of sweep
peakRSSI = 0 ;
2020-08-21 05:27:55 +08:00
maxRSSI = 0 ;
2020-08-16 02:03:43 +08:00
sweepStartDone = true ; // Make sure this initialize is only done once per sweep
initSweep = false ;
changedSetting = false ;
2020-09-05 06:54:52 +08:00
if ( setActualPowerRequested )
{
SetPowerLevel ( actualPower ) ;
setActualPowerRequested = false ;
// Serial.printf ( "Setting actual Power %f \n", actualPower );
}
2020-08-16 02:03:43 +08:00
lastSweepStartMicros = sweepStartMicros ; // Set last time we got here
sweepStartMicros = micros ( ) ; // Current time
sweepMicros = sweepStartMicros - lastSweepStartMicros ; // Calculate sweep time (no rollover handling)
2020-09-08 02:01:14 +08:00
2020-08-16 02:03:43 +08:00
} // End of "if ( !sweepStartDone ) || initSweep || changedSetting )"
/*
* Here we do the actual sweep . Save the current step and frequencies for the next time
* through , then wait the required amount of time based on the RBW before taking the
* signal strength reading and changing the transmitter ( LO ) frequency .
*/
uint16_t oldSweepStep = autoSweepStep ;
2020-09-08 02:01:14 +08:00
uint32_t oldSweepFreq = actualFreq ;
2020-08-16 02:03:43 +08:00
/*
2020-09-08 02:01:14 +08:00
* 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
2020-08-16 02:03:43 +08:00
*/
2020-09-08 02:01:14 +08:00
2020-08-16 02:03:43 +08:00
nowMicros = micros ( ) ;
while ( ( nowMicros - setFreqMicros ) < delaytime )
{
2020-09-08 02:01:14 +08:00
if ( ( nowMicros - setFreqMicros + delaytime > MIN_DELAY_WEBSOCKETS ) & &
2020-08-16 02:03:43 +08:00
( ( nowMicros - lastWebsocketMicros > websocketInterval ) | | ( numberOfWebsocketClients > 0 ) ) )
{
// Serial.print("W");
webSocket . loop ( ) ; // Check websockets - includes Yield() to allow other events to run
// Serial.println("w");
lastWebsocketMicros = nowMicros ;
}
if ( nowMicros - setFreqMicros > 100 ) // Wait some time to allow DMA sprite write to finish!
UiProcessTouch ( ) ; // Check the touch screen
// Serial.println("w");
nowMicros = micros ( ) ;
}
int rxRSSI = rcvr . GetRSSI ( ) ; // Read the RSSI from the RX SI4432
/*
* Note that there are two different versions of the print statement to send the
* RSSI readings to the serial output . You can change which one is commented out .
*
* The first one produces a tab separated list of just the frequency and RSSI
* reading . That format can be easily read inte something like Excel .
*
* The second one produces a listing more fit for human consumption !
*/
if ( showRSSI ) // Displaying RSSI?
{
// Serial.printf ( "%s\t%03d\n",
// FormatFrequency ( autoSweepFreq) , rxRSSI ); // Send it to the serial output
2020-09-08 02:01:14 +08:00
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
2020-08-16 02:03:43 +08:00
}
if ( ( numberOfWebsocketClients > 0 ) | | ( setting . ShowGain ) )
gainReading = GetPreampGain ( & AGC_On , & AGC_Reg ) ; // Record the preamp/lna gains
autoSweepFreq + = sweepFreqStep ; // Increment the frequency
sweepStep + + ; // and increment the step count
/*
* Change the transmitter frequency for the next reading and record the time for
* the RBW required settling delay .
*/
uint32_t f = tempIF + autoSweepFreq ;
xmit . SetFrequency ( f ) ; // Set the new LO frequency as soon as RSSI read
2020-08-21 05:27:55 +08:00
// Serial.printf("LO Required: %i Actual %i\n", tempIF+autoSweepFreq, xmit.GetFrequency());
2020-08-16 02:03:43 +08:00
2020-10-10 04:14:58 +08:00
# ifdef TG_LO_INSTALLED
2020-08-16 02:03:43 +08:00
if ( tgLO_OK & & ( trackGenSetting . Mode = = 1 ) )
{
tg_lo . SetFrequency ( f + trackGenSetting . Offset ) ; // Set tracking generator LO
2020-10-13 06:35:14 +08:00
2020-08-16 02:03:43 +08:00
}
# endif
setFreqMicros = micros ( ) ; // Store the time the LO frequency was changed
2020-09-08 02:01:14 +08:00
2020-10-10 04:14:58 +08:00
# ifdef TG_LO_INSTALLED
2020-08-16 02:03:43 +08:00
// if (trackGenSetting.Mode == 1)
2020-10-13 06:35:14 +08:00
// Serial.printf("tglo %i f=%i, lo=%02X, if=%02X\n", tg_lo.ReadFrequency()- tg_if.ReadFrequency(), autoSweepFreq, tg_lo.ReadByte(REG_OFC1) & 0x0F, tg_if.ReadByte(REG_OFC1) & 0x0F );
2020-08-16 02:03:43 +08:00
# endif
# ifdef USE_WIFI
if ( numberOfWebsocketClients > 0 )
{
if ( jsonDocInitialised )
{
JsonObject dataPoint = Points . createNestedObject ( ) ; // Add an object to the Json array to be pushed to the client
dataPoint [ " x " ] = oldSweepFreq / 1000000.0 ; // Set the x(frequency) value
dataPoint [ " y " ] = rxRSSI ; // Set the y (RSSI) value
// Serial.printf ( "Add point chunkIndex %u, sweepStep %u of %u \n", chunkIndex, sweepStep, sweepPoints);
chunkIndex + + ; // increment no of data points in current WiFi chunk
if ( chunkIndex > = wiFiPoints ) // Send the chunk of data and start new jSon document
{
String wsBuffer ;
if ( wsBuffer )
{
// Serial.print("D");
serializeJson ( jsonDocument , wsBuffer ) ;
// Serial.printf("J%u", wsBuffer.length() );
unsigned long s = millis ( ) ;
webSocket . broadcastTXT ( wsBuffer ) ; // Send to all connected websocket clients
if ( millis ( ) - s > 1000 )
{
Serial . println ( " webSocketTimeout " ) ;
Serial . println ( wsBuffer ) ;
2020-09-09 06:17:41 +08:00
websocketFailCount + + ;
if ( websocketFailCount > 2 )
numberOfWebsocketClients = 0 ;
} else {
websocketFailCount = 0 ; // reset if OK
2020-08-16 02:03:43 +08:00
}
// Serial.print("j");
}
else
Serial . println ( " No buffer :( " ) ;
}
}
if ( ( chunkIndex > = wiFiPoints ) | | ! jsonDocInitialised ) // Start new jSon document
{
chunkIndex = 0 ;
2020-09-15 04:49:22 +08:00
initChunkSweepDoc ( sweepStep ) ;
Points = jsonDocument . createNestedArray ( " Points " ) ; // Add Points array
2020-08-16 02:03:43 +08:00
jsonDocInitialised = true ;
}
}
2020-09-08 02:01:14 +08:00
/*
* 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
2020-08-16 02:03:43 +08:00
# endif // #ifdef USE_WIFI
if ( rxRSSI > pointMaxRSSI ) // RSSI > maximum value for this point so far?
{
myActual [ autoSweepStep ] = rxRSSI ; // Yes, save it
pointMaxRSSI = rxRSSI ; // Added by G3ZQC - Remember new maximim
pointMaxFreq = oldSweepFreq ;
}
if ( gainReading < pointMinGain ) // Gain < minimum gain for this point so far?
{
myGain [ autoSweepStep ] = gainReading ; // Yes, save it
pointMinGain = gainReading ; // Added by G3ZQC - Remember new minimum
}
if ( rxRSSI < minRSSI ) // Detect minimum for sweep
minRSSI = rxRSSI ;
/*
* Have we enough readings for this display point ? If yes , so do any averaging etc , reset
* the values so peak in the frequency step is recorded and update the display .
*/
if ( autoSweepFreq > = nextPointFreq )
{
nextPointFreq = nextPointFreq + autoSweepFreqStep ; // Next display point frequency
autoSweepStep + + ; // Increment the index
pointMinGain = 100 ; // Reset min/max values
pointMaxRSSI = 0 ;
DrawCheckerBoard ( oldSweepStep ) ; // Draw the grid for the point in the sweep we have just read
if ( resetAverage | | setting . Average = = AV_OFF ) // Store data, either as read or as rolling average
myData [ oldSweepStep ] = myActual [ oldSweepStep ] ;
else
{
switch ( setting . Average )
{
case AV_MIN :
if ( myData [ oldSweepStep ] > myActual [ oldSweepStep ] )
myData [ oldSweepStep ] = myActual [ oldSweepStep ] ;
break ;
case AV_MAX :
if ( myData [ oldSweepStep ] < myActual [ oldSweepStep ] )
myData [ oldSweepStep ] = myActual [ oldSweepStep ] ;
break ;
case AV_2 :
myData [ oldSweepStep ] = ( myData [ oldSweepStep ] + myActual [ oldSweepStep ] ) / 2 ;
break ;
case AV_4 :
myData [ oldSweepStep ] = ( myData [ oldSweepStep ] * 3 + myActual [ oldSweepStep ] ) / 4 ;
break ;
case AV_8 :
myData [ oldSweepStep ] = ( myData [ oldSweepStep ] * 7 + myActual [ oldSweepStep ] ) / 8 ;
break ;
}
DisplayPoint ( myData , oldSweepStep , AVG_COLOR ) ;
}
if ( setting . ShowSweep )
DisplayPoint ( myActual , oldSweepStep , DB_COLOR ) ;
if ( setting . ShowGain )
displayGainPoint ( myGain , oldSweepStep , GAIN_COLOR ) ;
if ( setting . ShowStorage )
DisplayPoint ( myStorage , oldSweepStep , STORAGE_COLOR ) ;
if ( setting . SubtractStorage )
rxRSSI = 128 + rxRSSI - myStorage [ oldSweepStep ] ;
/*
* Record the peak values but not if freq low enough to detect the LO
*/
if ( ( autoSweepFreq > MARKER_MIN_FREQUENCY ) & & ( oldSweepStep > 0 ) )
{
2020-08-22 05:02:22 +08:00
if ( maxRSSI < = myActual [ oldSweepStep ] )
{
maxIndex = oldSweepStep ;
maxRSSI = myActual [ oldSweepStep ] ;
maxFreq = oldSweepFreq ;
// Serial.printf( "peakLevel set %i, index %i\n", peakLevel, oldSweepStep);
// displayPeakData ();
}
2020-08-16 02:03:43 +08:00
/*
* Save values used by peak detection . Need to save the previous value as we only
* know we have a peak once past it !
*/
prevPointRSSI = currentPointRSSI ;
currentPointRSSI = myData [ oldSweepStep ] ;
/*
* Peak point detection . Four peaks , used to position the markers
*/
if ( currentPointRSSI > = prevPointRSSI ) // Level or ascending
{
pointsPastDip + + ;
if ( pointsPastDip = = PAST_PEAK_LIMIT )
{
pointsPastPeak = 0 ;
}
if ( currentPointRSSI > peakRSSI )
{
peakRSSI = currentPointRSSI ; // Store values
peakFreq = oldSweepFreq ;
peakIndex = oldSweepStep ;
}
}
else
{
pointsPastPeak + + ; // only a true peak if value decreased for a number of consecutive points
if ( pointsPastPeak = = PAST_PEAK_LIMIT ) // We have a peak
{
pointsPastDip = 0 ;
/*
* Is this peak bigger than previous ones ? Only check if bigger than smallest peak so far
*/
if ( peakRSSI > peaks [ MARKER_COUNT - 1 ] . Level )
{
for ( uint16_t p = 0 ; p < MARKER_COUNT ; p + + )
{
if ( peakRSSI > peaks [ p ] . Level )
{
for ( uint16_t n = 3 ; n > p ; n - - ) // Shuffle lower level peaks down
memcpy ( & peaks [ n ] , & peaks [ n - 1 ] , sizeof ( peak_t ) ) ;
peaks [ p ] . Level = peakRSSI ; // Save the peak values
peaks [ p ] . Freq = peakFreq ;
peaks [ p ] . Index = peakIndex ;
break ;
}
}
}
peakRSSI = 0 ; // Reset peak values ready for next peak
} // We have a peak
} // Descending
} // if (( autoSweepFreq > 1000000 ) && (oldSweepStep > 0))
/*
* Draw the markers if main sweep is displayed . The markers know if they are enabled or not
* Only paint if sweep step is in range where there will be a marker
*/
if ( setting . ShowSweep | | setting . Average ! = AV_OFF )
{
for ( int p = 0 ; p < MARKER_COUNT ; p + + )
if ( ( abs ( oldSweepStep - oldPeaks [ p ] . Index )
< = MARKER_SPRITE_HEIGHT / 2 ) & & ( oldPeaks [ p ] . Level > ( lastMinRSSI + MARKER_NOISE_LIMIT ) ) )
marker [ p ] . Paint ( & img , oldPeaks [ p ] . Index - oldSweepStep ,
rssiToImgY ( oldPeaks [ p ] . Level ) ) ;
}
// If in the last few points and gain trace is displayed show the gain scale
2020-08-17 05:24:08 +08:00
if ( setting . ShowGain & & ( oldSweepStep > displayPoints - 2 * CHAR_WIDTH ) )
2020-08-16 02:03:43 +08:00
{
2020-08-17 05:24:08 +08:00
int16_t scaleX = displayPoints - 2 * CHAR_WIDTH - oldSweepStep + 1 ; // relative to the img sprite
2020-08-16 02:03:43 +08:00
img . setPivot ( scaleX , 0 ) ;
gainScaleSprite . pushRotated ( & img , 0 , TFT_BLACK ) ; // Send the sprite to the target sprite, with transparent colour
}
if ( oldSweepStep > 0 ) // Only push if not first point (two pixel wide img)
2020-08-17 05:24:08 +08:00
img . pushSprite ( xOrigin + oldSweepStep - 1 , yOrigin ) ;
2020-08-16 02:03:43 +08:00
myFreq [ oldSweepStep ] = oldSweepFreq ; // Store the frequency for XML file creation
} // End of "if ( autoSweepFreq >= nextPointFreq )"
if ( sweepStep > = sweepPoints ) // If we have got to the end of the sweep
{
// autoSweepStep = 0;
sweepStartDone = false ;
resetAverage = false ;
if ( sweepCount < 2 )
sweepCount + + ; // Used to disable wifi at start
2020-08-21 05:27:55 +08:00
// Serial.printf("MaxRSSI = %i, freq = %i\n", maxRSSI, maxFreq);
2020-08-22 05:02:22 +08:00
oldPeakLevel = maxRSSI ; //Save value of peak level for use by the "SetPowerLevel" function
2020-08-16 02:03:43 +08:00
2020-08-17 05:24:08 +08:00
if ( myActual [ displayPoints - 1 ] = = 0 ) // Ensure a value in last data point
2020-08-16 02:03:43 +08:00
{
2020-08-17 05:24:08 +08:00
myActual [ displayPoints - 1 ] = rxRSSI ; // Yes, save it
myGain [ displayPoints - 1 ] = gainReading ;
myFreq [ displayPoints - 1 ] = oldSweepFreq ;
2020-08-16 02:03:43 +08:00
}
if ( showRSSI = = 1 ) // Only show it once?
showRSSI = 0 ; // Then turn it off
# ifdef USE_WIFI
if ( ( numberOfWebsocketClients > 0 ) & & jsonDocInitialised & & ( chunkIndex > 0 ) )
{
2020-09-08 02:01:14 +08:00
2020-08-16 02:03:43 +08:00
String wsBuffer ;
if ( wsBuffer )
{
serializeJson ( jsonDocument , wsBuffer ) ;
webSocket . broadcastTXT ( wsBuffer ) ; // Send to all connected websocket clients
}
else
Serial . println ( " No buffer :( " ) ;
}
# endif // #ifdef USE_WIFI
} // End of "if ( sweepStep >= sweepPoints )"
} // End of "doSweepLow"