QO-100 Ground Station

Aus DL8RDS Wiki
Wechseln zu: Navigation, Suche

1 Scope

My first QSO via QO-100 took place on 01.03.2019 with DF6NM at the portable station of my friend Severin DL9SW. Since then I wanted to acquire the capabilities to transmit to the satellite myself and receive it's signals.

In summer 2022 I met a trainee in my company who wanted to learn about satellite communication, and given that I am working in a satellite project for Airbus, it was apparent that there was a chance to build it.

In fact such a project gives me quite a number of topics that I can teach to our trainees:

  • Requirements Engineering
  • Mechanical Planning
  • Electrical Planning
  • Electrical Engineering fundamentals
  • RF Engineering fundamentals
  • Electrical Safety
  • Specifics of Satellite Radio Communications
  • Electrical Measuring
  • Software Defined Radio
  • Microcontroller Programming
  • Embedded Systems / Embedded Linux (Raspberry Pi)
  • Linux System Programming
  • Networking
  • GUI Design / Browser Engineering
  • Quality Assurance (IVV)
  • Practical Radio Operations

So this project is rather fruitful.

2 Components

The installation consists of three units:

  1. The Antenna unit, which is mounted on a pole
  2. The main unit, which is mounted below the antenna installation, on the same pole, together with a PoE injector, that resides somewhere inside a house.
  3. The User workstation. This is just a normal PC, operating Ubuntu Linux (can be Windows too). It is also possible to operate it with an ordinary laptop.

The first two components are displayed in the following diagram:

2022-10-02-OQ100-Overview.png

2.1 Antenna Unit

2.2 Main Unit

2.3 User Unit

  • MPC-4LAN-N3700 MiniPC
  • Kingston KC600 256G SSD SATA3 mSATA - SKC600MS/256G
  • Crucial CT102464BF186D 8GB Speicher (DDR3, 1866 MT/s, PC3-14900, SODIMM, 204-Pin)
  • Rode USB-NT Microphone
  • USB speakers
  • MikroTik RBD52G-5HACD2HND-TC Wireless Access Points für hAP ac2
  • USB Port Extension
  • USB Keyboard
  • USB Mouse
  • Screen

3 Circuit Description

Generally I wanted to have a QO-100 transceiver that can be set up at a distant place with an internet connection so that I can access it through my VPN. It should be capable to work full duplex and the user interface should be just a Web GUI, so that using a simple browser would allow me to operate it from almost anywhere.

The configuration that was most likely to fulfill all these requirements was the RaspberryPi 4B based RemoreSDR software from André Buhart F1ATB. André also supports the usage of two HackRFs for full duplex and explicitly describes such a setup on his website: https://f1atb.fr/index.php/2022/05/21/remote-sdr-v5-raspberry-4b-or-orange-pi-image-installation/

The antenna unit is designed to downconvert the RX signals immediately to a reasonable frequency (10 GHz -> 430 MHz). The Kuhne LNC is actually for operation with analog 70cm devices, but it serves perfectly fine with a HackRF also. In order to produce the necessary voltages, a bank of DC buck converters was used. The needed voltage will then be chosen with a 4 module relay bank. The control of the relay bank, but also other parts of the entire installation is done by an Arduino which is hooked up serially to the RaspberryPi. This Arduino gives me full remote monitoring and station management capabilities.

Most interesting is the Kuhne Bias Tee, because one of the most challenging problems is frequency stability. My installation will e mounted outside with sunshine heating up all the arrangement. So frequency drift will be a major issue. The Kuhne Bias Tee will allow to insert a 10 MHz reference signal and send it up to the antenna. Off course I have more 10 MHz consumers, which are the HackRFs. So consequently I needed a distribution amplifier, which I found from CircuitValley, which has four ports. The generation of the 10 MHz signal will be done by a Weber GPSDXO disciplined oscillator.

3.1 Control Circuit

Here is my controller program (please save and rename):



/* Includes Files (libraries) =================================================== */
//#include <Arduino.h>       //Library only needed width Visual Studio Code
#include <SerialMenuCmd.h>   //Library referred to in this example
#include <OneWire.h>         //Libraty to read out OneWire sensors
#include <Wire.h>
#include <INA219.h>


/* Macros =============================================================================== */
#define LedOnBoard 13
#define PAPWR 2
#define RXREL1 3
#define RXREL2 4
#define RXREL3 5
#define RXREL4 6
#define ONEWIRE 9

#define LNCVOLTAGEPIN A1
#define SWRVOLTAGEPIN A2
#define FWDVOLTAGEPIN A3

/* Settings ============================================================================= */
int delayTime = 500; // allow milliseconds between switching


/* Class (instanciation) =============================================================== */
/**
   @brief Instanciation of the SerialMenuCmd library (Class)
          This library allows thez user(développeur) to implement a basic CLI (Common Line Interface).
          Operation is based on the serial monitor, for the user it consists of consulting a menu
          and then activating a command by sending the corresponding code.

          example menu (the text must include the corresponding code or othewise the key):
          a - todo command 1
          b - todo command 2
          1 - todo command 3
 *        * - todo command ....

          The menu items are put together in a structure MenCmdItem, see further in the file
*/
SerialMenuCmd myMmuCmd;

/* Variables ============================================================================= */

// none

/**
   @brief Initialization of the structure MenuCmdItem.
          This structure gather the different elements allowing to
          operate a basic CLI (Common Line Interface).

          Every item of the structure is composed as follows :
          text of menu
          code keybord (ASCII printable, see -> http://facweb.cs.depaul.edu/sjost/it212/documents/ascii-pr.htm)
          Fonction to execute (callback)
*/

/* CLI( Command Line Interface) making of ================================================ */
//Declaration texts of menu

tMenuCmdTxt txt_0_showMenu[]      = "?    - Show menu";
tMenuCmdTxt txt_1_getTemps[]      = "t    - get all temperatures";
tMenuCmdTxt txt_2_PAPWR_on[]      = "n    - PA power on";
tMenuCmdTxt txt_3_getPACurrent[]  = "c    - get PA current";
tMenuCmdTxt txt_4_PAPWR_off[]     = "f    - PA power off";
tMenuCmdTxt txt_5_PAFwd[]         = "w    - PA Forward Voltage";
tMenuCmdTxt txt_6_PARefl[]        = "r    - PA Reflected Voltage (SWR)";
tMenuCmdTxt txt_7_LNC0V[]       = "0    - select ZERO LNC voltage out";
tMenuCmdTxt txt_8_RXBand1[]       = "1    - select RX band 1 SSB mode 10368-10370, 9-11V out";
tMenuCmdTxt txt_9_RXBand2[]       = "2    - select RX band 2 SSB mode 10489-10490, 12-17V out";
tMenuCmdTxt txt_10_RXBand3[]      = "3    - select RX band 3 ATV mode 10490-10500, 18-23V out";
tMenuCmdTxt txt_11_RXBand4[]      = "4    - select RX band 4 SSB mode 10450-10452, 24-36V out";
tMenuCmdTxt txt_12_getRXVoltage[] = "v    - get RX control voltage";

//Declaration text of prompt
tMenuCmdTxt txt_Prompt[] = "User";

/* Function Prototype(s) ================================================================= */
/**
   @brief System malfunction is indicated by the led, it flash to form the
          morse message "SOS"
*/
void LedInfoUserPanic(void);

//Prototype of function which are callback by the library
void cmd_1_getTemps(void);
void cmd_2_PAPWR_on(void);
void cmd_3_getPACurrent(void);
void cmd_4_PAPWR_off(void);
void cmd_5_PAFwd(void);
void cmd_6_PARefl(void);
void cmd_7_LNC0V(void);
void cmd_8_RXBand1(void);
void cmd_9_RXBand2(void);
void cmd_10_RXBand3(void);
void cmd_11_RXBand4(void);
void cmd_12_RXVoltage(void);

//Structure initialisation
//Data type
//array sMenuTxt, code (character) , function (Reminder the code character must be printable character)
stMenuCmd list[] = {
  { txt_0_showMenu, '?', []() {
      myMmuCmd.ShowMenu();
      myMmuCmd.giveCmdPrompt();
    }
  },
  {txt_1_getTemps,      't', cmd_1_getTemps},
  {txt_2_PAPWR_on,      'n', cmd_2_PAPWR_on},
  {txt_3_getPACurrent,  'c', cmd_3_getPACurrent},
  {txt_4_PAPWR_off,     'f', cmd_4_PAPWR_off},
  {txt_5_PAFwd,         'w', cmd_5_PAFwd},
  {txt_6_PARefl,        'r', cmd_6_PARefl},
  {txt_7_LNC0V,         '0', cmd_7_LNC0V},
  {txt_8_RXBand1,       '1', cmd_8_RXBand1},
  {txt_9_RXBand2,       '2', cmd_9_RXBand2},
  {txt_10_RXBand3,      '3', cmd_10_RXBand3},
  {txt_11_RXBand4,      '4', cmd_11_RXBand4},
  {txt_12_getRXVoltage, 'v', cmd_12_RXVoltage}

};

//KmenuCount contains the number of command
#define NbCmds sizeof(list) / sizeof(stMenuCmd)

// Instantiations
OneWire  ds(ONEWIRE);  // pull-up 4k7 to Vcc
INA219 monitor;

/* Functions Implementation =================================================== */

void setup()
{
  //Activate and initialize the serial bus with the baudrate passed in parameter
  Serial.begin(115200);

  //Configure the pin to wich  the Led on board the card is connected
  pinMode(LedOnBoard, OUTPUT);
  //switch off the led
  digitalWrite(LedOnBoard, LOW);

  // PAPRW Relay
  pinMode (PAPWR, OUTPUT);

  // RX Relays
  pinMode (RXREL1, OUTPUT);
  pinMode (RXREL2, OUTPUT);
  pinMode (RXREL3, OUTPUT);
  pinMode (RXREL4, OUTPUT);

  // default Setting: Band 2 SSB mode 10489,5-10490,0, 16V out
  digitalWrite(RXREL1, LOW);
  digitalWrite(RXREL2, HIGH);
  digitalWrite(RXREL3, LOW);
  digitalWrite(RXREL4, LOW);

  // INA219
  // begin calls:
  // configure() with default values RANGE_32V, GAIN_8_320MV, ADC_12BIT, ADC_12BIT, CONT_SH_BUS
  // calibrate() with default values D_SHUNT=0.1, D_V_BUS_MAX=32, D_V_SHUNT_MAX=0.2, D_I_MAX_EXPECTED=2
  // in order to work directly with ADAFruit's INA219B breakout
  monitor.begin();

  // Switch PA Power ON by default
  digitalWrite (PAPWR, HIGH); // "NO" is now connected through
  delay (delayTime);

  //Initialize the library with structure defined by the user
  if (myMmuCmd.begin(list, NbCmds, txt_Prompt) == false)
  {
    //If the initialization fails, the system informs the user via the
    //led: panic mode, led flashes in Morse code the letters "SOS"
    while (true)
    {
      LedInfoUserPanic();
    }
  }
  //Display the menu
  
  //Serial.println("Welcome to the QO100 Control Interface!");
  myMmuCmd.ShowMenu();
  myMmuCmd.giveCmdPrompt();
}

void loop()
{
  uint8_t CmdCode;

  /**
     @brief management of the interaction between the system and the user.
     The "UserRequest" menbre function analyzes the characters transmitted by the user.
     If an command code is identified, its number is returned (return 0 if no command). This
     function is not blocking, it stores the intermediate data between 2 calls.
  */
  CmdCode = myMmuCmd.UserRequest();

  //possible pre-treatment here

  /**
     @brief Execute Command
     if a command code is returned, the system executes the corresponding command.
     To do this, it uses the "OpsCallback" member function. this function receives
     the command code parameter

     @note In this way, it is possible to carry out a preprocessing and postprocessing
  */
  if (CmdCode != 0)
  {
    myMmuCmd.ExeCommand(CmdCode);
  }

  //Led State Change to indicate to the user that the system is OK
  //Minnimum delay : 100ms
  digitalWrite(LedOnBoard, !digitalRead(LedOnBoard));
  delay(100);
}



/**
   @brief Flash led on-board in morse code

*/
void LedInfoUserPanic(void)
{
  /**
     @brief Timing Morse
     Letter S -> 3 dot (short mark)
     Letter O -> 3 dash (long mark)
     1 dot => 1 unit time
     1 dash => 3 units time
     1 intra-character space => 1 units time
     1 inter-character space => 3 units time
     1 word space => 7 untis time

  */

  ///letter S -> 3 dots
  digitalWrite(LedOnBoard, HIGH);
  delay(200);
  digitalWrite(LedOnBoard, LOW);
  delay(200); //intra-chacracter
  digitalWrite(LedOnBoard, HIGH);
  delay(200);
  digitalWrite(LedOnBoard, LOW);
  delay(200); //intra-chacracter
  digitalWrite(LedOnBoard, HIGH);
  delay(200);
  digitalWrite(LedOnBoard, LOW);
  delay(600); //inter-character space

  ///Letter O -> 3 dash
  digitalWrite(LedOnBoard, HIGH);
  delay(600);
  digitalWrite(LedOnBoard, LOW);
  delay(200);  //intra-chacracter
  digitalWrite(LedOnBoard, HIGH);
  delay(600);
  digitalWrite(LedOnBoard, LOW);
  delay(200);  //intra-chacracter
  digitalWrite(LedOnBoard, HIGH);
  delay(600);
  digitalWrite(LedOnBoard, LOW);
  delay(600); //inter-character space

  ///letter S -> 3 dots
  digitalWrite(LedOnBoard, HIGH);
  delay(200);
  digitalWrite(LedOnBoard, LOW);
  delay(200);  //intra-chacracter
  digitalWrite(LedOnBoard, HIGH);
  delay(200);
  digitalWrite(LedOnBoard, LOW);
  delay(200);  //intra-chacracter
  digitalWrite(LedOnBoard, HIGH);
  delay(200);
  digitalWrite(LedOnBoard, LOW);
  delay(1400); //word space
}

/* Code implementation for commands ======================================================== */

void cmd_1_getTemps(void)
{
  byte addr[8];
  float celsius;

  if ( !ds.search(addr)) {
    Serial.println(F(""));
    Serial.println("No more addresses.");
    Serial.println();
    ds.reset_search();
    delay(250);
    return;
  }

  ds.reset_search();
  ds.reset();
  
  while ( ds.search(addr) )
  {
    byte i;
    byte present = 0;
    byte type_s;
    byte data[9];

    Serial.println(F(""));

    Serial.print("ROM =");
    for ( i = 0; i < 8; i++) {
      Serial.write(' ');
      Serial.print(addr[i], HEX);
    }

    if (OneWire::crc8(addr, 7) != addr[7]) {
      Serial.println("CRC is not valid!");
      continue;
    }
    Serial.println();

    // the first ROM byte indicates which chip
    switch (addr[0]) {
      case 0x10:
        Serial.println("  Chip = DS18S20");  // or old DS1820
        type_s = 1;
        break;
      case 0x28:
        Serial.println("  Chip = DS18B20");
        type_s = 0;
        break;
      case 0x22:
        Serial.println("  Chip = DS1822");
        type_s = 0;
        break;
      default:
        Serial.println("Device is not a DS18x20 family device.");
        continue;
    }

    ds.reset();
    ds.select(addr);
    ds.write(0x44, 1);        // start conversion, with parasite power on at the end

    delay(1000);     // maybe 750ms is enough, maybe not
    // we might do a ds.depower() here, but the reset will take care of it.

    present = ds.reset();
    ds.select(addr);
    ds.write(0xBE);         // Read Scratchpad

    for ( i = 0; i < 9; i++) {           // we need 9 bytes
      data[i] = ds.read();
    }

    unsigned int raw = (data[1] << 8) | data[0];
    if (type_s) {
      raw = raw << 3; // 9 bit resolution default
      if (data[7] == 0x10) {
        // count remain gives full 12 bit resolution
        raw = (raw & 0xFFF0) + 12 - data[6];
      }
    } else {
      byte cfg = (data[4] & 0x60);
      if (cfg == 0x00) raw = raw << 3;  // 9 bit resolution, 93.75 ms
      else if (cfg == 0x20) raw = raw << 2; // 10 bit res, 187.5 ms
      else if (cfg == 0x40) raw = raw << 1; // 11 bit res, 375 ms
      // default is 12 bit resolution, 750 ms conversion time
    }
    celsius = (float)raw / 16.0;

    Serial.print("  Temperature = ");
    Serial.print(celsius);
    Serial.println(" Celsius, ");
  }


  myMmuCmd.giveCmdPrompt();
}


void cmd_2_PAPWR_on(void)
{
  Serial.println(F(""));
  Serial.println("Toggle PA Power switch");
  digitalWrite (PAPWR, HIGH); // "NO" is now connected through
  delay (delayTime);
  Serial.println("PA Power switched ON");

  myMmuCmd.giveCmdPrompt();
}

void cmd_3_getPACurrent(void)
{
  Serial.println(F(""));
  Serial.println("Get PA current:");



  Serial.print("raw shunt voltage: ");
  Serial.println(monitor.shuntVoltageRaw());

  Serial.print("raw bus voltage:   ");
  Serial.println(monitor.busVoltageRaw());

  Serial.println("--");

  Serial.print("shunt voltage: ");
  Serial.print(monitor.shuntVoltage() * 1000, 4);
  Serial.println(" mV");

  Serial.print("shunt current: ");
  Serial.print(monitor.shuntCurrent() * 1000, 4);
  Serial.println(" mA");

  Serial.print("bus voltage:   ");
  Serial.print(monitor.busVoltage(), 4);
  Serial.println(" V");

  Serial.print("bus power:     ");
  Serial.print(monitor.busPower() * 1000, 4);
  Serial.println(" mW");

  myMmuCmd.giveCmdPrompt();
}

void cmd_4_PAPWR_off(void)
{
  Serial.println(F(""));
  Serial.println("Toggle PA Power switch");
  digitalWrite (PAPWR, LOW); // "NO" is now disconnected through
  delay (delayTime);
  Serial.println("PA Power switched OFF");

  myMmuCmd.giveCmdPrompt();
}

void cmd_5_PAFwd(void)
{
  Serial.println(F(""));
  Serial.println("Get PA Forward Power (voltage)");

  delay(500);
  int fwd_raw = 0;
  float fwd_voltage = 0;
  fwd_raw = analogRead(FWDVOLTAGEPIN);

  Serial.print("PA Forward RAW >");
  Serial.println(fwd_raw);

  float steigung = 870/4.01;
  int offset = 0;
  float min_voltage = 0;

  fwd_voltage = min_voltage + (fwd_raw - offset) / steigung ;

  Serial.print("PA Forward Voltage >");
  Serial.println(fwd_voltage,1);

  myMmuCmd.giveCmdPrompt();
}

void cmd_6_PARefl(void)
{
  Serial.println(F(""));
  Serial.println("Get PA Reflected Power (voltage)");

  delay(500);
  int swr_raw = 0;
  float swr_voltage = 0;
  swr_raw = analogRead(SWRVOLTAGEPIN);

  Serial.print("PA Reflected RAW >");
  Serial.println(swr_raw);

  float steigung = 870/4.01;
  int offset = 0;
  float min_voltage = 0;

  swr_voltage = min_voltage + (swr_raw - offset) / steigung ;

  Serial.print("PA Reflected Voltage >");
  Serial.println(swr_voltage,1);

  myMmuCmd.giveCmdPrompt();
}

void cmd_7_LNC0V(void)
{
  Serial.println(F(""));
  Serial.println("Select ZERO LNC Volt out");

  // https://manuals.plus/joy-it/sbc-ssr01-solid-state-relays-manual

  digitalWrite(RXREL1, LOW);
  digitalWrite(RXREL2, LOW);
  digitalWrite(RXREL3, LOW);
  digitalWrite(RXREL4, LOW);

  cmd_12_RXVoltage();
}

void cmd_8_RXBand1(void)
{
  Serial.println(F(""));
  Serial.println("Select RX band 1 SSB mode 10368-10370, 9-11V out");

  // https://manuals.plus/joy-it/sbc-ssr01-solid-state-relays-manual

  digitalWrite(RXREL1, HIGH);
  digitalWrite(RXREL2, LOW);
  digitalWrite(RXREL3, LOW);
  digitalWrite(RXREL4, LOW);

  cmd_12_RXVoltage();
}

void cmd_9_RXBand2(void)
{
  Serial.println(F(""));
  Serial.println("Select RX band 2 SSB mode 10489-10490, 12-17V out");

  // https://manuals.plus/joy-it/sbc-ssr01-solid-state-relays-manual

  digitalWrite(RXREL1, LOW);
  digitalWrite(RXREL2, HIGH);
  digitalWrite(RXREL3, LOW);
  digitalWrite(RXREL4, LOW);

  cmd_12_RXVoltage();
}

void cmd_10_RXBand3(void)
{
  Serial.println(F(""));
  Serial.println("Select RX band 3 ATV mode 10490-10500, 18-23V out");

  // https://manuals.plus/joy-it/sbc-ssr01-solid-state-relays-manual

  digitalWrite(RXREL1, LOW);
  digitalWrite(RXREL2, LOW);
  digitalWrite(RXREL3, HIGH);
  digitalWrite(RXREL4, LOW);

  cmd_12_RXVoltage();
}

void cmd_11_RXBand4(void)
{
  Serial.println(F(""));
  Serial.println("Select RX band 4 SSB mode 10450-10452, 24-36V out");

  // https://manuals.plus/joy-it/sbc-ssr01-solid-state-relays-manual

  digitalWrite(RXREL1, LOW);
  digitalWrite(RXREL2, LOW);
  digitalWrite(RXREL3, LOW);
  digitalWrite(RXREL4, HIGH);

  cmd_12_RXVoltage();
}

void cmd_12_RXVoltage(void)
{
  Serial.println(F(""));
  Serial.println("Verify LNC Control Voltage");

  delay(500);
  int lnc_raw = 0;
  float lnc_voltage = 0;
  lnc_raw = analogRead(LNCVOLTAGEPIN);

  float steigung = 333/16.954;
  int offset = 208;
  float min_voltage = 10.686;

  lnc_voltage = min_voltage + (lnc_raw - offset) / steigung ;

  Serial.print("LNC Voltage >");
  Serial.println(lnc_voltage,1);

  myMmuCmd.giveCmdPrompt();
}

3.2 Software

The software I am using comes from André Buhart. It is well usable and does it's job. Note that André does not put great attention on station usage security, so I recommend to use it only in a trusted environment, i.e. within your VPN or in your home LAN. There however it is a really fabulous piece of operation software.

4 Test Management

Test Management is an important part in Quality Assurance and for every project in general. In order to assure that the device is working properly, the following tests were carried out:

4.1 GPSDO frequency stability and usage of GPS stability vs GPS disconnected state

Check how the GPSDO works without a GPD discipline and after it is connected

4.2 GPSDO distance main signal vs first overtone

Check the dB distance of the 10 MHz signal towards the first overtone

4.3 GPSDO spectral purity

Check if the signal produces only clean 10 MHz (and maybe overtones) but nothing else

4.4 GPSDO 10 MHz signal form assessment

Check if it is a proper sine wave.

4.5 GPSDO signal voltage

Check the voltage and wave form of the outputs and see if there are no bad things on the signal.

4.6 Distribution Amplifier output signal quality

Check the voltage and wave form of the outputs and see if there are no bad things on the signal.

4.7 Distribution Amplifier distance main signal vs first overtone

Check if the distance to the first overtone in terms of signal power is big enough

4.8 Distribution Amplifier Output Phase Difference

Ensure that there is no phase difference on the outputs

4.9 HackRF ref clock input

hackrf-debug --si5351c -n 0 -r -d <serial number>

0x01 bedeutet: GPSDO Signal wird erkannt und verwendet

4.10 HackRF Reception using RemSDR

See if we can receive signals generally

4.11 HackRF Transmit 70cm using GNURadio

Generate a carrier and see if we can produce something at all and if it arrives at an antenna

4.12 HackRF Transmit 2,4GHz using GNURadio

See if we can generate a reference signal at the target frequency

4.13 HackRF Transmit 2,4GHz using GNURadio with Power Amplifier

Check if we can drive the power amplifier. See if the 10dBm output is enough or if an intermediate driver is necessary. Use 30V input power for the PA.

Result: 10dBm input at the PA will produce about 5W out. That's enough. Even if we transmit less (2-3W), it is still OK.

The following picture is a measurement with 30dB 10W attenuator and 20dB low power attenuator, totalling 50dB attenuation. So TX power is 37dBm.

2022-10-02-qo100-tx-test-max-power.png

4.14 PA current at different input voltages

Measure current at 10V, 20V, 30V

Result: Decision to drive it constantly with 24V

4.15 PA FWD monitor voltage

See if the monitor voltage that comes out of the PA (nominal between 0-4V) acts as expected

Result: 2,2V auf Forward-Pin bei 37dBm Sendeleistung

4.16 PA SWR monitor voltage

See if there is a SWR voltage. Unfortunately a Calibrated Mismatch Load is too expesive.

Result: We do see a voltage, bu it is small. 0,57V Spannung auf SWR-Pin bei 37dBm Sendeleistung

4.17 48V / 24V Converter Ripple

Check ripple voltage in PA input voltage

Result: Smaller than 0,2 % (good)

4.18 Bias Tee Controll Voltages

Check if the voltages produced by the controller board arrive at the bias tee.

Result: OK

4.19 Generate HF via WebGUI

Check if all of the transmit path works properly. Talk into the notebook microphone and listen on a handheld radio on 70cm. Check if the audio is good and if the delay is still acceptable.

Result: Works

4.20 Receive HF via WebGUI

Check if all of the receive path works properly. Talk into the handheld radio's microphone and listen to the signal on the WebGUI. Check if the audio is good and if the delay is still acceptable.

Result: Works

4.21 Transmit HF on the target frequency

Check if HF comes out of the N socket on the bottom. Use attenuators of 50dB and see if the signal on the target freqency can be detected on my spectrum anayzer. Operate the PTT in the Web GUI

Result: Works

4.22 Receive HF via WebGUI

Check if the RX configuration is OK. Trasmit on my handheld and see if a carrier is visible on the target frequency minus the LO offset.

Result: Works

2022-10-04-trx-1.png

4.23 Receive 10 GHz

This is the pre-final test of the entire RX chain. It was only possible because I had access to a 10 GHz signal generator: Generate a sine at 10.490 MHz and inject it into the Kuhne LNC. The LNC can tolerae a signal up to 0 dBm (1mW), so start with a signal power of -130 dBm and gradualy increase power until a signal comes up in the waterfall.

The finding was that a signal of -65 dBm was accoustically detectable, with a stable signal at -55 dBm.

Result: Works. Now I can say that the entire setup works as designed. I just need to find the satellite up there.

4.24 Operate the rig

This is the final test of the entire setup.

Result: Works

2022-10-14-QO100.png

5 Images

  • 2022-10-01-qo100-1.jpg 2022-10-01-qo100-2.jpg
  • 2022-10-01-qo100-3.jpg 2022-10-01-qo100-4.jpg
  • 2022-10-01-qo100-5.jpg 2022-10-01-qo100-6.jpg
  • 2022-10-01-qo100-7.jpg 2022-10-01-qo100-8.jpg
  • 2022-10-01-qo100-9.jpg 2022-10-01-qo100-10.jpg
  • 2022-10-01-qo100-11.jpg 2022-10-01-qo100-12.jpg
  • 2022-10-01-qo100-13.jpg 2022-10-01-qo100-14.jpg
  • 2022-10-01-qo100-15.jpg 2022-10-01-qo100-16.jpg