/********************************************************************************** WSPR SENDER for uBITX by KD8CEC Some of the code that sends WSPR referenced the code in G3ZIL. Thanks to G3ZIL for sharing great code. Due to the limited memory of uBITX, I have implemented at least only a few of the codes in uBITX. Thanks for testing ----------------------------------------------------------------------------- This program 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. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . **********************************************************************************/ #include #include "ubitx.h" //begin of test byte WsprToneCode[164]; unsigned long lastTime=0; unsigned long TX_MSNB_P2; // Si5351 register MSNB_P2 PLLB for Tx unsigned long TX_P2; // Variable values for MSNB_P2 which defines the frequencies for the data extern int enc_read(void); byte WsprMSGCount = 0; #define WSPR_BAND1 401 extern uint8_t Wspr_Reg1[8]; //3, 4, 5, 6, 7 extern uint8_t Wspr_Reg2[8]; //2, 3, 4 void SendWSPRManage() { int knob = 0; byte knobPosition = 0; //char isNeedDisplayInfo = 0; char nowSelectedIndex = 0; char nowWsprStep = 0; //0 : select Message, 1 : select band, 2 : send char selectedWsprMessageIndex = -1; char selectedWsprBandIndex = -1; unsigned long WsprTXFreq = 0; unsigned int WsprMultiChan = 0; //unsigned long prevFreq; byte loopIndex; delay_background(500, 0); //Readed WsprMSGCount, WsprTone while(1) { knob = enc_read(); if (knobPosition > 0 && knob < 0) knobPosition--; else if (knob > 0 && (knobPosition <= (nowWsprStep == 0 ? WsprMSGCount : WSPR_BAND_COUNT) * 10 -2)) knobPosition++; nowSelectedIndex = knobPosition / 10; if (nowWsprStep == 0) //select Message status { //printLineF2(F("WSPR:")); if (selectedWsprMessageIndex != nowSelectedIndex) { selectedWsprMessageIndex = nowSelectedIndex; int wsprMessageBuffIndex = selectedWsprMessageIndex * 46; printLineF2(F("WSPR:")); //Display WSPR Name tag printLineFromEEPRom(0, 6, wsprMessageBuffIndex, wsprMessageBuffIndex + 4, 1); //Load WSPR Tonecode //Read Tone Code for (int i = 0; i < 41; i++) { byte readData = EEPROM.read(WSPR_MESSAGE1 + 5 + (wsprMessageBuffIndex) + i); //NAME TAG 5, MESSAGE 41 = 46 WsprToneCode[i * 4 + 0] = readData & 3; WsprToneCode[i * 4 + 1] = (readData >> 2) & 3; WsprToneCode[i * 4 + 2] = (readData >> 4) & 3; WsprToneCode[i * 4 + 3] = (readData >> 6) & 3; } } else if (btnDown()) { nowWsprStep = 1; //Change Status to Select Band knobPosition = 0; nowSelectedIndex = 0; delay_background(500, 0); } } else if (nowWsprStep == 1) { //printLineF2(F("Select Band")); if (selectedWsprBandIndex != nowSelectedIndex) { selectedWsprBandIndex = nowSelectedIndex; int bandBuffIndex = WSPR_BAND1 + selectedWsprBandIndex * 14; EEPROM.get(bandBuffIndex, WsprTXFreq); EEPROM.get(bandBuffIndex + 4, WsprMultiChan); for (loopIndex = 3; loopIndex < 8; loopIndex++) Wspr_Reg1[loopIndex] = EEPROM.read(bandBuffIndex + loopIndex + 3); //2, 3, 4 for (loopIndex = 2; loopIndex < 5; loopIndex++) Wspr_Reg2[loopIndex] = EEPROM.read(bandBuffIndex + loopIndex + 9); TX_MSNB_P2 = ((unsigned long)Wspr_Reg1[5] & 0x0F) << 16 | ((unsigned long)Wspr_Reg1[6]) << 8 | Wspr_Reg1[7]; } if (digitalRead(PTT) == 0) strcpy(c, "SEND: "); else strcpy(c, "PTT-> "); //ltoa(WsprTXFreq, b, DEC); //strcat(c, b); //display frequency, Frequency to String for KD8CEC unsigned long tmpFreq = WsprTXFreq; for (int i = 15; i >= 6; i--) { if (tmpFreq > 0) { if (i == 12 || i == 8) c[i] = '.'; else { c[i] = tmpFreq % 10 + 0x30; tmpFreq /= 10; } } else c[i] = ' '; } printLine1(c); #ifdef USE_SW_SERIAL SWS_Process(); if ((digitalRead(PTT) == 0) || (TriggerBySW == 1)) { TriggerBySW = 0; #else if (digitalRead(PTT) == 0) { #endif //SEND WSPR //If you need to consider the Rit and Sprite modes, uncomment them below. //remark = To reduce the size of the program //prevFreq = frequency; //frequency = WsprTXFreq; startTx(TX_CW, 0); setTXFilters(WsprTXFreq); //Start WSPR Set_WSPR_Param(); digitalWrite(CW_KEY, 1); for (int i = 0; i < 162; i++) { // Now this is the message loop lastTime = millis(); // Store away the time when the last message symbol was sent TX_P2 = TX_MSNB_P2 + WsprMultiChan * WsprToneCode[i]; // This represents the 1.46 Hz shift and is correct only for the bands specified in the array TXSubFreq(TX_P2); // TX at the appropriate channel frequency for.... //if (btnDown()) // break; while (millis() < lastTime + 683){} // .... 0,683 seconds } digitalWrite(CW_KEY, 0); stopTx(); //call setFrequency -> recovery TX Filter //frequency = prevFreq; selectedWsprBandIndex = -1; } //end of PTT Check else if (btnDown()) { return; } } //end of status check //delay_background(50, 1); } //end of while }