diff --git a/examples/PSK31-Transmit/PSK31-Transmit.ino b/examples/PSK31-Transmit/PSK31-Transmit.ino index 70fbc03..13a3e0f 100644 --- a/examples/PSK31-Transmit/PSK31-Transmit.ino +++ b/examples/PSK31-Transmit/PSK31-Transmit.ino @@ -5,6 +5,7 @@ DDS dds; void setup() { Serial.begin(9600); + pinMode(11, OUTPUT); pinMode(3, OUTPUT); pinMode(2, OUTPUT); // put your setup code here, to run once: diff --git a/examples/QPSK63-Transmit/QPSK63-Transmit.ino b/examples/QPSK63-Transmit/QPSK63-Transmit.ino new file mode 100644 index 0000000..e57c245 --- /dev/null +++ b/examples/QPSK63-Transmit/QPSK63-Transmit.ino @@ -0,0 +1,98 @@ +#include +#include "varicode.h" + +DDS dds; + +void setup() { + Serial.begin(9600); + pinMode(11, OUTPUT); + pinMode(3, OUTPUT); + pinMode(2, OUTPUT); + // put your setup code here, to run once: + dds.setReferenceClock(32000); + dds.start(); + dds.setFrequency(1000); + dds.on(); +} + +volatile bool sent = true; +volatile uint16_t bitsToSend = 0; +volatile uint8_t zeroCount = 0; + +void sendChar(uint8_t c) { + uint16_t bits = varicode[c]; + while((bits&0x8000)==0) { + bits<<=1; + } + while(!sent) {} //delay(32); + cli(); + sent = false; + bitsToSend = bits; + sei(); + while(!sent) {} //delay(32); + //PORTD &= ~_BV(2); // Diagnostic pin (D2) +} + +char *string = "Why hello there, friend. Nice to meet you. Welcome to PSK31. 73, VE6SLP sk\r\n"; +void loop() { + int i; + // put your main code here, to run repeatedly: + //for(i = 0; i<5; i++) + // sendChar(0); + // return; + for(i = 0; i < strlen(string); i++) { + sendChar(string[i]); + //Serial.println(string[i]); + } +} + +const uint8_t amplitudeShape[41] = { + 255, 241, 228, 215, 203, 191, 181, 171, 161, 152, 143, 135, 128, 121, 114, 107, 101, 96, 90, 85, 80, 76, 72, 68, 64, 60, 57, 54, 51, 48, 45, 42, 40, 38, 36, 34, 32, 30, 28, 27, 25 +}; + +// This will trigger at 8kHz +const uint16_t qpskConvolution[32] = { + 180, 90, -90, 0, -90, 0, 180, 90, + 0, -90, 90, 180, 90, 180, 0, -90, + 90, 180, 0, -90, 0, -90, 90, 180, + -90, 0, 180, 90, 180, 90, -90, 0 +}; +uint8_t last5Bits = 0b00000; +ISR(ADC_vect) { + static uint8_t outer = 0; + static uint8_t tcnt = 0; + TIFR1 |= _BV(ICF1); + // Wave shaping + // TODO: Improve how this would perform. + if(tcnt < 81) + dds.setAmplitude(amplitudeShape[(81-tcnt)/2]); + if(tcnt > (255-81)) + dds.setAmplitude(amplitudeShape[(tcnt-174)/2]); + dds.clockTick(); + + if(outer++ == 1) { + outer = 0; + } else { + return; + } + + if(tcnt++ == 0) { // Next bit + last5Bits <<= 1; + if(!sent) { + if((bitsToSend & 0x8000) == 0) { + zeroCount++; + } else { + zeroCount = 0; + last5Bits |= 1; + } + dds.changePhaseDeg(qpskConvolution[last5Bits&31]); + bitsToSend<<=1; + if(zeroCount == 2) { + sent = true; + } + } else { + // Idle on zeroes + dds.changePhaseDeg(qpskConvolution[last5Bits&31]); + } + } +} diff --git a/examples/QPSK63-Transmit/varicode.h b/examples/QPSK63-Transmit/varicode.h new file mode 100644 index 0000000..bac5fa2 --- /dev/null +++ b/examples/QPSK63-Transmit/varicode.h @@ -0,0 +1,130 @@ +const uint16_t varicode[] = { +0xAAC0, // ASCII = 0 1010101011 +0xB6C0, // ASCII = 1 1011011011 +0xBB40, // ASCII = 2 1011101101 +0xDDC0, // ASCII = 3 1101110111 +0xBAC0, // ASCII = 4 1011101011 +0xD7C0, // ASCII = 5 1101011111 +0xBBC0, // ASCII = 6 1011101111 +0xBF40, // ASCII = 7 1011111101 +0xBFC0, // ASCII = 8 1011111111 +0xEF00, // ASCII = 9 11101111 +0xE800, // ASCII = 10 11101 +0xDBC0, // ASCII = 11 1101101111 +0xB740, // ASCII = 12 1011011101 +0xF800, // ASCII = 13 11111 +0xDD40, // ASCII = 14 1101110101 +0xEAC0, // ASCII = 15 1110101011 +0xBDC0, // ASCII = 16 1011110111 +0xBD40, // ASCII = 17 1011110101 +0xEB40, // ASCII = 18 1110101101 +0xEBC0, // ASCII = 19 1110101111 +0xD6C0, // ASCII = 20 1101011011 +0xDAC0, // ASCII = 21 1101101011 +0xDB40, // ASCII = 22 1101101101 +0xD5C0, // ASCII = 23 1101010111 +0xDEC0, // ASCII = 24 1101111011 +0xDF40, // ASCII = 25 1101111101 +0xEDC0, // ASCII = 26 1110110111 +0xD540, // ASCII = 27 1101010101 +0xD740, // ASCII = 28 1101011101 +0xEEC0, // ASCII = 29 1110111011 +0xBEC0, // ASCII = 30 1011111011 +0xDFC0, // ASCII = 31 1101111111 +0x8000, // ASCII = ' ' 1 +0xFF80, // ASCII = '!' 111111111 +0xAF80, // ASCII = '"' 101011111 +0xFA80, // ASCII = '#' 111110101 +0xED80, // ASCII = '$' 111011011 +0xB540, // ASCII = '%' 1011010101 +0xAEC0, // ASCII = '&' 1010111011 +0xBF80, // ASCII = ''' 101111111 +0xFB00, // ASCII = '(' 11111011 +0xF700, // ASCII = ')' 11110111 +0xB780, // ASCII = '*' 101101111 +0xEF80, // ASCII = '+' 111011111 +0xEA00, // ASCII = ',' 1110101 +0xD400, // ASCII = '-' 110101 +0xAE00, // ASCII = '.' 1010111 +0xD780, // ASCII = '/' 110101111 +0xB700, // ASCII = '0' 10110111 +0xBD00, // ASCII = '1' 10111101 +0xED00, // ASCII = '2' 11101101 +0xFF00, // ASCII = '3' 11111111 +0xBB80, // ASCII = '4' 101110111 +0xAD80, // ASCII = '5' 101011011 +0xB580, // ASCII = '6' 101101011 +0xD680, // ASCII = '7' 110101101 +0xD580, // ASCII = '8' 110101011 +0xDB80, // ASCII = '9' 110110111 +0xF500, // ASCII = ':' 11110101 +0xDE80, // ASCII = ';' 110111101 +0xF680, // ASCII = '<' 111101101 +0xAA00, // ASCII = '=' 1010101 +0xEB80, // ASCII = '>' 111010111 +0xABC0, // ASCII = '?' 1010101111 +0xAF40, // ASCII = '@' 1010111101 +0xFA00, // ASCII = 'A' 1111101 +0xEB00, // ASCII = 'B' 11101011 +0xAD00, // ASCII = 'C' 10101101 +0xB500, // ASCII = 'D' 10110101 +0xEE00, // ASCII = 'E' 1110111 +0xDB00, // ASCII = 'F' 11011011 +0xFD00, // ASCII = 'G' 11111101 +0xAA80, // ASCII = 'H' 101010101 +0xFE00, // ASCII = 'I' 1111111 +0xFE80, // ASCII = 'J' 111111101 +0xBE80, // ASCII = 'K' 101111101 +0xD700, // ASCII = 'L' 11010111 +0xBB00, // ASCII = 'M' 10111011 +0xDD00, // ASCII = 'N' 11011101 +0xAB00, // ASCII = 'O' 10101011 +0xD500, // ASCII = 'P' 11010101 +0xEE80, // ASCII = 'Q' 111011101 +0xAF00, // ASCII = 'R' 10101111 +0xDE00, // ASCII = 'S' 1101111 +0xDA00, // ASCII = 'T' 1101101 +0xAB80, // ASCII = 'U' 101010111 +0xDA80, // ASCII = 'V' 110110101 +0xAE80, // ASCII = 'W' 101011101 +0xBA80, // ASCII = 'X' 101110101 +0xBD80, // ASCII = 'Y' 101111011 +0xAB40, // ASCII = 'Z' 1010101101 +0xFB80, // ASCII = '[' 1111101110 +0xF780, // ASCII = '\' 111101111 +0xFD80, // ASCII = ']' 111111011 +0xAFC0, // ASCII = '^' 1010111111 +0xB680, // ASCII = '_' 101101101 +0xB7C0, // ASCII = '`' 1011011111 +0xB000, // ASCII = 'a' 1011 +0xBE00, // ASCII = 'b' 1011111 +0xBC00, // ASCII = 'c' 101111 +0xB400, // ASCII = 'd' 101101 +0xC000, // ASCII = 'e' 11 +0xF400, // ASCII = 'f' 111101 +0xB600, // ASCII = 'g' 1011011 +0xAC00, // ASCII = 'h' 101011 +0xD000, // ASCII = 'i' 1101 +0xF580, // ASCII = 'j' 111101011 +0xBF00, // ASCII = 'k' 10111111 +0xD800, // ASCII = 'l' 11011 +0xEC00, // ASCII = 'm' 111011 +0xF000, // ASCII = 'n' 1111 +0xE000, // ASCII = 'o' 111 +0xFC00, // ASCII = 'p' 111111 +0xDF80, // ASCII = 'q' 110111111 +0xA800, // ASCII = 'r' 10101 +0xB800, // ASCII = 's' 10111 +0xA000, // ASCII = 't' 101 +0xDC00, // ASCII = 'u' 110111 +0xF600, // ASCII = 'v' 1111011 +0xD600, // ASCII = 'w' 1101011 +0xDF00, // ASCII = 'x' 11011111 +0xBA00, // ASCII = 'y' 1011101 +0xEA80, // ASCII = 'z' 111010101 +0xADC0, // ASCII = '{' 1010110111 +0xDD80, // ASCII = '|' 110111011 +0xAD40, // ASCII = '}' 1010110101 +0xB5C0, // ASCII = '~' 1011010111 +0xED40 // ASCII = 127 1110110101 +};