kopia lustrzana https://github.com/robertostling/wspr-tools
150 wiersze
3.4 KiB
C++
150 wiersze
3.4 KiB
C++
/* 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
|
|
}
|
|
}
|
|
|