Homebrew panadapter using a Teensy 3.5.
Test Code
#include "SPI.h"
#include "ILI9341_t3.h"
#include <si5351.h> // Si5351Jason library
#include <Audio.h>
//const int myInput = AUDIO_INPUT_MIC;
const int myInput = AUDIO_INPUT_LINEIN;
uint16_t WaterfallData[100][128] = {1};
int Gain = 50;
static const long bandInit = 9008450; // 8800000 8565000 to initially set the frequency. Was 9020000
volatile long freq = bandInit ;
// For optimized ILI9341_t3 library
#define TFT_DC 20
#define TFT_CS 21
#define TFT_RST 255 // 255 = unused, connect to 3.3V
#define TFT_MOSI 7
#define TFT_SCLK 14
#define TFT_MISO 12
ILI9341_t3 tft = ILI9341_t3(TFT_CS, TFT_DC, TFT_RST, TFT_MOSI, TFT_SCLK, TFT_MISO);
Si5351 si5351; // Name for the Si5351 DDS
// Setup audio shield
AudioInputI2S audioInput;
AudioMixer4 InputAmp;
AudioAnalyzeFFT256 FFT;
// Setup the audio connections
AudioConnection patchCord1(audioInput, 0, InputAmp, 0);
AudioConnection patchCord2(InputAmp, 0, FFT, 0);
// Instantiate the Audio Shield
AudioControlSGTL5000 audioShield;
void setup()
{
Serial.begin(9600);
// Setup screen
tft.begin();
tft.setRotation(1);
tft.fillScreen(ILI9341_BLACK);
tft.drawRect(31, 0, 257, 37, ILI9341_YELLOW);
tft.drawRect(31, 36, 257, 103, ILI9341_YELLOW);
tft.drawRect(31, 138, 257, 102, ILI9341_YELLOW);
// Setup audio shield.
AudioMemory(12);
audioShield.enable();
audioShield.inputSelect(myInput);
InputAmp.gain(0, Gain);
FFT.windowFunction(AudioWindowHanning256);
FFT.averageTogether(30);
// Setup the DDS
si5351.init(SI5351_CRYSTAL_LOAD_8PF, 0, 0);
si5351.set_pll(SI5351_PLL_FIXED, SI5351_PLLA);
si5351.drive_strength(SI5351_CLK1, SI5351_DRIVE_8MA);
si5351.set_freq(freq * 100ULL, SI5351_CLK1);
}
void loop()
{
if (FFT.available())
UpdateDisplay();
if (Serial.available() > 0)
{
char c = Serial.read();
switch (c)
{
case 'w': Gain = Gain + 10; break;
case 's': Gain = Gain - 10; break;
}
Serial.println(Gain);
InputAmp.gain(0, Gain);
}
}
void UpdateDisplay()
{
int bar = 0;
int xPos = 0;
int low = 0;
// Spectrum
for (int x = 0; x <= 127; x++)
{
WaterfallData[0][x] = abs(FFT.output[x]);
bar = WaterfallData[0][x];
if (bar > 100)
bar = 100;
tft.drawFastVLine(32 + (xPos * 2), 138 - bar, bar, ILI9341_GREEN); //draw green bar
tft.drawFastVLine(32 + (xPos * 2), 38, 100 - bar, ILI9341_BLACK); //finish off with black to the top of the screen
xPos++;
}
// Waterfall
for (int row = 99; row >= 0; row--)
for (int col = 0; col <= 127; col++)
{
WaterfallData[row][col] = WaterfallData[row - 1][col];
if (WaterfallData[row][col] >= low + 75)
tft.drawPixel(32 + (col * 2), 139 + row, ILI9341_RED);
else if ((WaterfallData[row][col] >= low + 50) && (WaterfallData[row][col] < low + 75))
tft.drawPixel(32 + (col * 2), 139 + row, ILI9341_MAGENTA);
else if ((WaterfallData[row][col] >= low + 30) && (WaterfallData[row][col] < low + 50))
tft.drawPixel(32 + (col * 2), 139 + row, ILI9341_YELLOW);
else if ((WaterfallData[row][col] >= low + 20) && (WaterfallData[row][col] < low + 30))
tft.drawPixel(32 + (col * 2), 139 + row, ILI9341_BLUE);
else if (WaterfallData[row][col] < low + 20)
tft.drawPixel(32 + (col * 2), 139 + row, ILI9341_BLACK);
}
}
void SendFrequency()
{
si5351.set_freq(freq * 100ULL, SI5351_CLK1);
}
This comment has been removed by a blog administrator.
ReplyDelete