From 1aa9ce1bd6c5e28515bac891a94f4871a283e13a Mon Sep 17 00:00:00 2001 From: Rob French Date: Sun, 3 May 2020 23:04:02 -0500 Subject: [PATCH] In theory, the code has now been modified to allow CW transmission when used with the IOP. However, at the moment, there is no way to put the IOP into CW mode. Intended behavior: PTT/Key in SSB = transmit (PTT) PTT/Key in CW = key down --- ubitx_20/ubitx_20.ino | 48 ++++++-- ubitx_20/ubitx_keyer.ino | 240 ++++++++++++++++++++++----------------- 2 files changed, 178 insertions(+), 110 deletions(-) diff --git a/ubitx_20/ubitx_20.ino b/ubitx_20/ubitx_20.ino index 2066939..c78da97 100644 --- a/ubitx_20/ubitx_20.ino +++ b/ubitx_20/ubitx_20.ino @@ -316,6 +316,17 @@ unsigned long delayBeforeTime = 0; byte delay_background(unsigned delayTime, byte fromType){ //fromType : 4 autoCWKey -> Check Paddle delayBeforeTime = millis(); + /* + * KC4UPR - IOP review, 2020-05-03 + * + * I don't see anything in here that is either important to, or will adversely affect, IOP + * operation. I'm not planning on using the uBITX autokeyer (since all keying will be in the + * IOP), so neither getPaddle() nor autoSendPTTCheck() will be issues. I do need to look into + * overall CAT operation, in general. + * + * UPDATE: Fixed getPaddle() to be compatible. + */ + while (millis() - delayBeforeTime <= delayTime) { if (fromType == 4) @@ -678,6 +689,10 @@ void ritDisable(){ */ void checkPTT(){ + /* + * KC4UPR - note that some of this is superfluous now that checkPTT() is only executed + * in SSB mode, and cwKeyer is only executed in CW mode... + */ //we don't check for ptt when transmitting cw if (cwTimeout > 0) return; @@ -1459,15 +1474,34 @@ void checkAutoSaveFreqMode() } void loop(){ - if (isCWAutoMode == 0){ //when CW AutoKey Mode, disable this process - if (!txCAT) + /* + * KC4UPR - IOP update, 2020-05-03 + * + * Getting rid of the autokeyer code... not planning on using, since any autokeying + * would actually be done by the IOP. We'll check the PTT, but only in SSB mode + * (same line as CW, so it would be caught by cwKeyer() in CW mode). + * + * Only check the CW keyer if we are in one of the CW modes. Why? Because we + * are using the same input for PTT and CW. + */ +// if (isCWAutoMode == 0){ //when CW AutoKey Mode, disable this process +// if (!txCAT) +// checkPTT(); +// checkButton(); +// } +// else +// controlAutoCW(); + // KC4UPR: Note, implementation below leaves no manual way to abort TX due to CAT. May + // want to add in a way to interrupt CAT transmission with a PTT/CW event. + if (!txCAT) { + if (cwMode == 0) checkPTT(); - checkButton(); + else + cwKeyer(); + checkButton(); } - else - controlAutoCW(); - - cwKeyer(); + +//cwKeyer(); //tune only when not tranmsitting if (!inTx){ diff --git a/ubitx_20/ubitx_keyer.ino b/ubitx_20/ubitx_keyer.ino index c38d2e3..691b1d0 100644 --- a/ubitx_20/ubitx_keyer.ino +++ b/ubitx_20/ubitx_keyer.ino @@ -39,6 +39,22 @@ char lastPaddle = 0; //reads the analog keyer pin and reports the paddle byte getPaddle(){ + /* + * KC4UPR - IOP update, 2020-05-03 + * + * Modifying this for the uBITX IOP. Big picture: + * + * (1) It uses the PTT input line. + * + * (2) It's always "straight key" mode (the IOP provides the keyer). + */ + + if (digitalRead(PTT) == 1) // key/PTT is up + return 0; + else + return PADDLE_STRAIGHT; + +/* int paddle = analogRead(ANALOG_KEYER); if (paddle > 800) // above 4v is up @@ -52,6 +68,7 @@ byte getPaddle(){ return PADDLE_BOTH; //both are between 1 and 2v else return PADDLE_STRAIGHT; //less than 1v is the straight key +*/ } /** @@ -96,11 +113,20 @@ unsigned char keyerState = IDLE; //Below is a test to reduce the keying error. do not delete lines //create by KD8CEC for compatible with new CW Logic char update_PaddleLatch(byte isUpdateKeyState) { + /* + * KC4UPR - IOP update, 2020-05-03 + * + * Modifying this for the uBITX IOP. Big picture: + * + * No iambic keyer. It's always "straight key" based on the IOP. + * + * It uses the PTT line. + */ + return (digitalRead(PTT) ? 0 : DIT_L); +/* unsigned char tmpKeyerControl = 0; int paddle = analogRead(ANALOG_KEYER); - return 0; // KC4UPR: temporarily disabling keyer while doing ubitx_iop development. - if (paddle >= cwAdcDashFrom && paddle <= cwAdcDashTo) tmpKeyerControl |= DAH_L; else if (paddle >= cwAdcDotFrom && paddle <= cwAdcDotTo) @@ -121,6 +147,7 @@ char update_PaddleLatch(byte isUpdateKeyState) { keyerControl |= tmpKeyerControl; return tmpKeyerControl; +*/ } /***************************************************************************** @@ -128,106 +155,113 @@ char update_PaddleLatch(byte isUpdateKeyState) { // modified by KD8CEC ******************************************************************************/ void cwKeyer(void){ - lastPaddle = 0; - 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)) { - 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: - //modified KD8CEC - /* - ktimer += millis(); // set ktimer to interval end time - keyerControl &= ~(DIT_L + DAH_L); // clear both paddle latch bits - keyerState = KEYED; // next state - if (!inTx){ - //DelayTime Option - delay_background(delayBeforeCWStartTime * 2, 2); - - keyDown = 0; - cwTimeout = millis() + cwDelayTime * 10; //+ CW_TIMEOUT; - startTx(TX_CW, 1); - } - */ - if (!inTx){ - //DelayTime Option - delay_background(delayBeforeCWStartTime * 2, 2); - - keyDown = 0; - cwTimeout = millis() + cwDelayTime * 10; //+ CW_TIMEOUT; - startTx(TX_CW, 1); - } - ktimer += millis(); // set ktimer to interval end time - keyerControl &= ~(DIT_L + DAH_L); // clear both paddle latch bits - keyerState = KEYED; // next state - - 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; - } - - Check_Cat(2); - } //end of while - } - else{ + /* + * KC4UPR - IOP update, 2020-05-03 + * + * Modifying this for the uBITX IOP. Big picture: + * + * No iambic keyer. It's always "straight key" based on the IOP. + */ +// lastPaddle = 0; +// 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)) { +// 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: +// //modified KD8CEC +// /* +// ktimer += millis(); // set ktimer to interval end time +// keyerControl &= ~(DIT_L + DAH_L); // clear both paddle latch bits +// keyerState = KEYED; // next state +// if (!inTx){ +// //DelayTime Option +// delay_background(delayBeforeCWStartTime * 2, 2); +// +// keyDown = 0; +// cwTimeout = millis() + cwDelayTime * 10; //+ CW_TIMEOUT; +// startTx(TX_CW, 1); +// } +// */ +// if (!inTx){ +// //DelayTime Option +// delay_background(delayBeforeCWStartTime * 2, 2); +// +// keyDown = 0; +// cwTimeout = millis() + cwDelayTime * 10; //+ CW_TIMEOUT; +// startTx(TX_CW, 1); +// } +// ktimer += millis(); // set ktimer to interval end time +// keyerControl &= ~(DIT_L + DAH_L); // clear both paddle latch bits +// keyerState = KEYED; // next state +// +// 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; +// } +// +// Check_Cat(2); +// } //end of while +// } +// else{ while(1){ if (update_PaddleLatch(0) == DIT_L) { // if we are here, it is only because the key is pressed @@ -264,7 +298,7 @@ void cwKeyer(void){ Check_Cat(2); } //end of while - } //end of elese +// } //end of elese }