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 ]********************************************************