From 470e96c8eabe6bfa889182a71ca3bc21b2b9e31f Mon Sep 17 00:00:00 2001 From: SnkMtn000 Date: Thu, 1 Feb 2018 17:26:41 -0500 Subject: [PATCH] Add files via upload --- promini33_rfm69_FELD_HELL_Beacon_20180121.ino | 227 ++++++++ promini33_rfm69_FELD_HELL_GPS_20180116.ino | 261 +++++++++ ...ni33_rfm69_FELD_HELL_Keyboard_20180116.ino | 269 +++++++++ promini33_rfm69_Morse_Beacon_20180121.ino | 225 ++++++++ promini33_rfm69_Morse_GPS_20180118.ino | 261 +++++++++ promini33_rfm69_Morse_Keyboard_20180118.ino | 259 +++++++++ ...fm69_RTTY_5N1_4545_170_Beacon_20180121.ino | 464 +++++++++++++++ ...3_rfm69_RTTY_5N1_4545_170_GPS_20180119.ino | 507 +++++++++++++++++ ...69_RTTY_5N1_4545_170_Keyboard_20180118.ino | 535 ++++++++++++++++++ 9 files changed, 3008 insertions(+) create mode 100644 promini33_rfm69_FELD_HELL_Beacon_20180121.ino create mode 100644 promini33_rfm69_FELD_HELL_GPS_20180116.ino create mode 100644 promini33_rfm69_FELD_HELL_Keyboard_20180116.ino create mode 100644 promini33_rfm69_Morse_Beacon_20180121.ino create mode 100644 promini33_rfm69_Morse_GPS_20180118.ino create mode 100644 promini33_rfm69_Morse_Keyboard_20180118.ino create mode 100644 promini33_rfm69_RTTY_5N1_4545_170_Beacon_20180121.ino create mode 100644 promini33_rfm69_RTTY_5N1_4545_170_GPS_20180119.ino create mode 100644 promini33_rfm69_RTTY_5N1_4545_170_Keyboard_20180118.ino diff --git a/promini33_rfm69_FELD_HELL_Beacon_20180121.ino b/promini33_rfm69_FELD_HELL_Beacon_20180121.ino new file mode 100644 index 0000000..4dae64f --- /dev/null +++ b/promini33_rfm69_FELD_HELL_Beacon_20180121.ino @@ -0,0 +1,227 @@ +/* + * A simple GPS Feld Hell Beacon sender + * for the HopeRF rfm69hcw + * on a ProMini 3.3 + * Charles Webb + * KC1ENN@arrl.net + * + * with thanks to James Coxon + * + * Feld Hell for HopeRF rfm69hcw modifed from source below + * https://github.com/jamescoxon/PicoAtlas/blob/master/Pico6MK3/sketch_apr02b/sketch_apr02b.ino + * + * + */ + +#include + +#define MY_DELAY 5000 // delay in loop, between sending the message +//#define radioPower 0x50 // -2 dBm +///#define radioPower 0x52 // 0 dBm +//#define radioPower 0x55 // 3 dBm +//#define radioPower 0x58 // 6 dBm +//#define radioPower 0x5B // 9 dBm +//#define radioPower 0x5E // 12 dBm +#define radioPower 0x7F // 17 dBm +#define ssPin 10 // SS +//#define ssPin 8 // adafruit feather M0 +#define rstPin 9 // reset pin +//#define rstPin 4 // adafruit feather M0 +#define MODULATION 0x48 // Modulation for OOK, Continuous w.o bit synch, OOK, no shaping +#define myFrequency 433200000 +//#define myFrequency 915000000 + +unsigned int count = 0; +char mytext[80]; +String myCallSign = "CALLSIGN/B TEST BEACON"; +String myString = ""; + +void setup(){ + Serial.begin(9600); + pinMode(ssPin, OUTPUT); + pinMode(rstPin, OUTPUT); + setupSPI(); + delay(1000); + resetRFM69(); + delay(1000); + setupRFM69(); +} + +void loop(){ + count++; + buildString(); + myString.toCharArray(mytext,myString.length() + 1); + hellsendmsg(mytext); + delay(MY_DELAY); +} + +void buildString() { + myString = "..."; + myString += myCallSign; + myString += "..."; + Serial.print("I am sending: "); Serial.println(myString); +} + +void setupRFM69() { + writeReg(0x01,0x0C); + writeReg(0x02,MODULATION); + setFrequency(myFrequency); + Serial.print("Frequency set to "); Serial.println(myFrequency); + writeReg(0x26,0x07); // CLK off to save power +} + +// set the frequency (in Hz) +void setFrequency(uint32_t freqHz){ + freqHz /= 61; // divide down by FSTEP to get FRF + writeReg(0x07, freqHz >> 16); + writeReg(0x08, freqHz >> 8); + writeReg(0x09, freqHz); +} + +void resetRFM69() { + digitalWrite(rstPin, HIGH); + delay(100); + digitalWrite(rstPin, LOW); + delay(100); +} + +void printReg(byte data) { + Serial.print("Register "); + Serial.print(data); + Serial.print(" = "); + Serial.println(readReg(data), HEX); +} + +void writeReg(uint8_t addr, uint8_t value) { + digitalWrite(ssPin,LOW); + SPI.transfer(addr | 0x80); + SPI.transfer(value); + digitalWrite(ssPin, HIGH); +} + +uint8_t readReg(uint8_t addr) { + digitalWrite(ssPin, LOW); + SPI.transfer(addr & 0x7F); + uint8_t regval = SPI.transfer(0); + digitalWrite(ssPin, HIGH); + return regval; +} + +void setupSPI() { + SPI.begin(); + SPI.setBitOrder(MSBFIRST); + SPI.setClockDivider(SPI_CLOCK_DIV4); +} + +//***************Hellschreiber****************** + +struct t_htab { char c; int hellpat[5]; } ; + +struct t_htab helltab[] = { + + {'1', { B00000100, B00000100, B01111100, B00000000, B00000000 } }, + {'2', { B01001000, B01100100, B01010100, B01001100, B01000000 } }, + {'3', { B01000100, B01000100, B01010100, B01010100, B00111100 } }, + {'4', { B00011100, B00010000, B00010000, B01111100, B00010000 } }, + {'5', { B01000000, B01011100, B01010100, B01010100, B00110100 } }, + {'6', { B00111100, B01010010, B01001010, B01001000, B00110000 } }, + {'7', { B01000100, B00100100, B00010100, B00001100, B00000100 } }, + {'8', { B00111100, B01001010, B01001010, B01001010, B00111100 } }, + {'9', { B00001100, B01001010, B01001010, B00101010, B00111100 } }, + {'0', { B00111000, B01100100, B01010100, B01001100, B00111000 } }, + {'A', { B01111000, B00101100, B00100100, B00101100, B01111000 } }, + {'B', { B01000100, B01111100, B01010100, B01010100, B00101000 } }, + {'C', { B00111000, B01101100, B01000100, B01000100, B00101000 } }, + {'D', { B01000100, B01111100, B01000100, B01000100, B00111000 } }, + {'E', { B01111100, B01010100, B01010100, B01000100, B01000100 } }, + {'F', { B01111100, B00010100, B00010100, B00000100, B00000100 } }, + {'G', { B00111000, B01101100, B01000100, B01010100, B00110100 } }, + {'H', { B01111100, B00010000, B00010000, B00010000, B01111100 } }, + {'I', { B00000000, B01000100, B01111100, B01000100, B00000000 } }, + {'J', { B01100000, B01000000, B01000000, B01000000, B01111100 } }, + {'K', { B01111100, B00010000, B00111000, B00101000, B01000100 } }, + {'L', { B01111100, B01000000, B01000000, B01000000, B01000000 } }, + {'M', { B01111100, B00001000, B00010000, B00001000, B01111100 } }, + {'N', { B01111100, B00000100, B00001000, B00010000, B01111100 } }, + {'O', { B00111000, B01000100, B01000100, B01000100, B00111000 } }, + {'P', { B01000100, B01111100, B01010100, B00010100, B00011000 } }, + {'Q', { B00111000, B01000100, B01100100, B11000100, B10111000 } }, + {'R', { B01111100, B00010100, B00010100, B00110100, B01011000 } }, + {'S', { B01011000, B01010100, B01010100, B01010100, B00100100 } }, + {'T', { B00000100, B00000100, B01111100, B00000100, B00000100 } }, + {'U', { B01111100, B01000000, B01000000, B01000000, B01111100 } }, + {'V', { B01111100, B00100000, B00010000, B00001000, B00000100 } }, + {'W', { B01111100, B01100000, B01111100, B01000000, B01111100 } }, + {'X', { B01000100, B00101000, B00010000, B00101000, B01000100 } }, + {'Y', { B00000100, B00001000, B01110000, B00001000, B00000100 } }, + {'Z', { B01000100, B01100100, B01010100, B01001100, B01100100 } }, + {'.', { B01000000, B01000000, B00000000, B00000000, B00000000 } }, + {',', { B10000000, B10100000, B01100000, B00000000, B00000000 } }, + {'/', { B01000000, B00100000, B00010000, B00001000, B00000100 } }, + {'*', { B00000000, B00000000, B00000100, B00001110, B00000100 } } + +}; + +#define N_HELL (sizeof(helltab)/sizeof(helltab[0])) + +void helldelay() { + //Slow Hell + //delay(64); + //delayMicroseconds(900); + + //Feld-Hell + delay(8); // was 8 and hands off + delayMicroseconds(100); // was 160 used to adjust slope of displayed text +} + +void on() { + writeReg(0x11,radioPower); // PA On + helldelay(); + writeReg(0x11,0x00); +} + +void hellsend(char c) { + int i ; + if (c == ' ') { + for (int d=0; d<14; d++){ + helldelay(); + } + return ; + } + for (i=0; i>= 1; + } + } + for (int d=0; d<14; d++){ + helldelay(); + } + return ; + } + } + /* if we drop off the end, then we send a space */ + //Serial.print("?") ; +} + +void hellsendmsg(char *str) { + //flag = 1; + delay(1000); + while (*str) + hellsend(*str++) ; + //Serial.println(""); + //flag = 0; +} + + diff --git a/promini33_rfm69_FELD_HELL_GPS_20180116.ino b/promini33_rfm69_FELD_HELL_GPS_20180116.ino new file mode 100644 index 0000000..1ce79ba --- /dev/null +++ b/promini33_rfm69_FELD_HELL_GPS_20180116.ino @@ -0,0 +1,261 @@ +/* + * A simple GPS Feld Hell Telemetry sender + * for the HopeRF rfm69hcw + * on a ProMini 3.3 + * Charles Webb + * KC1ENN@arrl.net + * + * with thanks to James Coxon + * + * Feld Hell for HopeRF rfm69hcw modifed from source below + * https://github.com/jamescoxon/PicoAtlas/blob/master/Pico6MK3/sketch_apr02b/sketch_apr02b.ino + * + * + */ + +#include +#include +#include + +#define MY_DELAY 5000 // delay in loop, between sending the message +//#define radioPower 0x50 // -2 dBm +///#define radioPower 0x52 // 0 dBm +//#define radioPower 0x55 // 3 dBm +//#define radioPower 0x58 // 6 dBm +//#define radioPower 0x5B // 9 dBm +//#define radioPower 0x5E // 12 dBm +#define radioPower 0x7F // 17 dBm +#define ssPin 10 // SS +//#define ssPin 8 // adafruit feather M0 +#define rstPin 9 // reset pin +//#define rstPin 4 // adafruit feather M0 +#define myFrequency 433200000 +//#define myFrequency 915000000 + +unsigned int count = 0; +char mytext[80]; +String myCallSign = "CALLSIGN/B"; +String myString = ""; +int myHour, myMinute, mySecond, myAlt, mySpd, mySat; +double myLat, myLng; + +TinyGPSPlus gps; +SoftwareSerial ss(6,7); // Tx Rx + +void setup(){ + Serial.begin(9600); + ss.begin(9600); + pinMode(ssPin, OUTPUT); + pinMode(rstPin, OUTPUT); + setupSPI(); + delay(1000); + resetRFM69(); + delay(1000); + setupRFM69(); +} + +void loop(){ + count++; + fetchGPS(); + buildString(); + myString.toCharArray(mytext,myString.length() + 1); + hellsendmsg(mytext); + delay(MY_DELAY); +} + +void buildString() { + myString = "..."; + myString += myCallSign; + myString += " COUNT " + String(count); + myString += " TIME " + String(myHour) + "/" + String(myMinute) + "/" + String(mySecond); + myString += " LAT " + String(myLat,7) + " LNG " + String(myLng,7); + myString += " ALT " + String(myAlt) + " SPD " + String(mySpd) + " SAT " + String(mySat); + myString += "..."; + Serial.print("I am sending: "); Serial.println(myString); +} + +void fetchGPS() { //Remeber to only enable and softwear serial as needed, to thre the GPS then disable as it messes with the timing/printing of FH + myHour = gps.time.hour(); + myMinute = gps.time.minute(); + mySecond = gps.time.second(); + myLat = gps.location.lat(); + myLng = gps.location.lng(); + myAlt = gps.altitude.feet(); + mySpd = gps.speed.mph(); + mySat = gps.satellites.value(); + smartDelay(1000); +} + +void setupRFM69() { + writeReg(0x01,0x0C); + writeReg(0x02,0x34); // Modulation for OOK, Continuous w.o bit synch, OOK, no shaping + setFrequency(myFrequency); + Serial.print("Frequency set to "); Serial.println(myFrequency); + writeReg(0x26,0x07); // CLK off to save power +} + +// set the frequency (in Hz) +void setFrequency(uint32_t freqHz){ + freqHz /= 61; // divide down by FSTEP to get FRF + writeReg(0x07, freqHz >> 16); + writeReg(0x08, freqHz >> 8); + writeReg(0x09, freqHz); +} + +void resetRFM69() { + digitalWrite(rstPin, HIGH); + delay(100); + digitalWrite(rstPin, LOW); + delay(100); +} + +void printReg(byte data) { + Serial.print("Register "); + Serial.print(data); + Serial.print(" = "); + Serial.println(readReg(data), HEX); +} + +void writeReg(uint8_t addr, uint8_t value) { + digitalWrite(ssPin,LOW); + SPI.transfer(addr | 0x80); + SPI.transfer(value); + digitalWrite(ssPin, HIGH); +} + +uint8_t readReg(uint8_t addr) { + digitalWrite(ssPin, LOW); + SPI.transfer(addr & 0x7F); + uint8_t regval = SPI.transfer(0); + digitalWrite(ssPin, HIGH); + return regval; +} + +void setupSPI() { + SPI.begin(); + SPI.setBitOrder(MSBFIRST); + SPI.setClockDivider(SPI_CLOCK_DIV4); +} + +//***************Hellschreiber****************** + +struct t_htab { char c; int hellpat[5]; } ; + +struct t_htab helltab[] = { + + {'1', { B00000100, B00000100, B01111100, B00000000, B00000000 } }, + {'2', { B01001000, B01100100, B01010100, B01001100, B01000000 } }, + {'3', { B01000100, B01000100, B01010100, B01010100, B00111100 } }, + {'4', { B00011100, B00010000, B00010000, B01111100, B00010000 } }, + {'5', { B01000000, B01011100, B01010100, B01010100, B00110100 } }, + {'6', { B00111100, B01010010, B01001010, B01001000, B00110000 } }, + {'7', { B01000100, B00100100, B00010100, B00001100, B00000100 } }, + {'8', { B00111100, B01001010, B01001010, B01001010, B00111100 } }, + {'9', { B00001100, B01001010, B01001010, B00101010, B00111100 } }, + {'0', { B00111000, B01100100, B01010100, B01001100, B00111000 } }, + {'A', { B01111000, B00101100, B00100100, B00101100, B01111000 } }, + {'B', { B01000100, B01111100, B01010100, B01010100, B00101000 } }, + {'C', { B00111000, B01101100, B01000100, B01000100, B00101000 } }, + {'D', { B01000100, B01111100, B01000100, B01000100, B00111000 } }, + {'E', { B01111100, B01010100, B01010100, B01000100, B01000100 } }, + {'F', { B01111100, B00010100, B00010100, B00000100, B00000100 } }, + {'G', { B00111000, B01101100, B01000100, B01010100, B00110100 } }, + {'H', { B01111100, B00010000, B00010000, B00010000, B01111100 } }, + {'I', { B00000000, B01000100, B01111100, B01000100, B00000000 } }, + {'J', { B01100000, B01000000, B01000000, B01000000, B01111100 } }, + {'K', { B01111100, B00010000, B00111000, B00101000, B01000100 } }, + {'L', { B01111100, B01000000, B01000000, B01000000, B01000000 } }, + {'M', { B01111100, B00001000, B00010000, B00001000, B01111100 } }, + {'N', { B01111100, B00000100, B00001000, B00010000, B01111100 } }, + {'O', { B00111000, B01000100, B01000100, B01000100, B00111000 } }, + {'P', { B01000100, B01111100, B01010100, B00010100, B00011000 } }, + {'Q', { B00111000, B01000100, B01100100, B11000100, B10111000 } }, + {'R', { B01111100, B00010100, B00010100, B00110100, B01011000 } }, + {'S', { B01011000, B01010100, B01010100, B01010100, B00100100 } }, + {'T', { B00000100, B00000100, B01111100, B00000100, B00000100 } }, + {'U', { B01111100, B01000000, B01000000, B01000000, B01111100 } }, + {'V', { B01111100, B00100000, B00010000, B00001000, B00000100 } }, + {'W', { B01111100, B01100000, B01111100, B01000000, B01111100 } }, + {'X', { B01000100, B00101000, B00010000, B00101000, B01000100 } }, + {'Y', { B00000100, B00001000, B01110000, B00001000, B00000100 } }, + {'Z', { B01000100, B01100100, B01010100, B01001100, B01100100 } }, + {'.', { B01000000, B01000000, B00000000, B00000000, B00000000 } }, + {',', { B10000000, B10100000, B01100000, B00000000, B00000000 } }, + {'/', { B01000000, B00100000, B00010000, B00001000, B00000100 } }, + {'*', { B00000000, B00000000, B00000100, B00001110, B00000100 } } + +}; + +#define N_HELL (sizeof(helltab)/sizeof(helltab[0])) + +void helldelay() { + //Slow Hell + //delay(64); + //delayMicroseconds(900); + + //Feld-Hell + delay(8); // was 8 and hands off + delayMicroseconds(100); // was 160 used to adjust slope of displayed text +} + +void on() { + writeReg(0x11,radioPower); // PA On + helldelay(); + writeReg(0x11,0x00); +} + +void hellsend(char c) { + int i ; + if (c == ' ') { + for (int d=0; d<14; d++){ + helldelay(); + } + return ; + } + for (i=0; i>= 1; + } + } + for (int d=0; d<14; d++){ + helldelay(); + } + return ; + } + } + /* if we drop off the end, then we send a space */ + //Serial.print("?") ; +} + +void hellsendmsg(char *str) { + //flag = 1; + delay(1000); + while (*str) + hellsend(*str++) ; + //Serial.println(""); + //flag = 0; +} + +// This custom version of delay() ensures that the gps object is being "fed". +static void smartDelay(unsigned long ms) +{ + unsigned long start = millis(); + do + { + while (ss.available()) + gps.encode(ss.read()); + } while (millis() - start < ms); +} + diff --git a/promini33_rfm69_FELD_HELL_Keyboard_20180116.ino b/promini33_rfm69_FELD_HELL_Keyboard_20180116.ino new file mode 100644 index 0000000..79a15f5 --- /dev/null +++ b/promini33_rfm69_FELD_HELL_Keyboard_20180116.ino @@ -0,0 +1,269 @@ +/* + * A simple Feld Hell sender + * for the HopeRF rfm69hcw + * on a ProMini 3.3 + * Charles Webb + * KC1ENN@arrl.net + * + * with thanks to James Coxon + * + * Feld Hell for HopeRF rfm69hcw modifed from source below + * https://github.com/jamescoxon/PicoAtlas/blob/master/Pico6MK3/sketch_apr02b/sketch_apr02b.ino + * + * + */ + +#include + +#define MY_DELAY 5000 // delay in loop, between sending the message +#define ssPin 10 // SS +//#define ssPin 8 // adafruit feather M0 +#define rstPin 9 // reset pin +//#define rstPin 4 // adafruit feather M0 +//#define radioPower 0x58 // 6 dBm +//#define radioPower 0x5B // 9 dBm +//#define radioPower 0x5E // 12 dBm +#define radioPower 0x7F // 17 dBm + +char mytext[80]; +String inputString = ""; // a String to hold incoming data +boolean stringComplete = false; // whether the string is complete +long myFrequency = 433200000; +//long myFrequency = 915000000; +String myString = ""; +String myCall = "... CQ CQ CQ KC1ENN KC1ENN KC1ENN PSK ... "; +int myStringLen = 0; + +void setup(){ + Serial.begin(9600); + Serial.println("Starting up"); + pinMode(ssPin, OUTPUT); + pinMode(rstPin, OUTPUT); + setupSPI(); + delay(1000); + resetRFM69(); + delay(1000); + setupRFM69(); +} + +void loop (){ + if (stringComplete) { + // clear the string: + inputString = ""; + stringComplete = false; + } +} //ends void loop + +void serialEvent() { + while (Serial.available()) { + // get the new byte: + char inChar = (char)Serial.read(); + // add it to the inputString: + inputString += inChar; + // if the incoming character is a newline, set a flag so the main loop can + // do something about it: + if (inChar == '\n') { + stringComplete = true; + if(inputString.indexOf("@freq=") == 0) { + myFrequency = inputString.substring(6,15).toInt(); + setFrequency(myFrequency); + Serial.print("Frequency now set to: "); Serial.println(inputString.substring(6,15)); + inputString = ""; + } + if(inputString.indexOf("@freq+") == 0) { + myFrequency = myFrequency + 61; + setFrequency(myFrequency); + Serial.print("Frequency now set to: "); Serial.println(myFrequency); + inputString = ""; + } + if(inputString.indexOf("@freq-") == 0) { + myFrequency = myFrequency - 61; + setFrequency(myFrequency); + Serial.print("Frequency now set to: "); Serial.println(myFrequency); + inputString = ""; + } + if (inputString.indexOf("@cq") == 0) { + myString = myCall; + myString.toUpperCase(); + myStringLen = myString.length(); + myString.toCharArray(mytext,myString.length() + 1); + Serial.print("I am sending: "); Serial.println(myString); + hellsendmsg(mytext); + } + else { + inputString.trim(); + if(inputString.length() > 0) { + myString = "..." + inputString + " ... "; + myString.toUpperCase(); + myStringLen = myString.length(); + myString.toCharArray(mytext,myString.length() + 1); + Serial.print("I am sending: "); Serial.println(myString); + hellsendmsg(mytext); + } + } + } + } +} + +void setupRFM69() { + writeReg(0x02,0x34); // Modulation for OOK, Continuous w.o bit synch, OOK, no shaping + setFrequency(myFrequency); + Serial.print("Frequency set to "); Serial.println(myFrequency); + writeReg(0x26,0x07); // CLK off to save power + writeReg(0x01,0x0C); // Set mode to Transmitter TX mode + Serial.println("Transmitter is ready...."); +} + +// set the frequency (in Hz) +void setFrequency(uint32_t freqHz){ + freqHz /= 61; // divide down by FSTEP to get FRF + writeReg(0x07, freqHz >> 16); + writeReg(0x08, freqHz >> 8); + writeReg(0x09, freqHz); +} + +void resetRFM69() { + digitalWrite(rstPin, HIGH); + delay(100); + digitalWrite(rstPin, LOW); + delay(100); +} + +void printReg(byte data) { + Serial.print("Register "); + Serial.print(data); + Serial.print(" = "); + Serial.println(readReg(data), HEX); +} + +void writeReg(uint8_t addr, uint8_t value) { + digitalWrite(ssPin,LOW); + SPI.transfer(addr | 0x80); + SPI.transfer(value); + digitalWrite(ssPin, HIGH); +} + +uint8_t readReg(uint8_t addr) { + digitalWrite(ssPin, LOW); + SPI.transfer(addr & 0x7F); + uint8_t regval = SPI.transfer(0); + digitalWrite(ssPin, HIGH); + return regval; +} + +void setupSPI() { + SPI.begin(); + SPI.setBitOrder(MSBFIRST); + SPI.setClockDivider(SPI_CLOCK_DIV4); +} + +//***************Hellschreiber****************** + +struct t_htab { char c; int hellpat[5]; } ; + +struct t_htab helltab[] = { + + {'1', { B00000100, B00000100, B01111100, B00000000, B00000000 } }, + {'2', { B01001000, B01100100, B01010100, B01001100, B01000000 } }, + {'3', { B01000100, B01000100, B01010100, B01010100, B00111100 } }, + {'4', { B00011100, B00010000, B00010000, B01111100, B00010000 } }, + {'5', { B01000000, B01011100, B01010100, B01010100, B00110100 } }, + {'6', { B00111100, B01010010, B01001010, B01001000, B00110000 } }, + {'7', { B01000100, B00100100, B00010100, B00001100, B00000100 } }, + {'8', { B00111100, B01001010, B01001010, B01001010, B00111100 } }, + {'9', { B00001100, B01001010, B01001010, B00101010, B00111100 } }, + {'0', { B00111000, B01100100, B01010100, B01001100, B00111000 } }, + {'A', { B01111000, B00101100, B00100100, B00101100, B01111000 } }, + {'B', { B01000100, B01111100, B01010100, B01010100, B00101000 } }, + {'C', { B00111000, B01101100, B01000100, B01000100, B00101000 } }, + {'D', { B01000100, B01111100, B01000100, B01000100, B00111000 } }, + {'E', { B01111100, B01010100, B01010100, B01000100, B01000100 } }, + {'F', { B01111100, B00010100, B00010100, B00000100, B00000100 } }, + {'G', { B00111000, B01101100, B01000100, B01010100, B00110100 } }, + {'H', { B01111100, B00010000, B00010000, B00010000, B01111100 } }, + {'I', { B00000000, B01000100, B01111100, B01000100, B00000000 } }, + {'J', { B01100000, B01000000, B01000000, B01000000, B01111100 } }, + {'K', { B01111100, B00010000, B00111000, B00101000, B01000100 } }, + {'L', { B01111100, B01000000, B01000000, B01000000, B01000000 } }, + {'M', { B01111100, B00001000, B00010000, B00001000, B01111100 } }, + {'N', { B01111100, B00000100, B00001000, B00010000, B01111100 } }, + {'O', { B00111000, B01000100, B01000100, B01000100, B00111000 } }, + {'P', { B01000100, B01111100, B01010100, B00010100, B00011000 } }, + {'Q', { B00111000, B01000100, B01100100, B11000100, B10111000 } }, + {'R', { B01111100, B00010100, B00010100, B00110100, B01011000 } }, + {'S', { B01011000, B01010100, B01010100, B01010100, B00100100 } }, + {'T', { B00000100, B00000100, B01111100, B00000100, B00000100 } }, + {'U', { B01111100, B01000000, B01000000, B01000000, B01111100 } }, + {'V', { B01111100, B00100000, B00010000, B00001000, B00000100 } }, + {'W', { B01111100, B01100000, B01111100, B01000000, B01111100 } }, + {'X', { B01000100, B00101000, B00010000, B00101000, B01000100 } }, + {'Y', { B00000100, B00001000, B01110000, B00001000, B00000100 } }, + {'Z', { B01000100, B01100100, B01010100, B01001100, B01100100 } }, + {'.', { B01000000, B01000000, B00000000, B00000000, B00000000 } }, + {',', { B10000000, B10100000, B01100000, B00000000, B00000000 } }, + {'/', { B01000000, B00100000, B00010000, B00001000, B00000100 } }, + {'*', { B00000000, B00000000, B00000100, B00001110, B00000100 } } + +}; + +#define N_HELL (sizeof(helltab)/sizeof(helltab[0])) + +void helldelay() { + //Slow Hell + //delay(64); + //delayMicroseconds(900); + + //Feld-Hell + delay(8); // was 8 and hands off + delayMicroseconds(100); // was 160 used to adjust slope of displayed text +} + +void on() { + writeReg(0x11,radioPower); // PA On + helldelay(); + writeReg(0x11,0x00); +} + +void hellsend(char c) { + int i ; + if (c == ' ') { + for (int d=0; d<14; d++){ + helldelay(); + } + return ; + } + for (i=0; i>= 1; + } + } + for (int d=0; d<14; d++){ + helldelay(); + } + return ; + } + } + /* if we drop off the end, then we send a space */ + //Serial.print("?") ; +} + +void hellsendmsg(char *str) { + //flag = 1; + delay(1000); + while (*str) + hellsend(*str++) ; + //Serial.println(""); + //flag = 0; +} diff --git a/promini33_rfm69_Morse_Beacon_20180121.ino b/promini33_rfm69_Morse_Beacon_20180121.ino new file mode 100644 index 0000000..4a90416 --- /dev/null +++ b/promini33_rfm69_Morse_Beacon_20180121.ino @@ -0,0 +1,225 @@ +/* + * A simple GPS Morse Beacon Sender + * for the HopeRF rfm69hcw + * on a ProMini 3.3 + * Charles Webb + * KC1ENN@arrl.net + * + * With thanks to.... + * + * "This code is so trivial that I'm releasing it completely without restrictions." + * Simple Arduino Morse Beacon v0.0 + * Written by Mark VandeWettering + * Check out my blog @ http://brainwagon.org + */ + +#include + +#define ssPin 10 // SS Chip select pin for reading/writing to the rf69 registers with SPI +//#define ssPin 8 // adafruit feather M0 +#define rstPin 9 // reset pin +//#define rstPin 4 // adafruit feather M0 +#define MY_DELAY 3000 // 3 second delay between loops, sending the message +#define N_MORSE (sizeof(morsetab)/sizeof(morsetab[0])) +#define SPEED (15) // WORKS 5 - 50 wpm FL-DIGI +#define DOTLEN (1200/SPEED) +#define DASHLEN (3*(1200/SPEED)) +//#define MY_TX_POWER 0x50 // PA0 only range 0x50 -18dBm to 0x5F -3dBm +//#define MY_TX_POWER 0x58 // 6 dBm +//#define MY_TX_POWER 0x5B // 9 dBm +//#define MY_TX_POWER 0x5E // 12 dBm +//#define MY_TX_POWER 0x70 // 2 dbm +#define MY_TX_POWER 0x7F // 17 dBm +#define MY_MODULATION 0x48 // Modulation for OOK, Continuous w.o bit synch, OOK, no shaping + +char mytext[80]; +String inputString = ""; // a String to hold incoming data +String myCallSign = "CALLSIGN/B TEST BEACON"; // Put more than callsign here, put your beacon string here +long myFrequency = 433200000; +//long myFrequency = 915000000; +String myString = ""; +String myCall = ". CALLSIGN/B"; +int myStringLen = 0; +unsigned int count=0; +//char mycount = 0; +int myHour, myMinute, mySecond, myAlt, mySpd, mySat; +double myLat, myLng; + +void setup() { + Serial.begin(9600); // baud speed for sending to the arduino serial monitor + Serial.println("Starting up"); // print to the serial monitor + pinMode(ssPin, OUTPUT); // define + pinMode(rstPin, OUTPUT); + setupSPI(); + delay(1000); + resetRFM69(); + delay(1000); + setupRFM69(); +} + +void loop() { + count++; + buildString(); + //myString = myCall; + myString.toUpperCase(); + myStringLen = myString.length(); + myString.toCharArray(mytext,myString.length() + 1); + // Serial.print("I am sending: "); Serial.println(myString); + sendmsg(mytext); + inputString = ""; + myString = ""; +} + +void buildString() { + myString = myCallSign; + myString.toUpperCase(); + myStringLen = myString.length(); + Serial.print("I am sending: "); Serial.println(myString); +} + +void setupRFM69() { + writeReg(0x02,MY_MODULATION); + setFrequency(myFrequency); + writeReg(0x01,0x0C); // Set mode to Transmitter TX mode + Serial.println("Transmitter is ready...."); +} + +struct t_mtab { char c, pat; } ; + +struct t_mtab morsetab[] = { + {'.', 106}, + {',', 115}, + {'?', 76}, + {'/', 41}, + {'A', 6}, + {'B', 17}, + {'C', 21}, + {'D', 9}, + {'E', 2}, + {'F', 20}, + {'G', 11}, + {'H', 16}, + {'I', 4}, + {'J', 30}, + {'K', 13}, + {'L', 18}, + {'M', 7}, + {'N', 5}, + {'O', 15}, + {'P', 22}, + {'Q', 27}, + {'R', 10}, + {'S', 8}, + {'T', 3}, + {'U', 12}, + {'V', 24}, + {'W', 14}, + {'X', 25}, + {'Y', 29}, + {'Z', 19}, + {'1', 62}, + {'2', 60}, + {'3', 56}, + {'4', 48}, + {'5', 32}, + {'6', 33}, + {'7', 35}, + {'8', 39}, + {'9', 47}, + {'0', 63} +} ; + +void resetRFM69() { + digitalWrite(rstPin, HIGH); + delay(100); + digitalWrite(rstPin, LOW); + delay(100); +} + +void printReg(byte data) { + Serial.print("Register "); + Serial.print(data); + Serial.print(" = "); + Serial.println(readReg(data), HEX); +} + +void writeReg(uint8_t addr, uint8_t value) { + digitalWrite(ssPin,LOW); + SPI.transfer(addr | 0x80); + SPI.transfer(value); + digitalWrite(ssPin, HIGH); +} + +uint8_t readReg(uint8_t addr) { + digitalWrite(ssPin, LOW); + SPI.transfer(addr & 0x7F); + uint8_t regval = SPI.transfer(0); + digitalWrite(ssPin, HIGH); + return regval; +} + +void setupSPI() { + SPI.begin(); + SPI.setBitOrder(MSBFIRST); + SPI.setClockDivider(SPI_CLOCK_DIV4); +} + +void setFrequency(uint32_t freqHz){ // Setup the frequency + freqHz /= 61; // resolution is 61 Hz so divide it it down and mask it out + writeReg(0x07, freqHz >> 16); // Frequency MSB + writeReg(0x08, freqHz >> 8); // Frequency Middle Byte + writeReg(0x09, freqHz); // Frequency LSB + Serial.print("Frequency set to "); Serial.println(myFrequency); +} + +void txOn(int txTime) { + writeReg(0x11,MY_TX_POWER); // PA On ******************************************* + delay(txTime); + writeReg(0x11,0x00); // PA off ************************************************* +} + +void dash() { + txOn(DASHLEN); + delay(DOTLEN); +} + +void dit() { + txOn(DOTLEN); + delay(DOTLEN); +} + +void send(char c) { + int i ; + if (c == ' ') { + //Serial.print(c) ; + delay(7*DOTLEN) ; + return ; + } + for (i=0; i + * Check out my blog @ http://brainwagon.org + */ + +#include +#include +#include + +#define ssPin 10 // SS Chip select pin for reading/writing to the rf69 registers with SPI +//#define ssPin 8 // adafruit feather M0 +#define rstPin 9 // reset pin +//#define rstPin 4 // adafruit feather M0 +#define MY_DELAY 3000 // 3 second delay between loops, sending the message +#define N_MORSE (sizeof(morsetab)/sizeof(morsetab[0])) +#define SPEED (15) // WORKS 5 - 50 wpm FL-DIGI +#define DOTLEN (1200/SPEED) +#define DASHLEN (3*(1200/SPEED)) +//#define MY_TX_POWER 0x50 // PA0 only range 0x50 -18dBm to 0x5F -3dBm +//#define MY_TX_POWER 0x58 // 6 dBm +//#define MY_TX_POWER 0x5B // 9 dBm +//#define MY_TX_POWER 0x5E // 12 dBm +//#define MY_TX_POWER 0x70 // 2 dbm +#define MY_TX_POWER 0x7F // 17 dBm + +char mytext[80]; +String inputString = ""; // a String to hold incoming data +String myCallSign = "CALLSIGN/B"; +long myFrequency = 433200000; +//long myFrequency = 915000000; +String myString = ""; +String myCall = ". CALLSIGN/B"; +int myStringLen = 0; +unsigned int count=0; +//char mycount = 0; +int myHour, myMinute, mySecond, myAlt, mySpd, mySat; +double myLat, myLng; + +TinyGPSPlus gps; +SoftwareSerial ss(6,7); // Tx Rx + +void setup() { + Serial.begin(9600); // baud speed for sending to the arduino serial monitor + Serial.println("Starting up"); // print to the serial monitor + pinMode(ssPin, OUTPUT); // define + pinMode(rstPin, OUTPUT); + setupSPI(); + delay(1000); + resetRFM69(); + delay(1000); + setupRFM69(); +} + +void loop() { + count++; + fetchGPS(); + buildString(); + //myString = myCall; + myString.toUpperCase(); + myStringLen = myString.length(); + myString.toCharArray(mytext,myString.length() + 1); + // Serial.print("I am sending: "); Serial.println(myString); + sendmsg(mytext); + inputString = ""; + myString = ""; +} + +void buildString() { + myString = myCallSign; + myString += " COUNT " + String(count); + myString += " TIME " + String(myHour) + "/" + String(myMinute) + "/" + String(mySecond); + myString += " LAT " + String(myLat) + " LNG " + String(myLng); + myString += " ALT " + String(myAlt) + " SPD " + String(mySpd) + " SAT " + String(mySat); + myString += "..."; + myString.toUpperCase(); + myStringLen = myString.length(); + Serial.print("I am sending: "); Serial.println(myString); +} + +void fetchGPS() { //Remeber to only enable and softwear serial as needed, to thre the GPS then disable as it messes with the timing/printing of FH + ss.begin(9600); + myHour = gps.time.hour(); smartDelay(0); + myMinute = gps.time.minute(); smartDelay(0); + mySecond = gps.time.second(); smartDelay(0); + myLat = gps.location.lat(); smartDelay(0); + myLng = gps.location.lng(); smartDelay(0); + myAlt = gps.altitude.feet(); smartDelay(0); + mySpd = gps.speed.mph(); smartDelay(0); + mySat = gps.satellites.value(); smartDelay(0); + ss.end(); + delay(100); +} + +void setupRFM69() { + writeReg(0x02,0x34); // Modulation for OOK, Continuous w.o bit synch, OOK, no shaping + setFrequency(myFrequency); + writeReg(0x01,0x0C); // Set mode to Transmitter TX mode + Serial.println("Transmitter is ready...."); +} + +struct t_mtab { char c, pat; } ; + +struct t_mtab morsetab[] = { + {'.', 106}, + {',', 115}, + {'?', 76}, + {'/', 41}, + {'A', 6}, + {'B', 17}, + {'C', 21}, + {'D', 9}, + {'E', 2}, + {'F', 20}, + {'G', 11}, + {'H', 16}, + {'I', 4}, + {'J', 30}, + {'K', 13}, + {'L', 18}, + {'M', 7}, + {'N', 5}, + {'O', 15}, + {'P', 22}, + {'Q', 27}, + {'R', 10}, + {'S', 8}, + {'T', 3}, + {'U', 12}, + {'V', 24}, + {'W', 14}, + {'X', 25}, + {'Y', 29}, + {'Z', 19}, + {'1', 62}, + {'2', 60}, + {'3', 56}, + {'4', 48}, + {'5', 32}, + {'6', 33}, + {'7', 35}, + {'8', 39}, + {'9', 47}, + {'0', 63} +} ; + +void resetRFM69() { + digitalWrite(rstPin, HIGH); + delay(100); + digitalWrite(rstPin, LOW); + delay(100); +} + +void printReg(byte data) { + Serial.print("Register "); + Serial.print(data); + Serial.print(" = "); + Serial.println(readReg(data), HEX); +} + +void writeReg(uint8_t addr, uint8_t value) { + digitalWrite(ssPin,LOW); + SPI.transfer(addr | 0x80); + SPI.transfer(value); + digitalWrite(ssPin, HIGH); +} + +uint8_t readReg(uint8_t addr) { + digitalWrite(ssPin, LOW); + SPI.transfer(addr & 0x7F); + uint8_t regval = SPI.transfer(0); + digitalWrite(ssPin, HIGH); + return regval; +} + +void setupSPI() { + SPI.begin(); + SPI.setBitOrder(MSBFIRST); + SPI.setClockDivider(SPI_CLOCK_DIV4); +} + +void setFrequency(uint32_t freqHz){ // Setup the frequency + freqHz /= 61; // resolution is 61 Hz so divide it it down and mask it out + writeReg(0x07, freqHz >> 16); // Frequency MSB + writeReg(0x08, freqHz >> 8); // Frequency Middle Byte + writeReg(0x09, freqHz); // Frequency LSB + Serial.print("Frequency set to "); Serial.println(myFrequency); +} + +void txOn(int txTime) { + writeReg(0x11,MY_TX_POWER); // PA On ******************************************* + delay(txTime); + writeReg(0x11,0x00); // PA off ************************************************* +} + +void dash() { + txOn(DASHLEN); + delay(DOTLEN); +} + +void dit() { + txOn(DOTLEN); + delay(DOTLEN); +} + +void send(char c) { + int i ; + if (c == ' ') { + //Serial.print(c) ; + delay(7*DOTLEN) ; + return ; + } + for (i=0; i + * Check out my blog @ http://brainwagon.org + */ + +#include + +#define ssPin 10 // SS Chip select pin for reading/writing to the rf69 registers with SPI +//#define ssPin 8 // adafruit feather M0 +#define rstPin 9 // reset pin +//#define rstPin 4 // adafruit feather M0 +#define MY_DELAY 3000 // 3 second delay between loops, sending the message +#define N_MORSE (sizeof(morsetab)/sizeof(morsetab[0])) +#define SPEED (15) // WORKS 5 - 50 wpm FL-DIGI +#define DOTLEN (1200/SPEED) +#define DASHLEN (3*(1200/SPEED)) +//#define MY_TX_POWER 0x50 // PA0 only range 0x50 -18dBm to 0x5F -3dBm +//#define MY_TX_POWER 0x58 // 6 dBm +//#define MY_TX_POWER 0x5B // 9 dBm +//#define MY_TX_POWER 0x5E // 12 dBm +//#define MY_TX_POWER 0x70 // 2 dbm +#define MY_TX_POWER 0x7F // 17 dBm + +char mytext[80]; +String inputString = ""; // a String to hold incoming data +boolean stringComplete = false; // whether the string is complete +long myFrequency = 433200000; +//long myFrequency = 915000000; +String myString = ""; +String myCall = "CQ CQ CQ CALLSIGN/B CALLSIGN/B CALLSIGN/B TEST BEACON LOCATION DE PSK "; +int myStringLen = 0; + +void setup() { + Serial.begin(9600); // baud speed for sending to the arduino serial monitor + Serial.println("Starting up"); // print to the serial monitor + pinMode(ssPin, OUTPUT); // define + setupSPI(); + delay(1000); + resetRFM69(); + delay(1000); + setupRFM69(); +} + +void loop() { + if (stringComplete) { + // clear the string: + inputString = ""; + myString = ""; + stringComplete = false; + } +} + +void serialEvent() { + while (Serial.available()) { + // get the new byte: + char inChar = (char)Serial.read(); + // add it to the inputString: + inputString += inChar; + // if the incoming character is a newline, set a flag so the main loop can + // do something about it: + if (inChar == '\n') { + stringComplete = true; + if(inputString.indexOf("@freq=") == 0) { + myFrequency = inputString.substring(6,15).toInt(); + setFrequency(myFrequency); + Serial.print("Frequency now set to: "); Serial.println(inputString.substring(6,15)); + inputString = ""; + } + if(inputString.indexOf("@freq+") == 0) { + myFrequency = myFrequency + 61; + setFrequency(myFrequency); + Serial.print("Frequency now set to: "); Serial.println(myFrequency); + inputString = ""; + } + if(inputString.indexOf("@freq-") == 0) { + myFrequency = myFrequency - 61; + setFrequency(myFrequency); + Serial.print("Frequency now set to: "); Serial.println(myFrequency); + inputString = ""; + } + if (inputString.indexOf("@cq") == 0) { + myString = myCall; + myString.toUpperCase(); + myStringLen = myString.length(); + myString.toCharArray(mytext,myString.length() + 1); + Serial.print("I am sending: "); Serial.println(myString); + sendmsg(mytext); + } + else { + inputString.trim(); + myString = inputString; + myString.toUpperCase(); + myStringLen = myString.length(); + myString.toCharArray(mytext,myString.length() + 1); + if(myString.length() > 0) { + Serial.print("I am sending: "); Serial.println(myString); + } + sendmsg(mytext) ; + } + } + } +} + +void setupRFM69() { + writeReg(0x02,0x34); // Modulation for OOK, Continuous w.o bit synch, OOK, no shaping + setFrequency(myFrequency); + writeReg(0x01,0x0C); // Set mode to Transmitter TX mode + Serial.println("Transmitter is ready...."); +} + +struct t_mtab { char c, pat; } ; + +struct t_mtab morsetab[] = { + {'.', 106}, + {',', 115}, + {'?', 76}, + {'/', 41}, + {'A', 6}, + {'B', 17}, + {'C', 21}, + {'D', 9}, + {'E', 2}, + {'F', 20}, + {'G', 11}, + {'H', 16}, + {'I', 4}, + {'J', 30}, + {'K', 13}, + {'L', 18}, + {'M', 7}, + {'N', 5}, + {'O', 15}, + {'P', 22}, + {'Q', 27}, + {'R', 10}, + {'S', 8}, + {'T', 3}, + {'U', 12}, + {'V', 24}, + {'W', 14}, + {'X', 25}, + {'Y', 29}, + {'Z', 19}, + {'1', 62}, + {'2', 60}, + {'3', 56}, + {'4', 48}, + {'5', 32}, + {'6', 33}, + {'7', 35}, + {'8', 39}, + {'9', 47}, + {'0', 63} +} ; + +void resetRFM69() { + digitalWrite(rstPin, HIGH); + delay(100); + digitalWrite(rstPin, LOW); + delay(100); +} + +void printReg(byte data) { + Serial.print("Register "); + Serial.print(data); + Serial.print(" = "); + Serial.println(readReg(data), HEX); +} + +void writeReg(uint8_t addr, uint8_t value) { + digitalWrite(ssPin,LOW); + SPI.transfer(addr | 0x80); + SPI.transfer(value); + digitalWrite(ssPin, HIGH); +} + +uint8_t readReg(uint8_t addr) { + digitalWrite(ssPin, LOW); + SPI.transfer(addr & 0x7F); + uint8_t regval = SPI.transfer(0); + digitalWrite(ssPin, HIGH); + return regval; +} + +void setupSPI() { + SPI.begin(); + SPI.setBitOrder(MSBFIRST); + SPI.setClockDivider(SPI_CLOCK_DIV4); +} + +void setFrequency(uint32_t freqHz){ // Setup the frequency + freqHz /= 61; // resolution is 61 Hz so divide it it down and mask it out + writeReg(0x07, freqHz >> 16); // Frequency MSB + writeReg(0x08, freqHz >> 8); // Frequency Middle Byte + writeReg(0x09, freqHz); // Frequency LSB + Serial.print("Frequency set to "); Serial.println(myFrequency); +} + +void txOn(int txTime) { + writeReg(0x11,MY_TX_POWER); // PA On ******************************************* + delay(txTime); + writeReg(0x11,0x00); // PA off ************************************************* +} + +void dash() { + txOn(DASHLEN); + delay(DOTLEN); +} + +void dit() { + txOn(DOTLEN); + delay(DOTLEN); +} + +void send(char c) { + int i ; + if (c == ' ') { + //Serial.print(c) ; + delay(7*DOTLEN) ; + return ; + } + for (i=0; i + +#define MODULATION 0x60 +//#define radioPower 0x50 // -2 dBm +//#define radioPower 0x52 // 0 dBm +//#define radioPower 0x55 // 3 dBm +#define radioPower 0x58 // 6 dBm +//#define radioPower 0x5B // 9 dBm +//#define radioPower 0x5E // 12 dBm +//#define radioPower 0x7F // 17 dBm +#define ssPin 10 // SS +//#define ssPin 8 // adafruit feather M0 +#define rstPin 9 // reset pin +//#define rstPin 4 // adafruit feather M0 +#define myShift 3 // 3 x 61 Hz = 181 Hz ~ 170 Hz +#define myDelay 1 // delay in seconds between loops +#define myFrequency 433200000 // 70cm +//#define myFrequency 915000000 // 33cm + +char mytext[80]; +String myCallSign = "CALLSIGN/B TEST BEACON"; +String myString = ""; +int myStringLen = 0; +int current_state; +int previous_state; +int send_shift; +float baud = 45.45; +float bit_time = 1000/baud;; +float stop_bit_time = bit_time * 2; +int index = 0; +uint32_t myMark; +uint32_t mySpace; +unsigned int count=0; +char mycount = 0; +// For stats that happen every 5 seconds +unsigned long last = 0UL; + +void setup(){ + Serial.begin(9600); + pinMode(ssPin, OUTPUT); + pinMode(rstPin, OUTPUT); + setupSPI(); + delay(1000); + resetRFM69(); // a good thing to use and necessary if using boards with level shifters + delay(1000); + setupRFM69(); +} + +void loop (){ + count++; + buildString(); + transmitData(); + delay (myDelay * 1000); // delay between transmit cycle +} //ends void loop + +void txString(String dataString) { + Serial.println(dataString); // print to Serial Monitor + myString = dataString; + myStringLen = myString.length(); + transmitData(); +} + +void buildString() { + myString = myCallSign; + myString += "..."; + myString.toUpperCase(); + myStringLen = myString.length(); + Serial.print("I am sending: "); Serial.println(myString); +} + +void setupRFM69() { + writeReg(0x01,0x84); // set RegOpMode to Sequencer On Listen Off Standby = 0x04 + writeReg(0x02,MODULATION); // RegDataModul = Continuous mode w/0 synthesizer FSK No Shaping = 0x60 + setFrequency(myFrequency); + getMark(myFrequency); + getSpace(myFrequency); + writeReg(0x26,0x07); // CLK off to save power + writeReg(0x01, 0x0C); // set to TX mode + writeReg(0x11,radioPower); // 0x9F PA0 On only, 0x5F or 0x41 // Pa1On 0x40 to 0x5F ????? Was 0x70 +} + +void resetRFM69() { + digitalWrite(rstPin, HIGH); + delay(100); + digitalWrite(rstPin, LOW); + delay(100); +} + +void getMark(uint32_t freqHz) { + freqHz /= 61; // divide down by FSTEP to get FRF + myMark = freqHz; +} + +void getSpace(uint32_t freqHz) { + freqHz /= 61; // divide down by FSTEP to get FRF + mySpace = freqHz - 3; +} + +void printReg(byte data){ + Serial.print("Register "); + Serial.print(data); + Serial.print(" = "); + Serial.println(readReg(data), HEX); +} + +void writeReg(uint8_t addr, uint8_t value) +{ + digitalWrite(ssPin,LOW); + SPI.transfer(addr | 0x80); + SPI.transfer(value); + digitalWrite(ssPin, HIGH); +} + +uint8_t readReg(uint8_t addr) +{ + digitalWrite(ssPin, LOW); + SPI.transfer(addr & 0x7F); + uint8_t regval = SPI.transfer(0); + digitalWrite(ssPin, HIGH); + return regval; +} + +void setupSPI() { + SPI.begin(); + SPI.setBitOrder(MSBFIRST); + SPI.setClockDivider(SPI_CLOCK_DIV4); +} + +void setFrequency(uint32_t freqHz){ // Setup the frequency + freqHz /= 61; // resolution is 61 Hz so divide it it down and mask it out + writeReg(0x07, freqHz >> 16); // Frequency MSB + writeReg(0x08, freqHz >> 8); // Frequency Middle Byte + writeReg(0x09, freqHz); // Frequency LSB +} + +// Tim's code here ///////////////////////////////////////////// + +void transmitData(){ + for (index = 0; index < myStringLen; index++) { + check_current_state(myString[index]) ; + compare_state(); + send_shift_sig(); + lookup_send(myString, index); + } +} + +void check_current_state(char val) { + if (isalpha(val)) + current_state = 0; // is a letter + else + current_state = 1; // is a number + } + +void compare_state() { //compares states and sends letter shifts + if (current_state == previous_state) { + send_shift = 0; + } + else { + send_shift = 1; + previous_state = current_state; + } +} + +void send_shift_sig() { // shifts between letter and number ????? + if (send_shift == 1) { + if (current_state == 0) { + letter_shift(); } + else { figure_shift(); } // what is a figure ????? + } + if (current_state == 1) { // My addition + figure_shift(); // my addition + } +} + +void lookup_send(String checkletter, int indexofstring) { + if (checkletter[indexofstring] == 'A' || checkletter[indexofstring] == '-'){//11000 + start_bit(); + markF(); + markF(); + spaceF(); + spaceF(); + spaceF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'B' || checkletter[indexofstring] == '?') { //10011 + start_bit(); + markF(); + spaceF(); + spaceF(); + markF(); + markF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'C' || checkletter[indexofstring] == ':') { //01110 + start_bit(); + spaceF(); + markF(); + markF(); + markF(); + spaceF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'D') { //10010 WRU? will program later + start_bit(); + markF(); + spaceF(); + spaceF(); + markF(); + spaceF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'E' || checkletter[indexofstring] == '3') { //10000 + start_bit(); + markF(); + spaceF(); + spaceF(); + spaceF(); + spaceF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'F' || checkletter[indexofstring] == '!') { //10110 + start_bit(); + markF(); + spaceF(); + markF(); + markF(); + spaceF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'G' || checkletter[indexofstring] == '&') { //01011 + start_bit(); + spaceF(); + markF(); + spaceF(); + markF(); + markF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'H' || checkletter[indexofstring] == '#') { //00101 + start_bit(); + spaceF(); + spaceF(); + markF(); + spaceF(); + markF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'I' || checkletter[indexofstring] == '8') { //01100 + start_bit(); + spaceF(); + markF(); + markF(); + spaceF(); + spaceF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'J') { //11010 should send a ' as well, but errors + start_bit(); + markF(); + markF(); + spaceF(); + markF(); + spaceF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'K' || checkletter[indexofstring] == '(') { //11110 + start_bit(); + markF(); + markF(); + markF(); + markF(); + spaceF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'L' || checkletter[indexofstring] == ')') { //01001 + start_bit(); + spaceF(); + markF(); + spaceF(); + spaceF(); + markF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'M' || checkletter[indexofstring] == '.') { //00111 + start_bit(); + spaceF(); + spaceF(); + markF(); + markF(); + markF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'N' || checkletter[indexofstring] == ',') { //00110 + start_bit(); + spaceF(); + spaceF(); + markF(); + markF(); + spaceF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'O' || checkletter[indexofstring] == '9') { //00011 + start_bit(); + spaceF(); + spaceF(); + spaceF(); + markF(); + markF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'P' || checkletter[indexofstring] == '0') { //01101 + start_bit(); + spaceF(); + markF(); + markF(); + spaceF(); + markF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'Q' || checkletter[indexofstring] == '1') { //11101 + start_bit(); + markF(); + markF(); + markF(); + spaceF(); + markF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'R' || checkletter[indexofstring] == '4') { //01010 + start_bit(); + spaceF(); + markF(); + spaceF(); + markF(); + spaceF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'S') { //10100 should do Bell? + start_bit(); + markF(); + spaceF(); + markF(); + spaceF(); + spaceF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'T' || checkletter[indexofstring] == '5') { //00001 + start_bit(); + spaceF(); + spaceF(); + spaceF(); + spaceF(); + markF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'U' || checkletter[indexofstring] == '7') { //11100 + start_bit(); + markF(); + markF(); + markF(); + spaceF(); + spaceF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'V' || checkletter[indexofstring] == ';') { //01111 + start_bit(); + spaceF(); + markF(); + markF(); + markF(); + markF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'W' || checkletter[indexofstring] == '2') { //11001 + start_bit(); + markF(); + markF(); + spaceF(); + spaceF(); + markF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'X' || checkletter[indexofstring] == '/') { //10111 + start_bit(); + markF(); + spaceF(); + markF(); + markF(); + markF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'Y' || checkletter[indexofstring] == '6') { //10101 + start_bit(); + markF(); + spaceF(); + markF(); + spaceF(); + markF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'Z' || checkletter[indexofstring] == '"') { //10001 + start_bit(); + markF(); + spaceF(); + spaceF(); + spaceF(); + markF(); + stop_bit(); } + else if ( (checkletter[indexofstring] == ' ')) {//this seems to properly send a space 00100. for a new line i think i need 01000 + start_bit(); + spaceF(); + spaceF(); + markF(); + spaceF(); + spaceF(); + stop_bit(); } + else { //if no valid characters are provided a ? is returned for that character + figure_shift(); + start_bit(); + markF(); + spaceF(); + spaceF(); + markF(); + markF(); + stop_bit(); } +} + +void start_bit() { + writeReg(0x09,mySpace); // my addition + delay(bit_time); + } +void markF() { + writeReg(0x09,myMark); // my addition + delay(bit_time); +} + +void spaceF() { + writeReg(0x09,mySpace); // my addition + delay(bit_time); +} + +void stop_bit() { + writeReg(0x09,myMark); // my addition + delay(stop_bit_time); +} + +void figure_shift() { // switch to figures ???? Numbers ????? + //switch to figures + start_bit(); + //11011 + markF(); + markF(); + spaceF(); + markF(); + markF(); + //stop bit + stop_bit(); +} + +void letter_shift() { + //switch to letters + start_bit(); + //11011 + markF(); + markF(); + markF(); + markF(); + markF(); + //stop bit + stop_bit(); +} + + diff --git a/promini33_rfm69_RTTY_5N1_4545_170_GPS_20180119.ino b/promini33_rfm69_RTTY_5N1_4545_170_GPS_20180119.ino new file mode 100644 index 0000000..6db5def --- /dev/null +++ b/promini33_rfm69_RTTY_5N1_4545_170_GPS_20180119.ino @@ -0,0 +1,507 @@ +/* + * GPS telemetry using standard RTTY 5N1.5 170 45.45 sender + * for the HopeRF rfm69hcw + * on a ProMini 3.3 + * Charles Webb + * KC1ENN@arrl.net + * + * with thanks to Ted Van Slyck + * + * Written by Ted Van Slyck www.openrcdesign.com + * Feel free to use for personal non commercial use + * use at your own risk, no warranties. It probably has errors of some kind. + * + * -- Fixed the only error in Ted's most excellent code to fix an issue with shifted characters as noted below - cwebb + */ + +#include +#include +#include + +#define MODULATION 0x60 +//#define radioPower 0x50 // -2 dBm +//#define radioPower 0x52 // 0 dBm +//#define radioPower 0x55 // 3 dBm +#define radioPower 0x58 // 6 dBm +//#define radioPower 0x5B // 9 dBm +//#define radioPower 0x5E // 12 dBm +//#define radioPower 0x7F // 17 dBm +#define ssPin 10 // SS +//#define ssPin 8 // adafruit feather M0 +#define rstPin 9 // reset pin +//#define rstPin 4 // adafruit feather M0 +#define myShift 3 // 3 x 61 Hz = 181 Hz ~ 170 Hz +#define myDelay 1 // delay in seconds between loops +#define myFrequency 433200000 // 70cm +//#define myFrequency 915000000 // 33cm + +char mytext[80]; +String myCallSign = "CALLSIGN/B"; +String myString = ""; +int myStringLen = 0; +int current_state; +int previous_state; +int send_shift; +float baud = 45.45; +float bit_time = 1000/baud;; +float stop_bit_time = bit_time * 2; +int index = 0; +uint32_t myMark; +uint32_t mySpace; +unsigned int count=0; +char mycount = 0; +int myHour, myMinute, mySecond, myAlt, mySpd, mySat; +double myLat, myLng; +// For stats that happen every 5 seconds +unsigned long last = 0UL; + +TinyGPSPlus gps; +SoftwareSerial ss(6,7); // Tx Rx + +void setup(){ + Serial.begin(9600); + ss.begin(9600); + pinMode(ssPin, OUTPUT); + pinMode(rstPin, OUTPUT); + setupSPI(); + delay(1000); + resetRFM69(); // a good thing to use and necessary if using boards with level shifters + delay(1000); + setupRFM69(); +} + +void loop (){ + count++; + fetchGPS(); + buildString(); + transmitData(); + delay (myDelay * 1000); // delay between transmit cycle +} //ends void loop + +void txString(String dataString) { + Serial.println(dataString); // print to Serial Monitor + myString = dataString; + myStringLen = myString.length(); + transmitData(); +} + +void buildString() { + myString = myCallSign; + myString += " COUNT " + String(count); + myString += " TIME " + String(myHour) + "/" + String(myMinute) + "/" + String(mySecond); + myString += " LAT " + String(myLat,7) + " LNG " + String(myLng,7); + myString += " ALT " + String(myAlt) + " SPD " + String(mySpd) + " SAT " + String(mySat); + myString += "..."; + myString.toUpperCase(); + myStringLen = myString.length(); + Serial.print("I am sending: "); Serial.println(myString); +} + +void fetchGPS() { + myHour = gps.time.hour(); + myMinute = gps.time.minute(); + mySecond = gps.time.second(); + myLat = gps.location.lat(); + myLng = gps.location.lng(); + myAlt = gps.altitude.feet(); + mySpd = gps.speed.mph(); + mySat = gps.satellites.value(); + smartDelay(1000); +} + +void setupRFM69() { + writeReg(0x01,0x84); // set RegOpMode to Sequencer On Listen Off Standby = 0x04 + writeReg(0x02,MODULATION); // RegDataModul = Continuous mode w/0 synthesizer FSK No Shaping = 0x60 + setFrequency(myFrequency); + getMark(myFrequency); + getSpace(myFrequency); + writeReg(0x26,0x07); // CLK off to save power + writeReg(0x01, 0x0C); // set to TX mode + writeReg(0x11,radioPower); // 0x9F PA0 On only, 0x5F or 0x41 // Pa1On 0x40 to 0x5F ????? Was 0x70 +} + +void resetRFM69() { + digitalWrite(rstPin, HIGH); + delay(100); + digitalWrite(rstPin, LOW); + delay(100); +} + +void getMark(uint32_t freqHz) { + freqHz /= 61; // divide down by FSTEP to get FRF + myMark = freqHz; +} + +void getSpace(uint32_t freqHz) { + freqHz /= 61; // divide down by FSTEP to get FRF + mySpace = freqHz - 3; +} + +void printReg(byte data){ + Serial.print("Register "); + Serial.print(data); + Serial.print(" = "); + Serial.println(readReg(data), HEX); +} + +void writeReg(uint8_t addr, uint8_t value) +{ + digitalWrite(ssPin,LOW); + SPI.transfer(addr | 0x80); + SPI.transfer(value); + digitalWrite(ssPin, HIGH); +} + +uint8_t readReg(uint8_t addr) +{ + digitalWrite(ssPin, LOW); + SPI.transfer(addr & 0x7F); + uint8_t regval = SPI.transfer(0); + digitalWrite(ssPin, HIGH); + return regval; +} + +void setupSPI() { + SPI.begin(); + SPI.setBitOrder(MSBFIRST); + SPI.setClockDivider(SPI_CLOCK_DIV4); +} + +void setFrequency(uint32_t freqHz){ // Setup the frequency + freqHz /= 61; // resolution is 61 Hz so divide it it down and mask it out + writeReg(0x07, freqHz >> 16); // Frequency MSB + writeReg(0x08, freqHz >> 8); // Frequency Middle Byte + writeReg(0x09, freqHz); // Frequency LSB +} + +// Tim's code here ///////////////////////////////////////////// + +void transmitData(){ + for (index = 0; index < myStringLen; index++) { + check_current_state(myString[index]) ; + compare_state(); + send_shift_sig(); + lookup_send(myString, index); + } +} + +void check_current_state(char val) { + if (isalpha(val)) + current_state = 0; // is a letter + else + current_state = 1; // is a number + } + +void compare_state() { //compares states and sends letter shifts + if (current_state == previous_state) { + send_shift = 0; + } + else { + send_shift = 1; + previous_state = current_state; + } +} + +void send_shift_sig() { // shifts between letter and number ????? + if (send_shift == 1) { + if (current_state == 0) { + letter_shift(); } + else { figure_shift(); } // what is a figure ????? + } + if (current_state == 1) { // My addition + figure_shift(); // my addition + } +} + +void lookup_send(String checkletter, int indexofstring) { + if (checkletter[indexofstring] == 'A' || checkletter[indexofstring] == '-'){//11000 + start_bit(); + markF(); + markF(); + spaceF(); + spaceF(); + spaceF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'B' || checkletter[indexofstring] == '?') { //10011 + start_bit(); + markF(); + spaceF(); + spaceF(); + markF(); + markF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'C' || checkletter[indexofstring] == ':') { //01110 + start_bit(); + spaceF(); + markF(); + markF(); + markF(); + spaceF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'D') { //10010 WRU? will program later + start_bit(); + markF(); + spaceF(); + spaceF(); + markF(); + spaceF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'E' || checkletter[indexofstring] == '3') { //10000 + start_bit(); + markF(); + spaceF(); + spaceF(); + spaceF(); + spaceF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'F' || checkletter[indexofstring] == '!') { //10110 + start_bit(); + markF(); + spaceF(); + markF(); + markF(); + spaceF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'G' || checkletter[indexofstring] == '&') { //01011 + start_bit(); + spaceF(); + markF(); + spaceF(); + markF(); + markF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'H' || checkletter[indexofstring] == '#') { //00101 + start_bit(); + spaceF(); + spaceF(); + markF(); + spaceF(); + markF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'I' || checkletter[indexofstring] == '8') { //01100 + start_bit(); + spaceF(); + markF(); + markF(); + spaceF(); + spaceF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'J') { //11010 should send a ' as well, but errors + start_bit(); + markF(); + markF(); + spaceF(); + markF(); + spaceF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'K' || checkletter[indexofstring] == '(') { //11110 + start_bit(); + markF(); + markF(); + markF(); + markF(); + spaceF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'L' || checkletter[indexofstring] == ')') { //01001 + start_bit(); + spaceF(); + markF(); + spaceF(); + spaceF(); + markF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'M' || checkletter[indexofstring] == '.') { //00111 + start_bit(); + spaceF(); + spaceF(); + markF(); + markF(); + markF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'N' || checkletter[indexofstring] == ',') { //00110 + start_bit(); + spaceF(); + spaceF(); + markF(); + markF(); + spaceF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'O' || checkletter[indexofstring] == '9') { //00011 + start_bit(); + spaceF(); + spaceF(); + spaceF(); + markF(); + markF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'P' || checkletter[indexofstring] == '0') { //01101 + start_bit(); + spaceF(); + markF(); + markF(); + spaceF(); + markF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'Q' || checkletter[indexofstring] == '1') { //11101 + start_bit(); + markF(); + markF(); + markF(); + spaceF(); + markF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'R' || checkletter[indexofstring] == '4') { //01010 + start_bit(); + spaceF(); + markF(); + spaceF(); + markF(); + spaceF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'S') { //10100 should do Bell? + start_bit(); + markF(); + spaceF(); + markF(); + spaceF(); + spaceF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'T' || checkletter[indexofstring] == '5') { //00001 + start_bit(); + spaceF(); + spaceF(); + spaceF(); + spaceF(); + markF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'U' || checkletter[indexofstring] == '7') { //11100 + start_bit(); + markF(); + markF(); + markF(); + spaceF(); + spaceF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'V' || checkletter[indexofstring] == ';') { //01111 + start_bit(); + spaceF(); + markF(); + markF(); + markF(); + markF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'W' || checkletter[indexofstring] == '2') { //11001 + start_bit(); + markF(); + markF(); + spaceF(); + spaceF(); + markF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'X' || checkletter[indexofstring] == '/') { //10111 + start_bit(); + markF(); + spaceF(); + markF(); + markF(); + markF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'Y' || checkletter[indexofstring] == '6') { //10101 + start_bit(); + markF(); + spaceF(); + markF(); + spaceF(); + markF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'Z' || checkletter[indexofstring] == '"') { //10001 + start_bit(); + markF(); + spaceF(); + spaceF(); + spaceF(); + markF(); + stop_bit(); } + else if ( (checkletter[indexofstring] == ' ')) {//this seems to properly send a space 00100. for a new line i think i need 01000 + start_bit(); + spaceF(); + spaceF(); + markF(); + spaceF(); + spaceF(); + stop_bit(); } + else { //if no valid characters are provided a ? is returned for that character + figure_shift(); + start_bit(); + markF(); + spaceF(); + spaceF(); + markF(); + markF(); + stop_bit(); } +} + +void start_bit() { + writeReg(0x09,mySpace); // my addition + delay(bit_time); + } +void markF() { + writeReg(0x09,myMark); // my addition + delay(bit_time); +} + +void spaceF() { + writeReg(0x09,mySpace); // my addition + delay(bit_time); +} + +void stop_bit() { + writeReg(0x09,myMark); // my addition + delay(stop_bit_time); +} + +void figure_shift() { // switch to figures ???? Numbers ????? + //switch to figures + start_bit(); + //11011 + markF(); + markF(); + spaceF(); + markF(); + markF(); + //stop bit + stop_bit(); +} + +void letter_shift() { + //switch to letters + start_bit(); + //11011 + markF(); + markF(); + markF(); + markF(); + markF(); + //stop bit + stop_bit(); +} + +// This custom version of delay() ensures that the gps object is being "fed". +static void smartDelay(unsigned long ms) +{ + unsigned long start = millis(); + do + { + while (ss.available()) + gps.encode(ss.read()); + } while (millis() - start < ms); +} + +// +//Written by Ted Van Slyck www.openrcdesign.com +//Feel free to use for personal non commercial use +//use at your own risk, no warranties. It probably has errors of some kind. + +//this program has an issue with finishing a string on a non space. perhaps i should program it to send a new line or a space at the end of all strings regardless? this MIGHT be an issue with how droidRTTY interperets too... +//Also, i think i should make it send a letter or a figure shift each time it commences a string. + diff --git a/promini33_rfm69_RTTY_5N1_4545_170_Keyboard_20180118.ino b/promini33_rfm69_RTTY_5N1_4545_170_Keyboard_20180118.ino new file mode 100644 index 0000000..3875c68 --- /dev/null +++ b/promini33_rfm69_RTTY_5N1_4545_170_Keyboard_20180118.ino @@ -0,0 +1,535 @@ +/* + * My atempt to create a simple Morse code sender + * for rfm22b + * on a ProMini 3.3 + * + * 1) force all characters to upper case - failed + * 2) add command for CQ as /CQ but first need to capture and print string + * + * with thanks to Mark VandeWettering + * + * "This code is so trivial that I'm releasing it completely without restrictions." + * Simple Arduino Morse Beacon v0.0 + * Written by Mark VandeWettering + * Check out my blog @ http://brainwagon.org + */ + +// RTTY works! ProMini 3.3 +// Standard RTTY 5N1.5 170 45.45 +// RFM69HCW + +#include + +#define MODULATION 0x60 +#define radioPower 0x58 // 6 dBm +//#define radioPower 0x5B // 9 dBm +//#define radioPower 0x5E // 12 dBm +//#define radioPower 0x7F // 17 dBm +#define ssPin 10 // SS +//#define ssPin 8 // adafruit feather M0 +#define rstPin 9 // reset pin +//#define rstPin 4 // adafruit feather M0 +#define myDelay 5 +#define myShift 3 // 3 x 61 Hz = 181 Hz ~ 170 Hz + + +String myString = ""; +int myStringLen = 0; +int current_state; +int previous_state; +int send_shift; +float baud = 45.45; +float bit_time = 1000/baud;; +float stop_bit_time = bit_time * 2; +int index = 0; +String inputString = ""; // a String to hold incoming data + +String myCall = "... CQ CQ CQ DE KC1ENN KC1ENN KC1ENN PSE K ... "; +boolean stringComplete = false; // whether the string is complete +uint32_t myMark; +uint32_t mySpace; +long myFrequency = 433200000; // 70cm +//long myFrequency = 915000000; // 33cm + +void setup(){ + Serial.begin(9600); + Serial.println("Starting up"); + // reserve 200 bytes for the inputString: + inputString.reserve(200); + pinMode(ssPin, OUTPUT); + pinMode(rstPin, OUTPUT); + setupSPI(); + delay(1000); + resetRFM69(); + delay(1000); + setupRFM69(); +} + +void loop (){ + if (stringComplete) { + // clear the string: + inputString = ""; + //transmitData(); + stringComplete = false; + } +} //ends void loop +/////////////////////////////////////////////// + +void serialEvent() { + while (Serial.available()) { + // get the new byte: + char inChar = (char)Serial.read(); + // add it to the inputString: + inputString += inChar; + // if the incoming character is a newline, set a flag so the main loop can + // do something about it: + if (inChar == '\n') { + stringComplete = true; + if(inputString.indexOf("@freq=") == 0) { + myFrequency = inputString.substring(6,15).toInt(); + setFrequency(myFrequency); + getMark(myFrequency); + getSpace(myFrequency); + Serial.print("Frequency now set to: "); Serial.println(inputString.substring(6,15)); + inputString = ""; + myString = ""; + myStringLen = 0; + } + if(inputString.indexOf("@freq+") == 0) { + myFrequency = myFrequency + 61; + setFrequency(myFrequency); + getMark(myFrequency); + getSpace(myFrequency); + Serial.print("Frequency now set to: "); Serial.println(myFrequency); + inputString = ""; + myString = ""; + myStringLen = 0; + } + if(inputString.indexOf("@freq-") == 0) { + myFrequency = myFrequency - 61; + setFrequency(myFrequency); + getMark(myFrequency); + getSpace(myFrequency); + Serial.print("Frequency now set to: "); Serial.println(myFrequency); + inputString = ""; + myString = ""; + myStringLen = 0; + } + if (inputString.indexOf("@cq") == 0) { + myString = myCall; + myString.toUpperCase(); + myStringLen = myString.length(); + Serial.print("I am sending: "); Serial.println(myString); + transmitData(); + } + else { + inputString.trim(); + if(inputString.length() > 0) { + myString = " " +inputString + " "; + myString.toUpperCase(); + myStringLen = myString.length(); + Serial.print("I am sending: "); Serial.println(myString); + transmitData(); + } + } + } + } +} + +void resetRFM69() { + digitalWrite(rstPin, HIGH); + delay(100); + digitalWrite(rstPin, LOW); + delay(100); +} + +void setupRFM69() { + writeReg(0x01,0x84); // set RegOpMode to Sequencer On Listen Off Standby = 0x04 + writeReg(0x02,MODULATION); // RegDataModul = Continuous mode w/0 synthesizer FSK No Shaping = 0x60 + setFrequency(myFrequency); + Serial.print("Frequency set to "); Serial.println(myFrequency); + getMark(myFrequency); + getSpace(myFrequency); + writeReg(0x26,0x07); // CLK off to save power + writeReg(0x11,radioPower); // 0x9F PA0 On only, 0x5F or 0x41 // Pa1On 0x40 to 0x5F ????? + Serial.println("Transmitter is ready...."); +} + +void printReg(byte data){ + Serial.print("Register "); + Serial.print(data); + Serial.print(" = "); + Serial.println(readReg(data), HEX); +} + +void writeReg(uint8_t addr, uint8_t value) +{ + digitalWrite(ssPin,LOW); + SPI.transfer(addr | 0x80); + SPI.transfer(value); + digitalWrite(ssPin, HIGH); +} + +uint8_t readReg(uint8_t addr) +{ + digitalWrite(ssPin, LOW); + SPI.transfer(addr & 0x7F); + uint8_t regval = SPI.transfer(0); + digitalWrite(ssPin, HIGH); + return regval; +} + +void setupSPI() { + SPI.begin(); + SPI.setBitOrder(MSBFIRST); + SPI.setClockDivider(SPI_CLOCK_DIV4); +} + +void setFrequency(uint32_t freqHz){ // Setup the frequency + freqHz /= 61; // resolution is 61 Hz so divide it it down and mask it out + writeReg(0x07, freqHz >> 16); // Frequency MSB + writeReg(0x08, freqHz >> 8); // Frequency Middle Byte + writeReg(0x09, freqHz); // Frequency LSB +} + +void getMark(uint32_t freqHz) { + freqHz /= 61; // divide down by FSTEP to get FRF + myMark = freqHz; +} + +void getSpace(uint32_t freqHz) { + freqHz /= 61; // divide down by FSTEP to get FRF + mySpace = freqHz - 3; +} + +/////////////////////////////////////////////// + +void transmitData(){ + writeReg(0x01,0x0C); + delay(5000); + for (index = 0; index < myStringLen; index++) { + check_current_state(myString[index]) ; + compare_state(); + send_shift_sig(); + lookup_send(myString, index); + } + writeReg(0x01,0x84); // set RegOpMode to Sequencer On Listen Off Standby = 0x04 + delay(1000); +} + +void check_current_state(char val) { + if (isalpha(val)) + current_state = 0; + else + current_state = 1; + } + +void compare_state() { //compares states and sends letter shifts + if (current_state == previous_state) { + send_shift = 0; + } + else { + send_shift = 1; + previous_state = current_state; + } + } + +void send_shift_sig() { + if (send_shift == 1) { + if (current_state == 0) { + letter_shift(); } + else { figure_shift(); } + } + if (current_state == 1) { // My addition + figure_shift(); // my addition + } +} + +void lookup_send(String checkletter, int indexofstring) { + if (checkletter[indexofstring] == 'A' || checkletter[indexofstring] == '-'){//11000 + start_bit(); + markF(); + markF(); + spaceF(); + spaceF(); + spaceF(); + stop_bit();} + else if (checkletter[indexofstring] == 'B' || checkletter[indexofstring] == '?') { //10011 + start_bit(); + markF(); + spaceF(); + spaceF(); + markF(); + markF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'C' || checkletter[indexofstring] == ':') { //01110 + start_bit(); + spaceF(); + markF(); + markF(); + markF(); + spaceF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'D') { //10010 WRU? will program later + start_bit(); + markF(); + spaceF(); + spaceF(); + markF(); + spaceF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'E' || checkletter[indexofstring] == '3') { //10000 + start_bit(); + markF(); + spaceF(); + spaceF(); + spaceF(); + spaceF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'F' || checkletter[indexofstring] == '!') { //10110 + start_bit(); + markF(); + spaceF(); + markF(); + markF(); + spaceF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'G' || checkletter[indexofstring] == '&') { //01011 + start_bit(); + spaceF(); + markF(); + spaceF(); + markF(); + markF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'H' || checkletter[indexofstring] == '#') { //00101 + start_bit(); + spaceF(); + spaceF(); + markF(); + spaceF(); + markF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'I' || checkletter[indexofstring] == '8') { //01100 + start_bit(); + spaceF(); + markF(); + markF(); + spaceF(); + spaceF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'J') { //11010 should send a ' as well, but errors + start_bit(); + markF(); + markF(); + spaceF(); + markF(); + spaceF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'K' || checkletter[indexofstring] == '(') { //11110 + start_bit(); + markF(); + markF(); + markF(); + markF(); + spaceF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'L' || checkletter[indexofstring] == ')') { //01001 + start_bit(); + spaceF(); + markF(); + spaceF(); + spaceF(); + markF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'M' || checkletter[indexofstring] == '.') { //00111 + start_bit(); + spaceF(); + spaceF(); + markF(); + markF(); + markF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'N' || checkletter[indexofstring] == ',') { //00110 + start_bit(); + spaceF(); + spaceF(); + markF(); + markF(); + spaceF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'O' || checkletter[indexofstring] == '9') { //00011 + start_bit(); + spaceF(); + spaceF(); + spaceF(); + markF(); + markF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'P' || checkletter[indexofstring] == '0') { //01101 + start_bit(); + spaceF(); + markF(); + markF(); + spaceF(); + markF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'Q' || checkletter[indexofstring] == '1') { //11101 + start_bit(); + markF(); + markF(); + markF(); + spaceF(); + markF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'R' || checkletter[indexofstring] == '4') { //01010 + start_bit(); + spaceF(); + markF(); + spaceF(); + markF(); + spaceF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'S') { //10100 should do Bell? + start_bit(); + markF(); + spaceF(); + markF(); + spaceF(); + spaceF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'T' || checkletter[indexofstring] == '5') { //00001 + start_bit(); + spaceF(); + spaceF(); + spaceF(); + spaceF(); + markF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'U' || checkletter[indexofstring] == '7') { //11100 + start_bit(); + markF(); + markF(); + markF(); + spaceF(); + spaceF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'V' || checkletter[indexofstring] == ';') { //01111 + start_bit(); + spaceF(); + markF(); + markF(); + markF(); + markF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'W' || checkletter[indexofstring] == '2') { //11001 + start_bit(); + markF(); + markF(); + spaceF(); + spaceF(); + markF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'X' || checkletter[indexofstring] == '/') { //10111 + start_bit(); + markF(); + spaceF(); + markF(); + markF(); + markF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'Y' || checkletter[indexofstring] == '6') { //10101 + start_bit(); + markF(); + spaceF(); + markF(); + spaceF(); + markF(); + stop_bit(); } + else if (checkletter[indexofstring] == 'Z' || checkletter[indexofstring] == '"') { //10001 + start_bit(); + markF(); + spaceF(); + spaceF(); + spaceF(); + markF(); + stop_bit(); } + else if ( (checkletter[indexofstring] == ' ')) {//this seems to properly send a space 00100. for a new line i think i need 01000 + start_bit(); + spaceF(); + spaceF(); + markF(); + spaceF(); + spaceF(); + stop_bit(); } + + + else { //if no valid characters are provided a ? is returned for that character + figure_shift(); + start_bit(); + markF(); + spaceF(); + spaceF(); + markF(); + markF(); + stop_bit(); } + } + +void start_bit() { + writeReg(0x09,mySpace); // my addition + //tone(pin,space); + delay(bit_time); + } + + +void markF() { + writeReg(0x09,myMark); // my addition + //tone(pin,mark); + delay(bit_time); + } + +void spaceF() { + writeReg(0x09,mySpace); // my addition + //tone(pin,space); + delay(bit_time); + } + +void stop_bit() { + writeReg(0x09,myMark); // my addition + //tone(pin,mark); + delay(stop_bit_time); + } + +void figure_shift() { + //switch to figures + start_bit(); + //11011 + markF(); + markF(); + spaceF(); + markF(); + markF(); + //stop bit + stop_bit(); + } +void letter_shift() { + //switch to letters + start_bit(); + //11011 + markF(); + markF(); + markF(); + markF(); + markF(); + //stop bit + stop_bit(); + } + +// +//Written by Ted Van Slyck www.openrcdesign.com +//Feel free to use for personal non commercial use +//use at your own risk, no warranties. It probably has errors of some kind. + +//this program has an issue with finishing a string on a non space. perhaps i should program it to send a new line or a space at the end of all strings regardless? this MIGHT be an issue with how droidRTTY interperets too... +//Also, i think i should make it send a letter or a figure shift each time it commences a string. +