I have already described a RTTY Beacon that just sends out regular fixed text messages. Here is a modification of that code that allows users to input text messages to be sent out. The Transmit frequency still remains fixed, but that can be updated in the future.
A new Serial Terminal software is used, in place of the one built in to the Arduino IDE (I have so often opened a sketch , opened the Serial Monitor, then accidentally typed text into the sketch not the monitor window! that I decided to use a dedicated Serial Terminal program, its called iSerialTerm (Mac only)).
Input text on iSerialTerm, on iMac, connected by USB to Arduino UNO/AD9850
Received text on SDR Concept radio and using HDSDR and MultiMode Cocoa decoder running on my MacBook
Code
// RTTY_TEXT // V1.0 29-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 // chose address of 0x27 or 0x3F for LCD //#define LCDADDR 0x27 #define LCDADDR 0x3F #define LCDCOLS 16 #define LCDROWS 2 // baudot varicode in b4-b0 (sent b0->b4) char rttyVaricode[59] = { 4, 22, 17, 5, 18, 0, 11, 26, 30, 9, 0, 0, 6, 24, 7, 23, 13, 29, 25, 16, 10, 1, 21, 28, 12, 3, 14, 15, 0, 0, 0, 19, 0, 24, 19, 14, 18, 16, 22, 11, 5, 12, 26, 30, 9, 7, 6, 3, 13, 29, 10, 20, 1, 28, 15, 25, 23, 21, 17 }; #define FIGS 27 #define LTRS 31 // message to send (u.c.) char msg[40]; // freq in Hz and cHz double freqHz = 7080000; // frequency Hz double freqChz = 0; // sub freuency cHz // ads (analog-output digital synthesiser) object ADS9850 ads; // lcd object LiquidCrystal_I2C lcd(LCDADDR, LCDCOLS, LCDROWS); void setup() { // Serial Serial.begin(9600); // init LCD lcd.begin(); //init AD9850, off to start ads.begin(W_CLK, FQ_UD, DATA, RESET); // initialise synthesiser, pins ads.down(); dispMsg(3, 0, "RTTY TEXT"); dispFreq(3, 1, freqHz, freqChz, 0); } void loop() { if (getMsg(msg) == true) { dispMsg(3, 1, "Sending Text... "); // sending Serial.println(msg); // send message at frequency sendMsg(freqHz, freqChz, msg); dispMsg(0, 1, " "); // clear line } clearBuf(msg); } void sendMsg(double fHz, double fChz, char *m) { bool figsLtrs; // FIGS/LTRS toggle char c; figsLtrs = 1; // start in letter mode rttyTxByte(fHz, fChz, 8); // LFCR for new message rttyTxByte(fHz, fChz, 2); c = *m++; while ( c != '\0') { // EOM? c = toupper((int)c); // get char, uppercase if (c == 10) { // Line Feed 8 rttyTxByte(fHz, fChz, 8); } else if (c == 13) { // Carriage Return 2 rttyTxByte(fHz, fChz, 2); } else if (c == 32) { rttyTxByte(fHz, fChz, 4); } else if (c > ' ' && c <= 'Z' ) { // non-baudot chars sent as blanks 00000 c = c - ' '; // c index 0-58 if (c < 33) { if (figsLtrs == 1) { // if LTRS figsLtrs = 0; // toggle to FIGS rttyTxByte(fHz, fChz, FIGS); // send 27 } } else if (figsLtrs == 0) { // if FIGS figsLtrs = 1; // toggle to LTRS rttyTxByte(fHz, fChz, LTRS); // send 31 } rttyTxByte(fHz, fChz, rttyVaricode[c]); // Send the 5 bits word } c = *m++; // Next character in string } ads.down(); } // send at fHzSymb, fChzSymb, rttyVaricode symb nnnnn void rttyTxByte(long fHzSymb, long fChzSymb, char symb) { int bits, val; // build the byte to send symb = (symb << 2) + 3; // shift two left, add B00000011, makes B0nnnnn11 for (bits = 7; bits >= 0; bits--) { // MSB first, b7 -> b0 val = bitRead(symb, bits); // Read 1 bit ads.setFreq(fHzSymb + (170 * val), fChzSymb, 0); // Let's transmit (bit 1 is 170Hz shifted up) delay(22); // Gives the baud rate, 22ms per bit } delay(110); // intersumbol pause } // get input msg[] U.C. bool getMsg(char *m) { char ch; int n; n = 0; if (Serial.available() > 0) { // if input while (Serial.available() > 0) { // get input ch = Serial.read(); // use upper case as input if (ch == '\n') ch = '\0'; // end of text m[n++] = ch; delay(20); // let USB catch up } return true; // got input } return false; // no input } // clear msg and buffer void clearBuf(char *m) { m[0] = '\0'; while (Serial.available() > 0) Serial.read(); } // display freq at c)ol, r)ow, f (cHz), d decimal places void dispFreq(uint8_t c, uint8_t r, float f, float cf, uint8_t d) { lcd.setCursor(c, r); lcd.print((f + cf / 100.0), d); lcd.print("Hz "); } // 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); }