Bandscope Grid working
Waterfall next, then speed up frequency changes with offsets and reduce delaytime. Sort out 1 pixel error at start/end
This commit is contained in:
parent
64e45e76ad
commit
16289698dc
227
Bandscope.ino
227
Bandscope.ino
@ -4,6 +4,18 @@
|
|||||||
*/
|
*/
|
||||||
void initBandscope()
|
void initBandscope()
|
||||||
{
|
{
|
||||||
|
// set up checkerboard sizes
|
||||||
|
waterfallHeight = WATERFALL_HEIGHT;
|
||||||
|
gridHeight = SCREEN_HEIGHT - waterfallHeight - 10;
|
||||||
|
gridWidth = SCREEN_WIDTH;
|
||||||
|
yGrid = Y_GRID; // no of grid divisions
|
||||||
|
yDelta = gridHeight / yGrid; // no of points/division
|
||||||
|
xGrid = X_GRID;
|
||||||
|
xOrigin = 0;
|
||||||
|
yOrigin = 0;
|
||||||
|
displayPoints = setting.BandscopePoints;
|
||||||
|
xDelta = SCREEN_WIDTH / xGrid;
|
||||||
|
|
||||||
ClearDisplay ();
|
ClearDisplay ();
|
||||||
/*
|
/*
|
||||||
* Set up the "img" Sprite. This is the image for the graph. It makes for faster display
|
* Set up the "img" Sprite. This is the image for the graph. It makes for faster display
|
||||||
@ -22,19 +34,15 @@ void initBandscope()
|
|||||||
img.setTextSize ( 1 );
|
img.setTextSize ( 1 );
|
||||||
img.setColorDepth ( 16 );
|
img.setColorDepth ( 16 );
|
||||||
img.setAttribute ( PSRAM_ENABLE, false ); // Don't use the PSRAM on the WROVERs
|
img.setAttribute ( PSRAM_ENABLE, false ); // Don't use the PSRAM on the WROVERs
|
||||||
img.createSprite ( 9, GRID_HEIGHT + 1 ); // Only 2 columns wide
|
img.createSprite ( 2, gridHeight + 1 ); // Only 2 columns wide
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The "tSprite" is used for displaying the data above the scan grid.
|
* The "tSprite" is used for displaying the data above the scan grid - we don't use it in this mode
|
||||||
|
* The "sSprite" is for displaying the sidebar stuff, no sidebar in this mode
|
||||||
*/
|
*/
|
||||||
|
|
||||||
tSprite.deleteSprite();
|
tSprite.deleteSprite();
|
||||||
tSprite.setRotation ( 0 );
|
|
||||||
tSprite.setTextSize ( 1 );
|
|
||||||
tSprite.setColorDepth ( 16 );
|
|
||||||
tSprite.setAttribute ( PSRAM_ENABLE, false ); // Don't use the PSRAM on the WROVERs
|
|
||||||
tSprite.createSprite ( tft.width() - X_ORIGIN, Y_ORIGIN );
|
|
||||||
|
|
||||||
sSprite.deleteSprite();
|
sSprite.deleteSprite();
|
||||||
/*
|
/*
|
||||||
@ -65,9 +73,7 @@ void initBandscope()
|
|||||||
|
|
||||||
tinySA_mode = BANDSCOPE;
|
tinySA_mode = BANDSCOPE;
|
||||||
setting.Mode = tinySA_mode;
|
setting.Mode = tinySA_mode;
|
||||||
Serial.println("before reset bandscope stack");
|
|
||||||
ResetBandscopeMenuStack(); // Put menu stack back to root level
|
ResetBandscopeMenuStack(); // Put menu stack back to root level
|
||||||
Serial.println("End of initBandscope");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -134,7 +140,7 @@ static uint16_t chunkIndex;
|
|||||||
{
|
{
|
||||||
if ( initSweep || changedSetting ) // Something has changed, or a first start, so need to owrk out some basic things
|
if ( initSweep || changedSetting ) // Something has changed, or a first start, so need to owrk out some basic things
|
||||||
{
|
{
|
||||||
Serial.println("InitBandscope or changedSetting");
|
// Serial.println("InitBandscope or changedSetting");
|
||||||
sweepPoints = setting.BandscopePoints;
|
sweepPoints = setting.BandscopePoints;
|
||||||
autoSweepFreqStep = ( setting.BandscopeSpan ) / sweepPoints;
|
autoSweepFreqStep = ( setting.BandscopeSpan ) / sweepPoints;
|
||||||
|
|
||||||
@ -173,8 +179,6 @@ static uint16_t chunkIndex;
|
|||||||
pushBandscopeSettings ();
|
pushBandscopeSettings ();
|
||||||
#endif // #ifdef USE_WIFI
|
#endif // #ifdef USE_WIFI
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} // initSweep || changedSetting
|
} // initSweep || changedSetting
|
||||||
|
|
||||||
autoSweepStep = 0; // Set the step counter to zero
|
autoSweepStep = 0; // Set the step counter to zero
|
||||||
@ -226,36 +230,9 @@ static uint16_t chunkIndex;
|
|||||||
// Serial.printf ( "Setting actual Power %f \n", actualPower );
|
// Serial.printf ( "Setting actual Power %f \n", actualPower );
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
DisplayBandscopeInfo (); // Display axis and other info
|
DisplayBandscopeInfo (); // Display axis and other info
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
sweepStartDone = true; // Make sure this initialize is only done once per sweep
|
sweepStartDone = true; // Make sure this initialize is only done once per sweep
|
||||||
initSweep = false;
|
initSweep = false;
|
||||||
changedSetting = false;
|
changedSetting = false;
|
||||||
@ -386,159 +363,70 @@ static uint16_t chunkIndex;
|
|||||||
|
|
||||||
#endif // #ifdef USE_WIFI
|
#endif // #ifdef USE_WIFI
|
||||||
|
|
||||||
myActual[autoSweepStep] = rxRSSI;
|
|
||||||
|
|
||||||
myGain[autoSweepStep] = gainReading;
|
uint16_t pixelsPerPoint = SCREEN_WIDTH / displayPoints;
|
||||||
|
for (uint16_t i = 0; i< pixelsPerPoint; i++) {
|
||||||
|
|
||||||
DrawCheckerBoard ( oldSweepStep ); // Draw the grid for the point in the sweep we have just read
|
uint16_t tmp = oldSweepStep * pixelsPerPoint + i;
|
||||||
|
|
||||||
|
myActual[tmp] = rxRSSI;
|
||||||
|
|
||||||
|
myGain[tmp] = gainReading;
|
||||||
|
|
||||||
|
DrawCheckerBoard ( tmp ); // Draw the grid
|
||||||
|
|
||||||
if ( resetAverage || setting.Average == AV_OFF ) // Store data, either as read or as rolling average
|
if ( resetAverage || setting.Average == AV_OFF ) // Store data, either as read or as rolling average
|
||||||
myData[oldSweepStep] = myActual[oldSweepStep];
|
myData[tmp] = myActual[oldSweepStep];
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
switch ( setting.Average )
|
switch ( setting.Average )
|
||||||
{
|
{
|
||||||
case AV_MIN:
|
case AV_MIN:
|
||||||
if ( myData[oldSweepStep] > myActual[oldSweepStep] )
|
if ( myData[tmp] > myActual[oldSweepStep] )
|
||||||
myData[oldSweepStep] = myActual[oldSweepStep];
|
myData[tmp] = myActual[oldSweepStep];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AV_MAX:
|
case AV_MAX:
|
||||||
if ( myData[oldSweepStep] < myActual[oldSweepStep] )
|
if ( myData[tmp] < myActual[oldSweepStep] )
|
||||||
myData[oldSweepStep] = myActual[oldSweepStep];
|
myData[tmp] = myActual[oldSweepStep];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AV_2:
|
case AV_2:
|
||||||
myData[oldSweepStep] = ( myData[oldSweepStep] + myActual[oldSweepStep] ) / 2;
|
myData[tmp] = ( myData[tmp] + myActual[oldSweepStep] ) / 2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AV_4:
|
case AV_4:
|
||||||
myData[oldSweepStep] = ( myData[oldSweepStep]*3 + myActual[oldSweepStep] ) / 4;
|
myData[tmp] = ( myData[tmp]*3 + myActual[oldSweepStep] ) / 4;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AV_8:
|
case AV_8:
|
||||||
myData[oldSweepStep] = ( myData[oldSweepStep]*7 + myActual[oldSweepStep] ) / 8;
|
myData[tmp] = ( myData[tmp]*7 + myActual[oldSweepStep] ) / 8;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
DisplayPoint ( myData, oldSweepStep, AVG_COLOR );
|
DisplayPoint ( myData, tmp, AVG_COLOR );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( setting.ShowSweep )
|
if ( setting.ShowSweep )
|
||||||
DisplayPoint ( myActual, oldSweepStep, DB_COLOR );
|
DisplayPoint ( myActual, tmp, DB_COLOR );
|
||||||
|
|
||||||
if ( setting.ShowGain )
|
if ( setting.ShowGain )
|
||||||
displayGainPoint ( myGain, oldSweepStep, GAIN_COLOR );
|
displayGainPoint ( myGain, tmp, GAIN_COLOR );
|
||||||
|
|
||||||
if ( setting.ShowStorage )
|
if ( setting.ShowStorage )
|
||||||
DisplayPoint ( myStorage, oldSweepStep, STORAGE_COLOR );
|
DisplayPoint ( myStorage, tmp, 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 ( peakLevel < myData[oldSweepStep] )
|
|
||||||
{
|
|
||||||
peakIndex = oldSweepStep;
|
|
||||||
peakLevel = myData[oldSweepStep];
|
|
||||||
peakFreq = oldSweepFreq;
|
|
||||||
|
|
||||||
// Serial.printf( "peakLevel set %i, index %i\n", peakLevel, oldSweepStep);
|
|
||||||
// displayPeakData ();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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
|
// If in the last few points and gain trace is displayed show the gain scale
|
||||||
if ( setting.ShowGain && (oldSweepStep > setting.BandscopePoints - 2 * CHAR_WIDTH) )
|
if ( setting.ShowGain && (oldSweepStep > setting.BandscopePoints - 2 * CHAR_WIDTH) )
|
||||||
{
|
{
|
||||||
int16_t scaleX = setting.BandscopePoints - 2 * CHAR_WIDTH - oldSweepStep + 1; // relative to the img sprite
|
int16_t scaleX = setting.BandscopePoints - 2 * CHAR_WIDTH - tmp + 1; // relative to the img sprite
|
||||||
img.setPivot( scaleX, 0);
|
img.setPivot( scaleX, 0);
|
||||||
gainScaleSprite.pushRotated ( &img, 0, TFT_BLACK ); // Send the sprite to the target sprite, with transparent colour
|
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)
|
if ( tmp > 0 ) // Only push if not first point (two pixel wide img)
|
||||||
img.pushSprite ( X_ORIGIN+oldSweepStep-1, Y_ORIGIN );
|
img.pushSprite ( xOrigin+tmp, yOrigin );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
myFreq[oldSweepStep] = oldSweepFreq; // Store the frequency for XML file creation
|
myFreq[oldSweepStep] = oldSweepFreq; // Store the frequency for XML file creation
|
||||||
|
|
||||||
@ -552,8 +440,6 @@ static uint16_t chunkIndex;
|
|||||||
if ( sweepCount < 2 )
|
if ( sweepCount < 2 )
|
||||||
sweepCount++; // Used to disable wifi at start
|
sweepCount++; // Used to disable wifi at start
|
||||||
|
|
||||||
oldPeakLevel = peakLevel; //Save value of peak level for use by the "SetPowerLevel" function
|
|
||||||
|
|
||||||
if ( myActual[setting.BandscopePoints-1] == 0 ) // Ensure a value in last data point
|
if ( myActual[setting.BandscopePoints-1] == 0 ) // Ensure a value in last data point
|
||||||
{
|
{
|
||||||
myActual[setting.BandscopePoints-1] = rxRSSI; // Yes, save it
|
myActual[setting.BandscopePoints-1] = rxRSSI; // Yes, save it
|
||||||
@ -565,7 +451,6 @@ static uint16_t chunkIndex;
|
|||||||
showRSSI = 0; // Then turn it off
|
showRSSI = 0; // Then turn it off
|
||||||
|
|
||||||
#ifdef USE_WIFI
|
#ifdef USE_WIFI
|
||||||
|
|
||||||
if (( numberOfWebsocketClients > 0) && jsonDocInitialised && (chunkIndex > 0) )
|
if (( numberOfWebsocketClients > 0) && jsonDocInitialised && (chunkIndex > 0) )
|
||||||
{
|
{
|
||||||
String wsBuffer;
|
String wsBuffer;
|
||||||
@ -579,16 +464,16 @@ static uint16_t chunkIndex;
|
|||||||
else
|
else
|
||||||
Serial.println ( "No buffer :(");
|
Serial.println ( "No buffer :(");
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // #ifdef USE_WIFI
|
#endif // #ifdef USE_WIFI
|
||||||
|
|
||||||
} // End of "if ( sweepStep >= sweepPoints )"
|
} // End of "if ( autoSweepStep >= sweepPoints )"
|
||||||
} // End of "doSweepLow"
|
|
||||||
|
} // End of "doBandscope"
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* "DisplayInfo" - Draws the background text around the checkerboard. Called
|
* "DisplayBandscopeInfo" - Draws the frequency info below the checkerboard. Called
|
||||||
* when a setting is changed to set axis labels and top info bar
|
* when a setting is changed to set axis labels
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void DisplayBandscopeInfo ()
|
void DisplayBandscopeInfo ()
|
||||||
@ -618,30 +503,30 @@ double fStop;
|
|||||||
|
|
||||||
if ( old_startFreq != fStart || old_stopFreq != fStop )
|
if ( old_startFreq != fStart || old_stopFreq != fStop )
|
||||||
{
|
{
|
||||||
Serial.printf("DisplayBandscopeInfo fStart %f; old_startFreq %f \n", fStart, old_startFreq);
|
// Serial.printf("DisplayBandscopeInfo fStart %f; old_startFreq %f \n", fStart, old_startFreq);
|
||||||
Serial.printf("DisplayBandscopeInfo fStop %f; old_stopFreq %f \n", fStop, old_stopFreq);
|
// Serial.printf("DisplayBandscopeInfo fStop %f; old_stopFreq %f \n", fStop, old_stopFreq);
|
||||||
|
|
||||||
tft.fillRect ( X_ORIGIN, SCREEN_HEIGHT -
|
tft.fillRect ( xOrigin, SCREEN_HEIGHT -
|
||||||
CHAR_HEIGHT, SCREEN_WIDTH - X_ORIGIN - 1, SCREEN_HEIGHT - 1, BLACK );
|
CHAR_HEIGHT, SCREEN_WIDTH - xOrigin - 1, SCREEN_HEIGHT - 1, BLACK );
|
||||||
|
|
||||||
// Show operating mode
|
// Show operating mode
|
||||||
tft.setCursor ( X_ORIGIN + 50, SCREEN_HEIGHT - CHAR_HEIGHT );
|
tft.setCursor ( xOrigin + 50, SCREEN_HEIGHT - CHAR_HEIGHT );
|
||||||
tft.setTextColor ( DB_COLOR );
|
tft.setTextColor ( DB_COLOR );
|
||||||
tft.printf ( "Mode:%s", modeText[setting.Mode] );
|
tft.printf ( "Mode:%s", modeText[setting.Mode] );
|
||||||
tft.setTextColor ( WHITE );
|
tft.setTextColor ( WHITE );
|
||||||
|
|
||||||
tft.setCursor ( X_ORIGIN + 2, SCREEN_HEIGHT - CHAR_HEIGHT );
|
tft.setCursor ( xOrigin + 2, SCREEN_HEIGHT - CHAR_HEIGHT );
|
||||||
|
|
||||||
tft.print ( fStart );
|
tft.print ( fStart );
|
||||||
|
|
||||||
tft.setCursor ( SCREEN_WIDTH - 37, SCREEN_HEIGHT - CHAR_HEIGHT );
|
tft.setCursor ( SCREEN_WIDTH - 25, SCREEN_HEIGHT - CHAR_HEIGHT );
|
||||||
tft.print ( fStop );
|
tft.print ( fStop );
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Show the center frequency:
|
* Show the center frequency:
|
||||||
*/
|
*/
|
||||||
tft.setCursor ( SCREEN_WIDTH / 2 - 40 + X_ORIGIN, SCREEN_HEIGHT - CHAR_HEIGHT );
|
tft.setCursor ( SCREEN_WIDTH / 2 - 20 + xOrigin, SCREEN_HEIGHT - CHAR_HEIGHT );
|
||||||
tft.print ( fCenter );
|
tft.print ( fCenter );
|
||||||
tft.print ( "(MHz)" );
|
tft.print ( "(MHz)" );
|
||||||
|
|
||||||
@ -693,7 +578,7 @@ double fStop;
|
|||||||
int x = tSprite.width () - 45;
|
int x = tSprite.width () - 45;
|
||||||
tSprite.setTextColor ( WHITE );
|
tSprite.setTextColor ( WHITE );
|
||||||
|
|
||||||
tSprite.pushSprite ( X_ORIGIN, 0 ); // Write sprite to the display
|
tSprite.pushSprite ( xOrigin, 0 ); // Write sprite to the display
|
||||||
|
|
||||||
updateSidebar = false;
|
updateSidebar = false;
|
||||||
} // End of "DisplayBandscopeInfo"
|
} // End of "DisplayBandscopeInfo"
|
||||||
|
34
IFsweep.ino
34
IFsweep.ino
@ -8,6 +8,16 @@
|
|||||||
*/
|
*/
|
||||||
void initIF_Sweep()
|
void initIF_Sweep()
|
||||||
{
|
{
|
||||||
|
// 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;
|
||||||
|
|
||||||
init_sweep();
|
init_sweep();
|
||||||
|
|
||||||
@ -62,10 +72,10 @@ static uint16_t chunkIndex;
|
|||||||
if ( initSweep || changedSetting ) // Something has changed, or a first start, so need to work out some basic things
|
if ( initSweep || changedSetting ) // Something has changed, or a first start, so need to work out some basic things
|
||||||
{
|
{
|
||||||
Serial.println("Init IFSweep or changedSetting");
|
Serial.println("Init IFSweep or changedSetting");
|
||||||
autoSweepFreqStep = ( stopFreq_IF - startFreq_IF ) / DISPLAY_POINTS;
|
autoSweepFreqStep = ( stopFreq_IF - startFreq_IF ) / displayPoints;
|
||||||
|
|
||||||
vbw = autoSweepFreqStep / 1000.0; // Set the video resolution
|
vbw = autoSweepFreqStep / 1000.0; // Set the video resolution
|
||||||
// ownrbw = ((float) ( stopFreq_IF - startFreq_IF )) / DISPLAY_POINTS / 1000.0; // kHz
|
// ownrbw = ((float) ( stopFreq_IF - startFreq_IF )) / displayPoints / 1000.0; // kHz
|
||||||
//
|
//
|
||||||
// if ( ownrbw < 2.6 ) // If it's less than 2.6KHz
|
// if ( ownrbw < 2.6 ) // If it's less than 2.6KHz
|
||||||
// ownrbw = 2.6; // set it to 2.6KHz
|
// ownrbw = 2.6; // set it to 2.6KHz
|
||||||
@ -81,7 +91,7 @@ static uint16_t chunkIndex;
|
|||||||
|
|
||||||
bandwidth = rcvr.SetRBW ( 106.0, &delaytime ); // Set it in the receiver Si4432. delaytime is returned
|
bandwidth = rcvr.SetRBW ( 106.0, &delaytime ); // Set it in the receiver Si4432. delaytime is returned
|
||||||
|
|
||||||
sweepPoints = DISPLAY_POINTS; // At least the right number of points for the display
|
sweepPoints = displayPoints; // At least the right number of points for the display
|
||||||
|
|
||||||
sweepFreqStep = ( stopFreq_IF - startFreq_IF ) / sweepPoints; // Step for each reading
|
sweepFreqStep = ( stopFreq_IF - startFreq_IF ) / sweepPoints; // Step for each reading
|
||||||
|
|
||||||
@ -95,8 +105,8 @@ static uint16_t chunkIndex;
|
|||||||
wiFiPoints = wiFiTargetTime / delaytime;
|
wiFiPoints = wiFiTargetTime / delaytime;
|
||||||
if (wiFiPoints > MAX_WIFI_POINTS)
|
if (wiFiPoints > MAX_WIFI_POINTS)
|
||||||
wiFiPoints = MAX_WIFI_POINTS;
|
wiFiPoints = MAX_WIFI_POINTS;
|
||||||
if (wiFiPoints > DISPLAY_POINTS*OVERLAP)
|
if (wiFiPoints > displayPoints*OVERLAP)
|
||||||
wiFiPoints = DISPLAY_POINTS*OVERLAP;
|
wiFiPoints = displayPoints*OVERLAP;
|
||||||
// Serial.printf("No of wifiPoints set to %i\n", wiFiPoints);
|
// Serial.printf("No of wifiPoints set to %i\n", wiFiPoints);
|
||||||
|
|
||||||
pushIFSweepSettings();
|
pushIFSweepSettings();
|
||||||
@ -445,15 +455,15 @@ static uint16_t chunkIndex;
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If in the last few points and gain trace is displayed show the gain scale
|
// If in the last few points and gain trace is displayed show the gain scale
|
||||||
if ( setting.ShowGain && (oldSweepStep > DISPLAY_POINTS - 2 * CHAR_WIDTH) )
|
if ( setting.ShowGain && (oldSweepStep > displayPoints - 2 * CHAR_WIDTH) )
|
||||||
{
|
{
|
||||||
int16_t scaleX = DISPLAY_POINTS - 2 * CHAR_WIDTH - oldSweepStep + 1; // relative to the img sprite
|
int16_t scaleX = displayPoints - 2 * CHAR_WIDTH - oldSweepStep + 1; // relative to the img sprite
|
||||||
img.setPivot( scaleX, 0);
|
img.setPivot( scaleX, 0);
|
||||||
gainScaleSprite.pushRotated ( &img, 0, TFT_BLACK ); // Send the sprite to the target sprite, with transparent colour
|
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)
|
if ( oldSweepStep > 0 ) // Only push if not first point (two pixel wide img)
|
||||||
img.pushSprite ( X_ORIGIN+oldSweepStep-1, Y_ORIGIN );
|
img.pushSprite ( xOrigin+oldSweepStep-1, yOrigin );
|
||||||
|
|
||||||
myFreq[oldSweepStep] = oldSweepFreq; // Store the frequency for XML file creation
|
myFreq[oldSweepStep] = oldSweepFreq; // Store the frequency for XML file creation
|
||||||
|
|
||||||
@ -469,11 +479,11 @@ static uint16_t chunkIndex;
|
|||||||
|
|
||||||
oldPeakLevel = peakLevel; //Save value of peak level for use by the "SetPowerLevel" function
|
oldPeakLevel = peakLevel; //Save value of peak level for use by the "SetPowerLevel" function
|
||||||
|
|
||||||
if ( myActual[DISPLAY_POINTS-1] == 0 ) // Ensure a value in last data point
|
if ( myActual[displayPoints-1] == 0 ) // Ensure a value in last data point
|
||||||
{
|
{
|
||||||
myActual[DISPLAY_POINTS-1] = rxRSSI; // Yes, save it
|
myActual[displayPoints-1] = rxRSSI; // Yes, save it
|
||||||
myGain[DISPLAY_POINTS-1] = gainReading;
|
myGain[displayPoints-1] = gainReading;
|
||||||
myFreq[DISPLAY_POINTS-1] = oldSweepFreq;
|
myFreq[displayPoints-1] = oldSweepFreq;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( showRSSI == 1 ) // Only show it once?
|
if ( showRSSI == 1 ) // Only show it once?
|
||||||
|
@ -47,7 +47,7 @@ void initSigLow()
|
|||||||
setting.Mode = tinySA_mode;
|
setting.Mode = tinySA_mode;
|
||||||
|
|
||||||
tft.unloadFont();
|
tft.unloadFont();
|
||||||
tft.setCursor ( X_ORIGIN + 50, SCREEN_HEIGHT - CHAR_HEIGHT );
|
tft.setCursor ( xOrigin + 50, SCREEN_HEIGHT - CHAR_HEIGHT );
|
||||||
tft.setTextSize(1);
|
tft.setTextSize(1);
|
||||||
tft.setTextColor ( YELLOW );
|
tft.setTextColor ( YELLOW );
|
||||||
tft.printf ( "Mode:%s", modeText[setting.Mode] );
|
tft.printf ( "Mode:%s", modeText[setting.Mode] );
|
||||||
|
35
SweepLo.ino
35
SweepLo.ino
@ -4,6 +4,17 @@
|
|||||||
*/
|
*/
|
||||||
void initSweepLow()
|
void initSweepLow()
|
||||||
{
|
{
|
||||||
|
// 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;
|
||||||
|
|
||||||
init_sweep();
|
init_sweep();
|
||||||
|
|
||||||
tinySA_mode = SA_LOW_RANGE;
|
tinySA_mode = SA_LOW_RANGE;
|
||||||
@ -77,7 +88,7 @@ static uint16_t chunkIndex;
|
|||||||
if ( initSweep || changedSetting ) // Something has changed, or a first start, so need to owrk out some basic things
|
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 ) / DISPLAY_POINTS;
|
autoSweepFreqStep = ( setting.ScanStop - setting.ScanStart ) / displayPoints;
|
||||||
|
|
||||||
vbw = autoSweepFreqStep / 1000.0; // Set the video resolution
|
vbw = autoSweepFreqStep / 1000.0; // Set the video resolution
|
||||||
ownrbw = setting.Bandwidth10 / 10.0; // and the resolution bandwidth
|
ownrbw = setting.Bandwidth10 / 10.0; // and the resolution bandwidth
|
||||||
@ -104,8 +115,8 @@ static uint16_t chunkIndex;
|
|||||||
|
|
||||||
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
|
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
|
||||||
|
|
||||||
if ( sweepPoints < DISPLAY_POINTS )
|
if ( sweepPoints < displayPoints )
|
||||||
sweepPoints = DISPLAY_POINTS; // At least the right number of points for the display
|
sweepPoints = displayPoints; // At least the right number of points for the display
|
||||||
|
|
||||||
sweepFreqStep = ( setting.ScanStop - setting.ScanStart ) / sweepPoints; // Step for each reading
|
sweepFreqStep = ( setting.ScanStop - setting.ScanStart ) / sweepPoints; // Step for each reading
|
||||||
|
|
||||||
@ -126,8 +137,8 @@ static uint16_t chunkIndex;
|
|||||||
wiFiPoints = wiFiTargetTime / delaytime;
|
wiFiPoints = wiFiTargetTime / delaytime;
|
||||||
if (wiFiPoints > MAX_WIFI_POINTS)
|
if (wiFiPoints > MAX_WIFI_POINTS)
|
||||||
wiFiPoints = MAX_WIFI_POINTS;
|
wiFiPoints = MAX_WIFI_POINTS;
|
||||||
if (wiFiPoints > DISPLAY_POINTS*OVERLAP)
|
if (wiFiPoints > displayPoints*OVERLAP)
|
||||||
wiFiPoints = DISPLAY_POINTS*OVERLAP;
|
wiFiPoints = displayPoints*OVERLAP;
|
||||||
//Serial.printf("No of wifiPoints set to %i\n", wiFiPoints);
|
//Serial.printf("No of wifiPoints set to %i\n", wiFiPoints);
|
||||||
|
|
||||||
if ( numberOfWebsocketClients > 0 )
|
if ( numberOfWebsocketClients > 0 )
|
||||||
@ -586,15 +597,15 @@ static uint16_t chunkIndex;
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If in the last few points and gain trace is displayed show the gain scale
|
// If in the last few points and gain trace is displayed show the gain scale
|
||||||
if ( setting.ShowGain && (oldSweepStep > DISPLAY_POINTS - 2 * CHAR_WIDTH) )
|
if ( setting.ShowGain && (oldSweepStep > displayPoints - 2 * CHAR_WIDTH) )
|
||||||
{
|
{
|
||||||
int16_t scaleX = DISPLAY_POINTS - 2 * CHAR_WIDTH - oldSweepStep + 1; // relative to the img sprite
|
int16_t scaleX = displayPoints - 2 * CHAR_WIDTH - oldSweepStep + 1; // relative to the img sprite
|
||||||
img.setPivot( scaleX, 0);
|
img.setPivot( scaleX, 0);
|
||||||
gainScaleSprite.pushRotated ( &img, 0, TFT_BLACK ); // Send the sprite to the target sprite, with transparent colour
|
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)
|
if ( oldSweepStep > 0 ) // Only push if not first point (two pixel wide img)
|
||||||
img.pushSprite ( X_ORIGIN+oldSweepStep-1, Y_ORIGIN );
|
img.pushSprite ( xOrigin+oldSweepStep-1, yOrigin );
|
||||||
|
|
||||||
myFreq[oldSweepStep] = oldSweepFreq; // Store the frequency for XML file creation
|
myFreq[oldSweepStep] = oldSweepFreq; // Store the frequency for XML file creation
|
||||||
|
|
||||||
@ -611,11 +622,11 @@ static uint16_t chunkIndex;
|
|||||||
|
|
||||||
oldPeakLevel = peakLevel; //Save value of peak level for use by the "SetPowerLevel" function
|
oldPeakLevel = peakLevel; //Save value of peak level for use by the "SetPowerLevel" function
|
||||||
|
|
||||||
if ( myActual[DISPLAY_POINTS-1] == 0 ) // Ensure a value in last data point
|
if ( myActual[displayPoints-1] == 0 ) // Ensure a value in last data point
|
||||||
{
|
{
|
||||||
myActual[DISPLAY_POINTS-1] = rxRSSI; // Yes, save it
|
myActual[displayPoints-1] = rxRSSI; // Yes, save it
|
||||||
myGain[DISPLAY_POINTS-1] = gainReading;
|
myGain[displayPoints-1] = gainReading;
|
||||||
myFreq[DISPLAY_POINTS-1] = oldSweepFreq;
|
myFreq[displayPoints-1] = oldSweepFreq;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( showRSSI == 1 ) // Only show it once?
|
if ( showRSSI == 1 ) // Only show it once?
|
||||||
|
35
cmd.cpp
35
cmd.cpp
@ -17,9 +17,9 @@
|
|||||||
* here in place of much redundant code in those modules.
|
* here in place of much redundant code in those modules.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "Cmd.h" // Our associated header
|
#include "cmd.h" // Our associated header
|
||||||
#include "preferences.h" // For "SAVE" & "RECALL"
|
#include "preferences.h" // For "SAVE" & "RECALL"
|
||||||
#include "Marker.h" // Marker class definition
|
#include "marker.h" // Marker class definition
|
||||||
/*
|
/*
|
||||||
* These are the objects for the PE4302 and Si4432 modules. They are created in the
|
* These are the objects for the PE4302 and Si4432 modules. They are created in the
|
||||||
* main program file:
|
* main program file:
|
||||||
@ -47,8 +47,25 @@ extern int changedSetting; // Something in "setting" changed
|
|||||||
|
|
||||||
extern uint16_t tinySA_mode;
|
extern uint16_t tinySA_mode;
|
||||||
|
|
||||||
extern uint8_t myData[DISPLAY_POINTS+1];
|
/*
|
||||||
extern uint8_t myStorage[DISPLAY_POINTS+1];
|
* Variables to determine size of grid and waterfall
|
||||||
|
* In Bandscope mode the grid is reduced. In future it may be possible to add
|
||||||
|
* a waterfall to the main sweep, but not yet
|
||||||
|
*/
|
||||||
|
extern uint16_t gridHeight;
|
||||||
|
extern uint16_t gridWidth;
|
||||||
|
extern uint16_t yGrid; // no of grid divisions
|
||||||
|
extern uint16_t yDelta; // no of points/division
|
||||||
|
extern uint16_t xGrid;
|
||||||
|
extern uint16_t xOrigin;
|
||||||
|
extern uint16_t yOrigin;
|
||||||
|
extern uint16_t displayPoints;
|
||||||
|
extern uint16_t xDelta;
|
||||||
|
extern uint16_t waterfallHeight;
|
||||||
|
|
||||||
|
|
||||||
|
extern uint8_t myData[SCREEN_WIDTH+1];
|
||||||
|
extern uint8_t myStorage[SCREEN_WIDTH+1];
|
||||||
|
|
||||||
extern float bandwidth; // The current bandwidth (not * 10)
|
extern float bandwidth; // The current bandwidth (not * 10)
|
||||||
extern unsigned long delaytime; // In microseconds
|
extern unsigned long delaytime; // In microseconds
|
||||||
@ -1453,7 +1470,7 @@ uint8_t reg69; // Ditto
|
|||||||
{
|
{
|
||||||
tempValue = atoi ( dataBuff ); // Yes, get new value
|
tempValue = atoi ( dataBuff ); // Yes, get new value
|
||||||
// check valid
|
// check valid
|
||||||
if ( (tempValue > 10) && (tempValue < DISPLAY_POINTS * OVERLAP) )
|
if ( (tempValue > 10) && (tempValue < displayPoints * OVERLAP) )
|
||||||
{
|
{
|
||||||
wiFiPoints = tempValue;
|
wiFiPoints = tempValue;
|
||||||
Serial.printf ( "Chunk size set to: %u\n", tempValue );
|
Serial.printf ( "Chunk size set to: %u\n", tempValue );
|
||||||
@ -1461,7 +1478,7 @@ uint8_t reg69; // Ditto
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Serial.printf("Invalid - must be between 10 and %u\n", DISPLAY_POINTS * OVERLAP);
|
Serial.printf("Invalid - must be between 10 and %u\n", displayPoints * OVERLAP);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1953,7 +1970,7 @@ int oldMin = setting.MinGrid;
|
|||||||
int oldMax = setting.MaxGrid;
|
int oldMax = setting.MaxGrid;
|
||||||
|
|
||||||
setting.MaxGrid = ref;
|
setting.MaxGrid = ref;
|
||||||
setting.MinGrid = ref - Y_GRID * setting.PowerGrid;
|
setting.MinGrid = ref - yGrid * setting.PowerGrid;
|
||||||
|
|
||||||
if (( oldMin != setting.MinGrid ) || ( oldMax != setting.MaxGrid ))
|
if (( oldMin != setting.MinGrid ) || ( oldMax != setting.MaxGrid ))
|
||||||
{
|
{
|
||||||
@ -2014,7 +2031,7 @@ void SetPowerGrid ( int g )
|
|||||||
int oldGrid = setting.PowerGrid;
|
int oldGrid = setting.PowerGrid;
|
||||||
|
|
||||||
setting.PowerGrid = g;
|
setting.PowerGrid = g;
|
||||||
setting.MinGrid = setting.MaxGrid - Y_GRID * g;
|
setting.MinGrid = setting.MaxGrid - yGrid * g;
|
||||||
|
|
||||||
if ( oldGrid != setting.PowerGrid )
|
if ( oldGrid != setting.PowerGrid )
|
||||||
{
|
{
|
||||||
@ -2083,7 +2100,7 @@ int oldAtten = setting.Attenuate;
|
|||||||
|
|
||||||
void SetStorage ( void )
|
void SetStorage ( void )
|
||||||
{
|
{
|
||||||
for ( int i = 0; i < DISPLAY_POINTS; i++ )
|
for ( int i = 0; i < displayPoints; i++ )
|
||||||
myStorage[i] = myData[i];
|
myStorage[i] = myData[i];
|
||||||
|
|
||||||
setting.ShowStorage = true;
|
setting.ShowStorage = true;
|
||||||
|
4
cmd.h
4
cmd.h
@ -13,8 +13,8 @@
|
|||||||
#define _CMD_H_ // Prevent double inclusion
|
#define _CMD_H_ // Prevent double inclusion
|
||||||
|
|
||||||
#include "simpleSA.h" // General program definitions
|
#include "simpleSA.h" // General program definitions
|
||||||
#include "PE4302.h" // Class definition for thePE4302 attenuator
|
#include "pE4302.h" // Class definition for thePE4302 attenuator
|
||||||
#include "Si4432.h" // Class definition for the Si4432 transceiver
|
#include "si4432.h" // Class definition for the Si4432 transceiver
|
||||||
#include "preferences.h" // For saving the "setting" structure
|
#include "preferences.h" // For saving the "setting" structure
|
||||||
#include <SPI.h>
|
#include <SPI.h>
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* "Marker.cpp" Contains the code for the "Marker" class functions
|
* "Marker.cpp" Contains the code for the "Marker" class functions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "Marker.h" // Class definition
|
#include "marker.h" // Class definition
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* There are two constructors; the first simply creates an uninitialized
|
* There are two constructors; the first simply creates an uninitialized
|
||||||
|
2
menu.cpp
2
menu.cpp
@ -2,7 +2,7 @@
|
|||||||
* "Menu.cpp" implements the "Menuitem" class.
|
* "Menu.cpp" implements the "Menuitem" class.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "Menu.h" // Class definition
|
#include "menu.h" // Class definition
|
||||||
|
|
||||||
Menuitem::Menuitem () {} // Placeholder constructor
|
Menuitem::Menuitem () {} // Placeholder constructor
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
* I2C GPIO expander to drive a parallel version of the PE4302 module.
|
* I2C GPIO expander to drive a parallel version of the PE4302 module.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "PE4302.h"
|
#include "pE4302.h"
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <SPI.h> // Serial Peripheral Interface library
|
#include <SPI.h> // Serial Peripheral Interface library
|
||||||
#include "Si4432.h" // Our header file
|
#include "si4432.h" // Our header file
|
||||||
#include <esp32-hal-spi.h>
|
#include <esp32-hal-spi.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
#ifndef TINYSA_H_
|
#ifndef TINYSA_H_
|
||||||
#define TINYSA_H_ // Prevent double inclusion
|
#define TINYSA_H_ // Prevent double inclusion
|
||||||
|
|
||||||
#include "My_SA.h" // User settable parameters
|
#include "my_SA.h" // User settable parameters
|
||||||
#include <Arduino.h> // General Arduino definitions
|
#include <Arduino.h> // General Arduino definitions
|
||||||
#include <TFT_eSPI.h>
|
#include <TFT_eSPI.h>
|
||||||
|
|
||||||
@ -49,6 +49,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#define DISPLAY_POINTS 290 // Number of scan points in a sweep
|
#define DISPLAY_POINTS 290 // Number of scan points in a sweep
|
||||||
|
#define BANDSCOPE_POINTS 80 // Number of scan points in a bandscope sweep
|
||||||
#define CHAR_HEIGHT 8 // Height of a character
|
#define CHAR_HEIGHT 8 // Height of a character
|
||||||
#define HALF_CHAR_H 4 // Half a character height
|
#define HALF_CHAR_H 4 // Half a character height
|
||||||
#define CHAR_WIDTH 6 // Width of a character
|
#define CHAR_WIDTH 6 // Width of a character
|
||||||
@ -63,6 +64,9 @@
|
|||||||
|
|
||||||
#define GRID_HEIGHT ( Y_GRID * DELTA_Y ) // Height of checkerboard
|
#define GRID_HEIGHT ( Y_GRID * DELTA_Y ) // Height of checkerboard
|
||||||
|
|
||||||
|
#define WATERFALL_HEIGHT 100 // Height of waterfall in Bandscope mode
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Definitions used in signal generator mode
|
* Definitions used in signal generator mode
|
||||||
*/
|
*/
|
||||||
@ -249,7 +253,7 @@ typedef struct {
|
|||||||
int16_t TriggerLevel = -40; // Trigger level for ZeroIF mode (dBm)
|
int16_t TriggerLevel = -40; // Trigger level for ZeroIF mode (dBm)
|
||||||
uint32_t BandscopeStart = 7000000; // Start frequency for bandscope sweep
|
uint32_t BandscopeStart = 7000000; // Start frequency for bandscope sweep
|
||||||
uint32_t BandscopeSpan = 200000; // Span for the bandscope sweep
|
uint32_t BandscopeSpan = 200000; // Span for the bandscope sweep
|
||||||
uint16_t BandscopePoints = 80; // No of points in the sweep. 80/160/320
|
uint16_t BandscopePoints = BANDSCOPE_POINTS; // No of points in the sweep. 80/160/320
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
148
simpleSA.ino
148
simpleSA.ino
@ -128,10 +128,12 @@
|
|||||||
* SPI now runs at 16MHz (was at 1MHz - oops!)
|
* SPI now runs at 16MHz (was at 1MHz - oops!)
|
||||||
* Additional functions in ui.cmd to allow signed frequency entry.
|
* Additional functions in ui.cmd to allow signed frequency entry.
|
||||||
*
|
*
|
||||||
* Moved to github for trial
|
* Version 3.0f Changes by M0WID
|
||||||
* Added initial changes for bandscope mode
|
* renamed simpleSA. Doesn't seem that simple to me!
|
||||||
* Added indication of tracking generator on/off
|
* First go at bandscope mode
|
||||||
* Renamed to simpleSA
|
* VSPI reduced to 10Mhz as some boards will not run at 16MHz
|
||||||
|
* Put onto github - lets see how it works!
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@ -139,10 +141,10 @@
|
|||||||
#include <Arduino.h> // Basic Arduino definitions
|
#include <Arduino.h> // Basic Arduino definitions
|
||||||
#include <SPI.h> // Serial Peripheral Interface library
|
#include <SPI.h> // Serial Peripheral Interface library
|
||||||
#include <Wire.h> // I2C library
|
#include <Wire.h> // I2C library
|
||||||
#include "Si4432.h" // Si4432 tranceiver class definitions and prototypes
|
#include "si4432.h" // Si4432 tranceiver class definitions and prototypes
|
||||||
#include "PE4302.h" // PE4302 attenuator class
|
#include "pE4302.h" // PE4302 attenuator class
|
||||||
#include "Cmd.h" // Command processing functions
|
#include "cmd.h" // Command processing functions
|
||||||
#include "Marker.h" // Marker class
|
#include "marker.h" // Marker class
|
||||||
|
|
||||||
|
|
||||||
#if USE_WIFI // M0WID - We need the following if using WiFi
|
#if USE_WIFI // M0WID - We need the following if using WiFi
|
||||||
@ -163,7 +165,7 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Note the actual definitions for display and touch screen pins used are defined
|
* Note the actual definitions for display and touch screen pins used are defined
|
||||||
* in the file "M0WID_Setup_ILI9341_simpleSA.h" in the "User_Setups" directory of
|
* in the file "M0WID_Setup_ILI9341_TinySA.h" in the "User_Setups" directory of
|
||||||
* the "TFT_eSPI" library.
|
* the "TFT_eSPI" library.
|
||||||
*
|
*
|
||||||
* These are based on using HSPI (spi2) for display and VSPI (spi3) for the SI4432s
|
* These are based on using HSPI (spi2) for display and VSPI (spi3) for the SI4432s
|
||||||
@ -356,17 +358,35 @@ size_t capacity = JSON_ARRAY_SIZE ( MAX_WIFI_POINTS + 1 )
|
|||||||
|
|
||||||
static DynamicJsonDocument jsonDocument ( capacity ); // Buffer for json data to be pushed to the web clients
|
static DynamicJsonDocument jsonDocument ( capacity ); // Buffer for json data to be pushed to the web clients
|
||||||
static JsonArray Points = jsonDocument.createNestedArray ( "Points" ); // add Points array
|
static JsonArray Points = jsonDocument.createNestedArray ( "Points" ); // add Points array
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Variables to determine size of grid and waterfall
|
||||||
|
* In Bandscope mode the grid is reduced. In future it may be possible to add
|
||||||
|
* a waterfall to the main sweep, but not yet
|
||||||
|
*/
|
||||||
|
uint16_t gridHeight = GRID_HEIGHT;
|
||||||
|
uint16_t gridWidth = DISPLAY_POINTS;
|
||||||
|
uint16_t yGrid = Y_GRID; // no of grid divisions
|
||||||
|
uint16_t yDelta = gridHeight / yGrid; // no of points/division
|
||||||
|
uint16_t xGrid = X_GRID;
|
||||||
|
uint16_t xOrigin = X_ORIGIN;
|
||||||
|
uint16_t yOrigin = Y_ORIGIN;
|
||||||
|
uint16_t displayPoints = DISPLAY_POINTS;
|
||||||
|
uint16_t xDelta = displayPoints / xGrid;
|
||||||
|
uint16_t waterfallHeight = WATERFALL_HEIGHT;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Some varibales for the various operating modes
|
||||||
|
*/
|
||||||
uint16_t tinySA_mode = SA_LOW_RANGE; // Low frequency range
|
uint16_t tinySA_mode = SA_LOW_RANGE; // Low frequency range
|
||||||
const char *modeText[] = { "SALo", "SAHi", "SGLo", "SGHi", "IFSw", "0SpL", "0SpH", "TrGn", "Band" }; // For mode display
|
const char *modeText[] = { "SALo", "SAHi", "SGLo", "SGHi", "IFSw", "0SpL", "0SpH", "TrGn", "BScp" }; // For mode display
|
||||||
|
|
||||||
|
|
||||||
float bandwidth; // The current bandwidth (not * 10)
|
float bandwidth; // The current bandwidth (not * 10)
|
||||||
unsigned long delaytime = 2000; // M0WID - changed to microseconds and moved here
|
unsigned long delaytime = 2000; // M0WID - changed to microseconds and moved here
|
||||||
|
|
||||||
uint32_t steps = DISPLAY_POINTS; // Number of frequency steps in the sweep
|
uint32_t steps = displayPoints; // Number of frequency steps in the sweep
|
||||||
uint32_t sweepPoints; // Number of points in the sweep. Can be more than DISPLAY_POINTS if RBW is set less than video resolution
|
uint32_t sweepPoints; // Number of points in the sweep. Can be more than DISPLAY_POINTS if RBW is set less than video resolution
|
||||||
uint32_t startFreq = 0; // Default start frequency is 0MHz
|
uint32_t startFreq = 0; // Default start frequency is 0MHz
|
||||||
uint32_t stopFreq = 100000000; // Default stop frequency is 100MHz
|
uint32_t stopFreq = 100000000; // Default stop frequency is 100MHz
|
||||||
@ -430,14 +450,14 @@ uint32_t sweepCount; // Used to inhibit handling Wifi until
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* These arrays contain the data for the various scan points; they are used in
|
* These arrays contain the data for the various scan points; they are used in
|
||||||
* here and in the "simpleSA_wifi" modules:
|
* here and in the "TinySA_wifi" modules:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
uint8_t myData[DISPLAY_POINTS+1];
|
uint8_t myData[SCREEN_WIDTH+1];
|
||||||
uint8_t myStorage[DISPLAY_POINTS+1];
|
uint8_t myStorage[SCREEN_WIDTH+1];
|
||||||
uint8_t myActual[DISPLAY_POINTS+1];
|
uint8_t myActual[SCREEN_WIDTH+1];
|
||||||
uint8_t myGain[DISPLAY_POINTS+1]; // Preamp gain
|
uint8_t myGain[SCREEN_WIDTH+1]; // Preamp gain
|
||||||
uint32_t myFreq[DISPLAY_POINTS+1]; // Frequency for XML file
|
uint32_t myFreq[SCREEN_WIDTH+1]; // Frequency for XML file
|
||||||
|
|
||||||
uint16_t peakLevel; // Current maximum signal level
|
uint16_t peakLevel; // Current maximum signal level
|
||||||
uint16_t oldPeakLevel; // Old maximum signal level
|
uint16_t oldPeakLevel; // Old maximum signal level
|
||||||
@ -721,7 +741,7 @@ bool fsStatus = false; // True if SPIFFS loads ok
|
|||||||
startAP (); // Start it up
|
startAP (); // Start it up
|
||||||
|
|
||||||
#else // Connect to the router using SSID
|
#else // Connect to the router using SSID
|
||||||
// and password defined in simpleSA.h
|
// and password defined in TinySA.h
|
||||||
|
|
||||||
Serial.println ( "Connecting..." ); // Indicate trying to connect
|
Serial.println ( "Connecting..." ); // Indicate trying to connect
|
||||||
|
|
||||||
@ -769,7 +789,7 @@ bool fsStatus = false; // True if SPIFFS loads ok
|
|||||||
|
|
||||||
// tft.println("Setup Complete");
|
// tft.println("Setup Complete");
|
||||||
|
|
||||||
Serial.printf ( "\nsimpleSA Version %s Initialization Complete\n", PROGRAM_VERSION );
|
Serial.printf ( "\nTinySA Version %s Initialization Complete\n", PROGRAM_VERSION );
|
||||||
|
|
||||||
ShowMenu (); // Display the menu of commands on serial monitor
|
ShowMenu (); // Display the menu of commands on serial monitor
|
||||||
|
|
||||||
@ -990,7 +1010,7 @@ void init_sweep()
|
|||||||
img.setTextSize ( 1 );
|
img.setTextSize ( 1 );
|
||||||
img.setColorDepth ( 16 );
|
img.setColorDepth ( 16 );
|
||||||
img.setAttribute ( PSRAM_ENABLE, false ); // Don't use the PSRAM on the WROVERs
|
img.setAttribute ( PSRAM_ENABLE, false ); // Don't use the PSRAM on the WROVERs
|
||||||
img.createSprite ( 2, GRID_HEIGHT + 1 ); // Only 2 columns wide
|
img.createSprite ( 2, gridHeight + 1 ); // Only 2 columns wide
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1331,16 +1351,18 @@ void RedrawHisto ()
|
|||||||
old_settingAverage = -1;
|
old_settingAverage = -1;
|
||||||
old_settingSpur = -100;
|
old_settingSpur = -100;
|
||||||
ClearDisplay();
|
ClearDisplay();
|
||||||
switch (tinySA_mode) {
|
switch (tinySA_mode)
|
||||||
|
{
|
||||||
case BANDSCOPE:
|
case BANDSCOPE:
|
||||||
DisplayBandscopeInfo();
|
DisplayBandscopeInfo();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
DisplayInfo();
|
DisplayInfo();
|
||||||
DrawFullCheckerBoard();
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
DrawFullCheckerBoard();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1386,7 +1408,7 @@ double fStop;
|
|||||||
sSprite.setTextColor ( DB_COLOR );
|
sSprite.setTextColor ( DB_COLOR );
|
||||||
sSprite.printf ( "%4i", setting.MaxGrid );
|
sSprite.printf ( "%4i", setting.MaxGrid );
|
||||||
|
|
||||||
sSprite.setCursor ( 0, GRID_HEIGHT + Y_ORIGIN );
|
sSprite.setCursor ( 0, gridHeight + yOrigin );
|
||||||
sSprite.printf ( "%4i", setting.MinGrid );
|
sSprite.printf ( "%4i", setting.MinGrid );
|
||||||
|
|
||||||
sSprite.setTextColor ( WHITE );
|
sSprite.setTextColor ( WHITE );
|
||||||
@ -1511,16 +1533,16 @@ double fStop;
|
|||||||
|
|
||||||
if ( old_startFreq != fStart || old_stopFreq != fStop )
|
if ( old_startFreq != fStart || old_stopFreq != fStop )
|
||||||
{
|
{
|
||||||
tft.fillRect ( X_ORIGIN, SCREEN_HEIGHT -
|
tft.fillRect ( xOrigin, SCREEN_HEIGHT -
|
||||||
CHAR_HEIGHT, SCREEN_WIDTH - X_ORIGIN - 1, SCREEN_HEIGHT - 1, BLACK );
|
CHAR_HEIGHT, SCREEN_WIDTH - xOrigin - 1, SCREEN_HEIGHT - 1, BLACK );
|
||||||
|
|
||||||
// Show operating mode
|
// Show operating mode
|
||||||
tft.setCursor ( X_ORIGIN + 50, SCREEN_HEIGHT - CHAR_HEIGHT );
|
tft.setCursor ( xOrigin + 50, SCREEN_HEIGHT - CHAR_HEIGHT );
|
||||||
tft.setTextColor ( DB_COLOR );
|
tft.setTextColor ( DB_COLOR );
|
||||||
tft.printf ( "Mode:%s", modeText[setting.Mode] );
|
tft.printf ( "Mode:%s", modeText[setting.Mode] );
|
||||||
tft.setTextColor ( WHITE );
|
tft.setTextColor ( WHITE );
|
||||||
|
|
||||||
tft.setCursor ( X_ORIGIN + 2, SCREEN_HEIGHT - CHAR_HEIGHT );
|
tft.setCursor ( xOrigin + 2, SCREEN_HEIGHT - CHAR_HEIGHT );
|
||||||
|
|
||||||
tft.print ( fStart );
|
tft.print ( fStart );
|
||||||
// tft.print( "MHz" );
|
// tft.print( "MHz" );
|
||||||
@ -1533,7 +1555,7 @@ double fStop;
|
|||||||
/*
|
/*
|
||||||
* Show the center frequency:
|
* Show the center frequency:
|
||||||
*/
|
*/
|
||||||
tft.setCursor ( SCREEN_WIDTH / 2 - 40 + X_ORIGIN, SCREEN_HEIGHT - CHAR_HEIGHT );
|
tft.setCursor ( SCREEN_WIDTH / 2 - 40 + xOrigin, SCREEN_HEIGHT - CHAR_HEIGHT );
|
||||||
tft.print ( fCenter );
|
tft.print ( fCenter );
|
||||||
tft.print ( "(MHz)" );
|
tft.print ( "(MHz)" );
|
||||||
|
|
||||||
@ -1591,7 +1613,7 @@ double fStop;
|
|||||||
int x = tSprite.width () - 45;
|
int x = tSprite.width () - 45;
|
||||||
tSprite.setTextColor ( WHITE );
|
tSprite.setTextColor ( WHITE );
|
||||||
|
|
||||||
tSprite.pushSprite ( X_ORIGIN, 0 ); // Write sprite to the display
|
tSprite.pushSprite ( xOrigin, 0 ); // Write sprite to the display
|
||||||
|
|
||||||
updateSidebar = false;
|
updateSidebar = false;
|
||||||
} // End of "DisplayInfo"
|
} // End of "DisplayInfo"
|
||||||
@ -1604,12 +1626,12 @@ double fStop;
|
|||||||
|
|
||||||
void DrawFullCheckerBoard()
|
void DrawFullCheckerBoard()
|
||||||
{
|
{
|
||||||
for ( int p=0; p<DISPLAY_POINTS; p++ )
|
for ( int p=0; p<displayPoints; p++ )
|
||||||
{
|
{
|
||||||
DrawCheckerBoard ( p );
|
DrawCheckerBoard ( p );
|
||||||
|
|
||||||
if ( p > 0 )
|
if ( p > 0 )
|
||||||
img.pushSprite( X_ORIGIN+p-1, Y_ORIGIN );
|
img.pushSprite( xOrigin+p-1, yOrigin );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Serial.println ( "DrawFullCheckerBoard" );
|
// Serial.println ( "DrawFullCheckerBoard" );
|
||||||
@ -1620,7 +1642,7 @@ void DrawFullCheckerBoard()
|
|||||||
* "DrawCheckerBoard" - Paints the grid. It now uses a sprite so no need to
|
* "DrawCheckerBoard" - Paints the grid. It now uses a sprite so no need to
|
||||||
* erase the old grid, just draw a new one.
|
* erase the old grid, just draw a new one.
|
||||||
*
|
*
|
||||||
* The sprite is two pixels wide, and the image from the previous data point
|
* The img sprite is two pixels wide, and the image from the previous data point
|
||||||
* is scrolled and then new data point drawn. The data from last is scrolled
|
* is scrolled and then new data point drawn. The data from last is scrolled
|
||||||
* so any line from before is retained.
|
* so any line from before is retained.
|
||||||
*/
|
*/
|
||||||
@ -1633,24 +1655,24 @@ void DrawCheckerBoard ( int x )
|
|||||||
if ( x == 1 )
|
if ( x == 1 )
|
||||||
{
|
{
|
||||||
img.fillSprite ( BLACK ); // Clear the sprite
|
img.fillSprite ( BLACK ); // Clear the sprite
|
||||||
img.drawFastVLine ( 0, 0, GRID_HEIGHT, DARKGREY ); // Draw vertical line at edge
|
img.drawFastVLine ( 0, 0, gridHeight, DARKGREY ); // Draw vertical line at edge
|
||||||
|
|
||||||
for ( int y=0; y <= Y_GRID; y++ )
|
for ( int y=0; y <= yGrid; y++ )
|
||||||
img.drawPixel ( 1, y*DELTA_Y, DARKGREY ); // Draw the horizontal grid lines
|
img.drawPixel ( 1, y*yDelta, DARKGREY ); // Draw the horizontal grid lines
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
img.setScrollRect ( 0, 0, 2,GRID_HEIGHT, BLACK ); // Scroll the whole sprite
|
img.setScrollRect ( 0, 0, 2,gridHeight, BLACK ); // Scroll the whole sprite
|
||||||
img.scroll ( -1, 0 );
|
img.scroll ( -1, 0 );
|
||||||
int lastStep = x - 1;
|
int lastStep = x - 1;
|
||||||
|
|
||||||
if (( x % DELTA_X ) == 0 ) // Need a vertical line here
|
if (( x % xDelta ) == 0 ) // Need a vertical line here
|
||||||
img.drawFastVLine ( 1, 0, GRID_HEIGHT, DARKGREY );
|
img.drawFastVLine ( 1, 0, gridHeight, DARKGREY );
|
||||||
|
|
||||||
else
|
else
|
||||||
for ( int y = 0; y <= Y_GRID; y++ )
|
for ( int y = 0; y <= yGrid; y++ )
|
||||||
img.drawPixel ( 1, y * DELTA_Y, DARKGREY ); // Draw the horizontal grid lines
|
img.drawPixel ( 1, y * yDelta, DARKGREY ); // Draw the horizontal grid lines
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1665,15 +1687,15 @@ uint16_t rssiToImgY ( uint8_t rSSI )
|
|||||||
int delta = setting.MaxGrid - setting.MinGrid;
|
int delta = setting.MaxGrid - setting.MinGrid;
|
||||||
double y = rssiTodBm ( rSSI );
|
double y = rssiTodBm ( rSSI );
|
||||||
|
|
||||||
y = ( y - setting.MinGrid ) * GRID_HEIGHT / delta;
|
y = ( y - setting.MinGrid ) * gridHeight / delta;
|
||||||
|
|
||||||
if ( y >= GRID_HEIGHT )
|
if ( y >= gridHeight )
|
||||||
y = GRID_HEIGHT-1;
|
y = gridHeight-1;
|
||||||
|
|
||||||
if ( y < 0 )
|
if ( y < 0 )
|
||||||
y = 0;
|
y = 0;
|
||||||
|
|
||||||
return GRID_HEIGHT - 1 - (int) y;
|
return gridHeight - 1 - (int) y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1703,26 +1725,26 @@ void DisplayPoint ( uint8_t* data, int i, int color )
|
|||||||
int lastPoint = i - 1;
|
int lastPoint = i - 1;
|
||||||
int delta = setting.MaxGrid - setting.MinGrid;
|
int delta = setting.MaxGrid - setting.MinGrid;
|
||||||
double f0 = (( data[i] / 2.0 + setting.Attenuate ) - 120.0 ) + setting.LevelOffset; // Current point
|
double f0 = (( data[i] / 2.0 + setting.Attenuate ) - 120.0 ) + setting.LevelOffset; // Current point
|
||||||
f0 = ( f0 - setting.MinGrid ) * GRID_HEIGHT / delta;
|
f0 = ( f0 - setting.MinGrid ) * gridHeight / delta;
|
||||||
|
|
||||||
if ( f0 >= GRID_HEIGHT )
|
if ( f0 >= gridHeight )
|
||||||
f0 = GRID_HEIGHT-1;
|
f0 = gridHeight-1;
|
||||||
|
|
||||||
if ( f0 < 0 )
|
if ( f0 < 0 )
|
||||||
f0 = 0;
|
f0 = 0;
|
||||||
|
|
||||||
double f1 = (( data[lastPoint] / 2.0 + setting.Attenuate ) - 120.0) + setting.LevelOffset; // Previous point
|
double f1 = (( data[lastPoint] / 2.0 + setting.Attenuate ) - 120.0) + setting.LevelOffset; // Previous point
|
||||||
|
|
||||||
f1 = ( f1 - setting.MinGrid ) * GRID_HEIGHT / delta;
|
f1 = ( f1 - setting.MinGrid ) * gridHeight / delta;
|
||||||
|
|
||||||
if ( f1 >= GRID_HEIGHT )
|
if ( f1 >= gridHeight )
|
||||||
f1 = GRID_HEIGHT-1;
|
f1 = gridHeight-1;
|
||||||
|
|
||||||
if ( f1 < 0 )
|
if ( f1 < 0 )
|
||||||
f1 = 0;
|
f1 = 0;
|
||||||
|
|
||||||
int Y0 = GRID_HEIGHT - 1 - (int) f0;
|
int Y0 = gridHeight - 1 - (int) f0;
|
||||||
int Y1 = GRID_HEIGHT - 1 - (int) f1;
|
int Y1 = gridHeight - 1 - (int) f1;
|
||||||
|
|
||||||
img.drawLine ( 0, Y1, 1, Y0, color );
|
img.drawLine ( 0, Y1, 1, Y0, color );
|
||||||
}
|
}
|
||||||
@ -1743,26 +1765,26 @@ void displayGainPoint ( unsigned char *data, int i, int color )
|
|||||||
|
|
||||||
// Serial.printf ( "gain %f \n", f );
|
// Serial.printf ( "gain %f \n", f );
|
||||||
|
|
||||||
f0 = ( f0 ) * GRID_HEIGHT / delta;
|
f0 = ( f0 ) * gridHeight / delta;
|
||||||
|
|
||||||
if ( f0 >= GRID_HEIGHT )
|
if ( f0 >= gridHeight )
|
||||||
f0 = GRID_HEIGHT - 1;
|
f0 = gridHeight - 1;
|
||||||
|
|
||||||
if ( f0 < 0 )
|
if ( f0 < 0 )
|
||||||
f0 = 0;
|
f0 = 0;
|
||||||
|
|
||||||
double f1 = ( data[lastPoint] );
|
double f1 = ( data[lastPoint] );
|
||||||
|
|
||||||
f1 = ( f1 ) * GRID_HEIGHT / delta;
|
f1 = ( f1 ) * gridHeight / delta;
|
||||||
|
|
||||||
if ( f1 >= GRID_HEIGHT )
|
if ( f1 >= gridHeight )
|
||||||
f1 = GRID_HEIGHT - 1;
|
f1 = gridHeight - 1;
|
||||||
|
|
||||||
if ( f1 < 0 )
|
if ( f1 < 0 )
|
||||||
f1 = 0;
|
f1 = 0;
|
||||||
|
|
||||||
int Y0 = GRID_HEIGHT - 1 - (int) f0;
|
int Y0 = gridHeight - 1 - (int) f0;
|
||||||
int Y1 = GRID_HEIGHT - 1 - (int) f1;
|
int Y1 = gridHeight - 1 - (int) f1;
|
||||||
|
|
||||||
img.drawLine ( 0, Y1, 1, Y0, color );
|
img.drawLine ( 0, Y1, 1, Y0, color );
|
||||||
}
|
}
|
||||||
@ -1781,7 +1803,7 @@ void CreateGainScale ()
|
|||||||
gainScaleSprite.deleteSprite();
|
gainScaleSprite.deleteSprite();
|
||||||
gainScaleSprite.setAttribute ( PSRAM_ENABLE, false );
|
gainScaleSprite.setAttribute ( PSRAM_ENABLE, false );
|
||||||
gainScaleSprite.setColorDepth ( 16 ); // Using 16 bit (RGB565) colors
|
gainScaleSprite.setColorDepth ( 16 ); // Using 16 bit (RGB565) colors
|
||||||
gainScaleSprite.createSprite(CHAR_WIDTH * 2, GRID_HEIGHT);
|
gainScaleSprite.createSprite(CHAR_WIDTH * 2, gridHeight);
|
||||||
gainScaleSprite.fillSprite(BLACK);
|
gainScaleSprite.fillSprite(BLACK);
|
||||||
gainScaleSprite.setPivot( 0, 0 );
|
gainScaleSprite.setPivot( 0, 0 );
|
||||||
gainScaleSprite.setTextSize ( 1 );
|
gainScaleSprite.setTextSize ( 1 );
|
||||||
@ -1798,7 +1820,7 @@ void CreateGainScale ()
|
|||||||
|
|
||||||
for ( int i = 0; i < 5; i++ )
|
for ( int i = 0; i < 5; i++ )
|
||||||
{
|
{
|
||||||
gainScaleSprite.setCursor ( 0, 2 + ( DELTA_Y * i * 2 ));
|
gainScaleSprite.setCursor ( 0, 2 + ( yDelta * i * 2 ));
|
||||||
gainScaleSprite.print ( 50 - ( i * 10 ));
|
gainScaleSprite.print ( 50 - ( i * 10 ));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,8 +16,23 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "simpleSA_wifi.h" // WiFi definitions
|
#include "simpleSA_wifi.h" // WiFi definitions
|
||||||
#include "Si4432.h" // Si4432 definitions
|
#include "si4432.h" // Si4432 definitions
|
||||||
#include "Cmd.h" // Command processing functions
|
#include "cmd.h" // Command processing functions
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Variables to determine size of grid and waterfall
|
||||||
|
* In Bandscope mode the grid is reduced. In future it may be possible to add
|
||||||
|
* a waterfall to the main sweep, but not yet
|
||||||
|
*/
|
||||||
|
extern uint16_t gridHeight;
|
||||||
|
extern uint16_t gridWidth;
|
||||||
|
extern uint16_t yGrid; // no of grid divisions
|
||||||
|
extern uint16_t yDelta; // no of points/division
|
||||||
|
extern uint16_t xGrid;
|
||||||
|
extern uint16_t displayPoints;
|
||||||
|
extern uint16_t xDelta;
|
||||||
|
extern uint16_t waterfallHeight;
|
||||||
|
|
||||||
|
|
||||||
extern int bpfCount; // Number of elements in the bandpassFilters array
|
extern int bpfCount; // Number of elements in the bandpassFilters array
|
||||||
extern int updateSidebar; // Flag to indicate no of clients has changed
|
extern int updateSidebar; // Flag to indicate no of clients has changed
|
||||||
@ -376,7 +391,7 @@ void onGetScan ( AsyncWebServerRequest *request )
|
|||||||
response->print ( "<?xml version=\"1.0\" encoding=\"utf-16\"?>" );
|
response->print ( "<?xml version=\"1.0\" encoding=\"utf-16\"?>" );
|
||||||
response->println ( "<Points>" );
|
response->println ( "<Points>" );
|
||||||
|
|
||||||
for( int i = 0; i < DISPLAY_POINTS-1; i++ ) // For each data point
|
for( int i = 0; i < displayPoints-1; i++ ) // For each data point
|
||||||
{
|
{
|
||||||
// Serial.printf ( "<Point F=\"%i\" RSSI=\"%i\"/> %i\n",myFreq[i], myData[i], i );
|
// Serial.printf ( "<Point F=\"%i\" RSSI=\"%i\"/> %i\n",myFreq[i], myData[i], i );
|
||||||
response->printf ( "<P F=\"%i\" R=\"%i\"/>\n", myFreq[i], myData[i] );
|
response->printf ( "<P F=\"%i\" R=\"%i\"/>\n", myFreq[i], myData[i] );
|
||||||
@ -394,8 +409,8 @@ void onGetScan ( AsyncWebServerRequest *request )
|
|||||||
|
|
||||||
void onGetGainSweep ( AsyncWebServerRequest *request )
|
void onGetGainSweep ( AsyncWebServerRequest *request )
|
||||||
{
|
{
|
||||||
size_t bufferSize = JSON_ARRAY_SIZE ( DISPLAY_POINTS )
|
size_t bufferSize = JSON_ARRAY_SIZE ( SCREEN_WIDTH )
|
||||||
+ JSON_OBJECT_SIZE ( 1 ) + DISPLAY_POINTS * JSON_OBJECT_SIZE ( 2 );
|
+ JSON_OBJECT_SIZE ( 1 ) + SCREEN_WIDTH * JSON_OBJECT_SIZE ( 2 );
|
||||||
|
|
||||||
AsyncJsonResponse * response = new AsyncJsonResponse ( false, bufferSize );
|
AsyncJsonResponse * response = new AsyncJsonResponse ( false, bufferSize );
|
||||||
// response->addHeader ( "Server","ESP Async Web Server" );
|
// response->addHeader ( "Server","ESP Async Web Server" );
|
||||||
@ -407,7 +422,7 @@ void onGetGainSweep ( AsyncWebServerRequest *request )
|
|||||||
* Add the objects to the array
|
* Add the objects to the array
|
||||||
*/
|
*/
|
||||||
|
|
||||||
for ( int i = 0; i < DISPLAY_POINTS; i++ ) // For each data point
|
for ( int i = 0; i < displayPoints; i++ ) // For each data point
|
||||||
{
|
{
|
||||||
JsonObject dataPoint = gainPoints.createNestedObject(); // Add an object to the array
|
JsonObject dataPoint = gainPoints.createNestedObject(); // Add an object to the array
|
||||||
dataPoint["x"] = myFreq[i]/1000000.0; // set the x(frequency) value
|
dataPoint["x"] = myFreq[i]/1000000.0; // set the x(frequency) value
|
||||||
@ -426,14 +441,14 @@ void onGetGainSweep ( AsyncWebServerRequest *request )
|
|||||||
|
|
||||||
void onGetSweep ( AsyncWebServerRequest *request )
|
void onGetSweep ( AsyncWebServerRequest *request )
|
||||||
{
|
{
|
||||||
size_t bufferSize = JSON_ARRAY_SIZE ( DISPLAY_POINTS )
|
size_t bufferSize = JSON_ARRAY_SIZE ( SCREEN_WIDTH )
|
||||||
+ JSON_OBJECT_SIZE ( 14 ) + DISPLAY_POINTS * JSON_OBJECT_SIZE ( 2 );
|
+ JSON_OBJECT_SIZE ( 14 ) + SCREEN_WIDTH * JSON_OBJECT_SIZE ( 2 );
|
||||||
|
|
||||||
AsyncJsonResponse * response = new AsyncJsonResponse ( false, bufferSize );
|
AsyncJsonResponse * response = new AsyncJsonResponse ( false, bufferSize );
|
||||||
|
|
||||||
JsonObject root = response->getRoot();
|
JsonObject root = response->getRoot();
|
||||||
|
|
||||||
root["dispPoints"] = DISPLAY_POINTS;
|
root["dispPoints"] = displayPoints;
|
||||||
root["start"] = setting.ScanStart / 1000.0;
|
root["start"] = setting.ScanStart / 1000.0;
|
||||||
root["stop"] = setting.ScanStop / 1000.0;
|
root["stop"] = setting.ScanStop / 1000.0;
|
||||||
root["IF"] = setting.IF_Freq / 1000000.0;
|
root["IF"] = setting.IF_Freq / 1000000.0;
|
||||||
@ -454,7 +469,7 @@ void onGetSweep ( AsyncWebServerRequest *request )
|
|||||||
JsonArray Points = root.createNestedArray ( "Points" ); // Add Points array
|
JsonArray Points = root.createNestedArray ( "Points" ); // Add Points array
|
||||||
|
|
||||||
|
|
||||||
for ( int i = 0; i < DISPLAY_POINTS; i++ ) //For each data point
|
for ( int i = 0; i < displayPoints; i++ ) //For each data point
|
||||||
{
|
{
|
||||||
JsonObject dataPoint = Points.createNestedObject(); // add an object to the array
|
JsonObject dataPoint = Points.createNestedObject(); // add an object to the array
|
||||||
dataPoint["x"] = myFreq[i]/1000000.0; // set the x(frequency) value
|
dataPoint["x"] = myFreq[i]/1000000.0; // set the x(frequency) value
|
||||||
@ -477,7 +492,7 @@ void onGetSettings (AsyncWebServerRequest *request)
|
|||||||
JsonObject root = response->getRoot();
|
JsonObject root = response->getRoot();
|
||||||
|
|
||||||
root["mType"] = "Settings";
|
root["mType"] = "Settings";
|
||||||
root["dispPoints"] = DISPLAY_POINTS;
|
root["dispPoints"] = displayPoints;
|
||||||
root["start"] = setting.ScanStart / 1000.0;
|
root["start"] = setting.ScanStart / 1000.0;
|
||||||
root["stop"] = setting.ScanStop / 1000.0;
|
root["stop"] = setting.ScanStop / 1000.0;
|
||||||
root["IF"] = setting.IF_Freq / 1000000.0;
|
root["IF"] = setting.IF_Freq / 1000000.0;
|
||||||
@ -507,12 +522,12 @@ void onGetSettings (AsyncWebServerRequest *request)
|
|||||||
*/
|
*/
|
||||||
void pushSettings ()
|
void pushSettings ()
|
||||||
{
|
{
|
||||||
size_t capacity = JSON_ARRAY_SIZE ( DISPLAY_POINTS )
|
size_t capacity = JSON_ARRAY_SIZE ( SCREEN_WIDTH )
|
||||||
+ DISPLAY_POINTS*JSON_OBJECT_SIZE ( 2 ) + JSON_OBJECT_SIZE ( 13 );
|
+ 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
|
static DynamicJsonDocument jsonDocument ( capacity ); // buffer for json data to be pushed to the web clients
|
||||||
|
|
||||||
jsonDocument["mType"] = "Settings";
|
jsonDocument["mType"] = "Settings";
|
||||||
jsonDocument["dispPoints"] = DISPLAY_POINTS;
|
jsonDocument["dispPoints"] = displayPoints;
|
||||||
jsonDocument["start"] = setting.ScanStart / 1000.0;
|
jsonDocument["start"] = setting.ScanStart / 1000.0;
|
||||||
jsonDocument["stop"] = setting.ScanStop / 1000.0;
|
jsonDocument["stop"] = setting.ScanStop / 1000.0;
|
||||||
jsonDocument["IF"] = setting.IF_Freq / 1000000.0;
|
jsonDocument["IF"] = setting.IF_Freq / 1000000.0;
|
||||||
@ -551,12 +566,12 @@ static DynamicJsonDocument jsonDocument ( capacity ); // buffer for json data to
|
|||||||
*/
|
*/
|
||||||
void pushIFSweepSettings ()
|
void pushIFSweepSettings ()
|
||||||
{
|
{
|
||||||
size_t capacity = JSON_ARRAY_SIZE ( DISPLAY_POINTS )
|
size_t capacity = JSON_ARRAY_SIZE ( SCREEN_WIDTH )
|
||||||
+ DISPLAY_POINTS*JSON_OBJECT_SIZE ( 2 ) + JSON_OBJECT_SIZE ( 13 );
|
+ 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
|
static DynamicJsonDocument jsonDocument ( capacity ); // buffer for json data to be pushed to the web clients
|
||||||
|
|
||||||
jsonDocument["mType"] = "Settings";
|
jsonDocument["mType"] = "Settings";
|
||||||
jsonDocument["dispPoints"] = DISPLAY_POINTS;
|
jsonDocument["dispPoints"] = displayPoints;
|
||||||
jsonDocument["start"] = startFreq_IF / 1000.0;
|
jsonDocument["start"] = startFreq_IF / 1000.0;
|
||||||
jsonDocument["stop"] = stopFreq_IF / 1000.0;
|
jsonDocument["stop"] = stopFreq_IF / 1000.0;
|
||||||
jsonDocument["IF"] = sigFreq_IF / 1000000.0;
|
jsonDocument["IF"] = sigFreq_IF / 1000000.0;
|
||||||
@ -594,8 +609,8 @@ static DynamicJsonDocument jsonDocument ( capacity ); // buffer for json data to
|
|||||||
*/
|
*/
|
||||||
void pushBandscopeSettings ()
|
void pushBandscopeSettings ()
|
||||||
{
|
{
|
||||||
size_t capacity = JSON_ARRAY_SIZE ( DISPLAY_POINTS )
|
size_t capacity = JSON_ARRAY_SIZE ( SCREEN_WIDTH )
|
||||||
+ DISPLAY_POINTS*JSON_OBJECT_SIZE ( 2 ) + JSON_OBJECT_SIZE ( 13 );
|
+ 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
|
static DynamicJsonDocument jsonDocument ( capacity ); // buffer for json data to be pushed to the web clients
|
||||||
|
|
||||||
jsonDocument["mType"] = "Settings";
|
jsonDocument["mType"] = "Settings";
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
#include "Arduino.h" // Basic Arduino definitions
|
#include "Arduino.h" // Basic Arduino definitions
|
||||||
#include "simpleSA.h" // Program definitions
|
#include "simpleSA.h" // Program definitions
|
||||||
#include "Si4432.h" // RF module definitions
|
#include "si4432.h" // RF module definitions
|
||||||
|
|
||||||
#include <WiFi.h> // WiFi library
|
#include <WiFi.h> // WiFi library
|
||||||
#include <AsyncTCP.h>
|
#include <AsyncTCP.h>
|
||||||
@ -71,11 +71,11 @@
|
|||||||
|
|
||||||
extern settings_t setting;
|
extern settings_t setting;
|
||||||
|
|
||||||
extern uint8_t myData[DISPLAY_POINTS+1];
|
extern uint8_t myData[SCREEN_WIDTH+1];
|
||||||
extern uint8_t myStorage[DISPLAY_POINTS+1];
|
extern uint8_t myStorage[SCREEN_WIDTH+1];
|
||||||
extern uint8_t myActual[DISPLAY_POINTS+1];
|
extern uint8_t myActual[SCREEN_WIDTH+1];
|
||||||
extern uint8_t myGain[DISPLAY_POINTS+1]; // M0WID addition to record preamp gain
|
extern uint8_t myGain[SCREEN_WIDTH+1]; // M0WID addition to record preamp gain
|
||||||
extern uint32_t myFreq[DISPLAY_POINTS+1]; // M0WID addition to store frequency for XML file
|
extern uint32_t myFreq[SCREEN_WIDTH+1]; // M0WID addition to store frequency for XML file
|
||||||
|
|
||||||
|
|
||||||
extern WebSocketsServer webSocket; // Initiated in TinySA.ino
|
extern WebSocketsServer webSocket; // Initiated in TinySA.ino
|
||||||
|
8
ui.cpp
8
ui.cpp
@ -30,12 +30,12 @@
|
|||||||
#include <SPI.h> // SPI Bus handling library
|
#include <SPI.h> // SPI Bus handling library
|
||||||
#include "simpleSA.h"
|
#include "simpleSA.h"
|
||||||
#include "ui.h" // User interface definitions and prototypes
|
#include "ui.h" // User interface definitions and prototypes
|
||||||
#include "Cmd.h" // Command processing functions
|
#include "cmd.h" // Command processing functions
|
||||||
#include "preferences.h" // Save/recall functions
|
#include "preferences.h" // Save/recall functions
|
||||||
#include <TFT_eSPI.h> // Display/Touch Screen header file
|
#include <TFT_eSPI.h> // Display/Touch Screen header file
|
||||||
#include "Menu.h" // "Menuitem" class definition
|
#include "menu.h" // "Menuitem" class definition
|
||||||
#include "Marker.h" // Marker class definition
|
#include "marker.h" // Marker class definition
|
||||||
#include "Si4432.h" // Si4432 class definition
|
#include "si4432.h" // Si4432 class definition
|
||||||
|
|
||||||
|
|
||||||
extern Marker marker[MARKER_COUNT]; // Array of markers
|
extern Marker marker[MARKER_COUNT]; // Array of markers
|
||||||
|
Loading…
Reference in New Issue
Block a user