// include the library code: #include #include #include //__________________________________________________________________________________________________ // ENTER WSPR DATA: const char call[7] = "UA3REO"; const char locator[5] = "LO02"; // Use 4 character locator e.g. "EM64" const char freq_offset = 30; //offset from band center // LOAD BAND FREQUENCY DATA: const unsigned long band[10] = { 1838100 + freq_offset, // timeslot 0 00,20,40 minutes after hour 160m 3570100 + freq_offset, // timeslot 1 02,22,42 minutes after hour 80m 7040100 + freq_offset, // timeslot 2 04,24.44 minutes after hour 40m 10140200 + freq_offset, // timeslot 3 06,26,46 minutes after hour 30m 14097100 + freq_offset, // timeslot 4 08,28,48 minutes after hour 20m 18106100 + freq_offset, // timeslot 5 10,30,50 minutes after hour 17m 21096100 + freq_offset, // timeslot 6 12,32,52 minutes after hour 15m 24926100 + freq_offset, // timeslot 7 14,34,54 minutes after hour 12m 28126100 + freq_offset, // timeslot 8 16,36,56 minutes after hour 10m 50294500 + freq_offset, // timeslot 9 18,38,58 minutes after hour 6m }; // LOAD TRANSMIT TIME SLOT DATA: ( 0=idle, 1=transmit WSPR ) const byte TransmitFlag[10] = { 1, // timeslot 0 160m 1, // timeslot 1 80m 1, // timeslot 2 40m 1, // timeslot 3 30m 1, // timeslot 4 20m 1, // timeslot 5 17m 1, // timeslot 6 15m 1, // timeslot 7 12m 1, // timeslot 8 10m 0 // timeslot 9 6m }; //LPF to band association const byte LPFs[10] = { 0, // timeslot 0 160m 1, // timeslot 1 80m 2, // timeslot 2 40m 3, // timeslot 3 30m 4, // timeslot 4 20m 6, // timeslot 5 17m (5!) 6, // timeslot 6 15m 7, // timeslot 7 12m 7, // timeslot 8 10m 7 // timeslot 9 6m }; //Power to band association, // Min = 0 dBm, Max = 43 dBm, steps 0,3,7,10,13,17,20,23,27,30,33,37,40,43 const byte POWERs[10] = { 20, // timeslot 0 160m 17, // timeslot 1 80m 20, // timeslot 2 40m 20, // timeslot 3 30m 20, // timeslot 4 20m 17, // timeslot 5 17m 13, // timeslot 6 15m 20, // timeslot 7 12m 17, // timeslot 8 10m 3, // timeslot 9 6m }; const unsigned long fCLK = (125000000); // Enter clock frequency+calibration //__________________________________________________________________________________________________ const char WSPR2_SyncVec[162] = { 1,1,0,0,0,0,0,0,1,0,0,0,1,1,1,0,0,0,1,0,0,1,0,1,1,1,1,0,0,0,0,0,0,0,1,0,0,1,0,1,0,0, 0,0,0,0,1,0,1,1,0,0,1,1,0,1,0,0,0,1,1,0,1,0,0,0,0,1,1,0,1,0,1,0,1,0,1,0,0,1,0,0,1,0, 1,1,0,0,0,1,1,0,1,0,1,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,1,1,0,1,1,0,0,1,1,0,1,0,0,0,1, 1,1,0,0,0,0,0,1,0,1,0,0,1,1,0,0,0,0,0,0,0,1,1,0,1,0,1,1,0,0,0,1,1,0,0,0 }; //Initialize LCD library with the numbers of the interface pins LiquidCrystal lcd(19, 18, 17, 16, 15, 14); //---Defines #define GPS_RX_pin 0 #define BUTTON1 1 #define BUTTON2 2 #define BUTTON3 3 #define TX_pin 13 // TX (HIGH on transmit) #define BandBCD0pin 7 #define BandBCD1pin 8 #define BandBCD2pin 9 #define BandBCD3pin 10 #define DDS_data 6 #define DDS_clock 5 #define DDS_load 4 #define pulseHigh(pin) {digitalWrite(pin, HIGH); digitalWrite(pin, LOW); } #define GPS_buffer_length 300 #define TenMHz 10000000 #define buttonsDebounce 200 //---Configure variables //GPS bool GPS_Enabled = true; // GPS receiver control 0 = disable, 1 = enable char GPS_buffer[GPS_buffer_length] = ""; int GPS_IndiceCount = 0, GPS_StartCount = 0, GPS_Counter = 0; int GPS_indices[13] = { 0 }; int validGPSflag = 0; int GPS_sat1 = 0, GPS_sat10 = 0; bool GPS_inhibitFlag = true; // 1 will inhibit transmitter bool GPS_firstPass = true; //SYSTEM int second = 0, minute = 0, hour = 0; int mSecTimer = 0, mSecTimer2 = 0; byte BeginDelay = 0; byte timeslot; unsigned long buttInterruptTime = 0; bool firstSecond = true; unsigned long displayFreqValue = 0; byte Status = 0; // 0-idle 1-WSPR TX 3-GPS bool needRedrawLCD = false; //unsigned long tick_debug = 0; //unsigned long tick_debug_save = 0; //WSPR2 unsigned long WSPR2_OffsetFreq[4] = { 0 }; byte WSPR2_count = 0, WSPR2_start = 0; unsigned long WSPR2_FreqWord = 0; byte WSPR2_encMessage[11]; byte WSPR2_symTable[170]; // symbol table 162 byte WSPR2_symTableTemp[170]; // symbol table temp bool WSPR2_InhibitFlag = false; // 1 will inhibit transmitter //DDS unsigned long DDS_FreqWord = 0; long DDS_CalFactor; ISR(TIMER1_COMPA_vect) { /*tick_debug_save = tick_debug; tick_debug = 0; needRedrawLCD = true; return;*/ if(!firstSecond) second++ ; else { firstSecond = false; mSecTimer2++; } if (second >= 60) { minute++ ; second = 0 ; } if (minute >= 60) { hour++; minute = 0; } if (hour >= 24) { hour = 0; } needRedrawLCD = true; if (bitRead(minute, 0) == 0 && second == 0) { detectTimeslot(); setfreq(); transmit(); } }; //****************************************************************** //Timer2 Overflow Interrupt Vector, called every mSec to increment //the mSecTimer2 used for WSPR transmit timing. //Timer2 is also used for QRSS pattern generation ISR(TIMER2_COMPA_vect) { //tick_debug++; mSecTimer2++; //if (mSecTimer2 > 681) { if (mSecTimer2 > 999) { mSecTimer2 = 0; //if (BeginDelay < 3) { // Begin 2 second delay - actually 0.682mSec * 3 if (BeginDelay < 1) { // Begin delay - actually 0.682mSec DDS_FreqWord = WSPR2_FreqWord; TransmitSymbol(); BeginDelay++; } else { // Begin 162 WSPR symbol transmission if (WSPR2_count < 162) { DDS_FreqWord = WSPR2_FreqWord + WSPR2_OffsetFreq[WSPR2_symTable[WSPR2_count]]; TransmitSymbol(); WSPR2_count++; //Increments the interrupt counter } else { TIMSK2 = 0; // Disable WSPR timer digitalWrite(TX_pin, LOW); // External transmit control OFF DDS_FreqWord = 0; // Turn off transmitter TransmitSymbol(); //GPS_Enabled = true; //Turn GPS receiver back on Status = 0; //idle needRedrawLCD = true; } } } }; //****************************************************************** //****************************************************************** void setup() { //Set up Timer2 to fire every 1,4648baud / 682.59msec (WSPR timer) TIMSK2 = 0; //Disable timer during setup TCCR2A = 2; //CTC mode (2 - counter) TCCR2B = 6; //Timer Prescaler set to 256 OCR2A = 31; // Timer set //Set up Timer1A to fire every second (master clock) TCCR1B = 0; //Disable timer during setup TIMSK1 = 0; //Timer1 Interrupt disable TCCR1A = 0; //Normal port operation, Wave Gen Mode normal TCCR1B = 12; //Timer prescaler to 256 - CTC mode OCR1A = 46874; //Timer set for 1000 mSec using correction factor // 46875 is nominal for 1000 mSec. Decrease variable to increase clock speed // set up the LCD for 16 columns and 2 rows lcd.begin(16, 2); //Set up GPS pin pinMode(GPS_RX_pin, INPUT); digitalWrite(GPS_RX_pin, HIGH); // internal pull-up enabled // Set up TX pin to output pinMode(TX_pin, OUTPUT); //Set up band select pins pinMode(BandBCD0pin, OUTPUT); pinMode(BandBCD1pin, OUTPUT); pinMode(BandBCD2pin, OUTPUT); pinMode(BandBCD3pin, OUTPUT); // Set GPS input baud Serial.begin(115200); Serial.println("$PMTK251,9600*17"); Serial.println("$PSIMIPR,W,9600*1C"); Serial.end(); Serial.begin(57600); Serial.println("$PMTK251,9600*17"); Serial.println("$PSIMIPR,W,9600*1C"); Serial.end(); Serial.begin(38400); Serial.println("$PMTK251,9600*17"); Serial.println("$PSIMIPR,W,9600*1C"); Serial.end(); Serial.begin(19200); Serial.println("$PMTK251,9600*17"); Serial.println("$PSIMIPR,W,9600*1C"); Serial.end(); Serial.begin(14400); Serial.println("$PMTK251,9600*17"); Serial.println("$PSIMIPR,W,9600*1C"); Serial.end(); Serial.begin(9600); Serial.println("$PMTK251,9600*17"); Serial.println("$PSIMIPR,W,9600*1C"); Serial.end(); Serial.begin(4800); Serial.println("$PMTK251,9600*17"); Serial.println("$PSIMIPR,W,9600*1C"); Serial.end(); Serial.begin(9600); // Initialize a buffer for received data for (int i = 0; i < GPS_buffer_length; i++) GPS_buffer[i] = ' '; delay(3000); // Delay start GPS Serial.println("$PMTK251,9600*17"); Serial.println("$PMTK314,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*28"); // Init GPS NMEA output // Set up buttons pins pinMode(BUTTON1, INPUT); // declare pushbutton as input digitalWrite(BUTTON1, HIGH); // internal pull-up enabled pinMode(BUTTON2, INPUT); // declare pushbutton as input digitalWrite(BUTTON2, HIGH); // internal pull-up enabled pinMode(BUTTON3, INPUT); // declare pushbutton as input digitalWrite(BUTTON3, HIGH); // internal pull-up enabled // Set up DDS-60 pinMode (DDS_data, OUTPUT); // sets pin 38 as OUPUT pinMode (DDS_clock, OUTPUT); // sets pin 37 as OUTPUT pinMode (DDS_load, OUTPUT); // sets pin 36 as OUTPUT // Turn on LCD lcd.display(); // turn off transmitter DDS_FreqWord = 0; TransmitSymbol(); // Display "IDLE" on LCD Status = 0; // Load Cal Factor long cal1 = EEPROM.read(50); long cal2 = EEPROM.read(51); long cal3 = EEPROM.read(52); long cal4 = EEPROM.read(53); DDS_CalFactor = cal1 | (cal2 << 8) | (cal3 << 16) | (cal4 << 24); setfreq(); encode_wspr2(); // Calibration process follows: if (digitalRead(BUTTON2) == LOW) { WSPR2_FreqWord = TenMHz * pow(2, 32) / (fCLK + DDS_CalFactor * 20); DDS_FreqWord = WSPR2_FreqWord; TransmitSymbol(); detachInterrupt(0); // Disable transmit inhibit interrupt TIMSK1 = 0; // Disable timer1 interrupt (master clock) TIMSK2 = 0; // Disable timer2 interrupt (WSPR) lcd.setCursor(0, 0); lcd.print("Adjust to 10MHz"); lcd.setCursor(0, 1); lcd.print("Cal Factor= "); lcd.setCursor(12, 1); lcd.print(DDS_CalFactor); calibrate(); } //Load offset values WSPR2_OffsetFreq[0] = 0; WSPR2_OffsetFreq[1] = 6291268095.18f / (fCLK + DDS_CalFactor * 20); //1.4648f * pow(2, 32) WSPR2_OffsetFreq[2] = 12582536190.4f / (fCLK + DDS_CalFactor * 20); //2.9296f * pow(2, 32) WSPR2_OffsetFreq[3] = 18873804285.5f / (fCLK + DDS_CalFactor * 20); //4.3944f * pow(2, 32) TIMSK1 = 2; //Timer1 Interrupt enable //TIMSK2 = 2; //For Debug attachInterrupt(0, TXinhibit, LOW); // TX inhibit pin on interrupt } //****************************************************************** void loop() { if (GPS_Enabled) GPSprocess(); if (needRedrawLCD) redrawLCD(); } //****************************************************************** // normalize characters 0..9 A..Z Space in order 0..36 char chr_normf(char bc ) { char cc = 36; if (bc >= '0' && bc <= '9') cc = bc - '0'; if (bc >= 'A' && bc <= 'Z') cc = bc - 'A' + 10; if (bc >= 'a' && bc <= 'z') cc = bc - 'a' + 10; if (bc == ' ' ) cc = 36; return (cc); } //****************************************************************** void encode_wspr2() { // Begin WSPR message calculation encode_call(); encode_locator(); encode_conv(); interleave_sync(); } //****************************************************************** void encode_call() { //copy callsign char enc_call[7] = {0}; for(int ci=0 ; ci<7 ; ci++) enc_call[ci] = call[ci]; // coding of callsign if (chr_normf(enc_call[2]) > 9) { enc_call[5] = enc_call[4]; enc_call[4] = enc_call[3]; enc_call[3] = enc_call[2]; enc_call[2] = enc_call[1]; enc_call[1] = enc_call[0]; enc_call[0] = ' '; } unsigned long n1 = chr_normf(enc_call[0]); n1 = n1 * 36 + chr_normf(enc_call[1]); n1 = n1 * 10 + chr_normf(enc_call[2]); n1 = n1 * 27 + chr_normf(enc_call[3]) - 10; n1 = n1 * 27 + chr_normf(enc_call[4]) - 10; n1 = n1 * 27 + chr_normf(enc_call[5]) - 10; // merge coded callsign into message array c[] unsigned long t1 = n1; WSPR2_encMessage[0] = t1 >> 20; t1 = n1; WSPR2_encMessage[1] = t1 >> 12; t1 = n1; WSPR2_encMessage[2] = t1 >> 4; t1 = n1; WSPR2_encMessage[3] = t1 << 4; } //****************************************************************** void encode_locator() { // coding of locator unsigned long m1 = 179 - 10 * (chr_normf(locator[0]) - 10) - chr_normf(locator[2]); m1 = m1 * 180 + 10 * (chr_normf(locator[1]) - 10) + chr_normf(locator[3]); m1 = m1 * 128 + POWERs[timeslot] + 64; // merge coded locator and power into message array c[] unsigned long t1 = m1; WSPR2_encMessage[3] = WSPR2_encMessage[3] + ( 0x0f & t1 >> 18); t1 = m1; WSPR2_encMessage[4] = t1 >> 10; t1 = m1; WSPR2_encMessage[5] = t1 >> 2; t1 = m1; WSPR2_encMessage[6] = t1 << 6; } //****************************************************************** // convolutional encoding of message array c[] into a 162 bit stream void encode_conv() { int bc = 0; int cnt = 0; int cc; unsigned long sh1 = 0; cc = WSPR2_encMessage[0]; for (int i = 0; i < 81; i++) { if (i % 8 == 0 ) { cc = WSPR2_encMessage[bc]; bc++; } if (cc & 0x80) sh1 = sh1 | 1; WSPR2_symTableTemp[cnt++] = parity(sh1 & 0xF2D05351); WSPR2_symTableTemp[cnt++] = parity(sh1 & 0xE4613C47); cc = cc << 1; sh1 = sh1 << 1; } } //****************************************************************** byte parity(unsigned long li) { byte po = 0; while (li != 0) { po++; li &= (li - 1); } return (po & 1); } //****************************************************************** // interleave reorder the 162 data bits and and merge table with the sync vector void interleave_sync() { int ii, ij, b2, bis, ip; ip = 0; for (ii = 0; ii <= 255; ii++) { bis = 1; ij = 0; for (b2 = 0; b2 < 8 ; b2++) { if (ii & bis) ij = ij | (0x80 >> b2); bis = bis << 1; } if (ij < 162 ) { WSPR2_symTable[ij] = WSPR2_SyncVec[ij] + 2 * WSPR2_symTableTemp[ip]; ip++; } } } //****************************************************************** // Determine time slot and load band frequency data. Display // frequency and calculate frequency word for DDS void setfreq() { // Select band port pin and set HIGH for active band if (bitRead(LPFs[timeslot], 0) == 1) digitalWrite(BandBCD0pin, HIGH); else digitalWrite(BandBCD0pin, LOW); if (bitRead(LPFs[timeslot], 1) == 1) digitalWrite(BandBCD1pin, HIGH); else digitalWrite(BandBCD1pin, LOW); if (bitRead(LPFs[timeslot], 2) == 1) digitalWrite(BandBCD2pin, HIGH); else digitalWrite(BandBCD2pin, LOW); if (bitRead(LPFs[timeslot], 3) == 1) digitalWrite(BandBCD3pin, HIGH); else digitalWrite(BandBCD3pin, LOW); displayFreqValue = band[timeslot]; needRedrawLCD = true; WSPR2_FreqWord = band[timeslot] * pow(2, 32) / (fCLK + DDS_CalFactor * 20); encode_wspr2(); //update power } //****************************************************************** // Determine if it is time to transmit. If so, determine if it is // time to transmit the QRSS or the WSPR message void transmit() { if (GPS_inhibitFlag || WSPR2_InhibitFlag) return; else if (TransmitFlag[timeslot] == 1) { // Start WSPR transmit process WSPR2_start = 0; //GPS_Enabled = false; // Disable GPS receiver Status = 1; //WSPR TX needRedrawLCD = true; digitalWrite(TX_pin, HIGH); // External transmit control ON BeginDelay = 0; WSPR2_count = 0; // Start WSPR symbol transmit process TIMSK2 = 2; //Enable timer2 interrupt return; } else { // Turn off transmitter and idle TIMSK2 = 0; //Turn off WSPR timer WSPR2_start = 0; Status = 0; //IDLE needRedrawLCD = true; digitalWrite(TX_pin, LOW); // External transmit control OFF //GPS_Enabled = true; //Enable GPS receiver DDS_FreqWord = 0; TransmitSymbol(); return; } } //****************************************************************** void TransmitSymbol() { unsigned long freq = DDS_FreqWord; for (int b=0; b<4; b++, freq>>=8) { tfr_byte(freq & 0xFF); } tfr_byte(0); // Final control byte, all 0 for 9850 chip pulseHigh(DDS_load); // Done! Should see output } // transfers a byte to DDS, a bit at a time, LSB first to the 9850 via serial DATA line void tfr_byte(byte sdata) { for (int i=0; i<8; i++, sdata>>=1) { digitalWrite(DDS_data, sdata & 0x01); pulseHigh(DDS_clock); //after each bit sent, CLK is pulsed high } } // Конец передачи частоты в DDS //****************************************************************** //GPS timing process starts here void GPSprocess() { if (Serial.available() == 0) return; const char StartCommand[7] = "$GNGGA"; // $GPGGA / $GNGGA / $GNRMC int byteGPS = Serial.read(); // Read a byte of the serial port GPS_buffer[GPS_Counter] = byteGPS; // If there is serial port data, it is put in the buffer GPS_Counter++; if(GPS_Counter>=GPS_buffer_length) GPS_Counter = 0; //lcd.print(char(byteGPS)); return; //debug if (byteGPS == 13) { // If the received byte is = to 13, end of transmission //lcd.setCursor(0, 0); lcd.print("e"); delay(1000); return; //debug GPS_IndiceCount = 0; GPS_StartCount = 0; for (int i = 1; i < 7; i++) { // Verify the received command starts with $GPGGA / $GNGGA / $GNRMC if (GPS_buffer[i] == StartCommand[i - 1]) { GPS_StartCount++; } } if (GPS_StartCount == 6) { // If yes, continue and process the data for (int i = 0; i < GPS_buffer_length; i++) { if (GPS_buffer[i] == ',') { // check for the position of the "," separator GPS_indices[GPS_IndiceCount] = i; GPS_IndiceCount++; } if (GPS_buffer[i] == '*') { // ... and the "*" GPS_indices[12] = i; GPS_IndiceCount++; } } // Debug //lcd.setCursor(0, 0); for(int d=0;d<16;d++) lcd.print(String(char(GPS_buffer[d+1]))); return; // Load time data byte temp = GPS_indices[0]; hour = (GPS_buffer[temp + 1] - 48) * 10 + GPS_buffer[temp + 2] - 48; minute = (GPS_buffer[temp + 3] - 48) * 10 + GPS_buffer[temp + 4] - 48; second = (GPS_buffer[temp + 5] - 48) * 10 + GPS_buffer[temp + 6] - 48; // Loat status data temp = GPS_indices[5]; validGPSflag = GPS_buffer[temp + 1] - 48; temp = GPS_indices[6]; GPS_sat10 = GPS_buffer[temp + 1] - 48; GPS_sat1 = GPS_buffer[temp + 2] - 48; if(GPS_firstPass) { GPS_firstPass = false; detectTimeslot(); setfreq(); } } /*if (validGPSflag > 0) GPS_inhibitFlag = false; else GPS_inhibitFlag = true;*/ GPS_inhibitFlag = false; GPS_Counter = 0; // Reset the buffer for (int i = 0; i < GPS_buffer_length; i++) { // GPS_buffer[i] = ' '; } //Status = 3; needRedrawLCD = true; } } //****************************************************************** void calibrate() { // Process to determine frequency calibration factor while (digitalRead(BUTTON2) == LOW) { if ((millis()-buttInterruptTime) < buttonsDebounce) continue; if (digitalRead(BUTTON1) == LOW) { DDS_CalFactor++; buttInterruptTime = millis(); }; if (digitalRead(BUTTON3) == LOW) { DDS_CalFactor--; buttInterruptTime = millis(); }; DDS_FreqWord = TenMHz * pow(2, 32) / (fCLK + DDS_CalFactor * 20); TransmitSymbol(); lcd.setCursor(12, 1); lcd.print(DDS_CalFactor); lcd.print(" "); } // Writes CalFactor to address 50 + 3 bytes of EEprom EEPROM.write(50, DDS_CalFactor & 0xFF); EEPROM.write(51, (DDS_CalFactor >> 8) & 0xFF); EEPROM.write(52, (DDS_CalFactor >> 16) & 0xFF); EEPROM.write(53, (DDS_CalFactor >> 24) & 0xFF); needRedrawLCD = true; DDS_FreqWord = 0; // turn off 10 MHz calibrate signal TransmitSymbol(); setfreq(); attachInterrupt(0, TXinhibit, LOW); // TX inhibit pin on interrupt 1 - pin 3 TIMSK1 = 2; // Enable Timer1 Interrupt } //****************************************************************** void redrawLCD() { // Print Time lcd.setCursor(0, 1); if (hour < 10) lcd.print ("0"); lcd.print (hour); lcd.print (":"); if (minute < 10) lcd.print ("0"); lcd.print (minute); lcd.print (":"); if (second < 10) lcd.print ("0"); lcd.print (second); lcd.print (" "); // Print frequency to the LCD lcd.setCursor(0, 0); char buf[10]; ltoa(displayFreqValue, buf, 10); if (buf[7] == 0) { lcd.print(buf[0]); lcd.print(','); lcd.print(buf[1]); lcd.print(buf[2]); lcd.print(buf[3]); lcd.print('.'); lcd.print(buf[4]); lcd.print(buf[5]); lcd.print(buf[6]); lcd.print(" KHz "); } else { lcd.print(buf[0]); lcd.print(buf[1]); lcd.print(','); lcd.print(buf[2]); lcd.print(buf[3]); lcd.print(buf[4]); lcd.print('.'); lcd.print(buf[5]); lcd.print(buf[6]); lcd.print(buf[7]); lcd.print(" KHz "); } //Status lcd.setCursor(9, 1); if(Status == 0) lcd.print("IDLE "); if(Status == 1) lcd.print("WSPR TX"); if(Status==3) { lcd.print("GPS "); lcd.setCursor(13, 1); lcd.print(GPS_sat10); if(GPS_sat1 != -4) lcd.print(GPS_sat1); } //Inhibit lcd.setCursor(15, 0); if(WSPR2_InhibitFlag) lcd.print("S"); else lcd.print(" "); /*lcd.setCursor(12, 0); lcd.print(tick_debug_save);*/ needRedrawLCD = false; } //****************************************************************** void TXinhibit() { if ((millis()-buttInterruptTime) < buttonsDebounce) return; WSPR2_InhibitFlag = !WSPR2_InhibitFlag; if (WSPR2_InhibitFlag) // 1 turns OFF transmitter { needRedrawLCD = true; TIMSK2 = 0; //Turn off WSPR timer WSPR2_start = 0; digitalWrite(TX_pin, LOW); // External transmit control OFF Status = 0; //GPS_Enabled = true; //Enable GPS receiver DDS_FreqWord = 0; //Set DDS60 to 0Hz TransmitSymbol(); } else { needRedrawLCD = true; } buttInterruptTime = millis(); } //****************************************************************** void detectTimeslot() { if (minute < 20) { timeslot = minute / 2; } else { if (minute < 40) { timeslot = (minute - 20) / 2; } else { timeslot = (minute - 40) / 2; } } }