This commit is contained in:
phdlee 2018-01-10 10:59:03 +09:00
parent a75326cb2e
commit 16f5ba3518
6 changed files with 605 additions and 220 deletions

View File

@ -34,7 +34,7 @@
#define printLineF2(x) (printLineF(0, x))
//for broken protocol
#define MAX_PROTOCOL_SKIP_COUNT 200
#define CAT_RECEIVE_TIMEOUT 500
#define CAT_MODE_LSB 0x00
#define CAT_MODE_USB 0x01
@ -156,7 +156,14 @@ void CatSetPTT(boolean isPTTOn, byte fromType)
if (!inTx)
{
txCAT = true;
startTx(TX_SSB, 1);
//Exit menu, Memory Keyer... ETC
if (isCWAutoMode > 0) {
isCWAutoMode = 0;
printLineF2(F("AutoKey Exit/CAT"));
//delay_background(1000, 0);
}
}
}
else
@ -206,8 +213,51 @@ void CatSetMode(byte tmpMode, byte fromType)
Serial.write(ACK);
}
//Read EEProm by uBITX Manager Software
void ReadEEPRom(byte fromType)
{
//5BYTES
//CAT_BUFF[0] [1] [2] [3] [4] //4 COMMAND
//0, 1 START ADDRESS
uint16_t eepromStartIndex = CAT_BUFF[0] + CAT_BUFF[1] * 256;
uint16_t eepromReadLength = CAT_BUFF[2] + CAT_BUFF[3] * 256;;
byte checkSum = 0;
byte read1Byte = 0;
Serial.write(0x02); //STX
checkSum = 0x02;
for (uint16_t i = 0; i < eepromReadLength; i++)
{
read1Byte = EEPROM.read(eepromStartIndex + i);
checkSum += read1Byte;
Serial.write(read1Byte);
}
Serial.write(checkSum);
Serial.write(ACK);
}
//Write just proecess 1byes
void WriteEEPRom(byte fromType)
{
//5BYTES
uint16_t eepromStartIndex = CAT_BUFF[0] + CAT_BUFF[1] * 256;
byte write1Byte = CAT_BUFF[2];
//Check Checksum
if (CAT_BUFF[3] != ((CAT_BUFF[0] + CAT_BUFF[1] + CAT_BUFF[2]) % 256))
{
Serial.write(0x56); //CHECK SUM ERROR
Serial.write(ACK);
}
else
{
EEPROM.write(eepromStartIndex, write1Byte);
Serial.write(0x77); //OK
Serial.write(ACK);
}
}
void ReadEEPRom_FT817(byte fromType)
{
byte temp0 = CAT_BUFF[0];
byte temp1 = CAT_BUFF[1];
@ -346,7 +396,7 @@ void ReadEEPRom(byte fromType)
SendCatData(2);
}
void WriteEEPRom(byte fromType)
void WriteEEPRom_FT817(byte fromType)
{
byte temp0 = CAT_BUFF[0];
byte temp1 = CAT_BUFF[1];
@ -558,12 +608,13 @@ void CatTxStatus(byte fromType)
SendCatData(1);
}
unsigned int skiptimeCount = 0;
unsigned long rxBufferArriveTime = 0;
byte rxBufferCheckCount = 0;
//Prevent Stack Overflow
byte isProcessCheck_Cat = 0;
//fromType normal : 0, TX : 1, CW_STRAIGHT : 2, CW_PADDLE : 3
//fromType normal : 0, TX : 1, CW_STRAIGHT : 2, CW_PADDLE : 3, CW_AUTOMODE : 4
//if cw mode, no delay
void Check_Cat(byte fromType)
{
@ -572,23 +623,31 @@ void Check_Cat(byte fromType)
//Check Serial Port Buffer
if (Serial.available() == 0)
{
skipTimeCount = 0; //Init skipTimeCount for broken protocol
//Set Buffer Clear status
rxBufferCheckCount = 0;
return;
}
else if (Serial.available() < 5)
{
/*
//if Broken Protocol, Reset Buffer
//when TX mode very fast count because stkip dial check, button check functions
if ((fromType == 0 && ++skiptimeCount > MAX_PROTOCOL_SKIP_COUNT) ||
((fromType == 1 || 2) && ++skiptimeCount > MAX_PROTOCOL_SKIP_COUNT * 70) )
//First Arrived
if (rxBufferCheckCount == 0)
{
rxBufferCheckCount = Serial.available();
rxBufferArriveTime = millis() + CAT_RECEIVE_TIMEOUT; //Set time for timeout
}
else if (rxBufferArriveTime < millis()) //timeout
{
//Clear Buffer
for (i = 0; i < Serial.available(); i++)
CAT_BUFF[0] = Serial.read();
skipTimeCount = 0; //Init skipTimeCount for broken protocol
rxBufferCheckCount = Serial.read();
rxBufferCheckCount = 0;
}
else if (rxBufferCheckCount < Serial.available()) //increase buffer count, slow arrived
{
rxBufferCheckCount = Serial.available();
rxBufferArriveTime = millis() + CAT_RECEIVE_TIMEOUT; //Set time for timeout
}
*/
return;
}
@ -655,13 +714,17 @@ void Check_Cat(byte fromType)
break;
case 0xDB: //Read uBITX EEPROM Data
ReadEEPRom(fromType); //Call by uBITX Manager Program
break;
case 0xBB: //Read FT-817 EEPROM Data (for comfirtable)
ReadEEPRom(fromType);
ReadEEPRom_FT817(fromType);
break;
case 0xDC: //Write uBITX EEPROM Data
WriteEEPRom(fromType); //Call by uBITX Manager Program
break;
case 0xBC: //Write FT-817 EEPROM Data (for comfirtable)
WriteEEPRom(fromType);
WriteEEPRom_FT817(fromType);
break;
case 0xE7 : //Read RX Status

View File

@ -1,11 +1,18 @@
/*************************************************************************
This source code is written for uBITX, but it can also be used on other radios.
To minimize the use of memory space, we used bitwise operations.
For the alphabet, I put Morsecode in 1 byte. The front 4Bit is the length and the 4Bit is the Morse code.
Because the number is fixed in length, there is no separate length information. The 5Bit on the right side is the Morse code.
This source code is written for All amateur radio operator,
I have not had amateur radio communication for a long time. CW has been
around for a long time, and I do not know what kind of keyer and keying
software is fashionable. So I implemented the functions I need mainly.
If you exclude the '$' symbol, can put Length information to cwSymbolTable like Alphabet. Currently, it consumes 18 bytes to store Length.
by KD8CEC
To minimize the use of memory space, we used bitwise operations.
For the alphabet, I put Morsecode in 1 byte. The front 4Bit is the length
and the 4Bit is the Morse code. Because the number is fixed in length,
there is no separate length information. The 5Bit on the right side is
the Morse code.
I wrote this code myself, so there is no license restriction.
So this code allows anyone to write with confidence.
But keep it as long as the original author of the code.
-----------------------------------------------------------------------------
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -32,21 +39,141 @@ PGM_P pCwAZTable = reinterpret_cast<PGM_P>(cwAZTable);
const PROGMEM uint8_t cw09Table[27] = {0b00011111, 0b00001111, 0b00000111, 0b00000011, 0b00000001, 0b00000000, 0b00010000, 0b00011000, 0b00011100, 0b00011110};
PGM_P pcw09Table = reinterpret_cast<PGM_P>(cw09Table);
const PROGMEM uint8_t cwSymbolIndex[] = {'.', ',', '?', '"', '!', '/', '(', ')', '&', ':', ';', '=', '+', '-', '_', '\'', '@' };
//# : AR, ~:BT, [:AS, ]:SK, ^:KN
const PROGMEM uint8_t cwSymbolIndex[] = {'.', ',', '?', '"', '!', '/', '(', ')', '&', ':', ';', '=', '+', '-', '_', '\'', '@', '#', '~', '[', ']', '^' };
PGM_P pCwSymbolIndex = reinterpret_cast<PGM_P>(cwSymbolIndex);
const PROGMEM uint8_t cwSymbolTable[] = {0b11010101, 0b11110011, 0b11001100, 0b11011110, 0b11101011, 0b10100100, 0b10101100, 0b11101101, 0b10010000, 0b11111000, 0b11101010, 0b10100010, 0b10010100, 0b11100001, 0b11001101, 0b11010010, 0b11011010};
const PROGMEM uint8_t cwSymbolTable[] = {0b11010101, 0b11110011, 0b11001100, 0b11011110, 0b11101011, 0b10100100, 0b10101100, 0b11101101, 0b10010000, 0b11111000, 0b11101010, 0b10100010, 0b10010100, 0b11100001, 0b11001101, 0b11010010, 0b11011010, 0b10010100, 0b10100010, 0b10010000, 0b11000101, 0b10101100};
PGM_P pCwSymbolTable = reinterpret_cast<PGM_P>(cwSymbolTable);
////const PROGMEM uint8_t cwSymbolLength[] = {6, 6, 6, 6, 6, 5, 5, 6, 5, 6, 6, 5, 5, 6, 6, 6, 6};
////const PROGMEM uint8_t cwSymbolLength[] = {6, 6, 6, 6, 6, 5, 5, 6, 5, 6, 6, 5, 5, 6, 6, 6, 6, 5, 5, 5, 6, 5};
// ":(Start"), ':(End "), >: My callsign, <:QSO Callsign (Second Callsign), #:AR, ~:BT, [:AS, ]:SK
byte knobPosition = 0;
//byte cwTextData[30]; //Maximum 30 Remarked by KD8CE -> Direct Read EEPROM
byte autoCWSendCharEndIndex = 0;
byte autoCWSendCharIndex = 0;
unsigned long autoCWbeforeTime = 0; //for interval time between chars
byte pttBeforeStatus = 1; //PTT : default high
byte isKeyStatusAfterCWStart = 0; //0 : Init, 1 : Keyup after auto CW Start, 2 : Keydown after
byte selectedCWTextIndex = 0;
unsigned long autoCWKeydownCheckTime = 0; //for interval time between chars
byte changeReserveStatus = 0;
byte isAutoCWHold = 0; //auto CW Pause => Manual Keying => auto
void autoSendPTTCheck()
{
if (isCWAutoMode == 2) { //Sending Mode
//check PTT Button
//short Press => reservation or cancel
//long Press => Hold
if (digitalRead(PTT) == LOW)
{
//if (isKeyStatusAfterCWStart == 0) //Yet Press PTT from start TX
//{
//}
if (isKeyStatusAfterCWStart == 1) //while auto cw send, ptt up and ptt down again
{
//Start Time
autoCWKeydownCheckTime = millis() + 200; //Long push time
isKeyStatusAfterCWStart = 2; //Change status => ptt down agian
}
else if (isKeyStatusAfterCWStart == 2 && autoCWKeydownCheckTime < millis())
{
//Hold Mode
isAutoCWHold = 1;
isKeyStatusAfterCWStart = 3;
}
else if (isKeyStatusAfterCWStart == 3)
{
autoCWKeydownCheckTime = millis() + 200;
}
}
else
{
//PTT UP
if (isKeyStatusAfterCWStart == 2) //0 (down before cw start) -> 1 (up while cw sending) -> 2 (down while cw sending)
{
if (autoCWKeydownCheckTime > millis()) //Short : Reservation or cancel Next Text
{
if (autoCWSendReservCount == 0 ||
(autoCWSendReservCount < AUTO_CW_RESERVE_MAX &&
autoCWSendReserv[autoCWSendReservCount - 1] != selectedCWTextIndex))
{
//Reserve
autoCWSendReserv[autoCWSendReservCount++] = selectedCWTextIndex;
changeReserveStatus = 1;
}
else if (autoCWSendReservCount > 0 && autoCWSendReserv[autoCWSendReservCount - 1] == selectedCWTextIndex)
{
autoCWSendReservCount--;
changeReserveStatus = 1;
}
} // end of Short Key up
}
else if (isKeyStatusAfterCWStart == 3) //play from Hold (pause Auto CW Send)
{
isAutoCWHold = 0;
}
isKeyStatusAfterCWStart = 1; //Change status => ptt up (while cw send mode)
} //end of PTT UP
}
}
//Send 1 char
void sendCWChar(char cwKeyChar)
{
byte sendBuff[7];
byte i, j, charLength;
byte tmpChar;
//Encode Char by KD8CEC
if (cwKeyChar >= 'A' && cwKeyChar <= 'Z')
//For Macrofunction
//replace > and < to My callsign, qso callsign, use recursive function call
if (cwKeyChar == '>' || cwKeyChar == '<')
{
uint16_t callsignStartIndex = 0;
uint16_t callsignEndIndex = 0;
if (cwKeyChar == '>') //replace my callsign
{
if (userCallsignLength > 0)
{
callsignStartIndex = 0;
callsignEndIndex = userCallsignLength;
}
}
else if (cwKeyChar == '<') //replace qso callsign
{
//ReadLength
callsignEndIndex = EEPROM.read(CW_STATION_LEN);
if (callsignEndIndex > 0)
{
callsignStartIndex = CW_STATION_LEN - callsignEndIndex - USER_CALLSIGN_DAT;
callsignEndIndex = callsignStartIndex + callsignEndIndex;
}
}
if (callsignStartIndex == 0 && callsignEndIndex == 0)
return;
for (uint16_t i = callsignStartIndex; i <= callsignEndIndex; i++)
{
sendCWChar(EEPROM.read(USER_CALLSIGN_DAT + i));
autoSendPTTCheck(); //for reserve and cancel next CW Text
if (changeReserveStatus == 1)
{
changeReserveStatus = 0;
updateDisplay();
}
if (i < callsignEndIndex) delay_background(cwSpeed * 3, 4); //
}
return;
}
else if (cwKeyChar >= 'A' && cwKeyChar <= 'Z') //Encode Char by KD8CEC
{
tmpChar = pgm_read_byte(pCwAZTable + (cwKeyChar - 'A'));
charLength = (tmpChar >> 4) & 0x0F;
@ -61,7 +188,8 @@ void sendCWChar(char cwKeyChar)
}
else if (cwKeyChar == ' ')
{
delay_background(cwSpeed * 7, 3);
charLength = 0;
delay_background(cwSpeed * 4, 4); //7 -> basic interval is 3
}
else if (cwKeyChar == '$') //7 digit
{
@ -72,7 +200,7 @@ void sendCWChar(char cwKeyChar)
else
{
//symbol
for (i = 0; i < 17; i++)
for (i = 0; i < 22; i++)
{
if (pgm_read_byte(pCwSymbolIndex + i) == cwKeyChar)
{
@ -91,15 +219,16 @@ void sendCWChar(char cwKeyChar)
{
cwKeydown();
if (sendBuff[i] == 0)
delay_background(cwSpeed, 3);
delay_background(cwSpeed, 4);
else
delay_background(cwSpeed * 3, 3);
delay_background(cwSpeed * 3, 4);
cwKeyUp();
if (i != charLength -1)
delay_background(cwSpeed, 3);
delay_background(cwSpeed, 4);
}
}
/*
void sendAutoCW(int cwSendLength, char *sendString)
{
byte i;
@ -109,6 +238,8 @@ void sendAutoCW(int cwSendLength, char *sendString)
cwTimeout = millis() + cwDelayTime * 10;
startTx(TX_CW, 0); //disable updateDisplay Command for reduce latency time
updateDisplay();
delay_background(delayBeforeCWStartTime * 2, 2);
}
for (i = 0; i < cwSendLength; i++)
@ -120,4 +251,156 @@ void sendAutoCW(int cwSendLength, char *sendString)
delay_background(cwDelayTime * 10, 2);
stopTx();
}
*/
byte isNeedScroll = 0;
unsigned long scrollDispayTime = 0;
#define scrollSpeed 500
byte displayScrolStep = 0;
int controlAutoCW(){
int knob = 0;
byte i;
byte cwStartIndex, cwEndIndex;
if (cwAutoDialType == 0)
knob = enc_read();
if (knob != 0 || beforeCWTextIndex == 255 || isNeedScroll == 1){ //start display
if (knobPosition > 0 && knob < 0)
knobPosition--;
if (knobPosition < cwAutoTextCount * 10 -1 && knob > 0)
knobPosition++;
selectedCWTextIndex = knobPosition / 10;
if ((beforeCWTextIndex != selectedCWTextIndex) ||
(isNeedScroll == 1 && beforeCWTextIndex == selectedCWTextIndex && scrollDispayTime < millis())) {
//Read CW Text Data Position From EEProm
EEPROM.get(CW_AUTO_DATA + (selectedCWTextIndex * 2), cwStartIndex);
EEPROM.get(CW_AUTO_DATA + (selectedCWTextIndex * 2 + 1), cwEndIndex);
if (beforeCWTextIndex == selectedCWTextIndex)
{
if (++displayScrolStep > cwEndIndex - cwStartIndex)
displayScrolStep = 0;
}
else
{
displayScrolStep = 0;
}
printLineFromEEPRom(0, 2, cwStartIndex + displayScrolStep + CW_DATA_OFSTADJ, cwEndIndex + CW_DATA_OFSTADJ);
lcd.setCursor(0,0);
lcd.write(byteToChar(selectedCWTextIndex));
lcd.write(':');
isNeedScroll = (cwEndIndex - cwStartIndex) > 14 ? 1 : 0;
scrollDispayTime = millis() + scrollSpeed;
beforeCWTextIndex = selectedCWTextIndex;
}
} //end of check knob
if (isCWAutoMode == 1) { //ready status
if (digitalRead(PTT) == LOW) //PTT Down : Start Auto CW or DialMode Change
{
if (pttBeforeStatus == 1) //High to Low Change
{
autoCWbeforeTime = millis() + 500; //Long push time
pttBeforeStatus = 0;
}
else if (autoCWbeforeTime < millis()) //while press PTT, OK Long push then Send Auto CW Text
{
sendingCWTextIndex = selectedCWTextIndex;
//Information about Auto Send CW Text
autoCWSendCharEndIndex = cwEndIndex; //length of CW Text //ianlee
autoCWSendCharIndex = cwStartIndex; //position of Sending Char //ianlee
isCWAutoMode = 2; //auto sending start
autoCWbeforeTime = 0; //interval between chars, 0 = always send
isKeyStatusAfterCWStart = 0; //Init PTT Key status
autoCWSendReservCount = 0; //Init Reserve Count
isAutoCWHold = 0;
if (!inTx){ //if not TX Status, change RX -> TX
keyDown = 0;
startTx(TX_CW, 0); //disable updateDisplay Command for reduce latency time
updateDisplay();
delay_background(delayBeforeCWStartTime * 2, 2); //for External AMP or personal situation
}
}
}
else if (pttBeforeStatus == 0 && autoCWbeforeTime > 0) //while reade status LOW -> HIGH (before Auto send Before)
{
pttBeforeStatus = 1; //HIGH
if (autoCWbeforeTime > millis()) //short Press -> ? DialModeChange
{
cwAutoDialType = (cwAutoDialType == 1 ? 0 : 1); //Invert DialMode between select CW Text and Frequency Tune
if (cwAutoDialType == 0)
printLineF1(F("Dial:Select Text"));
else
printLineF1(F("Dial:Freq Tune"));
delay_background(1000, 0);
updateDisplay();
}
}
} //end of isCWAutoMode == 1 condition
if (isCWAutoMode == 2) { //Sending Mode
autoSendPTTCheck();
//check interval time, if you want adjust interval between chars, modify below
if (isAutoCWHold == 0 && (millis() - autoCWbeforeTime > cwSpeed * 3))
{
sendCWChar(EEPROM.read(CW_AUTO_DATA + autoCWSendCharIndex++));
if (autoCWSendCharIndex > autoCWSendCharEndIndex) { //finish auto cw send
//check reserve status
if (autoCWSendReservCount > 0)
{
//prepare
sendingCWTextIndex = autoCWSendReserv[0];
for (i = 0; i < AUTO_CW_RESERVE_MAX -1; i++)
autoCWSendReserv[i] = autoCWSendReserv[i + 1];
EEPROM.get(CW_AUTO_DATA + (sendingCWTextIndex * 2), cwStartIndex);
EEPROM.get(CW_AUTO_DATA + (sendingCWTextIndex * 2 + 1), cwEndIndex);
//Information about Auto Send CW Text
autoCWSendCharEndIndex = cwEndIndex; //length of CW Text //ianlee
autoCWSendCharIndex = cwStartIndex; //position of Sending Char //ianlee
autoCWSendReservCount--; //Decrease
sendCWChar(' '); //APPLY SPACE between CW Texts
changeReserveStatus = 1;
}
else
{
isCWAutoMode = 1; //ready status
delay_background(cwDelayTime * 10, 2);
stopTx();
}
}
autoCWbeforeTime = millis();
if (changeReserveStatus == 1)
{
changeReserveStatus = 0;
updateDisplay();
}
}
}
//abort if this button is down
if (btnDown())
{
isCWAutoMode = 0; //dsiable Auto CW Mode
printLine2ClearAndUpdate();
delay_background(1000, 0);
}
}

View File

@ -96,6 +96,8 @@
#include <LiquidCrystal.h>
LiquidCrystal lcd(8,9,10,11,12,13);
#define VERSION_NUM 0x01 //for KD8CEC'S firmware and for memory management software
/**
* The Arduino, unlike C/C++ on a regular computer with gigabytes of RAM, has very little memory.
* We have to be very careful with variables that are declared inside the functions as they are
@ -147,11 +149,20 @@ int count = 0; //to generally count ticks, loops, etc
#define CW_DELAY 258
#define CW_START 259
//
#define VERSION_ADDRESS 779 //check Firmware version
//USER INFORMATION
#define USER_CALLSIGN_KEY 780 //0x59
#define USER_CALLSIGN_LEN 781 //1BYTE (OPTION + LENGTH) + CALLSIGN (MAXIMUM 18)
#define USER_CALLSIGN_DAT 782 //CALL SIGN DATA //direct EEPROM to LCD basic offset
//AUTO KEY STRUCTURE
//AUTO KEY USE 800 ~ 1023
#define CW_AUTO_MAGIC_KEY 800 //0x73
#define CW_AUTO_COUNT 801 //0 ~ 255
#define CW_AUTO_DATA 803 //
#define CW_AUTO_DATA 803 //[INDEX, INDEX, INDEX,DATA,DATA, DATA (Positon offset is CW_AUTO_DATA
#define CW_DATA_OFSTADJ CW_AUTO_DATA - USER_CALLSIGN_DAT //offset adjust for ditect eeprom to lcd (basic offset is USER_CALLSIGN_DAT
#define CW_STATION_LEN 1023 //value range : 4 ~ 30
/**
* The uBITX is an upconnversion transceiver. The first IF is at 45 MHz.
* The first IF frequency is not exactly at 45 Mhz but about 5 khz lower,
@ -220,6 +231,18 @@ byte sideToneSub = 0;
byte isDialLock = 0;
byte isTxOff = 0;
//Variables for auto cw mode
byte isCWAutoMode = 0; //0 : none, 1 : CW_AutoMode_Menu_Selection, 2 : CW_AutoMode Sending
byte cwAutoTextCount = 0; //cwAutoText Count
byte beforeCWTextIndex = 255; //when auto cw start, always beforeCWTextIndex = 255, (for first time check)
byte cwAutoDialType = 0; //0 : CW Text Change, 1 : Frequency Tune
#define AUTO_CW_RESERVE_MAX 3
byte autoCWSendReserv[AUTO_CW_RESERVE_MAX]; //Reserve CW Auto Send
byte autoCWSendReservCount = 0; //Reserve CW Text Cound
byte sendingCWTextIndex = 0; //cw auto seding Text Index
byte userCallsignLength = 0; //7 : display callsign at system startup, 6~0 : callsign length (range : 1~18)
/**
* Raduino needs to keep track of current state of the transceiver. These are a few variables that do it
@ -249,13 +272,30 @@ boolean modeCalibrate = false;//this mode of menus shows extended menus to calib
*/
unsigned long delayBeforeTime = 0;
void delay_background(unsigned delayTime, byte fromType){
byte delay_background(unsigned delayTime, byte fromType){ //fromType : 4 autoCWKey -> Check Paddle
delayBeforeTime = millis();
while (millis() <= delayBeforeTime + delayTime) {
//Background Work
Check_Cat(fromType);
if (fromType == 4)
{
//CHECK PADDLE
if (getPaddle() != 0) //Interrupt : Stop cw Auto mode by Paddle -> Change Auto to Manual
return 1;
//Check PTT while auto Sending
autoSendPTTCheck();
Check_Cat(3);
}
else
{
//Background Work
Check_Cat(fromType);
}
}
return 0;
}
@ -316,7 +356,7 @@ void setFrequency(unsigned long f){
uint64_t osc_f;
//1 digits discarded
f = (f / 10) * 10;
f = (f / 50) * 50;
setTXFilters(f);
@ -458,14 +498,15 @@ void checkButton(){
*/
void doTuning(){
int s;
int s = 0;
unsigned long prev_freq;
int incdecValue = 0;
if (isDialLock == 1)
return;
s = enc_read();
if (isCWAutoMode == 0 || cwAutoDialType == 1)
s = enc_read();
if (s){
prev_freq = frequency;
@ -587,6 +628,14 @@ void initSettings(){
//CW interval between TX and CW Start
EEPROM.get(CW_START, delayBeforeCWStartTime);
//User callsign information
if (EEPROM.read(USER_CALLSIGN_KEY) == 0x59)
userCallsignLength = EEPROM.read(USER_CALLSIGN_LEN); //MAXIMUM 18 LENGTH
//Version Write for Memory Management Software
if (EEPROM.read(VERSION_ADDRESS) != VERSION_NUM)
EEPROM.write(VERSION_ADDRESS, VERSION_NUM);
if (cwDelayTime < 1 || cwDelayTime > 250)
cwDelayTime = 60;
@ -598,7 +647,7 @@ void initSettings(){
vfoB_mode = 3;
if (usbCarrier > 12010000l || usbCarrier < 11990000l)
usbCarrier = 11997000l;
usbCarrier = 11995000l;
if (vfoA > 35000000l || 3500000l > vfoA) {
vfoA = 7150000l;
@ -666,27 +715,31 @@ void initPorts(){
void setup()
{
//Init EEProm for factory reset test
//Init EEProm for Fault EEProm TEST and Factory Reset
/*
for (int i = 0; i < 512; i++)
for (int i = 0; i < 1024; i++)
EEPROM.write(i, 0);
*/
//Serial.begin(9600);
lcd.begin(16, 2);
//we print this line so this shows up even if the raduino
//crashes later in the code
//printLine2("CEC V v0.24");
printLineF(0, F("CEC V v0.24"));
printLineF(0, F("CEC V v0.24"));
printLineF(1, F("uBITX v0.20"));
delay_background(500, 0);
printLine2("");
Init_Cat(38400, SERIAL_8N1);
initMeter(); //not used in this build
initSettings();
printLineF(1, F("CECBT v0.25"));
if (userCallsignLength > 0 && ((userCallsignLength & 0x80) == 0x80))
{
userCallsignLength = userCallsignLength & 0x7F;
printLineFromEEPRom(0, 0, 0, userCallsignLength -1); //eeprom to lcd use offset (USER_CALLSIGN_DAT)
}
else
{
printLineF(0, F("uBITX v0.20"));
delay_background(500, 0);
printLine2("");
}
initPorts();
initOscillators();
@ -704,11 +757,11 @@ void setup()
EEPROM.put(CW_AUTO_MAGIC_KEY, 0x73); //MAGIC KEY
EEPROM.put(CW_AUTO_COUNT, 3); //WORD COUNT
EEPROM.put(CW_AUTO_DATA + 0, 6); // 0 word begin postion / CQCQ TEST K
EEPROM.put(CW_AUTO_DATA + 1, 21); // 0 word end postion / CQCQ TEST K
EEPROM.put(CW_AUTO_DATA + 2, 22); //1 word begin position / LOL LOL
EEPROM.put(CW_AUTO_DATA + 3, 28); //1 word end position / LOL LOL
EEPROM.put(CW_AUTO_DATA + 4, 29); //2 word begin position / /?![]789
EEPROM.put(CW_AUTO_DATA + 5, 36); //2 word end position / /?![]789
EEPROM.put(CW_AUTO_DATA + 1, 33); // 0 word end postion / CQCQ TEST K
EEPROM.put(CW_AUTO_DATA + 2, 34); //1 word begin position / LOL LOL
EEPROM.put(CW_AUTO_DATA + 3, 40); //1 word end position / LOL LOL
EEPROM.put(CW_AUTO_DATA + 4, 41); //2 word begin position / /?![]789
EEPROM.put(CW_AUTO_DATA + 5, 48); //2 word end position / /?![]789
EEPROM.put(CW_AUTO_DATA + 6, 'C'); //
EEPROM.put(CW_AUTO_DATA + 7, 'Q'); //
@ -725,24 +778,66 @@ void setup()
EEPROM.put(CW_AUTO_DATA + 18, 'E'); //
EEPROM.put(CW_AUTO_DATA + 19, 'C'); //
EEPROM.put(CW_AUTO_DATA + 20, ' '); //
EEPROM.put(CW_AUTO_DATA + 21, 'K'); //
EEPROM.put(CW_AUTO_DATA + 21, 'E'); //
EEPROM.put(CW_AUTO_DATA + 22, 'M'); //
EEPROM.put(CW_AUTO_DATA + 23, '3'); //
EEPROM.put(CW_AUTO_DATA + 24, '7'); //
EEPROM.put(CW_AUTO_DATA + 25, ' '); //
EEPROM.put(CW_AUTO_DATA + 26, 'D'); //
EEPROM.put(CW_AUTO_DATA + 27, 'E'); //
EEPROM.put(CW_AUTO_DATA + 28, ' '); //
EEPROM.put(CW_AUTO_DATA + 29, 'C'); //
EEPROM.put(CW_AUTO_DATA + 30, 'E'); //
EEPROM.put(CW_AUTO_DATA + 31, 'C'); //
EEPROM.put(CW_AUTO_DATA + 32, ' '); //
EEPROM.put(CW_AUTO_DATA + 33, 'K'); //
*/
EEPROM.put(CW_AUTO_DATA + 22, 'H'); //
EEPROM.put(CW_AUTO_DATA + 23, 'I'); //
EEPROM.put(CW_AUTO_DATA + 24, ' '); //
EEPROM.put(CW_AUTO_DATA + 25, 'H'); //
EEPROM.put(CW_AUTO_DATA + 26, 'A'); //
EEPROM.put(CW_AUTO_DATA + 27, 'M'); //
EEPROM.put(CW_AUTO_DATA + 28, '!'); //
/*
EEPROM.put(CW_AUTO_DATA + 34, '<'); //
EEPROM.put(CW_AUTO_DATA + 35, ' '); //
EEPROM.put(CW_AUTO_DATA + 36, '>'); //
EEPROM.put(CW_AUTO_DATA + 37, ' '); //
EEPROM.put(CW_AUTO_DATA + 38, '7'); //
EEPROM.put(CW_AUTO_DATA + 39, '3'); //
EEPROM.put(CW_AUTO_DATA + 40, 'K'); //
EEPROM.put(CW_AUTO_DATA + 29, '/'); //
EEPROM.put(CW_AUTO_DATA + 30, '?'); //
EEPROM.put(CW_AUTO_DATA + 31, '!'); //
EEPROM.put(CW_AUTO_DATA + 32, '"'); // start "
EEPROM.put(CW_AUTO_DATA + 33, '\''); // end "
EEPROM.put(CW_AUTO_DATA + 34, '7'); //
EEPROM.put(CW_AUTO_DATA + 35, '8'); //
EEPROM.put(CW_AUTO_DATA + 36, '9'); //
EEPROM.put(CW_AUTO_DATA + 41, 'C'); //
EEPROM.put(CW_AUTO_DATA + 42, 'Q'); //
EEPROM.put(CW_AUTO_DATA + 43, ' '); //
EEPROM.put(CW_AUTO_DATA + 44, '>'); // start "
EEPROM.put(CW_AUTO_DATA + 45, ' '); // end "
EEPROM.put(CW_AUTO_DATA + 46, '>'); //
EEPROM.put(CW_AUTO_DATA + 47, ' '); //
EEPROM.put(CW_AUTO_DATA + 48, 'K'); //
*/
/*
//This is for auto key test2
//USER CALL SIGN
EEPROM.put(USER_CALLSIGN_KEY, 0x59); //MAGIC KEY
//EEPROM.put(USER_CALLSIGN_LEN, 10); //WORD COUNT
EEPROM.put(USER_CALLSIGN_LEN, 10 + 0x80); //WORD COUNT
EEPROM.put(USER_CALLSIGN_DAT + 1, 'K'); //
EEPROM.put(USER_CALLSIGN_DAT + 2, 'D'); //
EEPROM.put(USER_CALLSIGN_DAT + 3, '8'); //
EEPROM.put(USER_CALLSIGN_DAT + 4, 'C'); //
EEPROM.put(USER_CALLSIGN_DAT + 5, 'E'); //
EEPROM.put(USER_CALLSIGN_DAT + 6, 'C'); //
EEPROM.put(USER_CALLSIGN_DAT + 7, '/'); //
EEPROM.put(USER_CALLSIGN_DAT + 8, 'A'); //
EEPROM.put(USER_CALLSIGN_DAT + 9, 'B'); //
EEPROM.put(USER_CALLSIGN_DAT + 10, 'C'); //
//CW QSO CALLSIGN
EEPROM.put(CW_STATION_LEN, 6); //
EEPROM.put(CW_STATION_LEN - 6 + 0 , 'A'); //
EEPROM.put(CW_STATION_LEN - 6 + 1 , 'B'); //
EEPROM.put(CW_STATION_LEN - 6 + 2 , '1'); //
EEPROM.put(CW_STATION_LEN - 6 + 3 , 'C'); //
EEPROM.put(CW_STATION_LEN - 6 + 4 , 'D'); //
EEPROM.put(CW_STATION_LEN - 6 + 5 , 'E'); //
*/
}
@ -789,11 +884,16 @@ void checkAutoSaveFreqMode()
}
void loop(){
cwKeyer();
if (!txCAT)
checkPTT();
checkButton();
if (isCWAutoMode == 0){ //when CW AutoKey Mode, disable this process
if (!txCAT)
checkPTT();
checkButton();
}
else
controlAutoCW();
cwKeyer();
//tune only when not tranmsitting
if (!inTx){
if (ritOn)
@ -803,8 +903,6 @@ void loop(){
}
//we check CAT after the encoder as it might put the radio into TX
//checkCAT();
Check_Cat(inTx? 1 : 0);
checkAutoSaveFreqMode();
}

View File

@ -98,6 +98,10 @@ void cwKeyer(){
// do nothing if the paddle has not been touched, unless
// we are in the cw mode and we have timed out
if (!paddle){
//modifed by KD8CEC for auto CW Send
if (isCWAutoMode > 1) //if while auto cw sending, dont stop tx by paddle position
return;
if (0 < cwTimeout && cwTimeout < millis()){
cwTimeout = 0;
keyDown = 0;
@ -121,6 +125,11 @@ void cwKeyer(){
continue;
}
//if while auto cw send, stop auto cw
//but isAutoCWHold for Manual Keying with cwAutoSend
if (isCWAutoMode > 1 && isAutoCWHold == 0)
isCWAutoMode = 1; //read status
//Remoark Debug code / Serial Use by CAT Protocol
//Serial.print("paddle:");Serial.println(paddle);
// if we are here, it is only because the key or the paddle is pressed

View File

@ -124,9 +124,9 @@ void menuVfoToggle(int btn)
ritDisable();
updateDisplay();
//updateDisplay();
delay_background(500, 0);
printLine1Clear();
printLine2ClearAndUpdate();
//exit the menu
menuOn = 0;
}
@ -171,6 +171,7 @@ void menuSidebandToggle(int btn){
isUSB = true;
printLineF2(F("USB Selected"));
}
setFrequency(frequency);
delay_background(500, 0);
printLine2ClearAndUpdate();
menuOn = 0;
@ -291,27 +292,14 @@ int menuCWSpeed(int btn){
}
int menuCWAutoKey(int btn){
int knob = 0;
byte i;
byte cwAutoMagic = 0;
byte cwAutoTextCount = 0;
byte selectedTextIndex = 0;
byte beforeTextIndex = 255;
byte knobPosition = 0;
byte cwStartIndex, cwEndIndex;
byte cwTextData[30]; //Maximum 30
if (!btn){
printLineF2(F("CW AutoKey Mode?"));
return;
}
//Check CW_AUTO_MAGIC_KEY
EEPROM.get(CW_AUTO_MAGIC_KEY, cwAutoMagic);
//Check CW_AUTO_MAGIC_KEY and CW Text Count
EEPROM.get(CW_AUTO_COUNT, cwAutoTextCount);
if (cwAutoMagic != 0x73 || cwAutoTextCount < 1)
if (EEPROM.read(CW_AUTO_MAGIC_KEY) != 0x73 || cwAutoTextCount < 1)
{
printLineF2(F("Empty CW data"));
delay_background(2000, 0);
@ -321,59 +309,9 @@ int menuCWAutoKey(int btn){
printLineF1(F("Press PTT to Send"));
delay_background(500, 0);
updateDisplay();
//while(!btnDown() && digitalRead(PTT) == HIGH){
while (1 == 1) {
knob = enc_read();
if (knob != 0 || beforeTextIndex == 255){ //start display
if (knobPosition > 0 && knob < 0)
knobPosition--;
if (knobPosition < (cwAutoTextCount + 1)* 10 && knob > 0) //+1 is Exit Menu
knobPosition++;
selectedTextIndex = knobPosition / 10;
if (beforeTextIndex != selectedTextIndex) {
if (selectedTextIndex >= cwAutoTextCount)
{
printLine2("Exit ?");
}
else
{
//Read Data From EEProm
EEPROM.get(CW_AUTO_DATA + (selectedTextIndex * 2), cwStartIndex);
EEPROM.get(CW_AUTO_DATA + (selectedTextIndex * 2 + 1), cwEndIndex);
memset(cwTextData, 0, 30);
for (i = cwStartIndex; i <= cwEndIndex; i++)
cwTextData[i - cwStartIndex] = EEPROM.read(CW_AUTO_DATA + i);
printLine2(cwTextData);
}
beforeTextIndex != selectedTextIndex;
}
}
//send CW Text
if (digitalRead(PTT) == LOW){
if (selectedTextIndex >= cwAutoTextCount)
break;
else
sendAutoCW(cwEndIndex - cwStartIndex +1, cwTextData);
}
//abort if this button is down
if (btnDown())
//re-enable the clock1 and clock 2
break;
Check_Cat(0); //To prevent disconnections
}
printLine2ClearAndUpdate();
menuOn = 0;
beforeCWTextIndex = 255; //255 value is for start check
isCWAutoMode = 1;
menuOn = 0;
}
int menuSetupCwDelay(int btn){
@ -415,7 +353,7 @@ int menuSetupCwDelay(int btn){
//save the setting
if (digitalRead(PTT) == LOW){
printLine2("CW Delay set!");
printLineF2(F("CW Delay set!"));
cwDelayTime = tmpCWDelay / 10;
EEPROM.put(CW_DELAY, cwDelayTime);
delay_background(2000, 0);
@ -434,7 +372,7 @@ int menuSetupTXCWInterval(int btn){
return;
}
printLine1("Press PTT to set");
printLineF1(F("Press PTT to set"));
strcpy(b, "Start Delay:");
itoa(tmpTXCWInterval,c, 10);
strcat(b, c);
@ -463,7 +401,7 @@ int menuSetupTXCWInterval(int btn){
//save the setting
if (digitalRead(PTT) == LOW){
printLine2("CW Start set!");
printLineF2(F("CW Start set!"));
delayBeforeCWStartTime = tmpTXCWInterval / 2;
EEPROM.put(CW_START, delayBeforeCWStartTime);
delay_background(2000, 0);
@ -498,7 +436,7 @@ int factoryCalibration(int btn){
delay(100);
if (!btn){
printLine2("Set Calibration?");
printLineF2(F("Set Calibration?"));
return 0;
}
@ -546,10 +484,10 @@ int factoryCalibration(int btn){
keyDown = 0;
stopTx();
printLine2("Calibration set!");
printLineF2(F("Calibration set!"));
EEPROM.put(MASTER_CAL, calibration);
initOscillators();
setFrequency(frequency);
setFrequency(frequency);
updateDisplay();
while(btnDown())
@ -562,12 +500,12 @@ int menuSetupCalibration(int btn){
int32_t prev_calibration;
if (!btn){
printLine2("Set Calibration?");
printLineF2(F("Set Calibration?"));
return 0;
}
printLine1("Set to Zero-beat,");
printLine2("press PTT to save");
printLineF1(F("Set to Zero-beat,"));
printLineF2(F("press PTT to save"));
delay_background(1000, 0);
prev_calibration = calibration;
@ -607,8 +545,8 @@ int menuSetupCalibration(int btn){
//save the setting
if (digitalRead(PTT) == LOW){
printLine1("Calibration set!");
printLine2("Set Carrier now");
printLineF1(F("Calibration set!"));
printLineF2(F("Set Carrier now"));
EEPROM.put(MASTER_CAL, calibration);
delay_background(2000, 0);
}
@ -643,13 +581,13 @@ void menuSetupCarrier(int btn){
unsigned long prevCarrier;
if (!btn){
printLine2("Set the BFO");
printLineF2(F("Set the BFO"));
return;
}
prevCarrier = usbCarrier;
printLine1("Tune to best Signal");
printLine2("PTT to confirm. ");
printLineF1(F("Tune to best Signal"));
printLineF1(F("PTT to confirm. "));
delay_background(1000, 0);
usbCarrier = 11995000l;
@ -677,7 +615,7 @@ void menuSetupCarrier(int btn){
//save the setting
if (digitalRead(PTT) == LOW){
printLine2("Carrier set! ");
printLineF2(F("Carrier set!"));
EEPROM.put(USB_CAL, usbCarrier);
delay_background(1000, 0);
}
@ -695,13 +633,13 @@ void menuSetupCwTone(int btn){
int prev_sideTone;
if (!btn){
printLine2("Change CW Tone");
printLineF2(F("Change CW Tone"));
return;
}
prev_sideTone = sideTone;
printLine1("Tune CW tone");
printLine2("PTT to confirm. ");
printLineF1(F("Tune CW tone"));
printLineF2(F("PTT to confirm."));
delay_background(1000, 0);
tone(CW_TONE, sideTone);
@ -727,7 +665,7 @@ void menuSetupCwTone(int btn){
noTone(CW_TONE);
//save the setting
if (digitalRead(PTT) == LOW){
printLine2("Sidetone set! ");
printLineF2(F("Sidetone set!"));
EEPROM.put(CW_SIDETONE, usbCarrier);
delay_background(2000, 0);
}
@ -744,9 +682,9 @@ void setDialLock(byte tmpLock, byte fromMode) {
if (fromMode == 2 || fromMode == 3) return;
if (isDialLock == 1)
printLine2("Dial Lock ON");
printLineF2(F("Dial Lock ON"));
else
printLine2("Dial Lock OFF");
printLineF2(F("Dial Lock OFF"));
delay_background(1000, 0);
printLine2ClearAndUpdate();
@ -774,21 +712,6 @@ void doMenu(){
}
delay(50); //debounce
/*
//check long time Down Button -> 3 Second
if (btnDownTimeCount > (3000 / 50)) {
isDialLock = isDialLock == 1 ? 0 : 1; //Reverse Dialo lock
if (isDialLock == 1)
printLine2("Dial Lock ON");
else
printLine2("Dial Lock OFF");
delay_background(1000);
printLine2("");
return;
}
*/
menuOn = 2;
while (menuOn){

View File

@ -143,35 +143,21 @@ void printLineF(char linenmbr, const __FlashStringHelper *c)
printLine(linenmbr, tmpBuff);
}
#define LCD_MAX_COLUMN 16
void printLineFromEEPRom(char linenmbr, char lcdColumn, byte eepromStartIndex, byte eepromEndIndex) {
lcd.setCursor(lcdColumn, linenmbr);
//#define printLineF1(x) (printLineF(1, x))
//#define printLineF2(x) (printLineF(0, x))
/*
//for reduce use memory
void printLineF(char linenmbr, const __FlashStringHelper *c) {
byte i;
byte sameData = 0;
for (i = 0;i < strlen
if (strcmp((char *)c, printBuff[linenmbr])) { // only refresh the display when there was a change
lcd.setCursor(0, linenmbr); // place the cursor at the beginning of the selected line
lcd.print(c);
strcpy(printBuff[linenmbr], c);
for (byte i = strlen((char *)c); i < 16; i++) { // add white spaces until the end of the 16 characters line is reached
lcd.print(' ');
}
}
else
for (byte i = eepromStartIndex; i <= eepromEndIndex; i++)
{
lcd.setCursor(0, linenmbr); // place the cursor at the beginning of the selected line
lcd.print("Exists");
if (++lcdColumn <= LCD_MAX_COLUMN)
lcd.write(EEPROM.read(USER_CALLSIGN_DAT + i));
else
break;
}
for (byte i = lcdColumn; i < 16; i++) //Right Padding by Space
lcd.write(' ');
}
*/
// short cut to print to the first line
void printLine1(char *c){
@ -196,6 +182,14 @@ void printLine2ClearAndUpdate(){
updateDisplay();
}
//012...89ABC...Z
char byteToChar(byte srcByte){
if (srcByte < 10)
return 0x30 + srcByte;
else
return 'A' + srcByte - 10;
}
// this builds up the top line of the display with frequency and mode
void updateDisplay() {
// tks Jack Purdum W8TEE
@ -208,10 +202,20 @@ void updateDisplay() {
memset(c, 0, sizeof(c));
if (inTx){
if (cwTimeout > 0)
strcpy(c, " CW:");
else
strcpy(c, " TX:");
if (isCWAutoMode == 2) {
for (i = 0; i < 4; i++)
c[3-i] = (i < autoCWSendReservCount ? byteToChar(autoCWSendReserv[i]) : ' ');
//display Sending Index
c[4] = byteToChar(sendingCWTextIndex);
c[5] = '=';
}
else {
if (cwTimeout > 0)
strcpy(c, " CW:");
else
strcpy(c, " TX:");
}
}
else {
if (ritOn)
@ -241,15 +245,20 @@ void updateDisplay() {
c[i] = ' ';
}
if (inTx)
strcat(c, " TX");
//remarked by KD8CEC
//already RX/TX status display, and over index (16 x 2 LCD)
//if (inTx)
// strcat(c, " TX");
printLine(1, c);
if (isDialLock == 1)
{
if (isDialLock == 1) {
lcd.setCursor(5,1);
lcd.write((uint8_t)0);
}
else if (isCWAutoMode == 2){
lcd.setCursor(5,1);
lcd.write(0x7E);
}
else
{
lcd.setCursor(5,1);