Program to transmit strings as Morse code using the CC1200. Useful for amateur radio projects!
Dependencies: CC1200 SerialStream
CC1200Morse.cpp
00001 // 00002 // Created by jamie on 8/24/2020. 00003 // 00004 00005 #include "CC1200Morse.h" 00006 00007 #include <cinttypes> 00008 00009 // Morse code tables. 00010 // Covers ASCII ranges 0x41-0x5A and 0x61-0x7A 00011 char const * const alphaMorse[] = {".-","-...","-.-.","-..",".","..-.","--.","....","..",".---", 00012 "-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-", 00013 "...-",".--","-..-","-.--","--.."}; 00014 00015 // Covers ASCII range 0x30-0x39 00016 char const * const numMorse[] = {"-----",".----","..---","...--","....-",".....","-....","--...","---..","----."}; 00017 00018 // covers ASCII range 0x21-0x2F 00019 char const * const punctuation1Morse[] = {"-.-.--", ".-..-.", nullptr, "...-..-", nullptr, ".-...", ".----.", "-.--.", 00020 "-.--.-", nullptr, ".-.-.", "--..--", nullptr, ".-.-.-", "-..-."}; 00021 00022 // covers ASCII range 0x3A-0x40 00023 char const * const punctuation2Morse[] = {"---...", "-.-.-.", nullptr, "-...-", nullptr, "..--..", ".--.-."}; 00024 00025 void CC1200Morse::configure(CC1200::Band band, float radioFrequency, float morseTimePeriod, float transmitPower) 00026 { 00027 radio.setPacketMode(CC1200::PacketMode::FIXED_LENGTH); 00028 radio.setCRCEnabled(false); 00029 00030 // set frequency 00031 radio.setSymbolRate(1/morseTimePeriod); 00032 radio.setRadioFrequency(band, radioFrequency); 00033 00034 // disable anything getting sent before the data 00035 radio.configureSyncWord(0x0, CC1200::SyncMode::SYNC_NONE, 8); 00036 radio.configurePreamble(0, 0); 00037 00038 // configure OOK modulation 00039 radio.setModulationFormat(CC1200::ModFormat::ASK); 00040 radio.disablePARamping(); 00041 radio.setASKPowers(transmitPower, CC1200::ASK_MIN_POWER_OFF); 00042 } 00043 00044 // helper function for convertToMorse 00045 static bool appendBits(uint8_t *outputBuffer, size_t bufferLen, uint8_t & nextBit, size_t & currByte, uint8_t toAppend, size_t count) 00046 { 00047 //printf("appendBits(%" PRIu8 ", %zu)\n", toAppend, count); 00048 for(size_t counter = 0; counter < count; ++counter) 00049 { 00050 outputBuffer[currByte] |= toAppend << nextBit; 00051 00052 if(nextBit == 0) 00053 { 00054 nextBit = 7; 00055 currByte += 1; 00056 if(currByte >= bufferLen) 00057 { 00058 // out of space 00059 return false; 00060 } 00061 } 00062 else 00063 { 00064 nextBit--; 00065 } 00066 } 00067 00068 return true; 00069 } 00070 00071 00072 CC1200Morse::EncodedMorse CC1200Morse::convertToMorse(const char *string, uint8_t *outputBuffer, size_t bufferLen) 00073 { 00074 memset(outputBuffer, 0, bufferLen); 00075 00076 // place in the output buffer where next items will be written 00077 uint8_t nextBit = 7; 00078 size_t currByte = 0; 00079 00080 EncodedMorse encoded; 00081 encoded.buffer = outputBuffer; 00082 encoded.valid = false; 00083 00084 if(!appendBits(outputBuffer, bufferLen, nextBit, currByte, 0, spaceBefore)) 00085 { 00086 return encoded; 00087 } 00088 00089 size_t stringLength = strlen(string); 00090 for(size_t charIndex = 0; charIndex < stringLength; ++charIndex) 00091 { 00092 char currChar = string[charIndex]; 00093 char const * morseToAppend = nullptr; 00094 if((currChar >= 'A' && currChar <= 'Z')) 00095 { 00096 morseToAppend = alphaMorse[currChar - 'A']; 00097 } 00098 else if(currChar >= 'a' && currChar <= 'z') 00099 { 00100 morseToAppend = alphaMorse[currChar - 'a']; 00101 } 00102 else if(currChar >= '0' && currChar <= '9') 00103 { 00104 morseToAppend = numMorse[currChar - '0']; 00105 } 00106 else if(currChar >= '!' && currChar <= '/') 00107 { 00108 morseToAppend = punctuation1Morse[currChar - '!']; 00109 } 00110 else if(currChar >= ':' && currChar <= '@') 00111 { 00112 morseToAppend = punctuation2Morse[currChar - ':']; 00113 } 00114 else if(currChar == '_') // underscore is off by itself in the ASCII chart 00115 { 00116 morseToAppend = "..--.-"; 00117 } 00118 00119 // append bit timings 00120 //printf("currChar = '%c'\n", currChar); 00121 if(currChar == ' ') 00122 { 00123 // space between words is 7 time units 00124 if(!appendBits(outputBuffer, bufferLen, nextBit, currByte, 0, 7)) 00125 { 00126 return encoded; 00127 } 00128 } 00129 else if(morseToAppend != nullptr) 00130 { 00131 size_t morseLength = strlen(morseToAppend); 00132 for(size_t morseIndex = 0; morseIndex < morseLength; ++morseIndex) 00133 { 00134 // dot is 1 time unit, dash is 3 time units 00135 if(!appendBits(outputBuffer, bufferLen, nextBit, currByte, 1, morseToAppend[morseIndex] == '-' ? 3 : 1)) 00136 { 00137 return encoded; 00138 } 00139 00140 // space between symbols is 1 time unit 00141 if(!appendBits(outputBuffer, bufferLen, nextBit, currByte, 0, 1)) 00142 { 00143 return encoded; 00144 } 00145 } 00146 00147 // extra space between letters is 2 time units 00148 if(!appendBits(outputBuffer, bufferLen, nextBit, currByte, 0, 2)) 00149 { 00150 return encoded; 00151 } 00152 } 00153 } 00154 00155 if(!appendBits(outputBuffer, bufferLen, nextBit, currByte, 0, spaceAfter)) 00156 { 00157 return encoded; 00158 } 00159 00160 encoded.valid = true; 00161 encoded.byteLen = currByte; 00162 encoded.bitLen = 7 - nextBit; 00163 encoded.totalLength = currByte + (encoded.bitLen > 0 ? 1 : 0); 00164 00165 return encoded; 00166 } 00167 00168 void CC1200Morse::transmit(const CC1200Morse::EncodedMorse &morse) 00169 { 00170 if(morse.totalLength > 128) 00171 { 00172 // too large to send in one packet 00173 return; 00174 } 00175 radio.setPacketLength(morse.byteLen, morse.bitLen); 00176 radio.enqueuePacket(reinterpret_cast<const char *>(morse.buffer), morse.totalLength); 00177 }
Generated on Sun Jul 24 2022 06:31:11 by 1.7.2