pull/5/head
Jason Milldrum 2016-07-09 20:04:45 -07:00
rodzic 7b06dd1890
commit 72a4129652
6 zmienionych plików z 246 dodań i 102 usunięć

105
README.md
Wyświetl plik

@ -1,6 +1,6 @@
JT65/JT9/JT4/WSPR Encoder Library for Arduino
JT65/JT9/JT4/WSPR/FSQ Encoder Library for Arduino
=============================================
This library very simply generates a set of channel symbols for JT65, JT9, JT4, or WSPR based on the user providing a properly formatted Type 6 message for JT65, JT9, or JT4 (which is 13 valid characters) or a callsign, Maidenhead grid locator, and power output for WSPR. When paired with a synthesizer that can output frequencies in fine, phase-continuous tuning steps (such as the Si5351), then a beacon or telemetry transmitter can be created which can change the transmitted characters as needed from the Arduino.
This library very simply generates a set of channel symbols for JT65, JT9, JT4, or WSPR based on the user providing a properly formatted Type 6 message for JT65, JT9, or JT4 (which is 13 valid characters) or a callsign, Maidenhead grid locator, and power output for WSPR. It will also generate an arbitrary FSQ message of up to 200 characters in both directed and non-directed format. When paired with a synthesizer that can output frequencies in fine, phase-continuous tuning steps (such as the Si5351), then a beacon or telemetry transmitter can be created which can change the transmitted characters as needed from the Arduino.
Please feel free to use the issues feature of GitHub if you run into problems or have suggestions for important features to implement.
@ -16,11 +16,11 @@ If you need to or would like to install the library in the old way, then you can
Example
-------
There is a simple example that is placed in your examples menu under JTEncode. Open this to see how to incorporate this library with your code. The example provided with with the library is meant to be used in conjuction with the [Etherkit Si5351A Breakout Board](https://www.etherkit.com/rf-modules/si5351a-breakout-board.html), although it could be modified to use with other synthesizers which meet the technical requirements of the JT65/JT9/JT4/WSPR modes.
There is a simple example that is placed in your examples menu under JTEncode. Open this to see how to incorporate this library with your code. The example provided with with the library is meant to be used in conjuction with the [Etherkit Si5351A Breakout Board](https://www.etherkit.com/rf-modules/si5351a-breakout-board.html), although it could be modified to use with other synthesizers which meet the technical requirements of the JT65/JT9/JT4/WSPR/FSQ modes.
To run this example, be sure to download the [Si5351Arduino](https://github.com/etherkit/Si5351Arduino) library and follow the instructions there to connect the Si5351A Breakout Board to your Arduino. In order to trigger transmissions, you will also need to connect a momentary pushbutton from pin 12 of the Arduino to ground.
The example sketch itself is fairly straightforward. JT65, JT9, JT4, and WSPR modes are modulated in same way: phase-continuous multiple-frequency shift keying (MFSK). The message to be transmitted is passed to the JTEncode method corresponding to the desired mode, along with a pointer to an array which holds the returned channel symbols. When the pushbutton is pushed, the sketch then transmits each channel symbol sequentially as an offset from the base frequency given in the sketch define section.
The example sketch itself is fairly straightforward. JT65, JT9, JT4, WSPR, and FSQ modes are modulated in same way: phase-continuous multiple-frequency shift keying (MFSK). The message to be transmitted is passed to the JTEncode method corresponding to the desired mode, along with a pointer to an array which holds the returned channel symbols. When the pushbutton is pushed, the sketch then transmits each channel symbol sequentially as an offset from the base frequency given in the sketch define section.
An instance of the JTEncode object is created:
@ -56,6 +56,26 @@ On sketch startup, the mode parameters are set based on which mode is currently
symbol_count = WSPR_SYMBOL_COUNT; // From the library defines
tone_spacing = WSPR_TONE_SPACING;
break;
case MODE_FSQ_2:
freq = FSQ_DEFAULT_FREQ;
ctc = FSQ_2_CTC;
tone_spacing = FSQ_TONE_SPACING;
break;
case MODE_FSQ_3:
freq = FSQ_DEFAULT_FREQ;
ctc = FSQ_3_CTC;
tone_spacing = FSQ_TONE_SPACING;
break;
case MODE_FSQ_4_5:
freq = FSQ_DEFAULT_FREQ;
ctc = FSQ_4_5_CTC;
tone_spacing = FSQ_TONE_SPACING;
break;
case MODE_FSQ_6:
freq = FSQ_DEFAULT_FREQ;
ctc = FSQ_6_CTC;
tone_spacing = FSQ_TONE_SPACING;
break;
}
Note that the number of channel symbols for each mode is defined in the library, so you can use those defines to initialize your own symbol array sizes.
@ -75,8 +95,16 @@ During transmit, the proper class method is chosen based on the desired mode, th
jtencode.jt4_encode(message, tx_buffer);
break;
case MODE_WSPR:
call.toUpperCase();
jtencode.wspr_encode(call, loc, dbm, tx_buffer);
break;
case MODE_FSQ_2:
case MODE_FSQ_3:
case MODE_FSQ_4_5:
case MODE_FSQ_6:
call.toLowerCase();
jtencode.fsq_dir_encode(call, "n0call", " ", "hello world", tx_buffer);
break;
}
Once the channel symbols have been generated, it is a simple matter of transmitting them in sequence, each the correct amount of time:
@ -91,10 +119,10 @@ Once the channel symbols have been generated, it is a simple matter of transmitt
Public Methods
------------------
###jt65_encode()
### jt65_encode()
```
/*
* jt65_encode(char * message, uint8_t * symbols)
* jt65_encode(String message, uint8_t * symbols)
*
* Takes an arbitrary message of up to 13 allowable characters and returns
* a channel symbol table.
@ -105,10 +133,10 @@ Public Methods
*
*/
```
###jt9_encode()
### jt9_encode()
```
/*
* jt9_encode(char * message, uint8_t * symbols)
* jt9_encode(String message, uint8_t * symbols)
*
* Takes an arbitrary message of up to 13 allowable characters and returns
* a channel symbol table.
@ -120,25 +148,25 @@ Public Methods
*/
```
###jt4_encode()
### jt4_encode()
```
/*
* jt4_encode(char * message, uint8_t * symbols)
* jt4_encode(String message, uint8_t * symbols)
*
* Takes an arbitrary message of up to 13 allowable characters and returns
* a channel symbol table.
*
* message - Plaintext Type 6 message.
* symbols - Array of channel symbols to transmit retunred by the method.
* Ensure that you pass a uint8_t array of size JT4_SYMBOL_COUNT to the method.
* Ensure that you pass a uint8_t array of size JT9_SYMBOL_COUNT to the method.
*
*/
```
###wspr_encode()
### wspr_encode()
```
/*
* wspr_encode(char * call, char * loc, uint8_t dbm, uint8_t * symbols)
* wspr_encode(String call, String loc, uint8_t dbm, uint8_t * symbols)
*
* Takes an arbitrary message of up to 13 allowable characters and returns
*
@ -150,6 +178,41 @@ Public Methods
*
*/
```
### fsq_encode()
```
/*
* fsq_encode(String from_call, String message, uint8_t * symbols)
*
* Takes an arbitrary message and returns a FSQ channel symbol table.
*
* from_call - Callsign of issuing station (maximum size: 20)
* message - Null-terminated message string, no greater than 200 chars in length
* symbols - Array of channel symbols to transmit retunred by the method.
* Ensure that you pass a uint8_t array of at least the size of the message
* plus 5 characters to the method. Terminated in 0xFF.
*
*/
```
### fsq_dir_encode()
```
/*
* fsq_dir_encode(String from_call, String to_call, String cmd, String message, uint8_t * symbols)
*
* Takes an arbitrary message and returns a FSQ channel symbol table.
*
* from_call - Callsign from which message is directed (maximum size: 20)
* to_call - Callsign to which message is directed (maximum size: 20)
* cmd - Directed command (maximum size: 20)
* message - Null-terminated message string, no greater than 200 chars in length
* symbols - Array of channel symbols to transmit retunred by the method.
* Ensure that you pass a uint8_t array of at least the size of the message
* plus 5 characters to the method. Terminated in 0xFF.
*
*/
```
Tokens
------
Here are the defines, structs, and enumerations you will find handy to use with the library.
@ -162,6 +225,22 @@ Acknowledgements
----------------
Many thanks to Joe Taylor K1JT for his innovative work in amateur radio. We are lucky to have him. The algorithms in this program were derived from the source code in the [WSJT](http://sourceforge.net/projects/wsjt/) suite of applications. Also, many thanks for Andy Talbot G4JNT for [his paper](http://www.g4jnt.com/JTModesBcns.htm) on the WSPR coding protocol, which helped me to understand the WSPR encoding process, which in turn helped me to understand the related JT protocols.
Also, a big thank you to Murray Greenman, ZL1BPU for working allowing me to pick his brain regarding his neat new mode FSQ.
Changelog
---------
* v1.1.0
Added FSQ, changed all public methods to take String instead of char *
* v1.0.1
Fixed a bug in jt65_interleave that was causing a buffer overrun.
* v1.0.0
Initial Release
License
-------
JTEncode is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

Wyświetl plik

@ -1,5 +1,5 @@
//
// Simple JT65/JT9/WSPR beacon for Arduino, with the Etherkit
// Simple JT65/JT9/WSPR/FSQ beacon for Arduino, with the Etherkit
// Si5351A Breakout Board, by Jason Milldrum NT7S.
//
// Transmit an abritrary message of up to 13 valid characters
@ -47,21 +47,24 @@
#define JT65_TONE_SPACING 269 // ~2.69 Hz
#define JT4_TONE_SPACING 437 // ~4.37 Hz
#define WSPR_TONE_SPACING 146 // ~1.46 Hz
#define FSQ_TONE_SPACING 174 // ~1.74 Hz
#define FSQ_TONE_SPACING 879 // ~1.74 Hz
#define JT9_CTC 9000 // CTC value for JT9-1
#define JT65_CTC 5812 // CTC value for JT65A
#define JT4_CTC 3578 // CTC value for JT4
#define JT4_CTC 3578 // CTC value for JT4A
#define WSPR_CTC 10672 // CTC value for WSPR
#define FSQ_2_CTC 7812 // CTC value for 2 baud FSQ
#define FSQ_3_CTC 5208 // CTC value for 3 baud FSQ
#define FSQ_4_5_CTC 3472 // CTC value for 4.5 baud FSQ
#define FSQ_6_CTC 2604 // CTC value for 6 baud FSQ
#define JT9_DEFAULT_FREQ 14078600UL
#define JT65_DEFAULT_FREQ 14077500UL
#define JT4_DEFAULT_FREQ 14077500UL
#define WSPR_DEFAULT_FREQ 14097100UL
#define FSQ_DEFAULT_FREQ 7105350UL; // Base freq is 1350 Hz higher than dial freq in USB
#define JT9_DEFAULT_FREQ 14080800UL
#define JT65_DEFAULT_FREQ 14078500UL
#define JT4_DEFAULT_FREQ 14078500UL
#define WSPR_DEFAULT_FREQ 14097200UL
#define FSQ_DEFAULT_FREQ 7105350UL // Base freq is 1350 Hz higher than dial freq in USB
#define DEFAULT_MODE MODE_JT4
#define DEFAULT_MODE MODE_JT65
// Hardware defines
#define BUTTON 12
@ -77,8 +80,8 @@ JTEncode jtencode;
// Global variables
unsigned long freq;
char message[14] = "N0CALL AA00";
char call[7] = "N0CALL";
String message = "N0CALL AA00";
String call = "N0CALL";
char loc[5] = "AA00";
uint8_t dbm = 27;
uint8_t tx_buffer[255];
@ -118,13 +121,15 @@ void encode()
jtencode.jt4_encode(message, tx_buffer);
break;
case MODE_WSPR:
call.toUpperCase();
jtencode.wspr_encode(call, loc, dbm, tx_buffer);
break;
case MODE_FSQ_2:
case MODE_FSQ_3:
case MODE_FSQ_4_5:
case MODE_FSQ_6:
jtencode.fsq_encode(call, message, tx_buffer);
call.toLowerCase();
jtencode.fsq_dir_encode(call, "n0call", " ", "hello world", tx_buffer);
break;
}
@ -133,6 +138,17 @@ void encode()
digitalWrite(LED_PIN, HIGH);
// Now transmit the channel symbols
if(cur_mode == MODE_FSQ_2 || cur_mode == MODE_FSQ_3 || cur_mode == MODE_FSQ_4_5 || cur_mode == MODE_FSQ_6)
{
uint8_t j = 0;
while(tx_buffer[j++] != 0xff)
{
}
symbol_count = j - 1;
}
for(i = 0; i < symbol_count; i++)
{
si5351.set_freq((freq * 100) + (tx_buffer[i] * tone_spacing), 0, SI5351_CLK0);
@ -156,9 +172,7 @@ void setup()
pinMode(BUTTON, INPUT_PULLUP);
// Set the mode to use
cur_mode = MODE_FSQ_2;
//Serial.begin(57600);
cur_mode = MODE_WSPR;
// Set the proper frequency, tone spacing, symbol count, and
// timer CTC depending on mode
@ -193,6 +207,21 @@ void setup()
ctc = FSQ_2_CTC;
tone_spacing = FSQ_TONE_SPACING;
break;
case MODE_FSQ_3:
freq = FSQ_DEFAULT_FREQ;
ctc = FSQ_3_CTC;
tone_spacing = FSQ_TONE_SPACING;
break;
case MODE_FSQ_4_5:
freq = FSQ_DEFAULT_FREQ;
ctc = FSQ_4_5_CTC;
tone_spacing = FSQ_TONE_SPACING;
break;
case MODE_FSQ_6:
freq = FSQ_DEFAULT_FREQ;
ctc = FSQ_6_CTC;
tone_spacing = FSQ_TONE_SPACING;
break;
}
// Initialize the Si5351

Wyświetl plik

@ -2,7 +2,10 @@ JTEncode KEYWORD1
jt65_encode KEYWORD2
jt9_encode KEYWORD2
jt4_encode KEYWORD2
wspr_encode KEYWORD2
fsq_encode KEYWORD2
fsq_dir_encode KEYWORD2
JT65_SYMBOL_COUNT LITERAL1
JT9_SYMBOL_COUNT LITERAL1

Wyświetl plik

@ -1,9 +1,9 @@
name=Etherkit JTEncode
version=1.0.1
version=1.1.0
author=Jason Milldrum <milldrum@gmail.com>
maintainer=Jason Milldrum <milldrum@gmail.com>
sentence=Generate JT65, JT9, JT4, and WSPR symbols on your Arduino.
paragraph=This library very simply generates a set of channel symbols for JT65, JT9, JT4, or WSPR based on the user providing a properly formatted Type 6 message for JT65, JT9, or JT4 (which is 13 valid characters) or a callsign, Maidenhead grid locator, and power output for WSPR. When paired with a synthesizer that can output frequencies in fine, phase-continuous tuning steps (such as the Si5351), then a beacon or telemetry transmitter can be created which can change the transmitted characters as needed from the Arduino.
sentence=Generate JT65, JT9, JT4, WSPR, and FSQ symbols on your Arduino.
paragraph=This library very simply generates a set of channel symbols for JT65, JT9, JT4, or WSPR based on the user providing a properly formatted Type 6 message for JT65, JT9, or JT4 (which is 13 valid characters) or a callsign, Maidenhead grid locator, and power output for WSPR. It will also generate an arbitrary FSQ message of up to 200 characters in both directed and non-directed format. When paired with a synthesizer that can output frequencies in fine, phase-continuous tuning steps (such as the Si5351), then a beacon or telemetry transmitter can be created which can change the transmitted characters as needed from the Arduino.
category=Data Processing
url=https://github.com/etherkit/JTEncode
architectures=*

Wyświetl plik

@ -1,7 +1,7 @@
/*
* JTEncode.cpp - JT65/JT9/WSPR encoder library for Arduino
* JTEncode.cpp - JT65/JT9/WSPR/FSQ encoder library for Arduino
*
* Copyright (C) 2015 Jason Milldrum <milldrum@gmail.com>
* Copyright (C) 2015-2016 Jason Milldrum <milldrum@gmail.com>
*
* Based on the algorithms presented in the WSJT software suite.
* Thanks to Andy Talbot G4JNT for the whitepaper on the WSPR encoding
@ -29,12 +29,14 @@
#include <stdint.h>
#include <stdio.h>
#include "Arduino.h"
// Define an upper bound on the number of glyphs. Defining it this
// way allows adding characters without having to update a hard-coded
// upper bound.
#define NGLYPHS (sizeof(fsq_code_table)/sizeof(fsq_code_table[0]))
uint8_t JTEncode::crc8_table[256];
//uint8_t JTEncode::crc8_table[256];
/* Public Class Members */
@ -42,13 +44,10 @@ JTEncode::JTEncode(void)
{
// Initialize the Reed-Solomon encoder
rs_inst = (struct rs *)(intptr_t)init_rs_int(6, 0x43, 3, 1, 51, 0);
// Initialize the CRC8 table
init_crc8();
}
/*
* jt65_encode(char * message, uint8_t * symbols)
* jt65_encode(String message, uint8_t * symbols)
*
* Takes an arbitrary message of up to 13 allowable characters and returns
* a channel symbol table.
@ -58,16 +57,22 @@ JTEncode::JTEncode(void)
* Ensure that you pass a uint8_t array of size JT65_SYMBOL_COUNT to the method.
*
*/
void JTEncode::jt65_encode(char * message, uint8_t * symbols)
void JTEncode::jt65_encode(String message, uint8_t * symbols)
{
char message_array[14];
// Convert the String to C-style char array
// ----------------------------------------
message.toCharArray(message_array, 14);
// Ensure that the message text conforms to standards
// --------------------------------------------------
jt_message_prep(message);
jt_message_prep(message_array);
// Bit packing
// -----------
uint8_t c[12];
jt65_bit_packing(message, c);
jt65_bit_packing(message_array, c);
// Reed-Solomon encoding
// ---------------------
@ -88,7 +93,7 @@ void JTEncode::jt65_encode(char * message, uint8_t * symbols)
}
/*
* jt9_encode(char * message, uint8_t * symbols)
* jt9_encode(String message, uint8_t * symbols)
*
* Takes an arbitrary message of up to 13 allowable characters and returns
* a channel symbol table.
@ -98,16 +103,22 @@ void JTEncode::jt65_encode(char * message, uint8_t * symbols)
* Ensure that you pass a uint8_t array of size JT9_SYMBOL_COUNT to the method.
*
*/
void JTEncode::jt9_encode(char * message, uint8_t * symbols)
void JTEncode::jt9_encode(String message, uint8_t * symbols)
{
char message_array[14];
// Convert the String to C-style char array
// ----------------------------------------
message.toCharArray(message_array, 14);
// Ensure that the message text conforms to standards
// --------------------------------------------------
jt_message_prep(message);
jt_message_prep(message_array);
// Bit packing
// -----------
uint8_t c[13];
jt9_bit_packing(message, c);
jt9_bit_packing(message_array, c);
// Convolutional Encoding
// ---------------------
@ -133,7 +144,7 @@ void JTEncode::jt9_encode(char * message, uint8_t * symbols)
}
/*
* jt9_encode(char * message, uint8_t * symbols)
* jt4_encode(String message, uint8_t * symbols)
*
* Takes an arbitrary message of up to 13 allowable characters and returns
* a channel symbol table.
@ -143,16 +154,22 @@ void JTEncode::jt9_encode(char * message, uint8_t * symbols)
* Ensure that you pass a uint8_t array of size JT9_SYMBOL_COUNT to the method.
*
*/
void JTEncode::jt4_encode(char * message, uint8_t * symbols)
void JTEncode::jt4_encode(String message, uint8_t * symbols)
{
char message_array[14];
// Convert the String to C-style char array
// ----------------------------------------
message.toCharArray(message_array, 14);
// Ensure that the message text conforms to standards
// --------------------------------------------------
jt_message_prep(message);
jt_message_prep(message_array);
// Bit packing
// -----------
uint8_t c[13];
jt9_bit_packing(message, c);
jt9_bit_packing(message_array, c);
// Convolutional Encoding
// ---------------------
@ -171,7 +188,7 @@ void JTEncode::jt4_encode(char * message, uint8_t * symbols)
}
/*
* wspr_encode(char * call, char * loc, uint8_t dbm, uint8_t * symbols)
* wspr_encode(String call, String loc, uint8_t dbm, uint8_t * symbols)
*
* Takes an arbitrary message of up to 13 allowable characters and returns
*
@ -182,11 +199,19 @@ void JTEncode::jt4_encode(char * message, uint8_t * symbols)
* Ensure that you pass a uint8_t array of size WSPR_SYMBOL_COUNT to the method.
*
*/
void JTEncode::wspr_encode(char * call, char * loc, uint8_t dbm, uint8_t * symbols)
void JTEncode::wspr_encode(String call, String loc, uint8_t dbm, uint8_t * symbols)
{
char call_array[8];
char loc_array[8];
// Convert the String to C-style char array
// ----------------------------------------
call.toCharArray(call_array, 8);
loc.toCharArray(loc_array, 8);
// Ensure that the message text conforms to standards
// --------------------------------------------------
wspr_message_prep(call, loc, dbm);
wspr_message_prep(call_array, loc_array, dbm);
// Bit packing
// -----------
@ -208,30 +233,28 @@ void JTEncode::wspr_encode(char * call, char * loc, uint8_t dbm, uint8_t * symbo
}
/*
* fsq_dir_encode(char * from_call, char * from_call, char * message, uint8_t * symbols)
* fsq_encode(String from_call, String message, uint8_t * symbols)
*
* Takes an arbitrary message and returns a FSQ channel symbol table.
*
* from_call - Callsign of issuing station
* from_call - Callsign of issuing station (maximum size: 20)
* message - Null-terminated message string, no greater than 200 chars in length
* symbols - Array of channel symbols to transmit retunred by the method.
* Ensure that you pass a uint8_t array of at least the size of the message
* plus 5 characters to the method. Terminated in 0xFF.
*
*/
void JTEncode::fsq_encode(char * from_call, char * message, uint8_t * symbols)
void JTEncode::fsq_encode(String from_call, String message, uint8_t * symbols)
{
char tx_buffer[255];
char * tx_message;
uint16_t symbol_pos = 0;
uint8_t i, fch, vcode1, vcode2, tone;
uint8_t cur_tone = 0;
char tx_buffer[255];
char * tx_message;
// Clearn the transmit message buffer
memset(tx_buffer, 0, 255);
// Create the message to be transmitted
sprintf(tx_buffer, " \n%s: %s", from_call, message);
// ------------------------------------
sprintf(tx_buffer, " \n%s: %s", from_call.c_str(), message.c_str());
tx_message = tx_buffer;
@ -291,39 +314,40 @@ void JTEncode::fsq_encode(char * from_call, char * message, uint8_t * symbols)
}
/*
* fsq_dir_encode(char * from_call, char * to_call, char * cmd, char * message, uint8_t * symbols)
* fsq_dir_encode(String from_call, String to_call, String cmd, String message, uint8_t * symbols)
*
* Takes an arbitrary message and returns a FSQ channel symbol table.
*
* from_call - Callsign from which message is directed
* to_call - Callsign to which message is directed
* cmd - Directed command
* from_call - Callsign from which message is directed (maximum size: 20)
* to_call - Callsign to which message is directed (maximum size: 20)
* cmd - Directed command (maximum size: 20)
* message - Null-terminated message string, no greater than 200 chars in length
* symbols - Array of channel symbols to transmit retunred by the method.
* Ensure that you pass a uint8_t array of at least the size of the message
* plus 5 characters to the method. Terminated in 0xFF.
*
*/
void JTEncode::fsq_dir_encode(char * from_call, char * to_call, char * cmd, char * message, uint8_t * symbols)
void JTEncode::fsq_dir_encode(String from_call, String to_call, String cmd, String message, uint8_t * symbols)
{
//char from_call_array[20];
//char to_call_array[20];
//char cmd_array[20];
//char message_array[200];
char tx_buffer[255];
char * tx_message;
uint16_t symbol_pos = 0;
uint8_t i, fch, vcode1, vcode2, tone, from_call_crc;
uint8_t cur_tone = 0;
char tx_buffer[255];
char * tx_message;
// Generate a CRC on from_call
// ---------------------------
from_call_crc = crc8(from_call);
// Clearn the transmit message buffer
memset(tx_buffer, 0, 255);
from_call_crc = crc8(from_call.c_str());
// Create the message to be transmitted
// We are building a directed message here.
// FSQ very specifically needs " \b " in
// directed mode to indicate EOT. A single backspace won't do it.
sprintf(tx_buffer, " \n%s:%02x%s%s%s%s", from_call, from_call_crc, to_call, cmd, message, " \b ");
sprintf(tx_buffer, " \n%s:%02x%s%s%s%s", from_call.c_str(), from_call_crc, to_call.c_str(), cmd.c_str(), message.c_str(), " \b ");
tx_message = tx_buffer;
@ -985,23 +1009,7 @@ void JTEncode::rs_encode(uint8_t * data, uint8_t * symbols)
}
}
void JTEncode::init_crc8(void)
{
int i,j;
uint8_t crc;
for(i = 0; i < 256; i++)
{
crc = i;
for(j = 0; j < 8; j++)
{
crc = (crc << 1) ^ ((crc & 0x80) ? 0x07 : 0);
}
crc8_table[i] = crc & 0xFF;
}
}
uint8_t JTEncode::crc8(char * text)
uint8_t JTEncode::crc8(const char * text)
{
uint8_t crc = '\0';
uint8_t ch;
@ -1010,7 +1018,7 @@ uint8_t JTEncode::crc8(char * text)
for(i = 0; i < strlen(text); i++)
{
ch = text[i];
crc = crc8_table[(crc) ^ ch];
crc = pgm_read_byte(&(crc8_table[(crc) ^ ch]));
crc &= 0xFF;
}

Wyświetl plik

@ -1,7 +1,7 @@
/*
* JTEncode.h - JT65/JT9/WSPR encoder library for Arduino
* JTEncode.h - JT65/JT9/WSPR/FSQ encoder library for Arduino
*
* Copyright (C) 2015 Jason Milldrum <milldrum@gmail.com>
* Copyright (C) 2015-2016 Jason Milldrum <milldrum@gmail.com>
*
* Based on the algorithms presented in the WSJT software suite.
* Thanks to Andy Talbot G4JNT for the whitepaper on the WSPR encoding
@ -24,6 +24,8 @@
#include "int.h"
#include "rs_common.h"
#include "Arduino.h"
#include <stdint.h>
#include <avr/pgmspace.h>
@ -158,16 +160,41 @@ const Varicode fsq_code_table[] PROGMEM =
{8, {27, 31}} // BS
};
const uint8_t crc8_table[] PROGMEM = {
0x00, 0x07, 0x0e, 0x09, 0x1c, 0x1b, 0x12, 0x15, 0x38, 0x3f, 0x36, 0x31,
0x24, 0x23, 0x2a, 0x2d, 0x70, 0x77, 0x7e, 0x79, 0x6c, 0x6b, 0x62, 0x65,
0x48, 0x4f, 0x46, 0x41, 0x54, 0x53, 0x5a, 0x5d, 0xe0, 0xe7, 0xee, 0xe9,
0xfc, 0xfb, 0xf2, 0xf5, 0xd8, 0xdf, 0xd6, 0xd1, 0xc4, 0xc3, 0xca, 0xcd,
0x90, 0x97, 0x9e, 0x99, 0x8c, 0x8b, 0x82, 0x85, 0xa8, 0xaf, 0xa6, 0xa1,
0xb4, 0xb3, 0xba, 0xbd, 0xc7, 0xc0, 0xc9, 0xce, 0xdb, 0xdc, 0xd5, 0xd2,
0xff, 0xf8, 0xf1, 0xf6, 0xe3, 0xe4, 0xed, 0xea, 0xb7, 0xb0, 0xb9, 0xbe,
0xab, 0xac, 0xa5, 0xa2, 0x8f, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9d, 0x9a,
0x27, 0x20, 0x29, 0x2e, 0x3b, 0x3c, 0x35, 0x32, 0x1f, 0x18, 0x11, 0x16,
0x03, 0x04, 0x0d, 0x0a, 0x57, 0x50, 0x59, 0x5e, 0x4b, 0x4c, 0x45, 0x42,
0x6f, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7d, 0x7a, 0x89, 0x8e, 0x87, 0x80,
0x95, 0x92, 0x9b, 0x9c, 0xb1, 0xb6, 0xbf, 0xb8, 0xad, 0xaa, 0xa3, 0xa4,
0xf9, 0xfe, 0xf7, 0xf0, 0xe5, 0xe2, 0xeb, 0xec, 0xc1, 0xc6, 0xcf, 0xc8,
0xdd, 0xda, 0xd3, 0xd4, 0x69, 0x6e, 0x67, 0x60, 0x75, 0x72, 0x7b, 0x7c,
0x51, 0x56, 0x5f, 0x58, 0x4d, 0x4a, 0x43, 0x44, 0x19, 0x1e, 0x17, 0x10,
0x05, 0x02, 0x0b, 0x0c, 0x21, 0x26, 0x2f, 0x28, 0x3d, 0x3a, 0x33, 0x34,
0x4e, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5c, 0x5b, 0x76, 0x71, 0x78, 0x7f,
0x6a, 0x6d, 0x64, 0x63, 0x3e, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2c, 0x2b,
0x06, 0x01, 0x08, 0x0f, 0x1a, 0x1d, 0x14, 0x13, 0xae, 0xa9, 0xa0, 0xa7,
0xb2, 0xb5, 0xbc, 0xbb, 0x96, 0x91, 0x98, 0x9f, 0x8a, 0x8d, 0x84, 0x83,
0xde, 0xd9, 0xd0, 0xd7, 0xc2, 0xc5, 0xcc, 0xcb, 0xe6, 0xe1, 0xe8, 0xef,
0xfa, 0xfd, 0xf4, 0xf3
};
class JTEncode
{
public:
JTEncode(void);
void jt65_encode(char *, uint8_t *);
void jt9_encode(char *, uint8_t *);
void jt4_encode(char *, uint8_t *);
void wspr_encode(char *, char *, uint8_t, uint8_t *);
void fsq_encode(char *, char *, uint8_t *);
void fsq_dir_encode(char *, char *, char *, char *, uint8_t *);
void jt65_encode(String, uint8_t *);
void jt9_encode(String, uint8_t *);
void jt4_encode(String, uint8_t *);
void wspr_encode(String, String, uint8_t, uint8_t *);
void fsq_encode(String, String, uint8_t *);
void fsq_dir_encode(String, String, String, String, uint8_t *);
private:
uint8_t jt_code(char);
uint8_t wspr_code(char);
@ -191,11 +218,9 @@ private:
void encode_rs_int(void *,data_t *, data_t *);
void free_rs_int(void *);
void * init_rs_int(int, int, int, int, int, int);
void init_crc8(void);
uint8_t crc8(char *);
uint8_t crc8(const char *);
void * rs_inst;
char callsign[7];
char locator[5];
uint8_t power;
static uint8_t crc8_table[256];
};