Friday 15 March 2019

Homebrew RF Power Amplifier

RF Power amplifier based on the W6JL amp. The intent is to use readily available parts in the first instant. These may be swapped out depending on how well they perform.

See YouTube for videos. https://www.youtube.com/channel/UCSNPW3_gzuMJcX_ErBZTv2g

The original circuit (minus the biasing RFCs)



My version of the bias network





The final amp has used a BN-43-202 for T1 (8:4) and a BN-43-3312 for T2 (1:3). I also left off the RFCs for the YouTube video. Adding the RFCs would increase the gain a little. 

Friday 8 March 2019

Homebrew Panadapter

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);
}