Following up from the last project, the CW Beacon - I have re-written the code to use a set of Varicode for PSK31 symbols and to switch the frequency output by phase (0 or 180deg).
Reception on Mac cocoaModem software
This is the Arduino code.
Code
// BCN_PSK Beacon for PSK31 // V2 7-3-17 // thanks to F0GOJ for principles of the code // AD9850 // W_CLK 8 // FQ_UD 9 // DATA 10 // RESET 11 // LCD I2C bus (16x2) // SDA = A4 // SCL = A5 // ADS9850 and LCD I2C libraries #include "ADS9850.h" #include "LiquidCrystal_I2C.h" // AD9850 pins #define W_CLK 8 #define FQ_UD 9 #define DATA 10 #define RESET 11 // chose address of 0x27 or 0x3F for LCD #define LCDADDR 0x27 //#define LCDADDR 0x3F #define LCDCOLS 16 #define LCDROWS 2 // init freqs #define STARTHZ 7070000 #define STARTCHZ 0 #define BAUD 32 // psk varicode and index of length int pskVaricode[2][128] = { { 683, 731, 749, 887, 747, 863, 751, 765, 767, 239, 29, 879, 733, 31, 885, 939, 759, 757, 941, 943, 859, 875, 877, 855, 891, 893, 951, 853, 861, 955, 763, 895, 1, 511, 351, 501, 475, 725, 699, 383, 251, 247, 367, 479, 117, 53, 87, 431, 183, 189, 237, 255, 375, 347, 363, 429, 427, 439, 245, 445, 493, 85, 471, 687, 701, 125, 235, 173, 181, 119, 219, 253, 341, 127, 509, 381, 215, 187, 221, 171, 213, 477, 175, 111, 109, 343, 437, 349, 373, 379, 685, 503, 495, 507, 703, 365, 735, 11, 95, 47, 45, 3, 61, 91, 43, 13, 491, 191, 27, 59, 15, 7, 63, 447, 21, 23, 5, 55, 123, 107, 223, 93, 469, 695, 443, 693, 727, 949 }, { 10, 10, 10, 10, 10, 10, 10, 10, 10, 8, 5, 10, 10, 5, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 1, 9, 9, 9, 9, 10, 10, 9, 8, 8, 9, 9, 7, 6, 7, 9, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 8, 9, 9, 7, 9, 10, 10, 7, 8, 8, 8, 7, 8, 8, 9, 7, 9, 9, 8, 8, 8, 8, 8, 9, 8, 7, 7, 9, 9, 9, 9, 9, 10, 9, 9, 9, 10, 9, 10, 4, 7, 6, 6, 2, 6, 7, 6, 4, 9, 8, 5, 6, 4, 3, 6, 9, 5, 5, 3, 6, 7, 7, 8, 7, 9, 10, 9, 10, 10, 10 } }; // beacon message to send char msg[] = "Beacon de M0IFA..."; // freq in Hz and cHz long freqHz = STARTHZ; // frequency Hz long freqChz = STARTCHZ; // sub freuency cHz // repeat time (ms) long repeat = 2000; // ads (analog-output digital synthesiser) object ADS9850 ads; // lcd object LiquidCrystal_I2C lcd(LCDADDR, LCDCOLS, LCDROWS); void setup() { // init LCD lcd.begin(); //init AD9850 ads.begin(W_CLK, FQ_UD, DATA, RESET); // initialise synthesiser, pins dispMsg(0, 0, "BCNPSK"); dispFreq(7, 0, freqHz + freqChz / 100, 2); // display FREQ xxxxxx.xx kHz col 5 row 0 dispMsg(0, 1, msg); // out msg } void loop() { // send message at frequency sendMsg(freqHz, freqChz, msg); delay(repeat); // repeat } // send message void sendMsg(long fHz, long fChz, char m[]) { int c, vCode, bits; uint8_t phase; phase = 0x00; // Idle is zeroes so only phase inversion for (int n = 0; n < BAUD; n++) { phase = phase ^ 0x10; // XOR toggle b4 1 0000 <-> 0 0000 ads.setFreq(fHz, fChz, phase); delay((961 + BAUD) / BAUD); // fix baud rate } c = 0; while (m[c] != '\0') { vCode = pskVaricode[0][m[c]]; // Get PSK varicode bits = pskVaricode[1][m[c]]; // Get PSK varicode length vCode <<= 2; // add 00 on lsb for char space bits += 1; // msb to 0 //send char in psk for (int n = bits; n >= 0; n--) { // msb 1st, bits to 0 if (bitRead(vCode, n) == 0) // 0 | 1 ? phase = phase ^ 0x10; // XOR toggle b4 1 0000 <-> 0 0000 ads.setFreq(fHz, fChz, phase); // transmit delay((961 + BAUD) / BAUD); // set speed } c++; } phase = 0x00; // Idle is zeroes so only phase inversion for (int n = 0; n < BAUD; n++) { phase = phase ^ 0x10; // XOR toggle b4 1 0000 <-> 0 0000 ads.setFreq(fHz, fChz, phase); delay((961 + BAUD) / BAUD); // fix baud rate } // end of message ads.down(); } // display freq at c)ol, r)ow, f (cHz), to d decimal places (kHz) void dispFreq(uint8_t c, uint8_t r, uint64_t f, uint8_t d) { lcd.setCursor(c, r); lcd.print((float)f / 1000, d); // convert to float & kHz lcd.print("kHz "); } // display msg *m at c)ol, r)ow void dispMsg(uint8_t c, uint8_t r, char *m) { lcd.setCursor(c, r); lcd.print(m); }
No comments:
Post a Comment