kopia lustrzana https://github.com/robertostling/wspr-tools
Added transmitter code
rodzic
5d6cc31fbc
commit
74218716e3
15
README.md
15
README.md
|
@ -8,3 +8,18 @@ Code for the WSPR protocol
|
|||
Currently only simple callsigns and 4-symbol locators are accepted. Power is
|
||||
in dBm.
|
||||
|
||||
## arduino_ad9851.ino
|
||||
|
||||
Arduino program to actually transmit the data generated by `encode.py` using
|
||||
an AD9851 module.
|
||||
|
||||
**Note**: if you use the square wave output (QOUT1 or its inverse QOUT2),
|
||||
make sure to tune the comparator voltage to achieve a reasonable duty cycle.
|
||||
If followed by a class E amplifier this is about 45% for maximum power output
|
||||
(anywhere near 50% should be OK). I use a DC voltmeter and approximate the
|
||||
duty cycle with V/5, so that a measured 2V reading translates into a 40% duty
|
||||
cycle.
|
||||
|
||||
You could of course also take either of the sine wave outputs (ZOUT1, ZOUT2)
|
||||
and amplify or feed directly into a low-pass filter to the antenna.
|
||||
|
||||
|
|
|
@ -0,0 +1,149 @@
|
|||
/* AD9851 module WSPR transmitter
|
||||
* Robert Östling SM0YSR 2017-08-29
|
||||
*
|
||||
* Use the encode.py script to generate the data to transmit, then paste it
|
||||
* into msg = { ... } below.
|
||||
*
|
||||
* You may also want to tweak the frequency:
|
||||
*/
|
||||
|
||||
// Set TX frequency
|
||||
#define F_BASE 3594086.0
|
||||
//#define F_BASE 10140186.0
|
||||
|
||||
byte msg[162] = { /* output of encode.py */ };
|
||||
|
||||
|
||||
byte pin_button = 2; // button that pulls LOW to start transmitting
|
||||
// internal pull-up is enabled, so just short to GND
|
||||
// This is just for timing, after the button is
|
||||
// pressed the system will go into an infinite loop
|
||||
// transmitting every 10 minutes.
|
||||
|
||||
byte pin_key = 3; // "keyer" output, HIGH = enable TX
|
||||
byte pin_reset = 4; // DDS reset pin
|
||||
byte pin_load = 5; // DDS load pin
|
||||
byte pin_clock = 6; // DDS clock pin
|
||||
byte pin_data = 7; // DDS data pin
|
||||
byte pin_led = 13; // Arduino LED
|
||||
|
||||
/*
|
||||
Left side of module (with LED facing up, at upper right corner):
|
||||
|
||||
VCC
|
||||
W_CLK (clock)
|
||||
FU_UD (load)
|
||||
DATA (data)
|
||||
RESET (reset)
|
||||
GND
|
||||
QOUT1
|
||||
QOUT2
|
||||
ZOUT1
|
||||
ZOUT2
|
||||
*/
|
||||
|
||||
// Encoded frequency table for the 4 FSK tones
|
||||
// This is pre-computed so that it can be sent directly to the DDS
|
||||
unsigned long fsk[4] = {
|
||||
(unsigned long)((F_BASE * 4294967296.0) / 180e6),
|
||||
(unsigned long)(((F_BASE + 1.0*1.4648) * 4294967296.0) / 180e6),
|
||||
(unsigned long)(((F_BASE + 2.0*1.4648) * 4294967296.0) / 180e6),
|
||||
(unsigned long)(((F_BASE + 3.0*1.4648) * 4294967296.0) / 180e6)
|
||||
};
|
||||
|
||||
void write_bit(byte x) {
|
||||
if(x) {
|
||||
digitalWrite(pin_clock, LOW);
|
||||
digitalWrite(pin_data, HIGH);
|
||||
digitalWrite(pin_clock, HIGH);
|
||||
digitalWrite(pin_data, LOW);
|
||||
} else {
|
||||
digitalWrite(pin_clock, LOW);
|
||||
digitalWrite(pin_data, LOW);
|
||||
digitalWrite(pin_clock, HIGH);
|
||||
}
|
||||
}
|
||||
|
||||
void write_byte(byte x) {
|
||||
for(byte i=0; i<8; i++) {
|
||||
write_bit(x&1);
|
||||
x >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
void set_frequency_word(unsigned long w) {
|
||||
digitalWrite(pin_load, LOW);
|
||||
for(byte i=0; i<32; i++) {
|
||||
write_bit(w&1);
|
||||
w >>= 1;
|
||||
}
|
||||
write_byte(0x09);
|
||||
digitalWrite(pin_load, HIGH);
|
||||
}
|
||||
|
||||
void setup() {
|
||||
pinMode(pin_reset, OUTPUT);
|
||||
pinMode(pin_load, OUTPUT);
|
||||
pinMode(pin_clock, OUTPUT);
|
||||
pinMode(pin_data, OUTPUT);
|
||||
pinMode(pin_led, OUTPUT);
|
||||
pinMode(pin_key, OUTPUT);
|
||||
pinMode(pin_button, INPUT_PULLUP);
|
||||
|
||||
digitalWrite(pin_reset, LOW);
|
||||
digitalWrite(pin_clock, LOW);
|
||||
digitalWrite(pin_data, LOW);
|
||||
digitalWrite(pin_load, LOW);
|
||||
digitalWrite(pin_led, LOW);
|
||||
digitalWrite(pin_key, LOW);
|
||||
|
||||
delay(2000);
|
||||
|
||||
digitalWrite(pin_reset, HIGH);
|
||||
delay(5);
|
||||
digitalWrite(pin_reset, LOW);
|
||||
delay(5);
|
||||
|
||||
digitalWrite(pin_clock, HIGH);
|
||||
delay(5);
|
||||
digitalWrite(pin_clock, LOW);
|
||||
delay(5);
|
||||
|
||||
digitalWrite(pin_load, HIGH);
|
||||
delay(5);
|
||||
digitalWrite(pin_load, LOW);
|
||||
delay(5);
|
||||
|
||||
// Arbitrary
|
||||
set_frequency_word(fsk[0]);
|
||||
}
|
||||
|
||||
// Infinite transmit loop, one message every 10 minutes
|
||||
void tx() {
|
||||
int i;
|
||||
unsigned long t0 = millis();
|
||||
|
||||
while(1) {
|
||||
digitalWrite(pin_key, HIGH);
|
||||
for (i=0; i<162; i++) {
|
||||
set_frequency_word(fsk[msg[i]]);
|
||||
double target =
|
||||
t0 + (unsigned long)(((double)(i+1))*(1000.0*8192.0/12000.0));
|
||||
digitalWrite(pin_led, (i&1));
|
||||
while(millis() < target);
|
||||
}
|
||||
digitalWrite(pin_key, LOW);
|
||||
digitalWrite(pin_led, LOW);
|
||||
t0 += 600000UL;
|
||||
while(millis() < t0);
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// Wait for button press, then start infinite loop
|
||||
if (digitalRead(pin_button) == LOW) {
|
||||
tx();
|
||||
// this will never be reached
|
||||
}
|
||||
}
|
||||
|
Ładowanie…
Reference in New Issue