kopia lustrzana https://github.com/SnkMtn000/Arduino-RFM69HCW-GPS
Add files via upload
rodzic
02938c4eab
commit
470e96c8ea
|
@ -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 <SPI.h>
|
||||
|
||||
#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<N_HELL; i++) {
|
||||
if (helltab[i].c == c) {
|
||||
//Serial.print(helltab[i].c) ;
|
||||
|
||||
for (int j=0; j<=4; j++)
|
||||
{
|
||||
byte mask = B10000000;
|
||||
for (int q=0; q<=6; q++)
|
||||
{
|
||||
if(helltab[i].hellpat[j] & mask) {
|
||||
on();
|
||||
} else {
|
||||
helldelay();
|
||||
}
|
||||
mask >>= 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;
|
||||
}
|
||||
|
||||
|
|
@ -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 <SPI.h>
|
||||
#include <TinyGPS++.h>
|
||||
#include <SoftwareSerial.h>
|
||||
|
||||
#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<N_HELL; i++) {
|
||||
if (helltab[i].c == c) {
|
||||
//Serial.print(helltab[i].c) ;
|
||||
|
||||
for (int j=0; j<=4; j++)
|
||||
{
|
||||
byte mask = B10000000;
|
||||
for (int q=0; q<=6; q++)
|
||||
{
|
||||
if(helltab[i].hellpat[j] & mask) {
|
||||
on();
|
||||
} else {
|
||||
helldelay();
|
||||
}
|
||||
mask >>= 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);
|
||||
}
|
||||
|
|
@ -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 <SPI.h>
|
||||
|
||||
#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<N_HELL; i++) {
|
||||
if (helltab[i].c == c) {
|
||||
//Serial.print(helltab[i].c) ;
|
||||
|
||||
for (int j=0; j<=4; j++)
|
||||
{
|
||||
byte mask = B10000000;
|
||||
for (int q=0; q<=6; q++)
|
||||
{
|
||||
if(helltab[i].hellpat[j] & mask) {
|
||||
on();
|
||||
} else {
|
||||
helldelay();
|
||||
}
|
||||
mask >>= 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;
|
||||
}
|
|
@ -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 <k6hx@arrl.net>
|
||||
* Check out my blog @ http://brainwagon.org
|
||||
*/
|
||||
|
||||
#include <SPI.h>
|
||||
|
||||
#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<N_MORSE; i++) {
|
||||
if (morsetab[i].c == c) {
|
||||
unsigned char p = morsetab[i].pat ;
|
||||
//Serial.print(morsetab[i].c) ;
|
||||
while (p != 1) {
|
||||
if (p & 1)
|
||||
dash() ;
|
||||
else
|
||||
dit() ;
|
||||
p = p / 2 ;
|
||||
}
|
||||
//tone(cwPin,500,2*DOTLEN);
|
||||
delay(2*DOTLEN) ;
|
||||
return ;
|
||||
}
|
||||
}
|
||||
/* if we drop off the end, then we send a space */
|
||||
//Serial.print("?") ;
|
||||
}
|
||||
|
||||
void sendmsg(char *str) {
|
||||
//send('.'); uncomment for fldigi
|
||||
while (*str)
|
||||
send(*str++) ;
|
||||
//Serial.println("");
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,261 @@
|
|||
/*
|
||||
* A simple GPS Morse Telemetry 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 <k6hx@arrl.net>
|
||||
* Check out my blog @ http://brainwagon.org
|
||||
*/
|
||||
|
||||
#include <SPI.h>
|
||||
#include <TinyGPS++.h>
|
||||
#include <SoftwareSerial.h>
|
||||
|
||||
#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<N_MORSE; i++) {
|
||||
if (morsetab[i].c == c) {
|
||||
unsigned char p = morsetab[i].pat ;
|
||||
//Serial.print(morsetab[i].c) ;
|
||||
while (p != 1) {
|
||||
if (p & 1)
|
||||
dash() ;
|
||||
else
|
||||
dit() ;
|
||||
p = p / 2 ;
|
||||
}
|
||||
//tone(cwPin,500,2*DOTLEN);
|
||||
delay(2*DOTLEN) ;
|
||||
return ;
|
||||
}
|
||||
}
|
||||
/* if we drop off the end, then we send a space */
|
||||
//Serial.print("?") ;
|
||||
}
|
||||
|
||||
void sendmsg(char *str) {
|
||||
//send('.'); uncomment for fldigi
|
||||
while (*str)
|
||||
send(*str++) ;
|
||||
//Serial.println("");
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,259 @@
|
|||
/*
|
||||
* A simple Morse code 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 <k6hx@arrl.net>
|
||||
* Check out my blog @ http://brainwagon.org
|
||||
*/
|
||||
|
||||
#include <SPI.h>
|
||||
|
||||
#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<N_MORSE; i++) {
|
||||
if (morsetab[i].c == c) {
|
||||
unsigned char p = morsetab[i].pat ;
|
||||
//Serial.print(morsetab[i].c) ;
|
||||
while (p != 1) {
|
||||
if (p & 1)
|
||||
dash() ;
|
||||
else
|
||||
dit() ;
|
||||
p = p / 2 ;
|
||||
}
|
||||
//tone(cwPin,500,2*DOTLEN);
|
||||
delay(2*DOTLEN) ;
|
||||
return ;
|
||||
}
|
||||
}
|
||||
/* if we drop off the end, then we send a space */
|
||||
//Serial.print("?") ;
|
||||
}
|
||||
|
||||
void sendmsg(char *str) {
|
||||
//send('.'); uncomment for fldigi
|
||||
while (*str)
|
||||
send(*str++) ;
|
||||
//Serial.println("");
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,464 @@
|
|||
/*
|
||||
* GPS telemetry using standard RTTY 5N1.5 170 45.45 Beacon
|
||||
* 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 <SPI.h>
|
||||
|
||||
#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();
|
||||
}
|
||||
|
||||
|
|
@ -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 <SPI.h>
|
||||
#include <TinyGPS++.h>
|
||||
#include <SoftwareSerial.h>
|
||||
|
||||
#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.
|
||||
|
|
@ -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 <k6hx@arrl.net>
|
||||
* Check out my blog @ http://brainwagon.org
|
||||
*/
|
||||
|
||||
// RTTY works! ProMini 3.3
|
||||
// Standard RTTY 5N1.5 170 45.45
|
||||
// RFM69HCW
|
||||
|
||||
#include <SPI.h>
|
||||
|
||||
#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.
|
||||
|
Ładowanie…
Reference in New Issue