diff --git a/ubitx_20/ubitx_20.ino b/ubitx_20/ubitx_20.ino index 5a2b8b6..a765fdb 100644 --- a/ubitx_20/ubitx_20.ino +++ b/ubitx_20/ubitx_20.ino @@ -152,6 +152,7 @@ int count = 0; //to generally count ticks, loops, etc #define TX_TUNE_TYPE 261 // #define HAM_BAND_RANGE 262 //FROM (2BYTE) TO (2BYTE) * 10 = 40byte #define HAM_BAND_FREQS 302 //40, 1 BAND = 4Byte most bit is mode +#define TUNING_STEP 342 //TUNING STEP * 6 (index 1 + STEPS 5) //Check Firmware type and version #define FIRMWAR_ID_ADDR 776 //776 : 0x59, 777 :0x58, 778 : 0x68 : Id Number, if not found id, erase eeprom(32~1023) for prevent system error. @@ -235,7 +236,8 @@ byte sideToneSub = 0; //DialLock byte isDialLock = 0; //000000[0]vfoB [0]vfoA 0Bit : A, 1Bit : B byte isTxType = 0; //000000[0 - isSplit] [0 - isTXStop] - +byte arTuneStep[5]; +byte tuneStepIndex; //default Value 0, start Offset is 0 because of check new user //Variables for auto cw mode byte isCWAutoMode = 0; //0 : none, 1 : CW_AutoMode_Menu_Selection, 2 : CW_AutoMode Sending @@ -422,8 +424,7 @@ void setTXFilters(unsigned long freq){ */ void setFrequency(unsigned long f){ - //1 digits discarded - f = (f / 50) * 50; + f = (f / arTuneStep[tuneStepIndex -1]) * arTuneStep[tuneStepIndex -1]; setTXFilters(f); @@ -559,13 +560,15 @@ void checkButton(){ } -/** - * The tuning jumps by 50 Hz on each step when you tune slowly - * As you spin the encoder faster, the jump size also increases - * This way, you can quickly move to another band by just spinning the - * tuning knob - */ - +/************************************ +Replace function by KD8CEC +prevent error controls +applied Threshold for reduct errors, dial Lock, dynamic Step + *************************************/ +byte threshold = 2; //noe action for count +unsigned long lastEncInputtime = 0; +int encodedSumValue = 0; +#define encodeTimeOut 1000 void doTuning(){ int s = 0; unsigned long prev_freq; @@ -578,46 +581,37 @@ void doTuning(){ if (isCWAutoMode == 0 || cwAutoDialType == 1) s = enc_read(); - if (s){ - prev_freq = frequency; - - if (s > 10) - incdecValue = 200000l; - if (s > 7) - incdecValue = 10000l; - else if (s > 4) - incdecValue = 1000l; - else if (s > 2) - incdecValue = 500; - else if (s > 0) - incdecValue = 50l; - else if (s > -2) - incdecValue = -50l; - else if (s > -4) - incdecValue = -500l; - else if (s > -7) - incdecValue = -1000l; - else if (s > -9) - incdecValue = -10000l; - else - incdecValue = -200000l; - - if (incdecValue > 0 && frequency + incdecValue > HIGHEST_FREQ_DIAL) - frequency = HIGHEST_FREQ_DIAL; - else if (incdecValue < 0 && frequency < (unsigned long)(-incdecValue + LOWEST_FREQ_DIAL)) //for compute and compare based integer type. - frequency = LOWEST_FREQ_DIAL; - else - frequency += incdecValue; - - if (prev_freq < 10000000l && frequency > 10000000l) - isUSB = true; - - if (prev_freq > 10000000l && frequency < 10000000l) - isUSB = false; - - setFrequency(frequency); - updateDisplay(); + //if time is exceeded, it is recognized as an error, + //ignore exists values, because of errors + if (s == 0) { + if (encodedSumValue != 0 && (millis() - encodeTimeOut) > lastEncInputtime) + encodedSumValue = 0; + return; } + lastEncInputtime = millis(); + + //for check moving direction + encodedSumValue += (s > 0 ? 1 : -1); + + //check threshold + if ((encodedSumValue * encodedSumValue) <= (threshold * threshold)) + return; + + //Valid Action without noise + encodedSumValue = 0; + + prev_freq = frequency; + //incdecValue = tuningStep * s; + frequency += (arTuneStep[tuneStepIndex -1] * s); + + if (prev_freq < 10000000l && frequency > 10000000l) + isUSB = true; + + if (prev_freq > 10000000l && frequency < 10000000l) + isUSB = false; + + setFrequency(frequency); + updateDisplay(); } /** @@ -730,19 +724,65 @@ void initSettings(){ EEPROM.get(HAM_BAND_COUNT, useHamBandCount); EEPROM.get(TX_TUNE_TYPE, tuneTXType); - - if ((3 < tuneTXType && tuneTXType < 100) || 103 < tuneTXType || useHamBandCount < 1) - tuneTXType = 0; + byte findedValidValueCount = 0; //Read band Information for (byte i = 0; i < useHamBandCount; i++) { unsigned int tmpReadValue = 0; EEPROM.get(HAM_BAND_RANGE + 4 * i, tmpReadValue); hamBandRange[i][0] = tmpReadValue; + + if (tmpReadValue > 1 && tmpReadValue < 55000) + findedValidValueCount++; + EEPROM.get(HAM_BAND_RANGE + 4 * i + 2, tmpReadValue); hamBandRange[i][1] = tmpReadValue; } + + //Check Value Range and default Set for new users + if ((3 < tuneTXType && tuneTXType < 100) || 103 < tuneTXType || useHamBandCount < 1 || findedValidValueCount < 5) + { + tuneTXType = 2; + //if empty band Information, auto insert default region 1 frequency range + //This part is made temporary for people who have difficulty setting up, so can remove it when you run out of memory. + useHamBandCount = 10; + hamBandRange[0][0] = 1810; hamBandRange[0][1] = 2000; + hamBandRange[1][0] = 3500; hamBandRange[1][1] = 3800; + hamBandRange[2][0] = 5351; hamBandRange[2][1] = 5367; + hamBandRange[3][0] = 7000; hamBandRange[3][1] = 7200; + hamBandRange[4][0] = 10100; hamBandRange[4][1] = 10150; + hamBandRange[5][0] = 14000; hamBandRange[5][1] = 14350; + hamBandRange[6][0] = 18068; hamBandRange[6][1] = 18168; + hamBandRange[7][0] = 21000; hamBandRange[7][1] = 21450; + hamBandRange[8][0] = 24890; hamBandRange[8][1] = 24990; + hamBandRange[9][0] = 28000; hamBandRange[9][1] = 29700; + } + + //Read Tuning Step Index, and steps + findedValidValueCount = 0; + EEPROM.get(TUNING_STEP, tuneStepIndex); + for (byte i = 0; i < 5; i++) { + arTuneStep[i] = EEPROM.read(TUNING_STEP + i + 1); + if (arTuneStep[i] >= 1 && arTuneStep[i] < 251) //Maximum 250 for check valid Value + findedValidValueCount++; + } + + //Check Value Range and default Set for new users + if (findedValidValueCount < 5) + { + //Default Setting + arTuneStep[0] = 10; + arTuneStep[1] = 20; + arTuneStep[2] = 50; + arTuneStep[3] = 100; + arTuneStep[4] = 200; + } + + if (tuneStepIndex == 0) //New User + tuneStepIndex = 3; + + if (cwDelayTime < 1 || cwDelayTime > 250) cwDelayTime = 60; diff --git a/ubitx_20/ubitx_keyer.ino b/ubitx_20/ubitx_keyer.ino index 5d2b668..cf950b8 100644 --- a/ubitx_20/ubitx_keyer.ino +++ b/ubitx_20/ubitx_keyer.ino @@ -1,5 +1,7 @@ /** * CW Keyer + * CW Key logic change with ron's code (ubitx_keyer.cpp) <=== ********************************** + * The file you are working on. The code only applies and is still in testing. <==== *********** * * The CW keyer handles either a straight key or an iambic / paddle key. * They all use just one analog input line. This is how it works. @@ -34,7 +36,6 @@ //when both are simultaneously pressed char lastPaddle = 0; - //reads the analog keyer pin and reports the paddle byte getPaddle(){ int paddle = analogRead(ANALOG_KEYER); @@ -81,13 +82,218 @@ void cwKeyUp(){ cwTimeout = millis() + cwDelayTime * 10; } +/***************************************************************************** +// New logic, by RON +// modified by KD8CEC +******************************************************************************/ +#define DIT_L 0x01 // DIT latch +#define DAH_L 0x02 // DAH latch +#define DIT_PROC 0x04 // DIT is being processed +#define PDLSWAP 0x08 // 0 for normal, 1 for swap +#define IAMBICB 0x10 // 0 for Iambic A, 1 for Iambic B +enum KSTYPE {IDLE, CHK_DIT, CHK_DAH, KEYED_PREP, KEYED, INTER_ELEMENT }; + +static long ktimer; + +bool Iambic_Key = true; +unsigned char keyerControl = IAMBICB; +unsigned char keyerState = IDLE; + +//Below is a test to reduce the keying error. +/* +char update_PaddleLatch(byte isUpdateKeyState) { + int paddle = analogRead(ANALOG_KEYER); + unsigned char tmpKeyerControl; + + if (paddle > 800) // above 4v is up + tmpKeyerControl = 0; + //else if (paddle > 600) // 4-3v is DASH + else if (paddle > 693 && paddle < 700) // 4-3v is DASH + tmpKeyerControl |= DAH_L; + //else if (paddle > 300) //1-2v is DOT + else if (paddle > 323 && paddle < 328) //1-2v is DOT + tmpKeyerControl |= DIT_L; + //else if (paddle > 50) + else if (paddle > 280 && paddle < 290) + tmpKeyerControl |= (DAH_L | DIT_L) ; //both are between 1 and 2v + else + tmpKeyerControl = 0 ; //STRAIGHT KEY in original code + //keyerControl |= (DAH_L | DIT_L) ; //STRAIGHT KEY in original code + + if (isUpdateKeyState == 1) { + keyerControl |= tmpKeyerControl; + } + + byte buff[17]; + sprintf(buff, "Key : %d", paddle); + if (tmpKeyerControl > 0) + printLine2(buff); + + return tmpKeyerControl; + + //if (analogRead(ANALOG_DOT) < 600 ) keyerControl |= DIT_L; + //if (analogRead(ANALOG_DASH) < 600 ) keyerControl |= DAH_L; +} +*/ + +//create by KD8CEC for compatible with new CW Logic +char update_PaddleLatch(byte isUpdateKeyState) { + int paddle = analogRead(ANALOG_KEYER); + unsigned char tmpKeyerControl; + + if (paddle > 800) // above 4v is up + tmpKeyerControl = 0; + else if (paddle > 600) // 4-3v is DASH + tmpKeyerControl |= DAH_L; + else if (paddle > 300) //1-2v is DOT + tmpKeyerControl |= DIT_L; + else if (paddle > 50) + tmpKeyerControl |= (DAH_L | DIT_L) ; //both are between 1 and 2v + else + tmpKeyerControl = 0 ; //STRAIGHT KEY in original code + //keyerControl |= (DAH_L | DIT_L) ; //STRAIGHT KEY in original code + + if (isUpdateKeyState == 1) { + keyerControl |= tmpKeyerControl; + } + + return tmpKeyerControl; + //if (analogRead(ANALOG_DOT) < 600 ) keyerControl |= DIT_L; + //if (analogRead(ANALOG_DASH) < 600 ) keyerControl |= DAH_L; +} + +void cwKeyer(void){ + byte paddle; + lastPaddle = 0; + int dot,dash; + bool continue_loop = true; + unsigned tmpKeyControl = 0; +if( Iambic_Key ){ + +while(continue_loop){ + switch (keyerState) { + case IDLE: + tmpKeyControl = update_PaddleLatch(0); + if ( tmpKeyControl == DAH_L || tmpKeyControl == DIT_L || + tmpKeyControl == (DAH_L | DIT_L) || (keyerControl & 0x03)) { + //DIT or DASH or current state DIT & DASH + //(analogRead(ANALOG_DOT) < 600) || //DIT + //(analogRead(ANALOG_DASH) < 600) || //DIT + // (keyerControl & 0x03)) { + update_PaddleLatch(1); + keyerState = CHK_DIT; + }else{ + if (0 < cwTimeout && cwTimeout < millis()){ + cwTimeout = 0; + stopTx(); + } + continue_loop = false; + } + break; + + case CHK_DIT: + if (keyerControl & DIT_L) { + keyerControl |= DIT_PROC; + ktimer = cwSpeed; + keyerState = KEYED_PREP; + }else{ + keyerState = CHK_DAH; + } + break; + + case CHK_DAH: + if (keyerControl & DAH_L) { + ktimer = cwSpeed*3; + keyerState = KEYED_PREP; + }else{ + keyerState = IDLE; + } + break; + + case KEYED_PREP: + ktimer += millis(); // set ktimer to interval end time + keyerControl &= ~(DIT_L + DAH_L); // clear both paddle latch bits + keyerState = KEYED; // next state + if (!inTx){ + keyDown = 0; + cwTimeout = millis() + cwDelayTime * 10; //+ CW_TIMEOUT; + startTx(TX_CW, 0); + } + cwKeydown(); + break; + + case KEYED: + if (millis() > ktimer) { // are we at end of key down ? + cwKeyUp(); + ktimer = millis() + cwSpeed; // inter-element time + keyerState = INTER_ELEMENT; // next state + }else if (keyerControl & IAMBICB) { + update_PaddleLatch(1); // early paddle latch in Iambic B mode + } + break; + + case INTER_ELEMENT: + // Insert time between dits/dahs + update_PaddleLatch(1); // latch paddle state + if (millis() > ktimer) { // are we at end of inter-space ? + if (keyerControl & DIT_PROC) { // was it a dit or dah ? + keyerControl &= ~(DIT_L + DIT_PROC); // clear two bits + keyerState = CHK_DAH; // dit done, check for dah + }else{ + keyerControl &= ~(DAH_L); // clear dah latch + keyerState = IDLE; // go idle + } + } + break; + } +} //end of while + +}else{ + while(1){ + //if (analogRead(ANALOG_DOT) < 600){ + if (update_PaddleLatch(0) == DIT_L) { + // if we are here, it is only because the key is pressed + if (!inTx){ + keyDown = 0; + cwTimeout = millis() + cwDelayTime * 10; //+ CW_TIMEOUT; + startTx(TX_CW, 0); + } + // start the transmission) + cwKeydown(); + //while ( analogRead(ANALOG_DOT) < 600 ) delay(1); + while ( update_PaddleLatch(0) == DIT_L ) delay(1); + cwKeyUp(); + }else{ + if (0 < cwTimeout && cwTimeout < millis()){ + cwTimeout = 0; + keyDown = 0; + stopTx(); + } + if (!cwTimeout) + return; + // got back to the beginning of the loop, if no further activity happens on straight key + // we will time out, and return out of this routine + delay(5); + continue; + } +} //end of else +} +} + + + +//======================================================================================= +//Before logic +//by Farhan and modified by KD8CEC +//====================================================================================== + /** * The keyer handles the straight key as well as the iambic key * This module keeps looping until the user stops sending cw * if the cwTimeout is set to 0, then it means, we have to exit the keyer loop * Each time the key is hit the cwTimeout is pushed to a time in the future by cwKeyDown() */ - + /* void cwKeyer(){ byte paddle; lastPaddle = 0; @@ -111,17 +317,7 @@ void cwKeyer(){ if (!cwTimeout) return; - //if a paddle was used (not a straight key) we should extend the space to be a full dash - //by adding two more dots long space (one has already been added at the end of the dot or dash) - /* - if (cwTimeout > 0 && lastPaddle != PADDLE_STRAIGHT) - delay_background(cwSpeed * 2, 3); - //delay(cwSpeed * 2); - - // got back to the begining of the loop, if no further activity happens on the paddle or the straight key - // we will time out, and return out of this routine - delay(5); - */ + Check_Cat(2); //for uBITX on Raspberry pi, when straight keying, disconnect / test complete continue; } @@ -184,3 +380,6 @@ void cwKeyer(){ delay(cwSpeed); } } +*/ + + diff --git a/ubitx_20/ubitx_menu.ino b/ubitx_20/ubitx_menu.ino index 3b58636..37165d9 100644 --- a/ubitx_20/ubitx_menu.ino +++ b/ubitx_20/ubitx_menu.ino @@ -36,21 +36,6 @@ void menuBand(int btn){ } else { tuneTXType = 2; - //if empty band Information, auto insert default region 1 frequency range - //This part is made temporary for people who have difficulty setting up, so can remove it when you run out of memory. - if (useHamBandCount < 1) { - useHamBandCount = 10; - hamBandRange[0][0] = 1810; hamBandRange[0][1] = 2000; - hamBandRange[1][0] = 3500; hamBandRange[1][1] = 3800; - hamBandRange[2][0] = 5351; hamBandRange[2][1] = 5367; - hamBandRange[3][0] = 7000; hamBandRange[3][1] = 7200; - hamBandRange[4][0] = 10100; hamBandRange[4][1] = 10150; - hamBandRange[5][0] = 14000; hamBandRange[5][1] = 14350; - hamBandRange[6][0] = 18068; hamBandRange[6][1] = 18168; - hamBandRange[7][0] = 21000; hamBandRange[7][1] = 21450; - hamBandRange[8][0] = 24890; hamBandRange[8][1] = 24990; - hamBandRange[9][0] = 28000; hamBandRange[9][1] = 29700; - } printLineF2(F("Ham band mode")); } delay_background(1000, 0); @@ -653,7 +638,8 @@ void menuSetupCarrier(int btn){ printLineF1(F("PTT to confirm. ")); delay_background(1000, 0); - usbCarrier = 11995000l; + //usbCarrier = 11995000l; //Remarked by KD8CEC, Suggest from many user, if entry routine factoryrest + si5351bx_setfreq(0, usbCarrier); printCarrierFreq(usbCarrier); @@ -756,22 +742,29 @@ void setDialLock(byte tmpLock, byte fromMode) { printLine2ClearAndUpdate(); } -int btnDownTimeCount; +unsigned int btnDownTimeCount; + +#define PRESS_ADJUST_TUNE 1000 +#define PRESS_LOCK_CONTROL 2000 void doMenu(){ int select=0, i,btnState; + char isNeedDisplay = 0; //for DialLock On/Off function btnDownTimeCount = 0; //wait for the button to be raised up + + //Appened Lines by KD8CEC for Adjust Tune step and Set Dial lock while(btnDown()){ delay(50); Check_Cat(0); //To prevent disconnections - //btnDownTimeCount++; - //check long time Down Button -> 3 Second - if (btnDownTimeCount++ > (2000 / 50)) { + if (btnDownTimeCount++ == (PRESS_ADJUST_TUNE / 50)) { //Set Tune Step + printLineF2(F("Set Tune Step?")); + } + else if (btnDownTimeCount > (PRESS_LOCK_CONTROL / 50)) { //check long time Down Button -> 2.5 Second => Lock if (vfoActive == VFO_A) setDialLock((isDialLock & 0x01) == 0x01 ? 0 : 1, 0); //Reverse Dial lock else @@ -781,6 +774,55 @@ void doMenu(){ } delay(50); //debounce + //ADJUST TUNE STEP + if (btnDownTimeCount > (PRESS_ADJUST_TUNE / 50)) + { + printLineF1(F("Press Key to set")); + isNeedDisplay = 1; //check to need display for display current value + + while (digitalRead(PTT) == HIGH && !btnDown()) + { + Check_Cat(0); //To prevent disconnections + delay(50); //debounce + + if (isNeedDisplay) { + strcpy(b, "Tune Step:"); + itoa(arTuneStep[tuneStepIndex -1], c, 10); + strcat(b, c); + printLine2(b); + isNeedDisplay = 0; + } + + i = enc_read(); + + if (i != 0) { + select += (i > 0 ? 1 : -1); + + if (select * select >= 25) { //Threshold 5 * 5 = 25 + if (select < 0) { + if (tuneStepIndex > 1) + tuneStepIndex--; + } + else { + if (tuneStepIndex < 5) + tuneStepIndex++; + } + select = 0; + isNeedDisplay = 1; + } + } + } //end of while + + printLineF2(F("Changed Step!")); + //SAVE EEPROM + EEPROM.put(TUNING_STEP, tuneStepIndex); + delay_background(500, 0); + printLine2ClearAndUpdate(); + return; + } //set tune step + + //Below codes are origial code with modified by KD8CEC + //Select menu menuOn = 2; while (menuOn){ @@ -793,10 +835,13 @@ void doMenu(){ if (!modeCalibrate && select + i < 80) select += i; } - if (i < 0 && select - i >= 0) + //if (i < 0 && select - i >= 0) + if (i < 0 && select - i >= -10) select += i; //caught ya, i is already -ve here, so you add it - if (select < 10) + if (select < -5) + menuExit(btnState); + else if (select < 10) menuBand(btnState); else if (select < 20) menuRitToggle(btnState);