Here are the details of a CW Beacon I made, based on the AD9850 Arduino shield. Code below, insert your own message in the code and upload. Can easily be modified to read in the message from your keyboard and send it. PSK31 version underway, watch this space
Code
// CWTX Beacon
// V1.1 4-3-17
// Thanks to F0GOJ for some of the code
// AD9850
// W_CLK 8
// FQ_UD 9
// DATA 10
// RESET 11
// LCD I2C bus (16x2)
// SDA = A4
// SCL = A5
// ADS9850, LCD and Rotary Encoder libraries
#include "ADS9850.h"
#include "LiquidCrystal_I2C.h"
// AD9850 pins
#define W_CLK 8
#define FQ_UD 9
#define DATA 10
#define RESET 11
// xtal calibration
#define CALIBRATE 124999500
// chose address of 0x27 or 0x3F for LCD
#define LCDADDR 0x27
//#define LCDADDR 0x3F
#define LCDCOLS 16
#define LCDROWS 2
// morse varicode index 0-58 is SP to Z
// [code in a byte][7-n bits to send, MSB first]
// e.g. 192 = 1100 0000, top 4 bits 7-4 = --.. or Z
// 0 = dot, 1 = dash
static int morseVaricode[2][59] = {
{ 0, 212, 72, 0, 144, 0, 128, 120, 176, 180,
0, 80, 204, 132, 84, 144, 248, 120, 56, 24,
8, 0, 128, 192, 224, 240, 224, 168, 0, 136,
0, 48, 104, 64, 128, 160, 128, 0, 32, 192,
0, 0, 112, 160, 64, 192, 128, 224, 96, 208,
64, 0, 128, 32, 16, 96, 144, 176, 192
},
{ 7, 6, 5, 0, 4, 0, 4, 6, 5, 6,
0, 5, 6, 6, 6, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 6, 6, 0, 5,
0, 6, 6, 2, 4, 4, 3, 1, 4, 3,
4, 2, 4, 3, 4, 2, 2, 3, 4, 4,
3, 3, 1, 3, 4, 3, 4, 4, 4
}
};
// beacon message to send (u.c.)
char msg[] = "YOUR MESSAGE GOES HERE";
// freq is fHz + cHz, 7030000
long fHz = 7030000; // frequency Hz
long cHz = 0; // sub freuency cHz
//speed WPM
int wpm = 10;
// 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
// calibrate to xtal actual frequency
ads.calibrate(CALIBRATE);
dispMsg(0, 0, "cwTX");
dispFreq(5, 0, fHz+cHz/100, 2); // display FREQ xxxxxx.xx kHz col 5 row 0
dispMsg(0, 1, msg); // out msg
}
void loop() {
cwTx(fHz, cHz, msg, wpm); // send CW message
delay(5000); //repeat 5sec
}
// send CW on freqHz+freqChz, message, WPM
void cwTx(long freqHz, long freqChz, char *stringCw, int cwWpm) {
byte nbBits, bitVal; // nobits to send 7-nbBits
int d; // varicode data
// calculate dot time
int dotTime = 1200 / cwWpm; // Duration of 1 dot
// get 1st char
int c = *stringCw++; // read char
//send chars in CW
while (c != '\0') {
c = toupper(c); // u.c.just in case
if (c == ' ') { // catch ASCII SP
c = c - ' '; // convert c-32 to index 0 - 58
ads.down();
delay(dotTime * 7);
}
else if (c > ' ' && c < ']') {
c = c - ' '; // convert c-32 to index 0 - 58
d = morseVaricode[0][c]; // get CW varicode data
nbBits = morseVaricode[1][c]; // get CW varicode length
if (nbBits != 0) { // if not invalid morse
// characters # % < >
for (int b = 7; b > 7 - nbBits; b--) { // Send CW character
// (0 for dot, 1 for dash) MSB first
bitVal = bitRead(d, b); // look up varicode bit
ads.setFreq(freqHz, freqChz, 0); // transmit for
delay(dotTime + 2 * dotTime * bitVal);// dot length or a dash length
// dash = 3 times the dot
ads.down(); // synth off for
delay(dotTime); // 1 dot space between dots|dashes
}
}
ads.down(); // synth off 3 dots
delay(dotTime * 3); // between characters in a word
}
c = *stringCw++; // next character in string
}
ads.down(); // No more transmission
}
// 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