diff --git a/TeensyDSP/TeensyDSP.h b/TeensyDSP/TeensyDSP.h index 6d00f8e..4e1dccd 100644 --- a/TeensyDSP/TeensyDSP.h +++ b/TeensyDSP/TeensyDSP.h @@ -8,6 +8,8 @@ KD8CEC, Ian Lee **********************************************************************/ #include +#include "Nextion.h" +#include "Sensors.h" //================================================================ //COMMUNICATION SECTION @@ -58,7 +60,3 @@ extern int magnitudelimit_low; //SWR #define I2CMETER_CALCR 0x55 //Calculated SWR Meter #define I2CMETER_UNCALCR 0x54 //Uncalculated SWR Meter - -#define SIGNAL_METER_ADC A7 -#define POWER_METER_ADC A3 -#define SWR_METER_ADC A2 diff --git a/TeensyDSP/TeensyDSP.ino b/TeensyDSP/TeensyDSP.ino index 97aaf2c..cb87d15 100644 --- a/TeensyDSP/TeensyDSP.ino +++ b/TeensyDSP/TeensyDSP.ino @@ -7,232 +7,21 @@ Version : 0.8 License : See fftfunctions.cpp for FFT and CW Decode. **********************************************************************/ +#include #include // using i2c_t3 library for multiple I2C busses #include #include "TeensyDSP.h" -#define SWS_HEADER_CHAR_TYPE 'c' //1Byte Protocol Prefix -#define SWS_HEADER_INT_TYPE 'v' //Numeric Protocol Prefex -#define SWS_HEADER_STR_TYPE 's' //for TEXT Line compatiable Character LCD Control +//const uint8_t responseHeader[11]={'p', 'm', '.', 's', 'p', '.', 't', 'x', 't', '=', '"'}; //for Spectrum from DSP +//const uint8_t responseFooter[4]={'"', 0xFF, 0xFF, 0xFF}; +//const char hexCodes[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', }; -//Control must have prefix 'v' or 's' -char softSTRHeader[11] = {'p', 'm', '.', 's', '0', '.', 't', 'x', 't', '=', '\"'}; -char softINTHeader[10] = {'p', 'm', '.', 'v', '0', '.', 'v', 'a', 'l', '='}; - -char softTemp[20]; - -const uint8_t responseHeader[11]={'p', 'm', '.', 's', 'p', '.', 't', 'x', 't', '=', '"'}; //for Spectrum from DSP -const uint8_t responseFooter[4]={'"', 0xFF, 0xFF, 0xFF}; -const char hexCodes[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', }; - -void FFT(double *x,double *y, int n, long m); - -double FFTReal[SAMPLESIZE]; -double FFTImag[SAMPLESIZE]; -int ADC_MAX = 0; -int ADC_MIN = 0; -int ADC_DIFF = 0; unsigned long SAMPLE_INTERVAL = 0; -char nowADCSampling = 0; //prevent for loss signal - -//=================================================================== -//Begin of Nextion LCD Protocol -// -// v0~v9, va~vz : Numeric (Transceiver -> Nextion LCD) -// s0~s9 : String (Text) (Transceiver -> Nextion LCD) -// vlSendxxx, vloxxx: Reserve for Nextion (Nextion LCD -> Transceiver) -// -//=================================================================== - -#define CMD_NOW_DISP '0' //c0 -char L_nowdisp = -1; //Sended nowdisp - -#define CMD_VFO_TYPE 'v' //cv -char L_vfoActive; //vfoActive - -#define CMD_CURR_FREQ 'c' //vc -unsigned long L_vfoCurr; //vfoA -#define CMD_CURR_MODE 'c' //cc -byte L_vfoCurr_mode; //vfoA_mode - -#define CMD_VFOA_FREQ 'a' //va -unsigned long L_vfoA; //vfoA -#define CMD_VFOA_MODE 'a' //ca -byte L_vfoA_mode; //vfoA_mode - -#define CMD_VFOB_FREQ 'b' //vb -unsigned long L_vfoB; //vfoB -#define CMD_VFOB_MODE 'b' //cb -byte L_vfoB_mode; //vfoB_mode - -#define CMD_IS_RIT 'r' //cr -char L_ritOn; -#define CMD_RIT_FREQ 'r' //vr -unsigned long L_ritTxFrequency; //ritTxFrequency - -#define CMD_IS_TX 't' //ct -char L_inTx; - -#define CMD_IS_DIALLOCK 'l' //cl -byte L_isDialLock; //byte isDialLock - -#define CMD_IS_SPLIT 's' //cs -byte L_Split; //isTxType -#define CMD_IS_TXSTOP 'x' //cx -byte L_TXStop; //isTxType - -#define CMD_TUNEINDEX 'n' //cn -byte L_tuneStepIndex; //byte tuneStepIndex - -#define CMD_SMETER 'p' //cs -byte L_scaledSMeter; //scaledSMeter - -#define CMD_SIDE_TONE 't' //vt -unsigned long L_sideTone; //sideTone -#define CMD_KEY_TYPE 'k' //ck -byte L_cwKeyType; //L_cwKeyType 0: straight, 1 : iambica, 2: iambicb - -#define CMD_CW_SPEED 's' //vs -unsigned int L_cwSpeed; //cwSpeed - -#define CMD_CW_DELAY 'y' //vy -byte L_cwDelayTime; //cwDelayTime - -#define CMD_CW_STARTDELAY 'e' //ve -byte L_delayBeforeCWStartTime; //byte delayBeforeCWStartTime - -#define CMD_ATT_LEVEL 'f' //vf -byte L_attLevel; - -byte L_isIFShift; //1 = ifShift, 2 extend -#define CMD_IS_IFSHIFT 'i' //ci - -int L_ifShiftValue; -#define CMD_IFSHIFT_VALUE 'i' //vi - -byte L_sdrModeOn; -#define CMD_SDR_MODE 'j' //cj - -#define CMD_UBITX_INFO 'm' //cm Complete Send uBITX Information - -//Once Send Data, When boot -//arTuneStep, When boot, once send -//long arTuneStep[5]; - -#define CMD_AR_TUNE1 '1' //v1 -#define CMD_AR_TUNE2 '2' //v2 -#define CMD_AR_TUNE3 '3' //v3 -#define CMD_AR_TUNE4 '4' //v4 -#define CMD_AR_TUNE5 '5' //v5 - -//int idleStep = 0; -byte scaledSMeter = 0; - -/*! - @brief Send a string or numeric variable to the Nextion LCD. - @param varType - The type of the variable being sent to the Nextion LCD. - @param varIndex - The index (ID) of the variable being sent to the Nextion LCD. - */ -void sendHeader(char varType, char varIndex) -{ - if (varType == SWS_HEADER_STR_TYPE) - { - softSTRHeader[4] = varIndex; - for (unsigned i = 0; i < sizeof(softSTRHeader)/sizeof(softSTRHeader[0]); i++) - Serial1.write(softSTRHeader[i]); - } - else - { - softINTHeader[4] = varIndex; - for (unsigned i = 0; i < sizeof(softINTHeader)/sizeof(softINTHeader[0]); i++) - Serial1.write(softINTHeader[i]); - } -} - -/*! - @brief Send an unsigned long variable to the Nextion LCD. - @param varIndex - The index (ID) of the variable being sent to the Nextion LCD. - @param sendValue - The value of the variable being sent to the Nextion LCD. - */ -void sendCommandUL(char varIndex, unsigned long sendValue) -{ - sendHeader(SWS_HEADER_INT_TYPE, varIndex); - - memset(softTemp, 0, 20); - ultoa(sendValue, softTemp, DEC); - Serial1.print(softTemp); - Serial1.write(0xff); - Serial1.write(0xff); - Serial1.write(0xff); -} - -/*! - @brief Send a (signed) long variable to the Nextion LCD. - @param varIndex - The index (ID) of the variable being sent to the Nextion LCD. - @param sendValue - The value of the variable being sent to the Nextion LCD. - */ -void sendCommandL(char varIndex, long sendValue) -{ - sendHeader(SWS_HEADER_INT_TYPE, varIndex); - - memset(softTemp, 0, 20); - ltoa(sendValue, softTemp, DEC); - Serial1.print(softTemp); - Serial1.write(0xff); - Serial1.write(0xff); - Serial1.write(0xff); -} - -/*! - @brief Send a string variable to the Nextion LCD. - @param varIndex - The index (ID) of the variable being sent to the Nextion LCD. - @param sendValue - The value of the variable being sent to the Nextion LCD. - */ -void sendCommandStr(char varIndex, const char* sendValue) -{ - sendHeader(SWS_HEADER_STR_TYPE, varIndex); - - Serial1.print(sendValue); - Serial1.write('\"'); - Serial1.write(0xFF); - Serial1.write(0xFF); - Serial1.write(0xFF); -} - -unsigned char softBuff1Num[14] = {'p', 'm', '.', 'c', '0', '.', 'v', 'a', 'l', '=', 0, 0xFF, 0xFF, 0xFF}; - -/*! - @brief Send a single digit variable to the Nextion LCD. - @param varIndex - The index (ID) of the variable being sent to the Nextion LCD. - Values 0~9 are: Mode, nowDisp, ActiveVFO, IsDialLock, IsTxtType, IsSplitType. - @param sendValue - The value of the variable being sent to the Nextion LCD. - */ -void sendCommand1Num(char varIndex, char sendValue) -{ - softBuff1Num[4] = varIndex; - softBuff1Num[10] = sendValue + 0x30; // convert to character digit - - for (unsigned i = 0; i < sizeof(softBuff1Num)/sizeof(softBuff1Num[0]); i++) - Serial1.write(softBuff1Num[i]); -} - -//======================================================= -//END OF Nextion Protocol -//======================================================= - int i2cCommand = 0; -void calculateCoeff(uint8_t freqIndex); +//void calculateCoeff(uint8_t freqIndex); +uint8_t cwDecodeHz = 9; +int magnitudelimit_low = 30; char forwardBuff[MAX_FORWARD_BUFF_LENGTH + 1]; static int nowBuffIndex = 0; @@ -250,6 +39,9 @@ char FFTToUartIdleCount = 0; elapsedMillis sinceForward = 0; uint8_t responseCommand = 0; // bool isTX = false; + +/**********************************************************************/ + void responseConfig() { if (responseCommand == 2) @@ -357,7 +149,7 @@ char commandParser(int lastIndex) else if (cmd1 >= 100 && cmd1 <= 145) { cwDecodeHz = cmd1 - 100; - calculateCoeff(cwDecodeHz); + //calculateCoeff(cwDecodeHz); DSPType = 2; EEPROM.put(EEPROM_DSPTYPE, DSPType); EEPROM.put(EEPROM_CW_FREQ, cwDecodeHz); @@ -462,49 +254,11 @@ void forwardData(void) } } +/**********************************************************************/ + void sendMeterData(uint8_t isSend) { - //basic : 1.5Khz - int newScaledSMeter = 0; - //if (ADC_DIFF > 26) //-63dBm : S9 + 10dBm - if (ADC_DIFF > 26) //-63dBm : S9 + 10dBm (subtract loss rate) - //if (ADC_DIFF > 55) //-63dBm : S9 + 15dBm - { - newScaledSMeter = 8; - } - else if (ADC_DIFF > 11) //~ -72 S9 - { - newScaledSMeter = 7; - } - else if (ADC_DIFF > 8) - { - newScaledSMeter = 6; - } - else if (ADC_DIFF > 6) //~-80 S7 - //else if (ADC_DIFF > 5) //~-80 S7 - { - newScaledSMeter = 5; - } - else if (ADC_DIFF > 4) - { - newScaledSMeter = 4; //79 S8 - } - else if (ADC_DIFF > 3) - { - newScaledSMeter = 3; //-81 ~ -78 => S7 - } - else if (ADC_DIFF > 2) - { - newScaledSMeter = 2; // -88 ~ -82 => S7 or S6 - } - else if (ADC_DIFF > 1) //-93 ~ -89 => S5 or S4 - { - newScaledSMeter = 1; - } - else // ~ -93.0dBm ~S3 or S4 - { - newScaledSMeter = 0; - } + scaledSMeter = Sensors.sMeterScaled(); /* 1 : with noise (not use 0 ~ S3) @@ -514,8 +268,6 @@ void sendMeterData(uint8_t isSend) 5 : -77 ~ -72 6 : -71 ~ -69 */ - - scaledSMeter = newScaledSMeter; if (isSend == 1) { @@ -527,74 +279,32 @@ void sendMeterData(uint8_t isSend) } } +/**********************************************************************/ -void grepADC(void) -{ - int readValue = 0; - unsigned long currentms = 0; - int readSampleCount = 0; - - if (DSPType == 2 || DSPType == 0) //Decode Morse - { - readSampleCount = DECODE_MORSE_SAMPLESIZE; - } - else if (DSPType == 3) //Decode RTTY - { - readSampleCount = DECODE_MORSE_SAMPLESIZE; - } - else - { - readSampleCount = SAMPLESIZE; - } - - ADC_MAX = 0; - ADC_MIN = 30000; - - for(int i=0; i < readSampleCount; i++) - { - currentms = micros(); - readValue = analogRead(SIGNAL_METER_ADC);; - FFTReal[i] = readValue; - FFTImag[i] = 0; - - if (ADC_MAX < readValue) - { - ADC_MAX = readValue; - } - - if (ADC_MIN > readValue) - { - ADC_MIN = readValue; - } - - while(micros() < (currentms + SAMPLE_INTERVAL)){} - } //end of for -} - -void sendFFTData(void) -{ - int readValue = 0; - for (int i = 0; i < 11; i++) - Serial1.write(responseHeader[i]); - - for(int i = 1; i < 64; i++) - { - readValue = (int)(FFTReal[i]); - if (readValue < 0) - { - readValue = 0; - } - else if (readValue>255) - { - readValue=255; - } - Serial1.write(hexCodes[readValue >> 4]); - Serial1.write(hexCodes[readValue & 0xf]); - } - - for (int i = 0; i < 4; i++) - Serial1.write(responseFooter[i]); -} +//void sendFFTData(void) +//{ +// int readValue = 0; +// for (int i = 0; i < 11; i++) +// Serial1.write(responseHeader[i]); +// +// for(int i = 1; i < 64; i++) +// { +// readValue = (int)(FFTReal[i]); +// if (readValue < 0) +// { +// readValue = 0; +// } +// else if (readValue>255) +// { +// readValue=255; +// } +// Serial1.write(hexCodes[readValue >> 4]); +// Serial1.write(hexCodes[readValue & 0xf]); +// } +// +// for (int i = 0; i < 4; i++) +// Serial1.write(responseFooter[i]); +//} void setup() { @@ -666,8 +376,8 @@ void i2cReceiveEvent(size_t numBytes) } /*! - @brief Respond to a request from the I2C Master (Raduino). Returns the appropriate data - based on whatever command was previously issued. + * @brief Respond to a request from the I2C Master (Raduino). Returns the appropriate data + * based on whatever command was previously issued. */ void i2cRequestEvent(void) { @@ -684,53 +394,17 @@ void i2cRequestEvent(void) case I2CMETER_UNCALCS: // Returns a raw signal strength value. - // KC4UPR: I'm going to replace this with a "process" that continually updates the ADC values. - // So then this would just grab the current value, and return it. - for(int i=0; i < 7; i++) - { - curr = micros(); - readValue = analogRead(SIGNAL_METER_ADC);; - - if (readValue > maxValue) - { - maxValue = readValue; - } - - if (readValue < minValue) - { - minValue = readValue; - } - while(micros() < (curr + 127)){} //8Khz / 7 - } //end of for - - readValue = maxValue - minValue; - readValue = readValue * readValue; - //readValue = readValue / 2; - if (readValue < 0) - { - readValue = 0; - } - else if (readValue > 255) - { - readValue = 255; - } - Wire1.write(readValue); + Wire1.write(Sensors.sMeterUnscaled() >> 2); // divided by 4... do we want this? break; case I2CMETER_CALCP: // Returns a raw forward power value. - // KC4UPR: I'm going to replace this with a "process" that continually updates the ADC values. - // So then this would just grab the current value, and return it. - readValue = analogRead(POWER_METER_ADC); //POWER - Wire1.write(readValue); + Wire1.write(fwdPower); break; case I2CMETER_CALCR: // Returns a raw reverse power value. - // KC4UPR: I'm going to replace this with a "process" that continually updates the ADC values. - // So then this would just grab the current value, and return it. - readValue = analogRead(SWR_METER_ADC); - Wire1.write(readValue); + Wire1.write(revPower); break; default: @@ -738,28 +412,40 @@ void i2cRequestEvent(void) } } -extern void Decode_Morse(float magnitude); -extern double coeff; +//extern void Decode_Morse(float magnitude); +//extern double coeff; #define LAST_TIME_INTERVAL 159 -//int SWRAdcValue = 0; -float adcFWD = 0; -float adcRWD = 0; -uint16_t adjustPower = 230; -float swrMeasured; - -int clcCount = 0; - - // for boot delay, a lot of data to transfer // Delay 2.5 Sec byte isBooted = 0; +//====================================================================== +// ADC PROCESSES +//====================================================================== + +elapsedMillis sinceFrameMillis = 0; +elapsedMillis sinceADCMillis = 0; + +#define FRAME_RATE 40 +#define FRAME_INTERVAL_MS (1000/FRAME_RATE) + +const int frameIntervalMillis = FRAME_INTERVAL_MS; + +#define ADC_SAMPLE_RATE 120 +#define ADC_INTERVAL_MS (1000/ADC_SAMPLE_RATE) + +const int adcIntervalMillis = ADC_INTERVAL_MS; + +//====================================================================== +// MAIN LOOP +//====================================================================== + void loop() { - char isProcess = 0; // 0: init, 1: complete ADC sampling, 2: complete FFT - isProcess = 0; + //char isProcess = 0; // 0: init, 1: complete ADC sampling, 2: complete FFT + //isProcess = 0; forwardData(); @@ -775,229 +461,169 @@ void loop() return; } - //=========================================== - // TRANSCEIVER STATUS : TX - //=========================================== - if (isTX) //TX Mode - { - //************************************************ - //Read FWD and RWD - adcFWD = adcFWD * 0.8 + analogRead(A2) * 0.2; - adcRWD = adcRWD * 0.8 + analogRead(A3) * 0.2; - - if (adcRWD > adcFWD) - { - adcRWD = adcFWD; - } + if (sinceFrameMillis > frameIntervalMillis) { + // Do stuff that we do once per frame--I/O. + // TODO: debug output (frame skipping / utilization). + sinceFrame = 0; - //for realtime LCD Display - forwardData(); - - if (clcCount++ > 10) - { - //Calculated Power and swr and Send Information - clcCount = 0; - - //Calc PWR - float PWR = pow(adcFWD, 2); - PWR = PWR / adjustPower / 100; - - //Calc SWR - float Vratio = adcRWD / adcFWD; - if (adcRWD < 0.05 && adcFWD < 0.05) - { - //No signal - swrMeasured = 0; - } - else if (Vratio > 0.99) - { - swrMeasured = 1999; - } - else - { - swrMeasured = ((1 + Vratio)/ (1 - Vratio)); - } - - //For Version 0.8 - //Send SWR Information using Receive Signal Meter Protocol - scaledSMeter = (int)(swrMeasured + 0.5); - if (scaledSMeter > 9) - { - scaledSMeter = 9; - } - - if (L_scaledSMeter != scaledSMeter) - { - L_scaledSMeter = scaledSMeter; - sendCommand1Num(CMD_SMETER, L_scaledSMeter); - } - - //For Version 1.0 - //need mod uBITX firmware and Nextion LCD and add Power adjust value option (uBITX Manager) - //Send Information - //SWR Send - //sendCommandL('m', SWRAdcValue); - //sendCommand1Num('m', 3); - //SMeterToUartIdleCount = 0; - //Send Power Information - int readValue = (int)(PWR * 100); - sendCommandL('m', readValue); - sendCommand1Num('m',2); - - //Delay 250msec ~ 500msec for Nextion LCD Processing (using m protocol) - - for (int i = 0; i < 10; i++) - { - forwardData(); - if (!isTX) //if TX -> RX break - { - break; - } - delay(25); - } //end of delay time + if (isTX) { + calcVSWR = Sensors.VSWR(); + scaledVSWR = byte(Sensors.scaledVSWR()); + fwdPower = Sensors.Pfwd(); + revPower = Sensors.Prev(); - //Send SWR - readValue = (int)(swrMeasured * 100); - sendCommandL('m', readValue); - sendCommand1Num('m', 3); + // Send SWR meter information. + if (L_scaledVSWR != scaledVSWR) { + L_scaledVSWR = scaledVSWR + sendCommand1Num(CMD_SMETER, scaledVSWR); + } + + // Send forward power. + if (L_fwdPower != fwdPower) { + L_fwdPower = fwdPower; + sendCommandL('m', fwdPower * 100); // watts x 100? + sendCommand1Num('m', 2); + } + + // Send reverse power. + //if (L_revPower != revPower) { + // L_revPower = revPower; + // sendCommandL('m', revPower * 100); // watts x 100? + // sendCommand1Num('m', 2); + //} - //delay(50); - //return; - } - - delay(30); - return; //Do not processing ADC, FFT, Decode Morse or RTTY, only Power and SWR Data Return - } + // Does there need to be some kind of 250-500ms delay after this??? + // Delay 250msec ~ 500msec for Nextion LCD Processing (using m protocol) + //for (int i = 0; i < 10; i++) { + // forwardData(); + // if (!isTX) { //if TX -> RX break + // break; + // } + // delay(25); + //} //end of delay time + + // Send SWR. + if (L_calcSWR != calcSWR) { + L_calcSWR = calcSWR; + sendCommandL('m', int(calcSWR * 100.0)); // SWR x 100? + sendCommand1Num('m', 3); + } + + } else { // RX - //=========================================== - //TRANSCEIVER STATUS : RX - //=========================================== - //=========================================== - // ADC Sampling - //=========================================== - if (nowSendingProtocol == 0) //Idle Status - { - nowADCSampling = 1; //Mark => Start Sampling - grepADC(); - - //if(nowADCSampling == 2) //Marked ? While ADC Sampling, receive I2C - //{ - // nowADCSampling = 0; //Mark => Finish Sampling - // i2cRequestEvent(); - //} - nowADCSampling = 0; //Mark => Finish Sampling - - int newDiff = ADC_MAX - ADC_MIN; //Calculated for Signal Meter (ADC_DIFF => Signal Strength) - //ADC_DIFF = ((ADC_DIFF * 7) + (newDiff * 3)) / 10; - ADC_DIFF = newDiff; - isProcess = 1; //Mark => Complete ADC Sampling - } - - forwardData(); - - //=========================================== - // Send Signal Meter to UART - //=========================================== - if (SMeterToUartSend == 1) //SMeter To Uart Send - { - //When selected Morse decode mode, not send signal Meter - //if ((DSPType != 2) && (SMeterToUartIdleCount++ > (SMeterToUartInterval * (DSPType == 1 ? 1 : 12)))) - //User Option - if (SMeterToUartIdleCount++ > (SMeterToUartInterval * (DSPType == 1 ? 1 : 12))) - { - //nowSendingProtocol -> not finished data forward, (not found 0xff, 0xff, 0xff yet) - if (nowSendingProtocol == 0 && isProcess == 1) //Complete ADC Sampling and Idle status + // Send Signal Meter to UART + if (SMeterToUartSend == 1 && nowSendingProtocol == 0) //SMeter To Uart Send { + //nowSendingProtocol -> not finished data forward, (not found 0xff, 0xff, 0xff yet) sendMeterData(1); - SMeterToUartIdleCount = 0; + } else { + sendMeterData(0); //only calculate Signal Level } + } - } //end of if - else - { - sendMeterData(0); //only calculate Signal Level - } - - forwardData(); - //Check Response Command + // Forward any data that came in while we were updating stuff. + ForwardData(); + } + + if (sinceADCMillis > adcIntervalMillis) { + // Do stuff that we do once per ADC interval--ADC colllection. + // TODO: debug output (frame skipping / utilization). + sinceADC = 0; + + if (isTX) { + Sensors.updatePower(); + } else { // RX + Sensors.updateSMeter(); + Sensors.updateSupply(); + } + + // Forward any data that came in while we were reading sensors. + //ForwardData(); + } + + // Check Response Command if (responseCommand > 0 && sinceForward > LAST_TIME_INTERVAL) { responseConfig(); } - //=================================================================================== - // DSP Routine - //=================================================================================== - if (DSPType == 1 && sinceForward > LAST_TIME_INTERVAL) // spectrum: FFT => send To UART - { - FFTToUartIdleCount = 0; - - if (isProcess == 1) - { - FFT(FFTReal, FFTImag, SAMPLESIZE, 7); - isProcess = 2; - } - - forwardData(); - - if (isProcess == 2) - { - for (uint16_t k = 0; k < SAMPLESIZE; k++) - { - FFTReal[k] = sqrt(FFTReal[k] * FFTReal[k] + FFTImag[k] * FFTImag[k]); - } - - isProcess = 3; - } - - forwardData(); - - if (isProcess == 3) - { - if (nowSendingProtocol == 0) //Idle Status - { - sendFFTData(); - } - } - } - else if (DSPType == 2) //Decode Morse - { - //Implement Goertzel_algorithm - //https://en.wikipedia.org/wiki/Goertzel_algorithm +// //=========================================== +// //TRANSCEIVER STATUS : RX +// //=========================================== +// //=================================================================================== +// // DSP Routine +// //=================================================================================== +// if (DSPType == 1 && sinceForward > LAST_TIME_INTERVAL) // spectrum: FFT => send To UART +// { +// FFTToUartIdleCount = 0; +// +// if (isProcess == 1) +// { +// FFT(FFTReal, FFTImag, SAMPLESIZE, 7); +// isProcess = 2; +// } +// +// forwardData(); +// +// if (isProcess == 2) +// { +// for (uint16_t k = 0; k < SAMPLESIZE; k++) +// { +// FFTReal[k] = sqrt(FFTReal[k] * FFTReal[k] + FFTImag[k] * FFTImag[k]); +// } +// +// isProcess = 3; +// } +// +// forwardData(); +// +// if (isProcess == 3) +// { +// if (nowSendingProtocol == 0) //Idle Status +// { +// sendFFTData(); +// } +// } +// } +// else if (DSPType == 2) //Decode Morse +// { +// //Implement Goertzel_algorithm +// //https://en.wikipedia.org/wiki/Goertzel_algorithm +// +// /* +// ω = 2 * π * Kterm / Nterms; +// cr = cos(ω); +// ci = sin(ω); +// coeff = 2 * cr; +// +// sprev = 0; +// sprev2 = 0; +// for each index n in range 0 to Nterms-1 +// s = x[n] + coeff * sprev - sprev2; +// sprev2 = sprev; +// sprev = s; +// end +// +// power = sprev2 * sprev2 + sprev * sprev - coeff * sprev * sprev2; +// */ +// double Q1 = 0; +// double Q2 = 0; +// +// for (unsigned index = 0; index < DECODE_MORSE_SAMPLESIZE; index++) +// { +// float Q0; +// Q0 = coeff * Q1 - Q2 + FFTReal[index]; +// Q2 = Q1; +// Q1 = Q0; +// } +// double magnitudeSquared = (Q1*Q1)+(Q2*Q2)-Q1*Q2*coeff; // we do only need the real part // +// double magnitude = sqrt(magnitudeSquared); +// +// Decode_Morse(magnitude); +// } //end of if - /* - ω = 2 * π * Kterm / Nterms; - cr = cos(ω); - ci = sin(ω); - coeff = 2 * cr; - - sprev = 0; - sprev2 = 0; - for each index n in range 0 to Nterms-1 - s = x[n] + coeff * sprev - sprev2; - sprev2 = sprev; - sprev = s; - end - - power = sprev2 * sprev2 + sprev * sprev - coeff * sprev * sprev2; - */ - double Q1 = 0; - double Q2 = 0; - - for (unsigned index = 0; index < DECODE_MORSE_SAMPLESIZE; index++) - { - float Q0; - Q0 = coeff * Q1 - Q2 + FFTReal[index]; - Q2 = Q1; - Q1 = Q0; - } - double magnitudeSquared = (Q1*Q1)+(Q2*Q2)-Q1*Q2*coeff; // we do only need the real part // - double magnitude = sqrt(magnitudeSquared); - - Decode_Morse(magnitude); - } //enf of if -} //end of main +} //====================================================================== // EOF diff --git a/TeensyDSP/fftfunctions.cpp b/TeensyDSP/fftfunctions.cpp deleted file mode 100644 index 057e77d..0000000 --- a/TeensyDSP/fftfunctions.cpp +++ /dev/null @@ -1,361 +0,0 @@ -/* -FFTFunctions for Nextion LCD and Control MCU -This code is for FFT and CW Decode. -KD8CEC, Ian Lee ------------------------------------------------------------------------ -//The section on CW decode logic is specified at the bottom of this code. -License : I follow the license of the previous code and I do not add any extra constraints. -I hope that the Comment I made or the Comment of OZ1JHM will be maintained. -**********************************************************************/ -#include -#include "TeensyDSP.h" - -// Code Referency : http://paulbourke.net/miscellaneous/dft/ -// DFT, FFT Wiritten by Paul Bourke, June 1993 -void FFT(double *x,double *y, int n, long m) -{ - long i,i1,j,k,i2,l,l1,l2; - double c1,c2,tx,ty,t1,t2,u1,u2,z; - short int dir = 0; - - /* Do the bit reversal */ - i2 = n >> 1; - j = 0; - for (i=0;i>= 1; - } - j += k; - } - - /* Compute the FFT */ - c1 = -1.0; - c2 = 0.0; - l2 = 1; - - for (l=0;l 20) - //{ - //writeCount = 0; - //Serial.println(""); - //} -} - -uint8_t docode() -{ - if (strcmp(code,".-") == 0) printascii(65); - if (strcmp(code,"-...") == 0) printascii(66); - if (strcmp(code,"-.-.") == 0) printascii(67); - if (strcmp(code,"-..") == 0) printascii(68); - if (strcmp(code,".") == 0) printascii(69); - if (strcmp(code,"..-.") == 0) printascii(70); - if (strcmp(code,"--.") == 0) printascii(71); - if (strcmp(code,"....") == 0) printascii(72); - if (strcmp(code,"..") == 0) printascii(73); - if (strcmp(code,".---") == 0) printascii(74); - if (strcmp(code,"-.-") == 0) printascii(75); - if (strcmp(code,".-..") == 0) printascii(76); - if (strcmp(code,"--") == 0) printascii(77); - if (strcmp(code,"-.") == 0) printascii(78); - if (strcmp(code,"---") == 0) printascii(79); - if (strcmp(code,".--.") == 0) printascii(80); - if (strcmp(code,"--.-") == 0) printascii(81); - if (strcmp(code,".-.") == 0) printascii(82); - if (strcmp(code,"...") == 0) printascii(83); - if (strcmp(code,"-") == 0) printascii(84); - if (strcmp(code,"..-") == 0) printascii(85); - if (strcmp(code,"...-") == 0) printascii(86); - if (strcmp(code,".--") == 0) printascii(87); - if (strcmp(code,"-..-") == 0) printascii(88); - if (strcmp(code,"-.--") == 0) printascii(89); - if (strcmp(code,"--..") == 0) printascii(90); - - if (strcmp(code,".----") == 0) printascii(49); - if (strcmp(code,"..---") == 0) printascii(50); - if (strcmp(code,"...--") == 0) printascii(51); - if (strcmp(code,"....-") == 0) printascii(52); - if (strcmp(code,".....") == 0) printascii(53); - if (strcmp(code,"-....") == 0) printascii(54); - if (strcmp(code,"--...") == 0) printascii(55); - if (strcmp(code,"---..") == 0) printascii(56); - if (strcmp(code,"----.") == 0) printascii(57); - if (strcmp(code,"-----") == 0) printascii(48); - - if (strcmp(code,"..--..") == 0) printascii(63); - if (strcmp(code,".-.-.-") == 0) printascii(46); - if (strcmp(code,"--..--") == 0) printascii(44); - if (strcmp(code,"-.-.--") == 0) printascii(33); - if (strcmp(code,".--.-.") == 0) printascii(64); - if (strcmp(code,"---...") == 0) printascii(58); - if (strcmp(code,"-....-") == 0) printascii(45); - if (strcmp(code,"-..-.") == 0) printascii(47); - - if (strcmp(code,"-.--.") == 0) printascii(40); - if (strcmp(code,"-.--.-") == 0) printascii(41); - if (strcmp(code,".-...") == 0) printascii(95); - if (strcmp(code,"...-..-") == 0) printascii(36); - if (strcmp(code,"...-.-") == 0) printascii(62); - if (strcmp(code,".-.-.") == 0) printascii(60); - if (strcmp(code,"...-.") == 0) printascii(126); - ////////////////// - // The specials // - ////////////////// - if (strcmp(code,".-.-") == 0) printascii(3); - if (strcmp(code,"---.") == 0) printascii(4); - if (strcmp(code,".--.-") == 0) printascii(6); - -} - -void Decode_Morse(float magnitude) -{ - //magnitudelimit auto Increase - if (magnitude > magnitudelimit_low) - { - magnitudelimit = (magnitudelimit +((magnitude - magnitudelimit)/6)); /// moving average filter - } - - if (magnitudelimit < magnitudelimit_low) - magnitudelimit = magnitudelimit_low; - - if(magnitude > magnitudelimit*0.6) // just to have some space up - realstate = HIGH; - else - realstate = LOW; - - if (realstate != realstatebefore) - laststarttime = millis(); - - if ((millis()-laststarttime) > nbtime) - { - if (realstate != filteredstate) - { - filteredstate = realstate; - } - } - - if (filteredstate != filteredstatebefore) - { - if (filteredstate == HIGH) - { - starttimehigh = millis(); - lowduration = (millis() - startttimelow); - } - - if (filteredstate == LOW) - { - startttimelow = millis(); - highduration = (millis() - starttimehigh); - - if (highduration < (2*hightimesavg) || hightimesavg == 0) - { - hightimesavg = (highduration+hightimesavg+hightimesavg)/3; // now we know avg dit time ( rolling 3 avg) - } - - if (highduration > (5*hightimesavg) ) - { - hightimesavg = highduration+hightimesavg; // if speed decrease fast .. - } - } - } - - /////////////////////////////////////////////////////////////// - // now we will check which kind of baud we have - dit or dah // - // and what kind of pause we do have 1 - 3 or 7 pause // - // we think that hightimeavg = 1 bit // - /////////////////////////////////////////////////////////////// - - if (filteredstate != filteredstatebefore) - { - stop = LOW; - if (filteredstate == LOW) - { - if (highduration < (hightimesavg*2) && highduration > (hightimesavg*0.6)) /// 0.6 filter out false dits - { - strcat(code,"."); - } - if (highduration > (hightimesavg*2) && highduration < (hightimesavg*6)) - { - strcat(code,"-"); - wpm = (wpm + (1200/((highduration)/3)))/2; //// the most precise we can do ;o) - } - } - - if (filteredstate == HIGH) - { - float lacktime = 1; - if(wpm > 25)lacktime=1.0; /// when high speeds we have to have a little more pause before new letter or new word - if(wpm > 30)lacktime=1.2; - if(wpm > 35)lacktime=1.5; - - if (lowduration > (hightimesavg*(2*lacktime)) && lowduration < hightimesavg*(5*lacktime)) // letter space - { - docode(); - code[0] = '\0'; - } - if (lowduration >= hightimesavg*(5*lacktime)) - { // word space - docode(); - code[0] = '\0'; - printascii(32); - } - } - } - - if ((millis() - startttimelow) > (highduration * 6) && stop == LOW) - { - docode(); - code[0] = '\0'; - stop = HIGH; - } - - /* - if(filteredstate == HIGH) - { - digitalWrite(ledPin, HIGH); - tone(audioOutPin,target_freq); - } - else - { - digitalWrite(ledPin, LOW); - noTone(audioOutPin); - } -*/ - - realstatebefore = realstate; - lasthighduration = highduration; - filteredstatebefore = filteredstate; -}