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
Hello Charlie, i can't compile this :-(
ReplyDeleteWhere did you download the library:
#include
thanks Daniel/Germany
Ohh the software cuts the Library name :-(
ReplyDeleteThe name is: DDS.h
Hi David. This was in the README file for the DDS library:
ReplyDeleteDDS : A Library to host an AD9850 DDS Module on Arduino, using soft SPI
This is a library which controls the widely available,
low-cost Direct Digital Synthesis ('DDS') Modules,
based on the Analog Devices 9850 chip
on the Arduino.
For more information:
http://m0xpd.blogspot.co.uk/2014/03/dds-and-duedds-libraries.html
Four IO lines are required to connect to the AD9850 module...
(W_CLK, FQ_UD, DATA & RESET).
To download and use this Library, click the Download ZIP button (on the RHS of this screen).
Uncompressed the downloaded ZIP archive and rename the folder DDS.
Put this DDS folder in you Arduino Libraries folder and restart the Arduino IDE.
To control multiple DDS Modules, see here:
http://m0xpd.blogspot.co.uk/2015/06/handling-two-dds-modules-in-library.html
Thank you Charlie, now i can compile the sketch :-)
ReplyDeleteWill set up the LEDs and the AD module.
I like the Si5351 more, its only half the size and 2 ports A4/A5
Great videos and a lot of calculations on your papers for all the resistors..etc!
That's great. Glad to hear!
Delete