diff --git a/ubitx_20/cat_libs.ino b/ubitx_20/cat_libs.ino index b82f639..85a4111 100644 --- a/ubitx_20/cat_libs.ino +++ b/ubitx_20/cat_libs.ino @@ -130,10 +130,21 @@ void CatGetFreqMode(unsigned long freq, byte fromType) } //Mode Check - if (isUSB) - CAT_BUFF[4] = CAT_MODE_USB; + if (cwMode == 0) + { + if (isUSB) + CAT_BUFF[4] = CAT_MODE_USB; + else + CAT_BUFF[4] = CAT_MODE_LSB; + } + else if (cwMode == 1) + { + CAT_BUFF[4] = CAT_MODE_CW; + } else - CAT_BUFF[4] = CAT_MODE_LSB; + { + CAT_BUFF[4] = CAT_MODE_CW; + } SendCatData(5); } @@ -198,12 +209,18 @@ void CatSetMode(byte tmpMode, byte fromType) if (!inTx) { - if (tmpMode == CAT_MODE_USB) + if (tmpMode == CAT_MODE_CW) { + cwMode = 1; + } + else if (tmpMode == CAT_MODE_USB) + { + cwMode = 0; isUSB = true; } else { + cwMode = 0; isUSB = false; } @@ -358,10 +375,21 @@ void ReadEEPRom_FT817(byte fromType) CAT_BUFF[1] = 0xB2; break; case 0x69 : //FM Mic (#29) Contains 0-100 (decimal) as displayed case 0x78 : - if (isUSB) - CAT_BUFF[0] = CAT_MODE_USB; - else - CAT_BUFF[0] = CAT_MODE_LSB; + if (cwMode == 0) + { + if (isUSB) + CAT_BUFF[0] = CAT_MODE_USB; + else + CAT_BUFF[0] = CAT_MODE_LSB; + } + else if (cwMode == 1) + { + CAT_BUFF[0] = CAT_MODE_CW; + } + else if (cwMode == 2) + { + CAT_BUFF[0] = CAT_MODE_CW; + } if (CAT_BUFF[0] != 0) CAT_BUFF[0] = 1 << 5; break; diff --git a/ubitx_20/ubitx_20.ino b/ubitx_20/ubitx_20.ino index cc5119a..1ba7d95 100644 --- a/ubitx_20/ubitx_20.ino +++ b/ubitx_20/ubitx_20.ino @@ -151,6 +151,7 @@ int count = 0; //to generally count ticks, loops, etc #define CW_SPEED 28 //AT328 has 1KBytes EEPROM +#define CW_CAL 252 #define VFO_A_MODE 256 #define VFO_B_MODE 257 #define CW_DELAY 258 @@ -232,7 +233,7 @@ int count = 0; //to generally count ticks, loops, etc char ritOn = 0; char vfoActive = VFO_A; int8_t meter_reading = 0; // a -1 on meter makes it invisible -unsigned long vfoA=7150000L, vfoB=14200000L, sideTone=800, usbCarrier; +unsigned long vfoA=7150000L, vfoB=14200000L, sideTone=800, usbCarrier, cwmCarrier; unsigned long vfoA_eeprom, vfoB_eeprom; //for protect eeprom life unsigned long frequency, ritRxFrequency, ritTxFrequency; //frequency is the current frequency on the dial @@ -300,6 +301,10 @@ char inTx = 0; //it is set to 1 if in transmit mode (whatever the char splitOn = 0; //working split, uses VFO B as the transmit frequency char keyDown = 0; //in cw mode, denotes the carrier is being transmitted char isUSB = 0; //upper sideband was selected, this is reset to the default for the + +char cwMode = 0; //compatible original source, and extend mode //if cwMode == 0, mode check : isUSB, cwMode > 0, mode Check : cwMode + //iscwMode = 0 : ssbmode, 1 :cwl, 2 : cwu, 3 : cwn (none tx) + //frequency when it crosses the frequency border of 10 MHz byte menuOn = 0; //set to 1 when the menu is being displayed, if a menu item sets it to zero, the menu is exited unsigned long cwTimeout = 0; //milliseconds to go before the cw transmit line is released and the radio goes back to rx mode @@ -310,6 +315,10 @@ boolean modeCalibrate = false;//this mode of menus shows extended menus to calib unsigned long beforeIdle_ProcessTime = 0; //for check Idle time byte line2DisplayStatus = 0; //0:Clear, 1 : menu, 1: DisplayFrom Idle, +char lcdMeter[17]; + +byte isIFShift = 0; //1 = ifShift, 2 extend +long ifShiftValue = 0; // /** * Below are the basic functions that control the uBitx. Understanding the functions before @@ -363,8 +372,10 @@ void setNextHamBandFreq(unsigned long f, char moveDirection) EEPROM.get(HAM_BAND_FREQS + 4 * findedIndex, resultFreq); - loadMode = (byte)(resultFreq >> 30); - resultFreq = resultFreq & 0x3FFFFFFF; + //loadMode = (byte)(resultFreq >> 30); + //resultFreq = resultFreq & 0x3FFFFFFF; + loadMode = (byte)(resultFreq >> 29); + resultFreq = resultFreq & 0x1FFFFFFF; if ((resultFreq / 1000) < hamBandRange[(unsigned char)findedIndex][0] || (resultFreq / 1000) > hamBandRange[(unsigned char)findedIndex][1]) resultFreq = (unsigned long)(hamBandRange[(unsigned char)findedIndex][0]) * 1000; @@ -375,7 +386,8 @@ void setNextHamBandFreq(unsigned long f, char moveDirection) void saveBandFreqByIndex(unsigned long f, unsigned long mode, char bandIndex) { if (bandIndex >= 0) - EEPROM.put(HAM_BAND_FREQS + 4 * bandIndex, (f & 0x3FFFFFFF) | (mode << 30) ); + //EEPROM.put(HAM_BAND_FREQS + 4 * bandIndex, (f & 0x3FFFFFFF) | (mode << 30) ); + EEPROM.put(HAM_BAND_FREQS + 4 * bandIndex, (f & 0x1FFFFFFF) | (mode << 29) ); } /* @@ -471,13 +483,27 @@ void setFrequency(unsigned long f){ setTXFilters(f); - if (isUSB){ - si5351bx_setfreq(2, SECOND_OSC_USB - usbCarrier + f); - si5351bx_setfreq(1, SECOND_OSC_USB); + if (cwMode == 0) + { + if (isUSB){ + si5351bx_setfreq(2, SECOND_OSC_USB - usbCarrier + f + (isIFShift ? ifShiftValue : 0)); + si5351bx_setfreq(1, SECOND_OSC_USB); + } + else{ + si5351bx_setfreq(2, SECOND_OSC_LSB + usbCarrier + f + (isIFShift ? ifShiftValue : 0)); + si5351bx_setfreq(1, SECOND_OSC_LSB); + } } - else{ - si5351bx_setfreq(2, SECOND_OSC_LSB + usbCarrier + f); - si5351bx_setfreq(1, SECOND_OSC_LSB); + else + { + if (cwMode == 1){ //CWL + si5351bx_setfreq(2, SECOND_OSC_LSB + cwmCarrier + f + (isIFShift ? ifShiftValue : 0)); + si5351bx_setfreq(1, SECOND_OSC_LSB); + } + else{ //CWU + si5351bx_setfreq(2, SECOND_OSC_USB - cwmCarrier + f + (isIFShift ? ifShiftValue : 0)); + si5351bx_setfreq(1, SECOND_OSC_USB); + } } frequency = f; @@ -530,10 +556,22 @@ void startTx(byte txMode, byte isDisplayUpdate){ //shif the first oscillator to the tx frequency directly //the key up and key down will toggle the carrier unbalancing //the exact cw frequency is the tuned frequency + sidetone - if (isUSB) - si5351bx_setfreq(2, frequency + sideTone); - else - si5351bx_setfreq(2, frequency - sideTone); + + if (cwMode == 0) + { + if (isUSB) + si5351bx_setfreq(2, frequency + sideTone); + else + si5351bx_setfreq(2, frequency - sideTone); + } + else if (cwMode == 1) //CWL + { + si5351bx_setfreq(2, frequency - sideTone); + } + else //CWU + { + si5351bx_setfreq(2, frequency + sideTone); + } } //reduce latency time when begin of CW mode @@ -545,7 +583,11 @@ void stopTx(){ inTx = 0; digitalWrite(TX_RX, 0); //turn off the tx - si5351bx_setfreq(0, usbCarrier); //set back the carrier oscillator anyway, cw tx switches it off + + if (cwMode == 0) + si5351bx_setfreq(0, usbCarrier + (isIFShift ? ifShiftValue : 0)); //set back the carrier oscillator anyway, cw tx switches it off + else + si5351bx_setfreq(0, cwmCarrier + (isIFShift ? ifShiftValue : 0)); //set back the carrier oscillator anyway, cw tx switches it off if (ritOn) setFrequency(ritRxFrequency); @@ -713,6 +755,24 @@ void doRIT(){ } } +/* +void doIFShift(){ + int knob = enc_read(); + unsigned long old_freq = frequency; + + if (knob != 0) + { + if (knob < 0) + ifShiftValue -= 1l; + else if (knob > 0) + ifShiftValue += 1; + + updateLine2Buffer(1); + setFrequency(frequency); + } +} +*/ + /** save Frequency and mode to eeprom */ @@ -788,6 +848,7 @@ void initSettings(){ if (EEPROM.read(VERSION_ADDRESS) != VERSION_NUM) EEPROM.write(VERSION_ADDRESS, VERSION_NUM); + EEPROM.get(CW_CAL, cwmCarrier); //for Save VFO_A_MODE to eeprom //0: default, 1:not use, 2:LSB, 3:USB, 4:CW, 5:AM, 6:FM @@ -808,7 +869,7 @@ void initSettings(){ else { Iambic_Key = true; - if (cwKeyType = 1) + if (cwKeyType == 1) keyerControl &= ~IAMBICB; else keyerControl |= IAMBICB; @@ -936,6 +997,9 @@ void initSettings(){ //original code with modified by kd8cec if (usbCarrier > 12010000l || usbCarrier < 11990000l) usbCarrier = 11995000l; + + if (cwmCarrier > 12010000l || cwmCarrier < 11990000l) + cwmCarrier = 11995000l; if (vfoA > 35000000l || 3500000l > vfoA) { vfoA = 7150000l; @@ -1020,7 +1084,7 @@ void setup() //Serial.begin(9600); lcd.begin(16, 2); - printLineF(1, F("CECBT v0.32")); + printLineF(1, F("CECBT v0.33")); Init_Cat(38400, SERIAL_8N1); initMeter(); //not used in this build @@ -1038,11 +1102,12 @@ void setup() } initPorts(); + + byteToMode(vfoA_mode); initOscillators(); frequency = vfoA; saveCheckFreq = frequency; //for auto save frequency - byteToMode(vfoA_mode); setFrequency(vfoA); updateDisplay(); @@ -1106,10 +1171,12 @@ void loop(){ if (!inTx){ if (ritOn) doRIT(); + //else if (isIFShift) + // doIFShift(); else doTuningWithThresHold(); - if (isCWAutoMode == 0 && beforeIdle_ProcessTime < millis() - 500) { + if (isCWAutoMode == 0 && beforeIdle_ProcessTime < millis() - 250) { idle_process(); beforeIdle_ProcessTime = millis(); } diff --git a/ubitx_20/ubitx_factory_alignment.ino b/ubitx_20/ubitx_factory_alignment.ino index b73a1c0..8178a20 100644 --- a/ubitx_20/ubitx_factory_alignment.ino +++ b/ubitx_20/ubitx_factory_alignment.ino @@ -37,6 +37,7 @@ void factory_alignment(){ printLine2("#3:Test 3.5MHz"); + cwMode = 0; isUSB = false; setFrequency(3500000l); updateDisplay(); @@ -59,6 +60,7 @@ void factory_alignment(){ btnWaitForClick(); printLine2("#5:Test 14MHz"); + cwMode = 0; isUSB = true; setFrequency(14000000l); updateDisplay(); @@ -80,6 +82,7 @@ void factory_alignment(){ printLine2("Alignment done"); delay(1000); + cwMode = 0; isUSB = false; setFrequency(7150000l); updateDisplay(); diff --git a/ubitx_20/ubitx_idle.ino b/ubitx_20/ubitx_idle.ino index 55f2fdf..2e1c782 100644 --- a/ubitx_20/ubitx_idle.ino +++ b/ubitx_20/ubitx_idle.ino @@ -23,24 +23,55 @@ byte line2Buffer[16]; //U14.150 +150khz int freqScrollPosition = 0; //Example Line2 Optinal Display -void updateLine2Buffer() +//immediate execution, not call by scheulder +void updateLine2Buffer(char isDirectCall) { unsigned long tmpFreq = 0; - - if (ritOn) + if (isDirectCall == 0) { - line2Buffer[0] = 'R'; - line2Buffer[1] = 'i'; - line2Buffer[2] = 't'; - line2Buffer[3] = 'T'; - line2Buffer[4] = 'X'; - line2Buffer[5] = ':'; - + if (ritOn) + { + line2Buffer[0] = 'R'; + line2Buffer[1] = 'i'; + line2Buffer[2] = 't'; + line2Buffer[3] = 'T'; + line2Buffer[4] = 'X'; + line2Buffer[5] = ':'; + + //display frequency + tmpFreq = ritTxFrequency; + for (int i = 15; i >= 6; i--) { + if (tmpFreq > 0) { + if (i == 12 || i == 8) line2Buffer[i] = '.'; + else { + line2Buffer[i] = tmpFreq % 10 + 0x30; + tmpFreq /= 10; + } + } + else + line2Buffer[i] = ' '; + } + + return; + } + + if (vfoActive == VFO_B) + { + tmpFreq = vfoA; + //line2Buffer[0] = 'A'; + } + else + { + tmpFreq = vfoB; + //line2Buffer[0] = 'B'; + } + + // EXAMPLE 1 & 2 + //U14.150.100 //display frequency - tmpFreq = ritTxFrequency; - for (int i = 15; i >= 6; i--) { + for (int i = 9; i >= 0; i--) { if (tmpFreq > 0) { - if (i == 12 || i == 8) line2Buffer[i] = '.'; + if (i == 2 || i == 6) line2Buffer[i] = '.'; else { line2Buffer[i] = tmpFreq % 10 + 0x30; tmpFreq /= 10; @@ -49,106 +80,136 @@ void updateLine2Buffer() else line2Buffer[i] = ' '; } - - return; - } - if (vfoActive == VFO_B) - { - tmpFreq = vfoA; - //line2Buffer[0] = 'A'; - } - else - { - tmpFreq = vfoB; - //line2Buffer[0] = 'B'; - } - - // EXAMPLE 1 & 2 - //U14.150.100 - //display frequency - for (int i = 9; i >= 0; i--) { - if (tmpFreq > 0) { - if (i == 2 || i == 6) line2Buffer[i] = '.'; - else { - line2Buffer[i] = tmpFreq % 10 + 0x30; - tmpFreq /= 10; - } - } - else - line2Buffer[i] = ' '; - } - - //EXAMPLE #1 - if ((displayOption1 & 0x04) == 0x00) - line2Buffer[6] = 'k'; - else - { - //example #2 - if (freqScrollPosition++ > 18) - { + //EXAMPLE #1 + if ((displayOption1 & 0x04) == 0x00) line2Buffer[6] = 'k'; - if (freqScrollPosition > 25) - freqScrollPosition = -1; - } else { - line2Buffer[10] = 'H'; - line2Buffer[11] = 'z'; - - if (freqScrollPosition < 7) + //example #2 + if (freqScrollPosition++ > 18) { - for (int i = 11; i >= 0; i--) - if (i - (7 - freqScrollPosition) >= 0) - line2Buffer[i] = line2Buffer[i - (7 - freqScrollPosition)]; - else - line2Buffer[i] = ' '; + line2Buffer[6] = 'k'; + if (freqScrollPosition > 25) + freqScrollPosition = -1; } else { - for (int i = 0; i < 11; i++) - if (i + (freqScrollPosition - 7) <= 11) - line2Buffer[i] = line2Buffer[i + (freqScrollPosition - 7)]; - else - line2Buffer[i] = ' '; + line2Buffer[10] = 'H'; + line2Buffer[11] = 'z'; + + if (freqScrollPosition < 7) + { + for (int i = 11; i >= 0; i--) + if (i - (7 - freqScrollPosition) >= 0) + line2Buffer[i] = line2Buffer[i - (7 - freqScrollPosition)]; + else + line2Buffer[i] = ' '; + } + else + { + for (int i = 0; i < 11; i++) + if (i + (freqScrollPosition - 7) <= 11) + line2Buffer[i] = line2Buffer[i + (freqScrollPosition - 7)]; + else + line2Buffer[i] = ' '; + } } } - } - line2Buffer[7] = ' '; + line2Buffer[7] = ' '; + } //check direct call by encoder - //Step - byte tmpStep = arTuneStep[tuneStepIndex -1]; - for (int i = 10; i >= 8; i--) { - if (tmpStep > 0) { - line2Buffer[i] = tmpStep % 10 + 0x30; - tmpStep /= 10; + + if (isIFShift) + { + if (isDirectCall == 1) + for (int i = 0; i < 16; i++) + line2Buffer[i] = ' '; + + //IFShift Offset Value + line2Buffer[8] = 'I'; + line2Buffer[9] = 'F'; + + if (ifShiftValue == 0) + { + line2Buffer[10] = 'S'; + line2Buffer[11] = ':'; + line2Buffer[12] = 'O'; + line2Buffer[13] = 'F'; + line2Buffer[14] = 'F'; } else - line2Buffer[i] = ' '; - } - line2Buffer[11] = 'H'; - line2Buffer[12] = 'z'; - - line2Buffer[13] = ' '; - //if ( - //Check CW Key cwKeyType = 0; //0: straight, 1 : iambica, 2: iambicb - if (cwKeyType == 0) - { - line2Buffer[14] = 'S'; - line2Buffer[15] = 'T'; - } - else if (cwKeyType == 1) - { - line2Buffer[14] = 'I'; - line2Buffer[15] = 'A'; + { + line2Buffer[10] = ifShiftValue >= 0 ? '+' : 0; + line2Buffer[11] = 0; + line2Buffer[12] = ' '; + + //11, 12, 13, 14, 15 + memset(b, 0, sizeof(b)); + ltoa(ifShiftValue, b, DEC); + strncat(line2Buffer, b, 5); + } + + if (isDirectCall == 1) //if call by encoder (not scheduler), immediate print value + printLine2(line2Buffer); } else { - line2Buffer[14] = 'I'; - line2Buffer[15] = 'B'; + if (isDirectCall != 0) + return; + + //Step + byte tmpStep = arTuneStep[tuneStepIndex -1]; + for (int i = 10; i >= 8; i--) { + if (tmpStep > 0) { + line2Buffer[i] = tmpStep % 10 + 0x30; + tmpStep /= 10; + } + else + line2Buffer[i] = ' '; + } + line2Buffer[11] = 'H'; + line2Buffer[12] = 'z'; + + line2Buffer[13] = ' '; + //if ( + //Check CW Key cwKeyType = 0; //0: straight, 1 : iambica, 2: iambicb + if (cwKeyType == 0) + { + line2Buffer[14] = 'S'; + line2Buffer[15] = 'T'; + } + else if (cwKeyType == 1) + { + line2Buffer[14] = 'I'; + line2Buffer[15] = 'A'; + } + else + { + line2Buffer[14] = 'I'; + line2Buffer[15] = 'B'; + } } + } +//meterType : 0 = S.Meter, 1 : P.Meter +void DisplayMeter(byte meterType, byte meterValue, char drawPosition) +{ + drawMeter(meterValue); //call original source code + int lineNumber = 0; + if ((displayOption1 & 0x01) == 0x01) + lineNumber = 1; + + lcd.setCursor(drawPosition, lineNumber); + + for (int i = 0; i < 6; i++) //meter 5 + +db 1 = 6 + lcd.write(lcdMeter[i]); + +} + +byte testValue = 0; +char checkCount = 0; void idle_process() { //space for user graphic display @@ -156,9 +217,20 @@ void idle_process() { //if line2DisplayStatus == 0 <-- this condition is clear Line, you can display any message if (line2DisplayStatus == 0 || (((displayOption1 & 0x04) == 0x04) && line2DisplayStatus == 2)) { - updateLine2Buffer(); - printLine2(line2Buffer); - line2DisplayStatus = 2; + if (checkCount++ > 1) + { + updateLine2Buffer(0); //call by scheduler + printLine2(line2Buffer); + line2DisplayStatus = 2; + checkCount = 0; + } + + //EX for Meters + /* + DisplayMeter(0, testValue++, 7); + if (testValue > 30) + testValue = 0; + */ } } } diff --git a/ubitx_20/ubitx_menu.ino b/ubitx_20/ubitx_menu.ino index e7f5670..c09ca6f 100644 --- a/ubitx_20/ubitx_menu.ino +++ b/ubitx_20/ubitx_menu.ino @@ -87,6 +87,8 @@ void menuBand(int btn){ stepChangeCount = 0; } } + + //setFrequency(frequency + 200000l); } else { //original source if (knob < 0 && frequency > 3000000l) @@ -119,30 +121,56 @@ void menuBand(int btn){ } //Convert Mode, Number by KD8CEC -//0: default, 1:not use, 2:LSB, 3:USB, 4:CW, 5:AM, 6:FM +//0: default, 1:not use, 2:LSB, 3:USB, 4:CWL, 5:CWU, 6:FM byte modeToByte(){ - if (isUSB) - return 3; + if (cwMode == 0) + { + if (isUSB) + return 3; + else + return 2; + } + else if (cwMode == 1) + { + return 4; + } else - return 2; + { + return 5; + } } //Convert Number to Mode by KD8CEC void byteToMode(byte modeValue){ - if (modeValue == 3) - isUSB = 1; + if (modeValue == 4) + cwMode = 1; + else if (modeValue == 5) + cwMode = 2; else - isUSB = 0; + { + cwMode = 0; + if (modeValue == 3) + isUSB = 1; + else + isUSB = 0; + } } //Convert Number to Mode by KD8CEC void byteWithFreqToMode(byte modeValue){ - if (modeValue == 3) - isUSB = 1; - else if (modeValue == 0) //Not Set - isUSB = (frequency > 10000000l) ? true : false; - else - isUSB = 0; + if (modeValue == 4) + cwMode = 1; + else if (modeValue == 5) + cwMode = 2; + else { + cwMode = 0; + if (modeValue == 3) + isUSB = 1; + else if (modeValue == 0) //Not Set + isUSB = (frequency > 10000000l) ? true : false; + else + isUSB = 0; + } } //VFO Toggle and save VFO Information, modified by KD8CEC @@ -179,10 +207,11 @@ void menuVfoToggle(int btn, char isUseDelayTime) } ritDisable(); + setFrequency(frequency); if (isUseDelayTime == 1) //Found Issue in wsjt-x Linux 32bit delay_background(500, 0); - + printLine2ClearAndUpdate(); //exit the menu menuOn = 0; @@ -212,6 +241,94 @@ void menuRitToggle(int btn){ } } +/* +void menuIFSToggle(int btn){ + if (!btn){ + if (isIFShift == 1) + printLineF2(F("IF Shift:On, Off?")); + else + printLineF2(F("IF Shift:Off, On?")); + } + else { + if (isIFShift == 0){ + printLineF2(F("IF Shift is ON")); + isIFShift = 1; + } + else{ + printLineF2(F("IF Shift is OFF")); + isIFShift = 0; + } + menuOn = 0; + delay_background(500, 0); + printLine2ClearAndUpdate(); + } +} +*/ +void menuIFSToggle(int btn){ + int knob = 0; + char needApplyChangeValue = 1; + + if (!btn){ + if (isIFShift == 1) + printLineF2(F("IF Shift Change?")); + else + printLineF2(F("IF Shift:Off, On?")); + } + else { + if (isIFShift == 0){ + printLineF2(F("IF Shift is ON")); + delay_background(500, 0); + isIFShift = 1; + } + + delay_background(500, 0); + updateLine2Buffer(1); + setFrequency(frequency); + + //Off or Change Value + while(!btnDown() && digitalRead(PTT) == HIGH){ + if (needApplyChangeValue ==1) + { + updateLine2Buffer(1); + setFrequency(frequency); + + if (cwMode == 0) + si5351bx_setfreq(0, usbCarrier + (isIFShift ? ifShiftValue : 0)); //set back the carrier oscillator anyway, cw tx switches it off + else + si5351bx_setfreq(0, cwmCarrier + (isIFShift ? ifShiftValue : 0)); //set back the carrier oscillator anyway, cw tx switches it off + + needApplyChangeValue = 0; + } + + knob = enc_read(); + if (knob != 0){ + if (knob < 0) + ifShiftValue -= 1l; + else if (knob > 0) + ifShiftValue += 1; + + needApplyChangeValue = 1; + } + } + + delay_background(500, 0); //for check Long Press function key + + if (btnDown() || digitalRead(PTT) == LOW || ifShiftValue == 0) + { + isIFShift = 0; + printLineF2(F("IF Shift is OFF")); + setFrequency(frequency); + delay_background(500, 0); + } + + menuOn = 0; + //delay_background(500, 0); + printLine2ClearAndUpdate(); + } +} + + +/* void menuSidebandToggle(int btn){ if (!btn){ if (isUSB == true) @@ -220,6 +337,7 @@ void menuSidebandToggle(int btn){ printLineF2(F("Select USB?")); } else { + cwMode = 0; if (isUSB == true){ isUSB = false; printLineF2(F("LSB Selected")); @@ -234,6 +352,107 @@ void menuSidebandToggle(int btn){ menuOn = 0; } } +*/ +void menuSelectMode(int btn){ + int knob = 0; + int selectModeType = 0; + int beforeMode = 0; + int moveStep = 0; + + if (!btn){ + printLineF2(F("Select Mode?")); + } + else { + delay_background(500, 0); + + //LSB, USB, CWL, CWU + if (cwMode == 0 && isUSB == 0) + selectModeType = 0; + else if (cwMode == 0 && isUSB == 1) + selectModeType = 1; + else if (cwMode == 1) + selectModeType = 2; + else + selectModeType = 3; + + beforeMode = selectModeType; + + while(!btnDown() && digitalRead(PTT) == HIGH){ + //Display Mode Name + printLineF1(F("LSB USB CWL CWU")); + if (selectModeType == 0) + printLineF1(F("LSB")); + else if (selectModeType == 1) + printLineF1(F("USB")); + else if (selectModeType == 2) + printLineF1(F("CWL")); + else if (selectModeType == 3) + printLineF1(F("CWU")); + + knob = enc_read(); + + if (knob != 0) + { + moveStep += (knob > 0 ? 1 : -1); + if (moveStep < -3) { + if (selectModeType > 0) + selectModeType--; + + moveStep = 0; + } + else if (moveStep > 3) { + if (selectModeType < 3) + selectModeType++; + + moveStep = 0; + } + } + + Check_Cat(0); //To prevent disconnections + } + + if (beforeMode != selectModeType) { + printLineF1(F("Changed Mode")); + + if (selectModeType == 0) { + cwMode = 0; isUSB = 0; + } + else if (selectModeType == 1) { + cwMode = 0; isUSB = 1; + } + else if (selectModeType == 2) { + cwMode = 1; + } + else if (selectModeType == 3) { + cwMode = 2; + } + + //Save Frequency & Mode Information + if (vfoActive == VFO_A) + { + vfoA = frequency; + vfoA_mode = modeToByte(); + storeFrequencyAndMode(1); + } + else + { + vfoB = frequency; + vfoB_mode = modeToByte(); + storeFrequencyAndMode(2); + } + } + + if (cwMode == 0) + si5351bx_setfreq(0, usbCarrier + (isIFShift ? ifShiftValue : 0)); //set back the carrier oscillator anyway, cw tx switches it off + else + si5351bx_setfreq(0, cwmCarrier + (isIFShift ? ifShiftValue : 0)); //set back the carrier oscillator anyway, cw tx switches it off + + setFrequency(frequency); + delay_background(500, 0); + printLine2ClearAndUpdate(); + menuOn = 0; + } +} void menuSplitOnOff(int btn){ if (!btn){ @@ -259,8 +478,6 @@ void menuSplitOnOff(int btn){ } } - - /* //Select CW Key Type by KD8CEC void menuSetupKeyType(int btn){ @@ -303,14 +520,15 @@ void menuSetupKeyType(int btn){ int knob = 0; int selectedKeyType = 0; int moveStep = 0; - if (!btn && digitalRead(PTT) == HIGH){ + if (!btn){ printLineF2(F("Change Key Type?")); } else { - printLineF2(F("Press PTT to set")); + printLineF2(F("Press to set Key")); delay_background(500, 0); selectedKeyType = cwKeyType; - while(!btnDown() && digitalRead(PTT) == HIGH){ + + while(!btnDown()){ //Display Key Type if (selectedKeyType == 0) @@ -325,12 +543,14 @@ void menuSetupKeyType(int btn){ if (knob != 0) { moveStep += (knob > 0 ? 1 : -1); - if (selectedKeyType > 0 && moveStep < -3) { - selectedKeyType--; + if (moveStep < -3) { + if (selectedKeyType > 0) + selectedKeyType--; moveStep = 0; } - else if (selectedKeyType < 2 && moveStep > 3) { - selectedKeyType++; + else if (moveStep > 3) { + if (selectedKeyType < 2) + selectedKeyType++; moveStep = 0; } } @@ -338,24 +558,21 @@ void menuSetupKeyType(int btn){ Check_Cat(0); //To prevent disconnections } - //save the setting - if (digitalRead(PTT) == LOW){ - printLineF2(F("CW Key Type set!")); - cwKeyType = selectedKeyType; - EEPROM.put(CW_KEY_TYPE, cwKeyType); + printLineF2(F("CW Key Type set!")); + cwKeyType = selectedKeyType; + EEPROM.put(CW_KEY_TYPE, cwKeyType); - if (cwKeyType == 0) - Iambic_Key = false; + if (cwKeyType == 0) + Iambic_Key = false; + else + { + Iambic_Key = true; + if (cwKeyType == 1) + keyerControl &= ~IAMBICB; else - { - Iambic_Key = true; - if (cwKeyType = 1) - keyerControl &= ~IAMBICB; - else - keyerControl |= IAMBICB; - } - delay_background(2000, 0); + keyerControl |= IAMBICB; } + delay_background(2000, 0); printLine2ClearAndUpdate(); menuOn = 0; @@ -517,7 +734,7 @@ void menuCWSpeed(int btn){ return; } - printLineF1(F("Press PTT to set")); + printLineF1(F("Press to set WPm")); strcpy(b, "WPM:"); itoa(wpm,c, 10); strcat(b, c); @@ -547,12 +764,12 @@ void menuCWSpeed(int btn){ } //save the setting - if (digitalRead(PTT) == LOW){ + //if (digitalRead(PTT) == LOW){ printLineF2(F("CW Speed set!")); cwSpeed = 1200/wpm; EEPROM.put(CW_SPEED, cwSpeed); delay_background(2000, 0); - } + //} printLine2ClearAndUpdate(); menuOn = 0; } @@ -592,7 +809,7 @@ void menuSetupCwDelay(int btn){ return; } - printLineF1(F("Press PTT to set")); + printLineF1(F("Press, set Delay")); strcpy(b, "DELAY:"); itoa(tmpCWDelay,c, 10); strcat(b, c); @@ -620,12 +837,12 @@ void menuSetupCwDelay(int btn){ } //save the setting - if (digitalRead(PTT) == LOW){ + //if (digitalRead(PTT) == LOW){ printLineF2(F("CW Delay set!")); cwDelayTime = tmpCWDelay / 10; EEPROM.put(CW_DELAY, cwDelayTime); delay_background(2000, 0); - } + //} printLine2ClearAndUpdate(); menuOn = 0; } @@ -641,7 +858,7 @@ void menuSetupTXCWInterval(int btn){ return; } - printLineF1(F("Press PTT to set")); + printLineF1(F("Press, set Delay")); strcpy(b, "Start Delay:"); itoa(tmpTXCWInterval,c, 10); strcat(b, c); @@ -669,12 +886,12 @@ void menuSetupTXCWInterval(int btn){ } //save the setting - if (digitalRead(PTT) == LOW){ + //if (digitalRead(PTT) == LOW){ printLineF2(F("CW Start set!")); delayBeforeCWStartTime = tmpTXCWInterval / 2; EEPROM.put(CW_START, delayBeforeCWStartTime); delay_background(2000, 0); - } + //} printLine2ClearAndUpdate(); menuOn = 0; } @@ -709,6 +926,7 @@ void factoryCalibration(int btn){ calibration = 0; + cwMode = 0; isUSB = true; //turn off the second local oscillator and the bfo @@ -837,7 +1055,7 @@ void printCarrierFreq(unsigned long freq){ strcat(c, "."); strncat(c, &b[2], 3); strcat(c, "."); - strncat(c, &b[5], 1); + strncat(c, &b[5], 3); printLine2(c); } @@ -889,12 +1107,71 @@ void menuSetupCarrier(int btn){ else usbCarrier = prevCarrier; - si5351bx_setfreq(0, usbCarrier); + //si5351bx_setfreq(0, usbCarrier); + if (cwMode == 0) + si5351bx_setfreq(0, usbCarrier); //set back the carrier oscillator anyway, cw tx switches it off + else + si5351bx_setfreq(0, cwmCarrier); //set back the carrier oscillator anyway, cw tx switches it off + setFrequency(frequency); printLine2ClearAndUpdate(); menuOn = 0; } +//Append by KD8CEC +void menuSetupCWCarrier(int btn){ + int knob = 0; + unsigned long prevCarrier; + + if (!btn){ + printLineF2(F("Set CW RX BFO")); + return; + } + + prevCarrier = cwmCarrier; + printLineF1(F("PTT to confirm. ")); + delay_background(1000, 0); + + si5351bx_setfreq(0, cwmCarrier); + printCarrierFreq(cwmCarrier); + + //disable all clock 1 and clock 2 + while (digitalRead(PTT) == HIGH && !btnDown()) + { + knob = enc_read(); + + if (knob > 0) + cwmCarrier -= 5; + else if (knob < 0) + cwmCarrier += 5; + else + continue; //don't update the frequency or the display + + si5351bx_setfreq(0, cwmCarrier); + printCarrierFreq(cwmCarrier); + + Check_Cat(0); //To prevent disconnections + delay(100); + } + + //save the setting + if (digitalRead(PTT) == LOW){ + printLineF2(F("Carrier set!")); + EEPROM.put(CW_CAL, cwmCarrier); + delay_background(1000, 0); + } + else + cwmCarrier = prevCarrier; + + if (cwMode == 0) + si5351bx_setfreq(0, usbCarrier); //set back the carrier oscillator anyway, cw tx switches it off + else + si5351bx_setfreq(0, cwmCarrier); //set back the carrier oscillator anyway, cw tx switches it off + + setFrequency(frequency); + printLine2ClearAndUpdate(); + menuOn = 0; +} //Modified by KD8CEC void menuSetupCwTone(int btn){ int knob = 0; @@ -998,7 +1275,7 @@ void doMenu(){ //ADJUST TUNE STEP if (btnDownTimeCount > (PRESS_ADJUST_TUNE / 50)) { - printLineF1(F("Press Key to set")); + printLineF1(F("Press to set step")); isNeedDisplay = 1; //check to need display for display current value while (digitalRead(PTT) == HIGH && !btnDown()) @@ -1051,9 +1328,9 @@ void doMenu(){ btnState = btnDown(); if (i > 0){ - if (modeCalibrate && select + i < 180) + if (modeCalibrate && select + i < 200) select += i; - if (!modeCalibrate && select + i < 80) + if (!modeCalibrate && select + i < 100) select += i; } //if (i < 0 && select - i >= 0) @@ -1065,38 +1342,42 @@ void doMenu(){ else if (select < 10) menuBand(btnState); else if (select < 20) - menuRitToggle(btnState); - else if (select < 30) menuVfoToggle(btnState, 1); + else if (select < 30) + menuSelectMode(btnState); else if (select < 40) - menuSidebandToggle(btnState); + menuRitToggle(btnState); else if (select < 50) - menuCWSpeed(btnState); + menuIFSToggle(btnState); else if (select < 60) - menuCWAutoKey(btnState); + menuCWSpeed(btnState); else if (select < 70) + menuSplitOnOff(btnState); //SplitOn / off + else if (select < 80) + menuCWAutoKey(btnState); + else if (select < 90) menuSetup(btnState); - else if (select < 80 && !modeCalibrate) + else if (select < 100) menuExit(btnState); - else if (select < 90 && modeCalibrate) - menuSetupCalibration(btnState); //crystal - else if (select < 100 && modeCalibrate) - menuSetupCarrier(btnState); //lsb else if (select < 110 && modeCalibrate) - menuSetupCwTone(btnState); + menuSetupCalibration(btnState); //crystal else if (select < 120 && modeCalibrate) - menuSetupCwDelay(btnState); + menuSetupCarrier(btnState); //lsb else if (select < 130 && modeCalibrate) - menuSetupTXCWInterval(btnState); + menuSetupCWCarrier(btnState); //lsb else if (select < 140 && modeCalibrate) - menuSetupKeyType(btnState); + menuSetupCwTone(btnState); else if (select < 150 && modeCalibrate) - menuADCMonitor(btnState); + menuSetupCwDelay(btnState); else if (select < 160 && modeCalibrate) - menuSplitOnOff(btnState); //TX OFF / ON + menuSetupTXCWInterval(btnState); else if (select < 170 && modeCalibrate) - menuTxOnOff(btnState, 0x01); //TX OFF / ON + menuSetupKeyType(btnState); else if (select < 180 && modeCalibrate) + menuADCMonitor(btnState); + else if (select < 190 && modeCalibrate) + menuTxOnOff(btnState, 0x01); //TX OFF / ON + else if (select < 200 && modeCalibrate) menuExit(btnState); Check_Cat(0); //To prevent disconnections diff --git a/ubitx_20/ubitx_si5351.ino b/ubitx_20/ubitx_si5351.ino index b437ad9..8098819 100644 --- a/ubitx_20/ubitx_si5351.ino +++ b/ubitx_20/ubitx_si5351.ino @@ -109,7 +109,11 @@ void initOscillators(){ //initialize the SI5351 si5351bx_init(); si5351bx_vcoa = (SI5351BX_XTAL * SI5351BX_MSA) + calibration; // apply the calibration correction factor - si5351bx_setfreq(0, usbCarrier); + + if (cwMode == 0) + si5351bx_setfreq(0, usbCarrier + (isIFShift ? ifShiftValue : 0)); + else + si5351bx_setfreq(0, cwmCarrier + (isIFShift ? ifShiftValue : 0)); } diff --git a/ubitx_20/ubitx_ui.ino b/ubitx_20/ubitx_ui.ino index 85229db..f415268 100644 --- a/ubitx_20/ubitx_ui.ino +++ b/ubitx_20/ubitx_ui.ino @@ -25,8 +25,8 @@ int btnDown(){ * The current reading of the meter is assembled in the string called meter */ -//char meter[17]; +/* const PROGMEM uint8_t s_meter_bitmap[] = { B00000,B00000,B00000,B00000,B00000,B00100,B00100,B11011, B10000,B10000,B10000,B10000,B10100,B10100,B10100,B11011, @@ -35,7 +35,18 @@ const PROGMEM uint8_t s_meter_bitmap[] = { B00010,B00010,B00010,B00010,B00110,B00110,B00110,B11011, B00001,B00001,B00001,B00001,B00101,B00101,B00101,B11011 }; -PGM_P ps_meter_bitmap = reinterpret_cast(s_meter_bitmap); +*/ + +const PROGMEM uint8_t meters_bitmap[] = { + B10000, B10000, B10000, B10000, B10000, B10000, B10000, B10000 , //custom 1 + B11000, B11000, B11000, B11000, B11000, B11000, B11000, B11000 , //custom 2 + B11100, B11100, B11100, B11100, B11100, B11100, B11100, B11100 , //custom 3 + B11110, B11110, B11110, B11110, B11110, B11110, B11110, B11110 , //custom 4 + B11111, B11111, B11111, B11111, B11111, B11111, B11111, B11111 , //custom 5 + B01000, B11100, B01000, B00000, B10111, B10101, B10101, B10111 //custom 6 +}; + +PGM_P p_metes_bitmap = reinterpret_cast(meters_bitmap); const PROGMEM uint8_t lock_bitmap[8] = { 0b01110, @@ -60,38 +71,56 @@ void initMeter(){ lcd.createChar(0, tmpbytes); for (i = 0; i < 8; i++) - tmpbytes[i] = pgm_read_byte(ps_meter_bitmap + i); + tmpbytes[i] = pgm_read_byte(p_metes_bitmap + i); lcd.createChar(1, tmpbytes); for (i = 0; i < 8; i++) - tmpbytes[i] = pgm_read_byte(ps_meter_bitmap + i + 8); + tmpbytes[i] = pgm_read_byte(p_metes_bitmap + i + 8); lcd.createChar(2, tmpbytes); for (i = 0; i < 8; i++) - tmpbytes[i] = pgm_read_byte(ps_meter_bitmap + i + 16); + tmpbytes[i] = pgm_read_byte(p_metes_bitmap + i + 16); lcd.createChar(3, tmpbytes); for (i = 0; i < 8; i++) - tmpbytes[i] = pgm_read_byte(ps_meter_bitmap + i + 24); + tmpbytes[i] = pgm_read_byte(p_metes_bitmap + i + 24); lcd.createChar(4, tmpbytes); for (i = 0; i < 8; i++) - tmpbytes[i] = pgm_read_byte(ps_meter_bitmap + i + 28); + tmpbytes[i] = pgm_read_byte(p_metes_bitmap + i + 32); lcd.createChar(5, tmpbytes); for (i = 0; i < 8; i++) - tmpbytes[i] = pgm_read_byte(ps_meter_bitmap + i + 32); + tmpbytes[i] = pgm_read_byte(p_metes_bitmap + i + 40); lcd.createChar(6, tmpbytes); } -/** - * The meter is drawn with special characters. - * character 1 is used to simple draw the blocks of the scale of the meter - * characters 2 to 6 are used to draw the needle in positions 1 to within the block - * This displays a meter from 0 to 100, -1 displays nothing - */ +//by KD8CEC +//0 ~ 25 : 30 over : + 10 +void drawMeter(int needle) { + //5Char + O over + int drawCharLength = needle / 5; + int drawCharLengthLast = needle % 5; + int i; - /* + for (i = 0; i < 5; i++) { + if (needle >= 5) + lcdMeter[i] = 5; //full + else if (needle > 0) + lcdMeter[i] = needle; //full + else //0 + lcdMeter[i] = 0x20; + + needle -= 5; + } + + if (needle > 0) + lcdMeter[5] = 6; + else + lcdMeter[5] = 0x20; +} + +/* void drawMeter(int8_t needle){ int16_t best, i, s; @@ -101,19 +130,18 @@ void drawMeter(int8_t needle){ s = (needle * 4)/10; for (i = 0; i < 8; i++){ if (s >= 5) - meter[i] = 1; + lcdMeter[i] = 1; else if (s >= 0) - meter[i] = 2 + s; + lcdMeter[i] = 2 + s; else - meter[i] = 1; + lcdMeter[i] = 1; s = s - 5; } if (needle >= 40) - meter[i-1] = 6; - meter[i] = 0; + lcdMeter[i-1] = 6; + lcdMeter[i] = 0; } */ - // The generic routine to display one line on the LCD void printLine(unsigned char linenmbr, const char *c) { if ((displayOption1 & 0x01) == 0x01) @@ -234,10 +262,21 @@ void updateDisplay() { if (ritOn) strcpy(c, "RIT "); else { - if (isUSB) - strcpy(c, "USB "); + if (cwMode == 0) + { + if (isUSB) + strcpy(c, "USB "); + else + strcpy(c, "LSB "); + } + else if (cwMode == 1) + { + strcpy(c, "CWL "); + } else - strcpy(c, "LSB "); + { + strcpy(c, "CWU "); + } } if (vfoActive == VFO_A) // VFO A is active strcat(c, "A:");