diff --git a/ubitx_20/ubitx_20.ino b/ubitx_20/ubitx_20.ino index e927cea..2ce915d 100644 --- a/ubitx_20/ubitx_20.ino +++ b/ubitx_20/ubitx_20.ino @@ -315,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 @@ -482,22 +486,22 @@ void setFrequency(unsigned long f){ if (cwMode == 0) { if (isUSB){ - si5351bx_setfreq(2, SECOND_OSC_USB - usbCarrier + f); + 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); + si5351bx_setfreq(2, SECOND_OSC_LSB + usbCarrier + f + (isIFShift ? ifShiftValue : 0)); si5351bx_setfreq(1, SECOND_OSC_LSB); } } else { if (cwMode == 1){ //CWL - si5351bx_setfreq(2, SECOND_OSC_LSB + cwmCarrier + f); + 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); + si5351bx_setfreq(2, SECOND_OSC_USB - cwmCarrier + f + (isIFShift ? ifShiftValue : 0)); si5351bx_setfreq(1, SECOND_OSC_USB); } } @@ -581,9 +585,9 @@ void stopTx(){ digitalWrite(TX_RX, 0); //turn off the tx if (cwMode == 0) - si5351bx_setfreq(0, usbCarrier); //set back the carrier oscillator anyway, cw tx switches it off + si5351bx_setfreq(0, usbCarrier + (isIFShift ? ifShiftValue : 0)); //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 + si5351bx_setfreq(0, cwmCarrier + (isIFShift ? ifShiftValue : 0)); //set back the carrier oscillator anyway, cw tx switches it off if (ritOn) setFrequency(ritRxFrequency); @@ -751,6 +755,22 @@ 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 */ @@ -1149,10 +1169,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_idle.ino b/ubitx_20/ubitx_idle.ino index 55f2fdf..b96e567 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,124 @@ 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; - } - else - line2Buffer[i] = ' '; - } - line2Buffer[11] = 'H'; - line2Buffer[12] = 'z'; + + if (isIFShift) + { + //IFShift Offset Value + line2Buffer[8] = 'I'; + line2Buffer[9] = 'F'; + + line2Buffer[10] = ifShiftValue >= 0 ? '+' : 0; + line2Buffer[11] = 0; + line2Buffer[12] = ' '; + line2Buffer[13] = ' '; + line2Buffer[14] = ' '; + line2Buffer[15] = ' '; + + //11, 12, 13, 14, 15 + memset(b, 0, sizeof(b)); + ltoa(ifShiftValue, b, DEC); + strncat(line2Buffer, b, 5); - 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'; + 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 +205,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 29cc43e..06823ca 100644 --- a/ubitx_20/ubitx_menu.ino +++ b/ubitx_20/ubitx_menu.ino @@ -205,10 +205,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; @@ -238,6 +239,29 @@ 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 menuSidebandToggle(int btn){ if (!btn){ @@ -286,9 +310,10 @@ void menuSelectMode(int btn){ 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) @@ -1190,7 +1215,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()) @@ -1243,9 +1268,9 @@ void doMenu(){ btnState = btnDown(); if (i > 0){ - if (modeCalibrate && select + i < 190) + 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) @@ -1257,40 +1282,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 < 40) + else if (select < 30) menuSelectMode(btnState); + else if (select < 40) + menuRitToggle(btnState); else if (select < 50) - menuCWSpeed(btnState); + menuIFSToggle(btnState); else if (select < 60) - menuCWAutoKey(btnState); + menuCWSpeed(btnState); else if (select < 70) - menuSetup(btnState); - else if (select < 80 && !modeCalibrate) - menuExit(btnState); - else if (select < 90 && modeCalibrate) - menuSetupCalibration(btnState); //crystal - else if (select < 100 && modeCalibrate) - menuSetupCarrier(btnState); //lsb - else if (select < 110 && modeCalibrate) - menuSetupCWCarrier(btnState); //lsb - else if (select < 120 && modeCalibrate) - menuSetupCwTone(btnState); - else if (select < 130 && modeCalibrate) - menuSetupCwDelay(btnState); - else if (select < 140 && modeCalibrate) - menuSetupTXCWInterval(btnState); - else if (select < 150 && modeCalibrate) - menuSetupKeyType(btnState); - else if (select < 160 && modeCalibrate) - menuADCMonitor(btnState); - else if (select < 170 && modeCalibrate) menuSplitOnOff(btnState); //SplitOn / off + else if (select < 80) + menuCWAutoKey(btnState); + else if (select < 90) + menuSetup(btnState); + else if (select < 100) + menuExit(btnState); + else if (select < 110 && modeCalibrate) + menuSetupCalibration(btnState); //crystal + else if (select < 120 && modeCalibrate) + menuSetupCarrier(btnState); //lsb + else if (select < 130 && modeCalibrate) + menuSetupCWCarrier(btnState); //lsb + else if (select < 140 && modeCalibrate) + menuSetupCwTone(btnState); + else if (select < 150 && modeCalibrate) + menuSetupCwDelay(btnState); + else if (select < 160 && modeCalibrate) + menuSetupTXCWInterval(btnState); + else if (select < 170 && modeCalibrate) + menuSetupKeyType(btnState); else if (select < 180 && modeCalibrate) - menuTxOnOff(btnState, 0x01); //TX OFF / ON + 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 9e79e51..8098819 100644 --- a/ubitx_20/ubitx_si5351.ino +++ b/ubitx_20/ubitx_si5351.ino @@ -111,9 +111,9 @@ void initOscillators(){ si5351bx_vcoa = (SI5351BX_XTAL * SI5351BX_MSA) + calibration; // apply the calibration correction factor if (cwMode == 0) - si5351bx_setfreq(0, usbCarrier); + si5351bx_setfreq(0, usbCarrier + (isIFShift ? ifShiftValue : 0)); else - si5351bx_setfreq(0, cwmCarrier); + si5351bx_setfreq(0, cwmCarrier + (isIFShift ? ifShiftValue : 0)); } diff --git a/ubitx_20/ubitx_ui.ino b/ubitx_20/ubitx_ui.ino index 71d35cd..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)