-
-
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 <[email protected]>. 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