Showing posts with label WSPR. Show all posts
Showing posts with label WSPR. Show all posts

Thursday 6 June 2019

20m WSPR Beacon


Below is the software. Looks like the formatting has been affected when it was copied over. Auto format in the Arduino IDE works great!

*****************************************************************


#include <DDS.h>
#include <SoftwareSerial.h>

#define RESET 2
#define FQ_UD 3
#define W_CLK 4
#define DATA 5
#define HighPWR_LED 6
#define LowPWR_LED 7
#define TX_LED 8
#define Percent25_LED 9
#define Percent50_LED 10
#define Percent75_LED 11
#define Percent100_LED 12
#define SerialTX 13
#define SerialRX A0
#define Tone0_LED A1
#define Tone1_LED A2
#define Tone2_LED A3
#define Tone3_LED A4

const int GPS_BUFFER_SIZE = 200;                              // The maximum size allowed for an NMEA sentence.
char sentence[GPS_BUFFER_SIZE] = {0};
volatile int _sentenceIndex = 0;
volatile char character = 0;
volatile int SymbolIndex = 0;
volatile int TX = 0;
volatile int Power = 0;
volatile int _UTCMinutes, _UTCSeconds = 0;
volatile long freq = 0;

const byte LowPWR_WSPR_Data[] = {3, 1, 2, 0, 2, 2, 0, 2, 3, 2, 0, 0, 1, 1, 1, 0, 2, 2, 3, 2, 2, 3, 2, 3, 1, 3, 3, 2, 0, 2, 0, 2,
                                 0, 2, 3, 2, 2, 3, 2, 1, 0, 0, 2, 0, 0, 0, 1, 0, 1, 3, 2, 2, 1, 3, 0, 3, 0, 2, 2, 1, 3, 0, 3, 0,
                                 2, 0, 0, 3, 3, 2, 3, 2, 3, 2, 3, 0, 1, 0, 0, 1, 2, 2, 1, 2, 1, 3, 0, 0, 0, 3, 3, 0, 1, 0, 1, 2,
                                 2, 2, 3, 0, 0, 0, 2, 0, 3, 0, 0, 3, 0, 0, 3, 3, 3, 2, 3, 1, 2, 0, 1, 3, 2, 3, 0, 0, 2, 1, 3, 1,
                                 2, 0, 0, 2, 2, 3, 0, 1, 0, 2, 1, 3, 0, 0, 0, 2, 2, 0, 0, 3, 3, 0, 3, 0, 3, 3, 2, 2, 2, 1, 3, 2,
                                 2, 0
                                };

const byte HighPWR_WSPR_Data[] = {3, 1, 2, 0, 2, 0, 0, 2, 3, 0, 0, 2, 1, 3, 1, 2, 2, 2, 3, 2, 2, 3, 2, 3, 1, 3, 3, 0, 0, 0, 0, 0,
                                  0, 2, 3, 0, 2, 1, 2, 3, 0, 0, 2, 0, 0, 0, 1, 0, 1, 1, 2, 0, 1, 1, 0, 3, 0, 0, 2, 1, 3, 0, 3, 0,
                                  2, 0, 0, 1, 3, 2, 3, 2, 3, 2, 3, 2, 1, 0, 0, 1, 2, 2, 1, 0, 1, 1, 0, 0, 0, 1, 3, 2, 1, 0, 1, 0,
                                  2, 2, 3, 0, 0, 2, 2, 0, 3, 2, 0, 1, 0, 2, 3, 1, 3, 0, 3, 1, 2, 2, 1, 3, 2, 1, 0, 2, 2, 3, 3, 1,
                                  2, 0, 0, 2, 2, 1, 0, 3, 0, 2, 1, 1, 0, 0, 0, 2, 2, 0, 0, 3, 3, 2, 3, 0, 3, 1, 2, 0, 2, 3, 3, 0,
                                  2, 0
                                 };

// Create the objects
DDS dds(W_CLK, FQ_UD, DATA, RESET);
SoftwareSerial mySerial(SerialRX, SerialTX);

void setup()
{
  // Initialize the AD9850
  dds.init();
  dds.trim(125000000);
  dds.setFrequency(0);

  // Initialize the Software serial port
  mySerial.begin(38400);

  pinMode(HighPWR_LED, OUTPUT);
  pinMode(LowPWR_LED, OUTPUT);
  pinMode(TX_LED, OUTPUT);
  pinMode(Percent25_LED, OUTPUT);
  pinMode(Percent50_LED, OUTPUT);
  pinMode(Percent75_LED, OUTPUT);
  pinMode(Percent100_LED, OUTPUT);
  pinMode(Tone0_LED, OUTPUT);
  pinMode(Tone1_LED, OUTPUT);
  pinMode(Tone2_LED, OUTPUT);
  pinMode(Tone3_LED, OUTPUT);

  digitalWrite(HighPWR_LED, LOW);
  digitalWrite(LowPWR_LED, LOW);
  digitalWrite(TX_LED, LOW);
  digitalWrite(Percent25_LED, LOW);
  digitalWrite(Percent50_LED, LOW);
  digitalWrite(Percent75_LED, LOW);
  digitalWrite(Percent100_LED, LOW);
  digitalWrite(Tone0_LED, LOW);
  digitalWrite(Tone1_LED, LOW);
  digitalWrite(Tone2_LED, LOW);
  digitalWrite(Tone3_LED, LOW);
}


void loop()
{
  if (TX == 0)
  {
    if (mySerial.available())
    {
      character = mySerial.read();                                                    // Get a single character
      sentence[_sentenceIndex] = character;                                           // Append the current character to the sentence
      _sentenceIndex++;

      if (_sentenceIndex == GPS_BUFFER_SIZE)                                          // Check for overrun of the sentence array. If so, restart
        _sentenceIndex = 0;

      if (character == '\r')                                                          // Carriage return. Look for RMC sentence
      {
        _sentenceIndex = 0;                                                           // Reset index counter ready for next timet

        if ((sentence[4] == 'R') && (sentence[5] == 'M') && (sentence[6] == 'C'))
        {
          _UTCSeconds = (10 * (sentence[12] - 48) + (sentence[13] - 48));
          _UTCMinutes = (10 * (sentence[10] - 48) + (sentence[11] - 48));

          if ((_UTCMinutes % 2 == 0) && ((_UTCSeconds == 0) || (_UTCSeconds == 1) || (_UTCSeconds == 2)))
            TX = 1;
        }
      }
    }
  }

  if (TX == 1)
  {
    digitalWrite(TX_LED, HIGH);                                                        // Turn on the TX LED
    freq = random(14097000, 14097200);                                                 // Select a random TX frequency

    if (Power == 0)
      for (SymbolIndex = 0; SymbolIndex <= 161; SymbolIndex++)
      {
        dds.setFrequency(freq + (LowPWR_WSPR_Data[SymbolIndex] * 1.4648));             // Change DDS freq
        ToneLEDs(LowPWR_WSPR_Data[SymbolIndex]);                                       // Update tone LEDs
        ProgressLEDs(SymbolIndex);                                                     // Update progress LEDs
        delay(683);
      }

    if (Power == 1)
      for (SymbolIndex = 0; SymbolIndex <= 161; SymbolIndex++)
      {
        dds.setFrequency(freq + (HighPWR_WSPR_Data[SymbolIndex] * 1.4648));             // Change DDS freq
        ToneLEDs(HighPWR_WSPR_Data[SymbolIndex]);                                       // Update tone LEDs
        ProgressLEDs(SymbolIndex);                                                      // Update progress LEDs
        delay(683);
      }

    dds.setFrequency(0);                                                                // Turn off the DDS
    ToneLEDs(4);                                                                        // Turn off the tone LEDs
    ProgressLEDs(0);                                                                    // Turn off the progress LEDs
    digitalWrite(TX_LED, LOW);                                                          // Turn off the TX LED
    TX = 0;
    Power = !Power;                                                                     // Toggle transmit power
    PowerLEDs(Power);                                                                   // Toggle power level LED
  }
}


void ToneLEDs(int x)
{
  switch (x)
  {
    case 4:
      digitalWrite(Tone0_LED, LOW);
      digitalWrite(Tone1_LED, LOW);
      digitalWrite(Tone2_LED, LOW);
      digitalWrite(Tone3_LED, LOW);
      break;
    case 3:
      digitalWrite(Tone0_LED, LOW);
      digitalWrite(Tone1_LED, LOW);
      digitalWrite(Tone2_LED, LOW);
      digitalWrite(Tone3_LED, HIGH);
      break;
    case 2:
      digitalWrite(Tone0_LED, LOW);
      digitalWrite(Tone1_LED, LOW);
      digitalWrite(Tone2_LED, HIGH);
      digitalWrite(Tone3_LED, LOW);
      break;
    case 1:
      digitalWrite(Tone0_LED, LOW);
      digitalWrite(Tone1_LED, HIGH);
      digitalWrite(Tone2_LED, LOW);
      digitalWrite(Tone3_LED, LOW);
      break;
    case 0:
      digitalWrite(Tone0_LED, HIGH);
      digitalWrite(Tone1_LED, LOW);
      digitalWrite(Tone2_LED, LOW);
      digitalWrite(Tone3_LED, LOW);
      break;
  }
}


void ProgressLEDs(int x)
{
  if (x <= 30)
  {
    digitalWrite(Percent25_LED, LOW);
    digitalWrite(Percent50_LED, LOW);
    digitalWrite(Percent75_LED, LOW);
    digitalWrite(Percent100_LED, LOW);
  }
  if ((x > 30) && (x <= 70))
  {
    digitalWrite(Percent25_LED, LOW);
    digitalWrite(Percent50_LED, LOW);
    digitalWrite(Percent75_LED, LOW);
    digitalWrite(Percent100_LED, HIGH);
  }
  if ((x > 70) && (x <= 110))
  {
    digitalWrite(Percent25_LED, LOW);
    digitalWrite(Percent50_LED, LOW);
    digitalWrite(Percent75_LED, HIGH);
    digitalWrite(Percent100_LED, HIGH);
  }
  if ((x > 110) && (x <= 150))
  {
    digitalWrite(Percent25_LED, LOW);
    digitalWrite(Percent50_LED, HIGH);
    digitalWrite(Percent75_LED, HIGH);
    digitalWrite(Percent100_LED, HIGH);
  }
  if (x > 150)
  {
    digitalWrite(Percent25_LED, HIGH);
    digitalWrite(Percent50_LED, HIGH);
    digitalWrite(Percent75_LED, HIGH);
    digitalWrite(Percent100_LED, HIGH);
  }
}


void PowerLEDs(int x)
{
  switch (x)
  {
    case 0:
      digitalWrite(LowPWR_LED, HIGH);
      digitalWrite(HighPWR_LED, LOW);
      break;
    case 1:
      digitalWrite(LowPWR_LED, LOW);
      digitalWrite(HighPWR_LED, HIGH);
      break;
  }
}
*************************************************************

The link to the GENWSPR file is: http://www.g4jnt.com/JTModesBcns.htm