SKETCH
WSPR PER
1 TX
//***************************************************************************************
//ESP_WSPR_ver_3_006
//
// Simple WSPR beacon for ESP8266, with Si5351A Breakout board
// FIX CLK0 Output for 20 m band with Fast time sync to prevent weather dependent time drift.
//
//***************************************************************************************
// Hardware info
// ---------------------
// serial debug port baud rate: 115200
// Si5351A is connected via I2C on pin D1 (SCL) and D2 (SDA) as marked on Wemos D1 mini Lite
// freq0 is used in clock0 output.
//
// Hardware Requirements
// ---------------------
// This firmware must be run on an ESP8266 compatible board
// tested on Wemos D1 Mini
// Required Libraries
// ------------------
// Etherkit Si5351 (Library Manager)
// Etherkit JTEncode (Library Manager)
// Time (Library Manager)
// Wire (Arduino Standard Library)
// NTPtimeESP
// ESP8266WiFi
//*******************************[ LICENCE and CREDITS ]*********************************************
// Original Code of Multiband NODEMCU WSPR by Marco,IW5EJM
//
// Modified for one output, fast time sync and LED mode flash modifications by Barbaros Asuroglu,WB2CBA
//
//Simple WSPR beacon for ESP8266, with the Etherkit or SV1AFN 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.
// 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.
// IK1LBW (GIUGNO 2022)
// COME ESP8266 IO UTILIZZO LA SCHEDA: NodeMCU 1.0(ESP-12E Module)
// NELLO SKETCH INSERISCI IL NOME DEL WI-FI COME E' SCRITTO SUL TUO COMPUTER opp.CELLULARE....COSI' COME LA TUA PASSWORD WI-FI....IL CALL E W.W.LOC. IN MAIUSCOLO.
// AD AVVIO AVVENUTO:
// IL LED BLEU DEL ESP8266 LAMPEGGIA MENTRE CERCA LA LINEA WIFI...SMETTE IL LAMPEGGIO AD AGGANCIO AVVENUTO...LAMPEGGIA BREVEMENTE OGNI TANTO PER CONVALIDARE L'AGGANCIO.
// PER IL TEMPO DELLA TRASMISSIONE (110 sec.) IL LED BLEU DEL ESP8266 RIMANE ACCESO IN MANIERA FISSA.
// DOPODICHE' SI SPEGNE E RICOMINCIA IL CICLO....
// PERCHE' TUTTO FUNZIONI AL PRIMO COLPO INSERISCI TUTTE LE LIBRERIE RICHIESTE....COSI' ANCHE IL GIUSTO ELENCO DELLE SCHEDE.
// LEGGERE BENE I VARI TUTORIAL IN RETE ---> https://antrak.org.tr/blog/esp-wspr-simple-and-inexpensive-wspr-transmitter/
// BUON LAVORO E DX !!
// 73 de ARMANDO.
//*********************************[ Libraries/Librerie ]*****************************************
#include <si5351.h>
#include "Wire.h"
#include <JTEncode.h>
#include <int.h>
#include <TimeLib.h>
#include <NTPtimeESP.h>
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
//******************************[ DEFINE'S ]********************************************
#define TONE_SPACING 146 // ~1.46 Hz
#define WSPR_DELAY 683 // Delay value for WSPR
#define WSPR_CTC 10672 // CTC value for WSPR
#define SYMBOL_COUNT WSPR_SYMBOL_COUNT
#define TX_LED_PIN 2 //integrated onboard led
#define SEND_INTV 10
#define RECV_TIMEOUT 10
#define SI5351_REF 25000000UL //si5351’s crystal frequency, 25 Mhz or 27 MHz
//****************************************************************************************************
//**************************[ USER DEFINED PARAMETERS DECLARATION ]***********************************
//****************************************************************************************************
unsigned long freq = 475685UL; // 475 Khz * 357008 Mhz * 704005 Mhz etc.Change this for different band frequencies-INSERIRE FREQUENZA WSPR
int32_t cal_factor = 0; // SI5351 Calibration factor obtained from Calibration firmware plugged in here.
const char* ssid = "Tenda-WiFi"; // SSID of your Wifi network-INSERIRE NOME DEL TUO WIFI
const char* password = "arma";//Password of your wifi network-INSERIRE PSW DEL TUO WIFI
char call[7] = "IK1LBW"; // USER CALLSIGN-INSERIRE IL TUO CALL PER INTERO
char loc[5] = "JN44"; // USER MAIDENHEAD GRID LOCATOR first 4 letters-INSERIRE PRIME 4 CIFRE W.W. LOC.
#define TIME_ZONE +2.0f // Your time zone difference in regards to UTC (floating point number-INSERIRE LA DIFFERENZA ORARIA TRA ORARIO ITALIANO E U.T.C.
//*****************************************************************************************************
//*********************************[ END OF USER DEFINED PARAMETERS ]**********************************
//*****************************************************************************************************
//****************************[ VARIABLES DECLARATION ]************************************************
uint8_t dbm = 37;//INSERISCI IL VALORE DELLA POTENZA OUT ESPRESSA IN dbm (10 dbm=10 mW)QUESTO VALORE VERRA ' VISUALIZZATO DAI CORRISPONDENTI
uint8_t tx_buffer[SYMBOL_COUNT];
const char* WiFi_hostname = "ESP_WSPR";
//Sync clock every 12 hours
#define NTPSYNC_DELAY 1
//NTP Server:
const char* NTP_Server = "ntp2.inrim.it";
Si5351 si5351;
JTEncode jtencode;
bool warmup=0;
NTPtime NTPch(NTP_Server);
strDateTime dateTime;
//****************************************[ TIME SYNC FUNCTION ]******************************************
time_t epochUnixNTP()
{
digitalWrite(TX_LED_PIN, LOW);
Serial.println("- NTP Time Sync...");
Serial.print("- NTP Time:");
NTPch.setSendInterval(SEND_INTV);
NTPch.setRecvTimeout(RECV_TIMEOUT);
do
{
dateTime = NTPch.getNTPtime(TIME_ZONE, 1);
delay(1);
}
while(!dateTime.valid);
NTPch.printDateTime(dateTime);
setTime(dateTime.hour,dateTime.minute,dateTime.second,dateTime.day,dateTime.month,dateTime.year);
Serial.println(now());
digitalWrite(TX_LED_PIN, HIGH);
return 0;
}
//*********************************[ WSPR ENCODE and TRANSMIT FUNCTION ]**********************************************
void encode()
{
uint8_t i;
jtencode.wspr_encode(call, loc, dbm, tx_buffer);
digitalWrite(TX_LED_PIN, LOW);
Serial.println("- TX ON - STARTING TRANSMISSION...");
// 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);
delay(WSPR_DELAY);
}
// Turn off the output
si5351.set_clock_pwr(SI5351_CLK0, 0);
digitalWrite(TX_LED_PIN, HIGH);
Serial.println("- TX OFF - END OF TRANSMISSION...");
}
//*****************************************[ WIFI CONNECTION FUNCTION ]****************************************
void ssidConnect()
{
Serial.println("- ESTABLISHING WIFI CONNECTION TO:");
Serial.println(ssid);
Serial.println(password);
WiFi.begin(ssid, password);
Serial.print("- Connecting");
while (WiFi.status() != WL_CONNECTED) {
digitalWrite(TX_LED_PIN, LOW);
delay(300);
digitalWrite(TX_LED_PIN, HIGH);
delay(300);
Serial.print(".");
}
Serial.println();
Serial.print(F("- Connected to: "));
Serial.println(ssid);
Serial.print(F("- IP address: "));
Serial.println(WiFi.localIP());
}
//**************************************[ SETUP FUNCTION ]*************************************************
void setup()
{
// Use the LED as a keying indicator.
pinMode(TX_LED_PIN, OUTPUT);
digitalWrite(TX_LED_PIN, LOW);
Serial.begin(115200); while (!Serial);
Serial.println(" ");
Serial.println("[ ESP WSPR - ESP8266 + SI5351A WSPR BEACON FW: ESP_WSPR_ver_3_006 ]");
Serial.println("- SERIAL COM setup Done!");
delay(10);
WiFi.mode(WIFI_OFF); //Prevents reconnection issue (taking too long to connect)
WiFi.mode(WIFI_STA); //This line hides the viewing of ESP as wifi hotspot
ssidConnect();
// Set time sync provider
setSyncProvider(epochUnixNTP); //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
Serial.println("- RADIO MODULE SETUP Begins...");
// The crystal load value needs to match in order to have an accurate calibration
si5351.init(SI5351_CRYSTAL_LOAD_8PF, 0, 0);
// Start on target frequency
si5351.set_correction(cal_factor, SI5351_PLL_INPUT_XO);
//si5351.init(SI5351_CRYSTAL_LOAD_8PF, SI5351_REF, CORRECTION);
Serial.println("- RADIO Module initializing...");
// Set CLK0 output
si5351.set_freq(freq * 100, SI5351_CLK0);
si5351.drive_strength(SI5351_CLK0, SI5351_DRIVE_8MA); // Set for max power-INSERISCI IL VALORE DELLA PWR OUT (2-8 ma)...8ma= 10Mw circa
si5351.set_clock_pwr(SI5351_CLK0, 0); // Disable the clock initially
Serial.println("- Radio Module setup successful...");
Serial.println("- Entering WSPR TX loop...");
digitalWrite(TX_LED_PIN, HIGH);
}
//*****************************************[ LOOP FUNCTION ]******************************************************
void loop()
{
// Trigger every 4 minute
// WSPR should start on the 1st second of the even minute.
// 30 seconds before trigger enable si5351a output to eliminate startup drift
if((minute() + 1) % 4 == 0 && second() == 30 && !warmup)
{ warmup=1; //warm up started, bypass this if for the next 30 seconds
Serial.println("- Radio Module Warm up Started...");
si5351.set_freq(freq * 100, SI5351_CLK0);
si5351.set_clock_pwr(SI5351_CLK0, 1);
}
if(minute() % 4 == 0 && second() == 0)
{ //time to start encoding
Serial.print("- Start of Transmission Time:");
Serial.println(now()); //prints on serialport actual time
encode();
warmup=0; //reset variable for next warmup cycle wich will start in 4 minutes and 30 seconds
delay(4000);
// Set time sync provider
setSyncProvider(epochUnixNTP); //set function to call when sync required
}
}
//*************************************[ END OF PROGRAM ]********************************************************