-
-
Save NT7S/2b5555aa28622c1b3fcbc4d7c74ad926 to your computer and use it in GitHub Desktop.
import serial | |
import sys | |
import time | |
# Arduino serial dev paramaters | |
DEVICE = '/dev/ttyUSB0' # Change this as necessary | |
BAUD = 9600 | |
# Open serial port | |
try: | |
ser = serial.Serial(port=DEVICE, baudrate=BAUD, timeout=1, writeTimeout=1) | |
except: | |
print('Cannot open serial port') | |
sys.exit(0) | |
#Wait for ASCII bell, then send the Unix time string | |
while True: | |
ser_in = ser.read() | |
if('\a' in ser_in): | |
ser.write('T' + str(int(time.time()))) |
// Si5351_WSPR | |
// | |
// Simple WSPR beacon for Arduino Uno, with the Etherkit Si5351A Breakout | |
// Board, by Jason Milldrum NT7S. | |
// | |
// Original code based on Feld Hell beacon for Arduino by Mark | |
// Vandewettering K6HX, adapted for the Si5351A by Robert | |
// Liesenfeld AK6L <ak6l@ak6l.org>. Timer setup | |
// code by Thomas Knutsen LA3PNA. | |
// | |
// Time code adapted from the TimeSerial.ino example from the Time library. | |
// Hardware Requirements | |
// --------------------- | |
// This firmware must be run on an Arduino AVR microcontroller | |
// | |
// Required Libraries | |
// ------------------ | |
// Etherkit Si5351 (Library Manager) | |
// Etherkit JTEncode (Library Manager) | |
// Time (Library Manager) | |
// Wire (Arduino Standard Library) | |
// | |
// License | |
// ------- | |
// Permission is hereby granted, free of charge, to any person obtaining | |
// a copy of this software and associated documentation files (the | |
// "Software"), to deal in the Software without restriction, including | |
// without limitation the rights to use, copy, modify, merge, publish, | |
// distribute, sublicense, and/or sell copies of the Software, and to | |
// permit persons to whom the Software is furnished to do so, subject | |
// to the following conditions: | |
// | |
// The above copyright notice and this permission notice shall be | |
// included in all copies or substantial portions of the Software. | |
// | |
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | |
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR | |
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF | |
// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | |
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
// | |
#include <si5351.h> | |
#include <JTEncode.h> | |
#include <int.h> | |
#include <TimeLib.h> | |
#include "Wire.h" | |
#define TONE_SPACING 146 // ~1.46 Hz | |
#define WSPR_CTC 10672 // CTC value for WSPR | |
#define SYMBOL_COUNT WSPR_SYMBOL_COUNT | |
#define CORRECTION 0 // Change this for your ref osc | |
#define TIME_HEADER "T" // Header tag for serial time sync message | |
#define TIME_REQUEST 7 // ASCII bell character requests a time sync message | |
#define TX_LED_PIN 12 | |
#define SYNC_LED_PIN 13 | |
// Global variables | |
Si5351 si5351; | |
JTEncode jtencode; | |
unsigned long freq = 10140200UL; // Change this | |
char call[7] = "N0CALL"; // Change this | |
char loc[5] = "AB12"; // Change this | |
uint8_t dbm = 10; | |
uint8_t tx_buffer[SYMBOL_COUNT]; | |
// Global variables used in ISRs | |
volatile bool proceed = false; | |
// Timer interrupt vector. This toggles the variable we use to gate | |
// each column of output to ensure accurate timing. Called whenever | |
// Timer1 hits the count set below in setup(). | |
ISR(TIMER1_COMPA_vect) | |
{ | |
proceed = true; | |
} | |
// Loop through the string, transmitting one character at a time. | |
void encode() | |
{ | |
uint8_t i; | |
jtencode.wspr_encode(call, loc, dbm, tx_buffer); | |
// Reset the tone to 0 and turn on the output | |
si5351.set_clock_pwr(SI5351_CLK0, 1); | |
digitalWrite(TX_LED_PIN, HIGH); | |
// Now do the rest of the message | |
for(i = 0; i < SYMBOL_COUNT; i++) | |
{ | |
si5351.set_freq((freq * 100) + (tx_buffer[i] * TONE_SPACING), SI5351_CLK0); | |
proceed = false; | |
while(!proceed); | |
} | |
// Turn off the output | |
si5351.set_clock_pwr(SI5351_CLK0, 0); | |
digitalWrite(TX_LED_PIN, LOW); | |
} | |
void processSyncMessage() | |
{ | |
unsigned long pctime; | |
const unsigned long DEFAULT_TIME = 1357041600; // Jan 1 2013 | |
if(Serial.find(TIME_HEADER)) | |
{ | |
pctime = Serial.parseInt(); | |
if( pctime >= DEFAULT_TIME) | |
{ // check the integer is a valid time (greater than Jan 1 2013) | |
setTime(pctime); // Sync Arduino clock to the time received on the serial port | |
} | |
} | |
} | |
time_t requestSync() | |
{ | |
Serial.write(TIME_REQUEST); | |
return 0; // the time will be sent later in response to serial mesg | |
} | |
void setup() | |
{ | |
// Use the Arduino's on-board LED as a keying indicator. | |
pinMode(TX_LED_PIN, OUTPUT); | |
pinMode(SYNC_LED_PIN, OUTPUT); | |
digitalWrite(TX_LED_PIN, LOW); | |
digitalWrite(SYNC_LED_PIN, LOW); | |
Serial.begin(9600); | |
// Set time sync provider | |
setSyncProvider(requestSync); //set function to call when sync required | |
// Initialize the Si5351 | |
// Change the 2nd parameter in init if using a ref osc other | |
// than 25 MHz | |
si5351.init(SI5351_CRYSTAL_LOAD_8PF, 0, CORRECTION); | |
// Set CLK0 output | |
si5351.set_freq(freq * 100, SI5351_CLK0); | |
si5351.drive_strength(SI5351_CLK0, SI5351_DRIVE_8MA); // Set for max power | |
si5351.set_clock_pwr(SI5351_CLK0, 0); // Disable the clock initially | |
// Set up Timer1 for interrupts every symbol period. | |
noInterrupts(); // Turn off interrupts. | |
TCCR1A = 0; // Set entire TCCR1A register to 0; disconnects | |
// interrupt output pins, sets normal waveform | |
// mode. We're just using Timer1 as a counter. | |
TCNT1 = 0; // Initialize counter value to 0. | |
TCCR1B = (1 << CS12) | // Set CS12 and CS10 bit to set prescale | |
(1 << CS10) | // to /1024 | |
(1 << WGM12); // turn on CTC | |
// which gives, 64 us ticks | |
TIMSK1 = (1 << OCIE1A); // Enable timer compare interrupt. | |
OCR1A = WSPR_CTC; // Set up interrupt trigger count; | |
interrupts(); // Re-enable interrupts. | |
} | |
void loop() | |
{ | |
if(Serial.available()) | |
{ | |
processSyncMessage(); | |
} | |
if(timeStatus() == timeSet) | |
{ | |
digitalWrite(SYNC_LED_PIN, HIGH); // LED on if synced | |
} | |
else | |
{ | |
digitalWrite(SYNC_LED_PIN, LOW); // LED off if needs refresh | |
} | |
// Trigger every 10th minute | |
// WSPR should start on the 1st second of the minute, but there's a slight delay | |
// in this code because it is limited to 1 second resolution. | |
if(timeStatus() == timeSet && minute() % 10 == 0 && second() == 0) | |
{ | |
encode(); | |
delay(1000); | |
} | |
//delay(100); | |
} |
Hi Jason,
I downloaded new versions of JTEncode 1.1.4 and Si5351 2.1.1 . The issues remained.
I then changed to an older Si5351 that I had, ver 2.0.2 and most of the issues were gone. There must have been due to correction method change from one to two parameters I think.
The only remained issues are with JTEncode which they remain even with version 1.1.2.
I attach the error log file and wait for your kind feedback.
Arduino: 1.8.2 (Linux), Board: "Arduino/Genuino Uno"
JTEncode.cpp:58: error: prototype for 'void JTEncode::jt65_encode(char*, uint8_t*)' does not match any in class 'JTEncode'
void JTEncode::jt65_encode(char * message, uint8_t * symbols)
^
In file included from sketch/JTEncode.cpp:24:0:
JTEncode.h:210: error: candidate is: void JTEncode::jt65_encode(const char*, uint8_t*)
void jt65_encode(const char , uint8_t );
^
JTEncode.cpp:98: error: prototype for 'void JTEncode::jt9_encode(char, uint8_t)' does not match any in class 'JTEncode'
void JTEncode::jt9_encode(char * message, uint8_t * symbols)
^
In file included from sketch/JTEncode.cpp:24:0:
JTEncode.h:211: error: candidate is: void JTEncode::jt9_encode(const char*, uint8_t*)
void jt9_encode(const char , uint8_t );
^
JTEncode.cpp:143: error: prototype for 'void JTEncode::jt4_encode(char, uint8_t)' does not match any in class 'JTEncode'
void JTEncode::jt4_encode(char * message, uint8_t * symbols)
^
In file included from sketch/JTEncode.cpp:24:0:
JTEncode.h:212: error: candidate is: void JTEncode::jt4_encode(const char*, uint8_t*)
void jt4_encode(const char , uint8_t );
^
JTEncode.cpp:182: error: prototype for 'void JTEncode::wspr_encode(char, char, uint8_t, uint8_t*)' does not match any in class 'JTEncode'
void JTEncode::wspr_encode(char * call, char * loc, uint8_t dbm, uint8_t * symbols)
^
In file included from sketch/JTEncode.cpp:24:0:
JTEncode.h:213: error: candidate is: void JTEncode::wspr_encode(const char*, const char*, uint8_t, uint8_t*)
void wspr_encode(const char , const char , const uint8_t, uint8_t );
^
JTEncode.cpp:219: error: prototype for 'void JTEncode::fsq_encode(char, char, uint8_t)' does not match any in class 'JTEncode'
void JTEncode::fsq_encode(char * from_call, char * message, uint8_t * symbols)
^
In file included from sketch/JTEncode.cpp:24:0:
JTEncode.h:214: error: candidate is: void JTEncode::fsq_encode(const char*, const char*, uint8_t*)
void fsq_encode(const char , const char , uint8_t );
^
JTEncode.cpp:306: error: prototype for 'void JTEncode::fsq_dir_encode(char, char, char, char, uint8_t*)' does not match any in class 'JTEncode'
void JTEncode::fsq_dir_encode(char * from_call, char * to_call, char cmd, char * message, uint8_t * symbols)
^
In file included from sketch/JTEncode.cpp:24:0:
JTEncode.h:215: error: candidate is: void JTEncode::fsq_dir_encode(const char*, const char*, char, const char*, uint8_t*)
void fsq_dir_encode(const char , const char , const char, const char , uint8_t );
^
sketch/JTEncode.cpp: In member function 'void JTEncode::rs_encode(uint8_t, uint8_t)':
JTEncode.cpp:974: error: no matching function for call to 'JTEncode::encode_rs_int(void&, unsigned int [12], unsigned int [51])'
encode_rs_int(rs_inst, dat1, b);
^
sketch/JTEncode.cpp:974:33: note: candidate is:
In file included from sketch/JTEncode.cpp:24:0:
/home/kostas/Arduino/libraries/Etherkit_JTEncode/src/JTEncode.h:236:8: note: void JTEncode::encode_rs_int(void, data_t*, data_t*)
void encode_rs_int(void ,data_t , data_t );
^
/home/kostas/Arduino/libraries/Etherkit_JTEncode/src/JTEncode.h:236:8: note: no known conversion for argument 2 from 'unsigned int [12]' to 'data_t {aka unsigned char}'
exit status 1
prototype for 'void JTEncode::jt65_encode(char, uint8_t*)' does not match any in class 'JTEncode'
73 de SV1ONW, Konstantinos
Hi Jason,
When I try to compile with Arduino IDE 1.8.2 I get issues with the libraries.
I have installed EtherkitJTEncode ver 1.1.2
EtherkitSi5351 ver 2.1.0
Time ver 1.4
Is that ok or do you recommend other versions.
Thanks in advance,
73 de Konstantinos, SV1ONW