/* RTTY carrier modem generator by serial programming the si5351a dds ocsilator by Alastair GW0AJU */ #include #include #include Si5351 si5351; long frequency = 14.060e6; long freq_display = 0; long start_freq; long last_Set; long IF_LO; long bfo_freq; int RTTY_logic=13; // Pin 9 - TTL output of RTTY data signal logic // rtty data from left shift, the "b0 = (1 * start low)" + "b1 to b5 = (5 bit data)" + " b6 + b7 = (2 * stop high)" = 8bit single byte // bit zero is the start bit, next five are the RTTY data, followed by bits 6 and 7 for stop bit. // 2 bits are used for the stop instead of the 1.5bits, the extra addition to 2bit for a stop bit will not matter, // it will only extenduate the data sequence, but still be synchronised by the rtty decoder. byte info[] = {0x13,0x7F,0x2B,0x57,0x2B,0x57,0x0B,0x23}; // space,letter shift,R,Y,R,Y,carrige return,line feed unsigned long freq; void collect_tx_message() // collect rtty data stream message { byte d; for (d=0 ; d<8 ; d++ ) // d = the number RTTY message + control characters in bytes { tx_data_message(info[d]); } } void tx_data_message(byte mess) // decode data stream message and transmit rtty signal { byte p; for (p=0; p<8 ; p++, mess<<1) // rtty data sent in pattern due to data sequence { if ((mess & 0x01) == 0x01) // detect for mark tone { // Serial.print("1"); digitalWrite(RTTY_logic, HIGH); // TTL RTTY output at pin 13 sendFrequency_mark(frequency); // mark carrier freq = (space freq + 170Hz) delay(20); // delay period of data bit transmission } else if ((mess & 0x01) == 0x00) // detect for space tone { // Serial.print("0"); digitalWrite(RTTY_logic, LOW); // TTL RTTY output at pin 13 sendFrequency_space(frequency); // space carrier freq delay(20); // delay period of data bit transmission } } // delay period before retransmission of RTTY message // TX tone is mark tone as last used for stop bit of 1.5bits } //******************* programming si5351a as vfo oscillator ******************** void sendFrequency_mark(unsigned long f) { IF_LO = frequency + 170; if (last_Set != IF_LO) { si5351.set_freq( IF_LO * 100ULL, SI5351_CLK2); // rx local oscillator vfo si5351.update_status(); last_Set = IF_LO; } } void sendFrequency_space(unsigned long f) { IF_LO = frequency; if (last_Set != IF_LO) { si5351.set_freq( IF_LO * 100ULL, SI5351_CLK2); // rx local oscillator vfo si5351.update_status(); last_Set = IF_LO; } } void setup() { // Serial.begin(9600); // configure arduino data pins for output si5351.init(SI5351_CRYSTAL_LOAD_8PF, 0, 0); si5351.set_pll(SI5351_PLL_FIXED, SI5351_PLLA); si5351.set_pll(SI5351_PLL_FIXED, SI5351_PLLB); si5351.drive_strength(SI5351_CLK2, SI5351_DRIVE_2MA); si5351.output_enable(SI5351_CLK0, 0); si5351.output_enable(SI5351_CLK1, 0); si5351.output_enable(SI5351_CLK2, 1); // calibration of vfo with digital frequency counter to test 25MHz crystal //si5351.set_freq(50000000, SI5351_CLK2); si5351.update_status(); digitalWrite(RTTY_logic, HIGH); // TTL RTTY output at pin 12 sendFrequency_mark(frequency); // mark freq = (space freq + 170Hz) } void transmission() { si5351.output_enable(SI5351_CLK2, 1); // switch on dds output si5351.update_status(); delay(2000); // two second period of mark tone before data transmission collect_tx_message(); delay(1000); // end carrier mark tone si5351.output_enable(SI5351_CLK2, 0); // switch off dds output si5351.update_status(); delay(2000); // two second transmission break before restarting data transmission } void loop() { transmission(); }