add Init version files
This commit is contained in:
parent
d5db04ff0e
commit
16e173b109
362
i2cmeter1/fftfunctions.cpp
Normal file
362
i2cmeter1/fftfunctions.cpp
Normal file
@ -0,0 +1,362 @@
|
||||
/*
|
||||
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 <arduino.h>
|
||||
#include "i2cmeter1.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<n-1;i++) {
|
||||
if (i < j) {
|
||||
tx = x[i];
|
||||
ty = y[i];
|
||||
x[i] = x[j];
|
||||
y[i] = y[j];
|
||||
x[j] = tx;
|
||||
y[j] = ty;
|
||||
}
|
||||
k = i2;
|
||||
while (k <= j) {
|
||||
j -= k;
|
||||
k >>= 1;
|
||||
}
|
||||
j += k;
|
||||
}
|
||||
|
||||
/* Compute the FFT */
|
||||
c1 = -1.0;
|
||||
c2 = 0.0;
|
||||
l2 = 1;
|
||||
|
||||
for (l=0;l<m;l++)
|
||||
{
|
||||
l1 = l2;
|
||||
l2 <<= 1;
|
||||
u1 = 1.0;
|
||||
u2 = 0.0;
|
||||
for (j=0;j<l1;j++)
|
||||
{
|
||||
for (i=j;i<n;i+=l2)
|
||||
{
|
||||
i1 = i + l1;
|
||||
t1 = u1 * x[i1] - u2 * y[i1];
|
||||
t2 = u1 * y[i1] + u2 * x[i1];
|
||||
x[i1] = x[i] - t1;
|
||||
y[i1] = y[i] - t2;
|
||||
x[i] += t1;
|
||||
y[i] += t2;
|
||||
}
|
||||
z = u1 * c1 - u2 * c2;
|
||||
u2 = u1 * c2 + u2 * c1;
|
||||
u1 = z;
|
||||
}
|
||||
c2 = sqrt((1.0 - c1) / 2.0);
|
||||
if (dir == 1)
|
||||
c2 = -c2;
|
||||
c1 = sqrt((1.0 + c1) / 2.0);
|
||||
}
|
||||
|
||||
/* Scaling for forward transform */
|
||||
/*
|
||||
if (dir == 1) {
|
||||
for (i=0;i<n;i++) {
|
||||
x[i] /= n;
|
||||
y[i] /= n;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
*/
|
||||
|
||||
//return(TRUE);
|
||||
}
|
||||
|
||||
double coeff;
|
||||
|
||||
void CalculateCoeff(uint8_t freqIndex)
|
||||
{
|
||||
float omega;
|
||||
int targetFrequency = freqIndex * 50 + 300;
|
||||
int k = (int) (0.5 + ((DECODE_MORSE_SAMPLESIZE * targetFrequency) / SAMPLE_PREQUENCY));
|
||||
omega = (2.0 * PI * k) / DECODE_MORSE_SAMPLESIZE;
|
||||
coeff = 2.0 * cos(omega);
|
||||
}
|
||||
|
||||
//=====================================================================
|
||||
//The CW Decode code refers to the site code below.
|
||||
//https://k2jji.org/2014/09/18/arduino-base-cw-decoder/
|
||||
//Some code has been modified, but the original comments remain intact.
|
||||
// code below is optimal for use in Arduino.
|
||||
//Thanks to OZ1JHM
|
||||
//KD8CEC
|
||||
//=====================================================================
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// CW Decoder made by Hjalmar Skovholm Hansen OZ1JHM VER 1.01 //
|
||||
// Feel free to change, copy or what ever you like but respect //
|
||||
// that license is http://www.gnu.org/copyleft/gpl.html //
|
||||
// Discuss and give great ideas on //
|
||||
// https://groups.yahoo.com/neo/groups/oz1jhm/conversations/messages //
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Read more here http://en.wikipedia.org/wiki/Goertzel_algorithm //
|
||||
// if you want to know about FFT the http://www.dspguide.com/pdfbook.htm //
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//int magnitudelimit = 50;
|
||||
//int magnitudelimit_low = 50;
|
||||
int magnitudelimit = 30;
|
||||
int magnitudelimit_low = 30;
|
||||
char realstate = LOW;
|
||||
char realstatebefore = LOW;
|
||||
char filteredstate = LOW;
|
||||
char filteredstatebefore = LOW;
|
||||
long laststarttime = 0;
|
||||
int nbtime = 6; /// ms noise blanker
|
||||
|
||||
long starttimehigh;
|
||||
long highduration;
|
||||
long lasthighduration;
|
||||
long hightimesavg;
|
||||
long lowtimesavg;
|
||||
long startttimelow;
|
||||
long lowduration;
|
||||
|
||||
char code[20];
|
||||
uint8_t stop = LOW;
|
||||
int wpm;
|
||||
uint8_t cwDecodeHz = 9;
|
||||
|
||||
extern void SendCommandStr(char varIndex, char* sendValue);
|
||||
|
||||
void printascii(int asciinumber)
|
||||
{
|
||||
char rstDecode[4] = {0, 0, 0, 0};
|
||||
|
||||
if (asciinumber == 3)
|
||||
{
|
||||
|
||||
}
|
||||
else if (asciinumber == 4)
|
||||
{
|
||||
|
||||
}
|
||||
else if (asciinumber == 6)
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
rstDecode[0] = asciinumber;
|
||||
}
|
||||
SendCommandStr('b', rstDecode);
|
||||
|
||||
//Serial.write(asciinumber);
|
||||
//if (writeCount++ > 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;
|
||||
}
|
||||
|
76
i2cmeter1/i2cmeter1.h
Normal file
76
i2cmeter1/i2cmeter1.h
Normal file
@ -0,0 +1,76 @@
|
||||
/*
|
||||
Configuration file for Nextion LCD and Control MCU
|
||||
The parameter can be set according to the CPU used.
|
||||
|
||||
KD8CEC, Ian Lee
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#include <arduino.h>
|
||||
|
||||
//================================================================
|
||||
//COMMUNICATION SECTION
|
||||
//================================================================
|
||||
#define USE_SW_SERIAL
|
||||
|
||||
extern void SWSerial_Write(uint8_t b);
|
||||
extern void SWSerial_Print(uint8_t *b);
|
||||
|
||||
#ifdef USE_SW_SERIAL
|
||||
extern void SWSerial_Begin(long speedBaud);
|
||||
extern int SWSerial_Available(void);
|
||||
extern int SWSerial_Read(void);
|
||||
#else
|
||||
|
||||
#define PRINT_MAX_LENGTH 30
|
||||
#endif
|
||||
|
||||
//================================================================
|
||||
//FFT and Decode Morse
|
||||
//================================================================
|
||||
#define FFTSIZE 64
|
||||
#define SAMPLE_PREQUENCY 6000
|
||||
#define SAMPLESIZE (FFTSIZE * 2)
|
||||
#define DECODE_MORSE_SAMPLESIZE 48
|
||||
|
||||
extern uint8_t cwDecodeHz;
|
||||
extern int magnitudelimit_low;
|
||||
|
||||
//================================================================
|
||||
//EEPROM Section
|
||||
//================================================================
|
||||
#define MAX_FORWARD_BUFF_LENGTH 128
|
||||
#define EEPROM_DSPTYPE 100
|
||||
#define EEPROM_SMETER_UART 111
|
||||
#define EEPROM_SMETER_TIME 112
|
||||
|
||||
#define EEPROM_CW_FREQ 120
|
||||
//#define EEPROM_CW_MAG_LIMIT 121
|
||||
#define EEPROM_CW_MAG_LOW 122
|
||||
#define EEPROM_CW_NBTIME 126
|
||||
#define EEPROM_RTTYDECODEHZ 130
|
||||
|
||||
//================================================================
|
||||
//DEFINE for I2C Command
|
||||
//================================================================
|
||||
//S-Meter Address
|
||||
#define I2CMETER_ADDR 0x58 //changed from 0x6A
|
||||
//VALUE TYPE============================================
|
||||
//Signal
|
||||
#define I2CMETER_CALCS 0x59 //Calculated Signal Meter
|
||||
#define I2CMETER_UNCALCS 0x58 //Uncalculated Signal Meter
|
||||
|
||||
//Power
|
||||
#define I2CMETER_CALCP 0x57 //Calculated Power Meter
|
||||
#define I2CMETER_UNCALCP 0x56 //UnCalculated Power Meter
|
||||
|
||||
//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
|
||||
|
||||
|
957
i2cmeter1/i2cmeter1.ino
Normal file
957
i2cmeter1/i2cmeter1.ino
Normal file
@ -0,0 +1,957 @@
|
||||
/*
|
||||
FFT, CW Decode for uBITX
|
||||
KD8CEC, Ian Lee
|
||||
-----------------------------------------------------------------------
|
||||
License : See fftfunctions.cpp for FFT and CW Decode.
|
||||
**********************************************************************/
|
||||
|
||||
#include <Wire.h>
|
||||
#include <EEPROM.h>
|
||||
#include "i2cmeter1.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
|
||||
|
||||
//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;
|
||||
|
||||
//send data for Nextion LCD
|
||||
void SendHeader(char varType, char varIndex)
|
||||
{
|
||||
if (varType == SWS_HEADER_STR_TYPE)
|
||||
{
|
||||
softSTRHeader[4] = varIndex;
|
||||
for (int i = 0; i < 11; i++)
|
||||
SWSerial_Write(softSTRHeader[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
softINTHeader[4] = varIndex;
|
||||
for (int i = 0; i < 10; i++)
|
||||
SWSerial_Write(softINTHeader[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void SendCommandUL(char varIndex, unsigned long sendValue)
|
||||
{
|
||||
SendHeader(SWS_HEADER_INT_TYPE, varIndex);
|
||||
|
||||
memset(softTemp, 0, 20);
|
||||
ultoa(sendValue, softTemp, DEC);
|
||||
SWSerial_Print(softTemp);
|
||||
SWSerial_Write(0xff);
|
||||
SWSerial_Write(0xff);
|
||||
SWSerial_Write(0xff);
|
||||
}
|
||||
|
||||
void SendCommandL(char varIndex, long sendValue)
|
||||
{
|
||||
SendHeader(SWS_HEADER_INT_TYPE, varIndex);
|
||||
|
||||
memset(softTemp, 0, 20);
|
||||
ltoa(sendValue, softTemp, DEC);
|
||||
SWSerial_Print(softTemp);
|
||||
SWSerial_Write(0xff);
|
||||
SWSerial_Write(0xff);
|
||||
SWSerial_Write(0xff);
|
||||
}
|
||||
|
||||
void SendCommandStr(char varIndex, char* sendValue)
|
||||
{
|
||||
SendHeader(SWS_HEADER_STR_TYPE, varIndex);
|
||||
|
||||
SWSerial_Print(sendValue);
|
||||
SWSerial_Write('\"');
|
||||
SWSerial_Write(0xFF);
|
||||
SWSerial_Write(0xFF);
|
||||
SWSerial_Write(0xFF);
|
||||
}
|
||||
|
||||
char softBuff1Num[14] = {'p', 'm', '.', 'c', '0', '.', 'v', 'a', 'l', '=', 0, 0xFF, 0xFF, 0xFF};
|
||||
void SendCommand1Num(char varType, char sendValue) //0~9 : Mode, nowDisp, ActiveVFO, IsDialLock, IsTxtType, IsSplitType
|
||||
{
|
||||
softBuff1Num[4] = varType;
|
||||
softBuff1Num[10] = sendValue + 0x30;
|
||||
|
||||
for (int i = 0; i < 14; i++)
|
||||
SWSerial_Write(softBuff1Num[i]);
|
||||
}
|
||||
|
||||
//=======================================================
|
||||
//END OF Nextion Protocol
|
||||
//=======================================================
|
||||
|
||||
int I2CCommand = 0;
|
||||
void CalculateCoeff(uint8_t freqIndex);
|
||||
|
||||
char ForwardBuff[MAX_FORWARD_BUFF_LENGTH + 1];
|
||||
static char nowBuffIndex = 0;
|
||||
static char etxCount = 0;
|
||||
static char nowSendingProtocol = 0;
|
||||
|
||||
uint8_t SMeterToUartSend = 0; //0 : Send, 1: Idle
|
||||
uint8_t SMeterToUartIdleCount = 0;
|
||||
#define SMeterToUartInterval 4
|
||||
|
||||
char DSPType = 1; //0 : Not Use, 1 : FFT, 2 : Morse Decoder, 3 : RTTY Decoder
|
||||
char FFTToUartIdleCount = 0;
|
||||
#define FFTToUartInterval 2
|
||||
|
||||
unsigned long lastForwardmili = 0;
|
||||
uint8_t responseCommand = 0; //
|
||||
uint8_t TXStatus = 0; //0:RX, 1:TX
|
||||
void ResponseConfig()
|
||||
{
|
||||
if (responseCommand == 2)
|
||||
{
|
||||
unsigned long returnValue = 0;
|
||||
if (DSPType == 0)
|
||||
{
|
||||
returnValue = 94; //None
|
||||
}
|
||||
else if (DSPType == 1)
|
||||
{
|
||||
returnValue = 95; //Spectrum (FFT) mode
|
||||
}
|
||||
else if (DSPType == 2)
|
||||
{
|
||||
returnValue = 100 + cwDecodeHz;
|
||||
}
|
||||
|
||||
returnValue = returnValue << 8;
|
||||
returnValue = returnValue | (SMeterToUartSend & 0xFF);
|
||||
returnValue = returnValue << 8;
|
||||
uint8_t tmpValue = 0;
|
||||
if (magnitudelimit_low > 255)
|
||||
tmpValue = 255;
|
||||
else if (magnitudelimit_low < 1)
|
||||
tmpValue = 0;
|
||||
else
|
||||
tmpValue = magnitudelimit_low;
|
||||
returnValue = returnValue | (tmpValue & 0xFF);
|
||||
|
||||
SendCommandUL('v', returnValue); //Return data
|
||||
SendCommandUL('g', 0x6A); //Return data
|
||||
}
|
||||
responseCommand = 0;
|
||||
}
|
||||
|
||||
//Result : if found .val=, 1 else 0
|
||||
char CommandPasrser(int lastIndex)
|
||||
{
|
||||
//Analysing Forwrd data
|
||||
//59 58 68 4A 1C 5F 6A E5 FF FF 73
|
||||
//Find Loopback protocol
|
||||
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
||||
//70 6D 2E 76 76 2E 76 61 6C 3D 33 38 34 38 39 35 33 36 32 38 FF FF FF
|
||||
//pm.vv.val=3848953628\xFF\xFF\xFF
|
||||
//1234567890XXX
|
||||
//
|
||||
int startIndex = 0;
|
||||
|
||||
//Loop back command has 13 ~ 23
|
||||
if (lastIndex < 13)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
//Protocol MAX Length : 22
|
||||
if (lastIndex >= 22)
|
||||
{
|
||||
startIndex = lastIndex - 22;
|
||||
}
|
||||
else
|
||||
{
|
||||
startIndex = 0;
|
||||
}
|
||||
|
||||
for (int i = lastIndex - 3; i >= startIndex + 7; i--)
|
||||
{
|
||||
//Find =
|
||||
if (ForwardBuff[i-3] == 'v' && ForwardBuff[i-2] == 'a' && ForwardBuff[i-1] == 'l' && ForwardBuff[i] == '=') //0x3D
|
||||
{
|
||||
uint8_t command1 = ForwardBuff[i-6]; //v
|
||||
uint8_t command2 = ForwardBuff[i-5]; //v
|
||||
// i-4 //.
|
||||
ForwardBuff[lastIndex - 2] = 0;
|
||||
long commandVal=atol(&ForwardBuff[i + 1]);
|
||||
uint8_t *ReadBuff = (uint8_t *)&commandVal;
|
||||
|
||||
//Loop Back
|
||||
if (command1 == 'v' && command2 == 'v')
|
||||
{
|
||||
//===========================================================
|
||||
//Test Code 1
|
||||
/*
|
||||
long tmpVal = 0;
|
||||
Serial.print("Found :");
|
||||
for (int k = i + 1; k <= lastIndex - 3; k++)
|
||||
{
|
||||
Serial.write(ForwardBuff[k]);
|
||||
}
|
||||
Serial.println();
|
||||
Serial.print("Reverse :");
|
||||
for (int k = lastIndex - 3; k >= i + 1; k--)
|
||||
{
|
||||
Serial.write(ForwardBuff[k]);
|
||||
}
|
||||
Serial.println();
|
||||
|
||||
ForwardBuff[lastIndex - 2] = 0;
|
||||
|
||||
tmpVal=atol(&ForwardBuff[i + 1]);
|
||||
Serial.println(tmpVal);
|
||||
|
||||
uint8_t *ReadBuff = (uint8_t *)&tmpVal;
|
||||
char buff[10];
|
||||
sprintf(buff, "%x,%x,%x,%x", ReadBuff[0], ReadBuff[1], ReadBuff[2], ReadBuff[3]);
|
||||
Serial.println(buff);
|
||||
|
||||
int calcChecksumA = ReadBuff[0] + ReadBuff[1] + ReadBuff[2];
|
||||
calcChecksumA = calcChecksumA % 256;
|
||||
|
||||
if (calcChecksumA == ReadBuff[3])
|
||||
{
|
||||
Serial.print("Correct Checksum : ");
|
||||
Serial.print(ReadBuff[3]);
|
||||
Serial.print(":");
|
||||
Serial.println(calcChecksumA);
|
||||
}
|
||||
//End of Test Code
|
||||
*/
|
||||
|
||||
/*
|
||||
//Test Code 2
|
||||
Serial.print("Found :");
|
||||
Serial.print(startIndex);
|
||||
Serial.print(",");
|
||||
Serial.print(lastIndex);
|
||||
Serial.print(":");
|
||||
for (int k = i + 1; k <= lastIndex - 3; k++)
|
||||
{
|
||||
Serial.write(ForwardBuff[k]);
|
||||
}
|
||||
Serial.println("");
|
||||
//End of Tet Code 2
|
||||
*/
|
||||
|
||||
int calcChecksum = ReadBuff[0] + ReadBuff[1] + ReadBuff[2];
|
||||
calcChecksum = calcChecksum % 256;
|
||||
|
||||
//Correct Checksum and Receiver is DSP Moudle protocol v1.0
|
||||
if (calcChecksum == ReadBuff[3] && ReadBuff[2] == 0x6A)
|
||||
{
|
||||
//Serial.print("Correct Checksum Command : ");
|
||||
//Serial.println(ReadBuff[1]);
|
||||
uint8_t cmd1 = ReadBuff[1];
|
||||
if (cmd1 == 94)
|
||||
{
|
||||
DSPType = 0;
|
||||
EEPROM.put(EEPROM_DSPTYPE, DSPType);
|
||||
}
|
||||
else if (cmd1 == 95)
|
||||
{
|
||||
//Serial.println("Spectrum Mode");
|
||||
DSPType = 1;
|
||||
EEPROM.put(EEPROM_DSPTYPE, DSPType);
|
||||
}
|
||||
else if (cmd1 >= 100 && cmd1 <= 145)
|
||||
{
|
||||
cwDecodeHz = cmd1 - 100;
|
||||
CalculateCoeff(cwDecodeHz);
|
||||
DSPType = 2;
|
||||
EEPROM.put(EEPROM_DSPTYPE, DSPType);
|
||||
EEPROM.put(EEPROM_CW_FREQ, cwDecodeHz);
|
||||
}
|
||||
else if (cmd1 > 1 && cmd1 <= 5) //2~5 : Request Configuration
|
||||
{
|
||||
responseCommand = cmd1;
|
||||
}
|
||||
else if (cmd1 == 50 || cmd1 == 51) //Set Configuration
|
||||
{
|
||||
SMeterToUartSend = (cmd1 == 51);
|
||||
EEPROM.put(EEPROM_SMETER_UART, SMeterToUartSend);
|
||||
}
|
||||
else if (cmd1 >= 146 && cmd1 <= 156 )
|
||||
{
|
||||
//Save Mode
|
||||
magnitudelimit_low = (cmd1 - 146) * 10;
|
||||
EEPROM.put(EEPROM_CW_MAG_LOW, magnitudelimit_low);
|
||||
} //end of if
|
||||
} //end of check Checksum
|
||||
} //end of check Protocol (vv)
|
||||
else if (command1 == 'c' && command2 == 't') //TX, RX
|
||||
{
|
||||
if (commandVal == 0) //RX
|
||||
{
|
||||
TXStatus = 0;
|
||||
SMeterToUartIdleCount = 0;
|
||||
}
|
||||
else if (commandVal == 1) //TX
|
||||
{
|
||||
TXStatus = 1;
|
||||
SMeterToUartIdleCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
} //end of check Protocol (.val)
|
||||
} //end of for
|
||||
|
||||
//Not found Protocol (.val=
|
||||
return 0;
|
||||
}
|
||||
|
||||
//#define PROTOCOL_TIMEOUT = 100
|
||||
int ForwardData(void)
|
||||
{
|
||||
uint8_t recvChar;
|
||||
|
||||
if (Serial.available() > 0)
|
||||
{
|
||||
#ifndef USE_SW_SERIAL
|
||||
Serial.flush();
|
||||
#endif
|
||||
//Check RX Buffer
|
||||
while (Serial.available() > 0)
|
||||
{
|
||||
recvChar = Serial.read();
|
||||
|
||||
ForwardBuff[nowBuffIndex] = recvChar;
|
||||
|
||||
if (recvChar == 0xFF) //found ETX
|
||||
{
|
||||
etxCount++; //Nextion Protocol, ETX : 0xFF, 0xFF, 0xFF
|
||||
if (etxCount >= 3)
|
||||
{
|
||||
//Finished Protocol
|
||||
if (CommandPasrser(nowBuffIndex) == 1)
|
||||
{
|
||||
nowSendingProtocol = 0; //Finished 1 Set Command
|
||||
etxCount = 0;
|
||||
nowBuffIndex = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
etxCount = 0x00;
|
||||
nowSendingProtocol = 1; //Sending Data
|
||||
}
|
||||
|
||||
SWSerial_Write(recvChar);
|
||||
lastForwardmili = millis();
|
||||
nowBuffIndex++;
|
||||
|
||||
if (nowBuffIndex > MAX_FORWARD_BUFF_LENGTH -2)
|
||||
{
|
||||
nowBuffIndex = 0;
|
||||
}
|
||||
} //end of while
|
||||
|
||||
#ifndef USE_SW_SERIAL
|
||||
Serial.flush();
|
||||
#endif
|
||||
|
||||
//lastReceivedTime = millis();
|
||||
} //end if (Serial.available
|
||||
else
|
||||
{
|
||||
//check Timeout
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
int SendMeterData(uint8_t isSend)
|
||||
{
|
||||
int newScaledSMeter = 0;
|
||||
if (ADC_DIFF > 11)
|
||||
{
|
||||
newScaledSMeter = 8;
|
||||
}
|
||||
else if (ADC_DIFF > 9)
|
||||
{
|
||||
newScaledSMeter = 7;
|
||||
}
|
||||
else if (ADC_DIFF > 8)
|
||||
{
|
||||
newScaledSMeter = 6;
|
||||
}
|
||||
else if (ADC_DIFF > 7)
|
||||
{
|
||||
newScaledSMeter = 5;
|
||||
}
|
||||
else if (ADC_DIFF > 6)
|
||||
{
|
||||
newScaledSMeter = 4;
|
||||
}
|
||||
else if (ADC_DIFF > 5)
|
||||
{
|
||||
newScaledSMeter = 3;
|
||||
}
|
||||
else if (ADC_DIFF > 4)
|
||||
{
|
||||
newScaledSMeter = 2;
|
||||
}
|
||||
else if (ADC_DIFF > 3)
|
||||
{
|
||||
newScaledSMeter = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
newScaledSMeter = 0;
|
||||
}
|
||||
scaledSMeter = newScaledSMeter;
|
||||
|
||||
if (isSend == 1)
|
||||
{
|
||||
if (L_scaledSMeter != scaledSMeter)
|
||||
{
|
||||
L_scaledSMeter = scaledSMeter;
|
||||
SendCommand1Num(CMD_SMETER, L_scaledSMeter);
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
int 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;
|
||||
}
|
||||
|
||||
/*
|
||||
1 : with noise (not use 0 ~ S3)
|
||||
2 : -93 ~ -89
|
||||
3 : -88 ~ -81
|
||||
4 : -80 ~ -78
|
||||
5 : -77 ~ -72
|
||||
6 : -71 ~ -69
|
||||
*/
|
||||
|
||||
scaledSMeter = newScaledSMeter;
|
||||
|
||||
if (isSend == 1)
|
||||
{
|
||||
if (L_scaledSMeter != scaledSMeter)
|
||||
{
|
||||
L_scaledSMeter = scaledSMeter;
|
||||
SendCommand1Num(CMD_SMETER, L_scaledSMeter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GrepADC(void)
|
||||
{
|
||||
int readedValue = 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();
|
||||
readedValue = analogRead(SIGNAL_METER_ADC);;
|
||||
FFTReal[i] = readedValue;
|
||||
FFTImag[i] = 0;
|
||||
|
||||
if (ADC_MAX < readedValue)
|
||||
{
|
||||
ADC_MAX = readedValue;
|
||||
}
|
||||
|
||||
if (ADC_MIN > readedValue)
|
||||
{
|
||||
ADC_MIN = readedValue;
|
||||
}
|
||||
|
||||
while(micros() < (currentms + SAMPLE_INTERVAL)){}
|
||||
} //end of for
|
||||
}
|
||||
|
||||
void SendFFTData(void)
|
||||
{
|
||||
int readedValue = 0;
|
||||
for (int i = 0; i < 11; i++)
|
||||
SWSerial_Write(ResponseHeader[i]);
|
||||
|
||||
for(int i = 1; i < 64; i++)
|
||||
{
|
||||
readedValue = (int)(FFTReal[i]);
|
||||
if (readedValue < 0)
|
||||
{
|
||||
readedValue = 0;
|
||||
}
|
||||
else if (readedValue>255)
|
||||
{
|
||||
readedValue=255;
|
||||
}
|
||||
SWSerial_Write(HexCodes[readedValue >> 4]);
|
||||
SWSerial_Write(HexCodes[readedValue & 0xf]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
SWSerial_Write(ResponseFooter[i]);
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
//Load Configuration
|
||||
EEPROM.get(EEPROM_DSPTYPE, DSPType);
|
||||
if (DSPType > 5)
|
||||
{
|
||||
DSPType = 1;
|
||||
}
|
||||
|
||||
//Signal Meter
|
||||
EEPROM.get(EEPROM_SMETER_UART, SMeterToUartSend);
|
||||
if (SMeterToUartSend > 2)
|
||||
{
|
||||
SMeterToUartSend = 1;
|
||||
}
|
||||
//
|
||||
EEPROM.get(EEPROM_CW_FREQ, cwDecodeHz);
|
||||
if (cwDecodeHz > 40 || cwDecodeHz < 1)
|
||||
{
|
||||
cwDecodeHz = 9;
|
||||
}
|
||||
|
||||
//EEPROM_CW_MAG_LOW
|
||||
EEPROM.get(EEPROM_CW_MAG_LOW, magnitudelimit_low);
|
||||
if (magnitudelimit_low > 1000 || magnitudelimit_low < 1)
|
||||
{
|
||||
magnitudelimit_low = 50;
|
||||
}
|
||||
|
||||
// put your setup code here, to run once:
|
||||
Wire.begin(I2CMETER_ADDR); //j : S-Meter Slave Address
|
||||
//Wire.begin(0x21); //j : S-Meter Slave Address
|
||||
Wire.onReceive(I2CReceiveEvent); //
|
||||
Wire.onRequest(I2CRequestEvent);
|
||||
|
||||
#ifdef USE_SW_SERIAL
|
||||
SWSerial_Begin(9600);
|
||||
#endif
|
||||
|
||||
Serial.begin(9600, SERIAL_8N1);
|
||||
Serial.flush();
|
||||
SAMPLE_INTERVAL = round(1000000 * (1.0 / SAMPLE_PREQUENCY));
|
||||
CalculateCoeff(cwDecodeHz); //Set 750Hz //9 * 50 + 300 = 750Hz
|
||||
//Serial.println("Start...");
|
||||
}
|
||||
|
||||
void I2CReceiveEvent(void)
|
||||
{
|
||||
int readCommand = 0; // byte를 읽어 int로 변환
|
||||
|
||||
while(Wire.available() > 0) // for Last command
|
||||
{
|
||||
readCommand = Wire.read();
|
||||
}
|
||||
|
||||
if (0x50 <= readCommand && readCommand <= 0x59)
|
||||
{
|
||||
I2CCommand = readCommand;
|
||||
}
|
||||
}
|
||||
|
||||
void I2CRequestEvent(void)
|
||||
{
|
||||
int maxValue = 0;
|
||||
int minValue = 30000;
|
||||
int readedValue = 0;
|
||||
unsigned long curr = 0;
|
||||
|
||||
//if (nowADCSampling == 1) //Now Sampling ADC's
|
||||
//{
|
||||
// nowADCSampling = 2; //when finished ADC Sampling, response I2CRequest Event
|
||||
// return;
|
||||
//} //end of if
|
||||
|
||||
if (I2CCommand == I2CMETER_CALCS)
|
||||
{
|
||||
Wire.write(scaledSMeter);
|
||||
}
|
||||
else if (I2CCommand == I2CMETER_UNCALCS)
|
||||
{
|
||||
//Wire.write(ADC_DIFF);
|
||||
//8292Hz
|
||||
for(int i=0; i < 7; i++)
|
||||
{
|
||||
curr = micros();
|
||||
readedValue = analogRead(SIGNAL_METER_ADC);;
|
||||
|
||||
if (readedValue > maxValue)
|
||||
{
|
||||
maxValue = readedValue;
|
||||
}
|
||||
|
||||
if (readedValue < minValue)
|
||||
{
|
||||
minValue = readedValue;
|
||||
}
|
||||
while(micros() < (curr + 127)){} //8Khz / 7
|
||||
} //end of for
|
||||
|
||||
readedValue = maxValue - minValue;
|
||||
readedValue = readedValue * readedValue;
|
||||
//readedValue = readedValue / 2;
|
||||
if (readedValue < 0)
|
||||
{
|
||||
readedValue = 0;
|
||||
}
|
||||
else if (readedValue > 255)
|
||||
{
|
||||
readedValue = 255;
|
||||
}
|
||||
Wire.write(readedValue);
|
||||
}
|
||||
else if (I2CCommand == I2CMETER_CALCP)
|
||||
{
|
||||
readedValue = analogRead(POWER_METER_ADC); //POWER
|
||||
Wire.write(readedValue);
|
||||
}
|
||||
else if (I2CCommand == I2CMETER_CALCR) //SWR
|
||||
{
|
||||
readedValue = analogRead(SWR_METER_ADC);
|
||||
Wire.write(readedValue);
|
||||
}
|
||||
}
|
||||
|
||||
extern void Decode_Morse(float magnitude);
|
||||
extern double coeff;
|
||||
|
||||
|
||||
#define LAST_TIME_INTERVAL 159
|
||||
|
||||
int SWRAdcValue = 0;
|
||||
|
||||
void loop()
|
||||
{
|
||||
char isProcess = 0; //0 : Init, 1 : Complete ADC Sampling, 2 : Complete FFT
|
||||
isProcess = 0;
|
||||
ForwardData();
|
||||
|
||||
//===========================================
|
||||
//TRANSCEIVER STATUS : RX
|
||||
//===========================================
|
||||
if (TXStatus == 1) //TX Mode
|
||||
{
|
||||
int readedValue = 0;
|
||||
SMeterToUartIdleCount++;
|
||||
if (SMeterToUartIdleCount > 130) //SWR
|
||||
{
|
||||
//SWR Send
|
||||
SendCommandL('m', SWRAdcValue);
|
||||
SendCommand1Num('m', 3);
|
||||
SMeterToUartIdleCount = 0;
|
||||
}
|
||||
else if (SMeterToUartIdleCount == 100) //POWER 500msec interval
|
||||
{
|
||||
readedValue = analogRead(POWER_METER_ADC );
|
||||
SWRAdcValue = analogRead(SWR_METER_ADC);
|
||||
SendCommandL('m', readedValue);
|
||||
SendCommand1Num('m',2);
|
||||
//PWR Send
|
||||
}
|
||||
ForwardData();
|
||||
delay(5);
|
||||
|
||||
return; //Do not processing ADC, FFT, Decode Morse or RTTY, only Power and SWR Data Return
|
||||
}
|
||||
|
||||
//===========================================
|
||||
//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
|
||||
{
|
||||
SendMeterData(1);
|
||||
SMeterToUartIdleCount = 0;
|
||||
}
|
||||
}
|
||||
} //end of if
|
||||
else
|
||||
{
|
||||
SendMeterData(0); //only calculate Signal Level
|
||||
}
|
||||
|
||||
ForwardData();
|
||||
|
||||
//Check Response Command
|
||||
if (responseCommand > 0 && millis() > lastForwardmili + LAST_TIME_INTERVAL)
|
||||
{
|
||||
ResponseConfig();
|
||||
}
|
||||
|
||||
//===================================================================================
|
||||
// DSP Routine
|
||||
//===================================================================================
|
||||
if (DSPType == 1 && millis() > lastForwardmili + 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 (char 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
|
||||
|
||||
|
355
i2cmeter1/uart_forward.cpp
Normal file
355
i2cmeter1/uart_forward.cpp
Normal file
@ -0,0 +1,355 @@
|
||||
/*
|
||||
Softserial for Nextion LCD and Control MCU
|
||||
KD8CEC, Ian Lee
|
||||
-----------------------------------------------------------------------
|
||||
It is a library rewritten in C format based on SoftwareSerial.c.
|
||||
I tried to use as much as possible without modifying the SoftwareSerial.
|
||||
But eventually I had to modify the code.
|
||||
|
||||
I rewrote it in C for the following reasons.
|
||||
- Problems occurred when increasing Program Size and Program Memory
|
||||
- We had to reduce the program size.
|
||||
Of course, Software Serial is limited to one.
|
||||
- reduce the steps for transmitting and receiving
|
||||
|
||||
useage
|
||||
extern void SWSerial_Begin(long speedBaud);
|
||||
extern void SWSerial_Write(uint8_t b);
|
||||
extern int SWSerial_Available(void);
|
||||
extern int SWSerial_Read(void);
|
||||
extern void SWSerial_Print(uint8_t *b);
|
||||
|
||||
If you use Softwreserial library instead of this library, you can modify the code as shown below.
|
||||
I kept the function name of SoftwareSerial so you only need to modify a few lines of code.
|
||||
|
||||
define top of source code
|
||||
#include <SoftwareSerial.h>
|
||||
SoftwareSerial sSerial(10, 11); // RX, TX
|
||||
|
||||
replace source code
|
||||
SWSerial_Begin to sSerial.begin
|
||||
SWSerial_Write to sSerial.write
|
||||
SWSerial_Available to sSerial.available
|
||||
SWSerial_Read to sSerial.read
|
||||
|
||||
KD8CEC, Ian Lee
|
||||
-----------------------------------------------------------------------
|
||||
License
|
||||
All licenses for the source code are subject to the license of the original source SoftwareSerial Library.
|
||||
However, if you use or modify this code, please keep the all comments in this source code.
|
||||
KD8CEC
|
||||
-----------------------------------------------------------------------
|
||||
License from SoftwareSerial
|
||||
-----------------------------------------------------------------------
|
||||
SoftwareSerial.cpp (formerly NewSoftSerial.cpp) -
|
||||
Multi-instance software serial library for Arduino/Wiring
|
||||
-- Interrupt-driven receive and other improvements by ladyada
|
||||
(http://ladyada.net)
|
||||
-- Tuning, circular buffer, derivation from class Print/Stream,
|
||||
multi-instance support, porting to 8MHz processors,
|
||||
various optimizations, PROGMEM delay tables, inverse logic and
|
||||
direct port writing by Mikal Hart (http://www.arduiniana.org)
|
||||
-- Pin change interrupt macros by Paul Stoffregen (http://www.pjrc.com)
|
||||
-- 20MHz processor support by Garrett Mace (http://www.macetech.com)
|
||||
-- ATmega1280/2560 support by Brett Hagman (http://www.roguerobotics.com/)
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
The latest version of this library can always be found at
|
||||
http://arduiniana.org.
|
||||
*/
|
||||
#include "i2cmeter1.h"
|
||||
|
||||
#ifdef USE_SW_SERIAL
|
||||
//================================================================
|
||||
//Public Variable
|
||||
//================================================================
|
||||
#define TX_PIN 9
|
||||
#define RX_PIN 8
|
||||
#define _SS_MAX_RX_BUFF 35 // RX buffer size
|
||||
#define PRINT_MAX_LENGTH 30
|
||||
|
||||
//================================================================
|
||||
//Internal Variable from SoftwareSerial.c and SoftwareSerial.h
|
||||
//================================================================
|
||||
//variable from softwareserial.c and softwareserial.h
|
||||
static uint8_t swr_receive_buffer[_SS_MAX_RX_BUFF];
|
||||
|
||||
volatile uint8_t *_transmitPortRegister; //Write Port Register
|
||||
uint8_t transmit_RegMask; //use Mask bit 1
|
||||
uint8_t transmit_InvMask; //use mask bit 0
|
||||
|
||||
volatile uint8_t *_receivePortRegister; //Read Port Register
|
||||
uint8_t _receiveBitMask;
|
||||
|
||||
//delay value for Bit
|
||||
uint16_t _tx_delay;
|
||||
|
||||
//delay value for Receive
|
||||
uint16_t _rx_delay_stopbit;
|
||||
uint16_t _rx_delay_centering;
|
||||
uint16_t _rx_delay_intrabit;
|
||||
|
||||
//Customize for uBITX Protocol
|
||||
int8_t receiveIndex = 0;
|
||||
int8_t receivedCommandLength = 0;
|
||||
int8_t ffCount = 0;
|
||||
|
||||
//Values for Receive Buffer
|
||||
//uint16_t _buffer_overflow;
|
||||
//static volatile uint8_t _receive_buffer_head;
|
||||
//static volatile uint8_t _receive_buffer_tail;
|
||||
|
||||
//Values for Interrupt (check Start Bit)
|
||||
volatile uint8_t *_pcint_maskreg;
|
||||
uint8_t _pcint_maskvalue;
|
||||
|
||||
//================================================================
|
||||
//Internal Function from SoftwareSerial.c
|
||||
//================================================================
|
||||
uint16_t subtract_cap(uint16_t num, uint16_t sub)
|
||||
{
|
||||
if (num > sub)
|
||||
return num - sub;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
inline void tunedDelay(uint16_t delay)
|
||||
{
|
||||
_delay_loop_2(delay);
|
||||
}
|
||||
|
||||
void setRxIntMsk(bool enable)
|
||||
{
|
||||
if (enable)
|
||||
*_pcint_maskreg |= _pcint_maskvalue;
|
||||
else
|
||||
*_pcint_maskreg &= ~_pcint_maskvalue;
|
||||
}
|
||||
|
||||
uint8_t rx_pin_read()
|
||||
{
|
||||
return *_receivePortRegister & _receiveBitMask;
|
||||
}
|
||||
|
||||
//
|
||||
// The receive routine called by the interrupt handler
|
||||
//
|
||||
void softSerail_Recv()
|
||||
{
|
||||
#if GCC_VERSION < 40302
|
||||
// Work-around for avr-gcc 4.3.0 OSX version bug
|
||||
// Preserve the registers that the compiler misses
|
||||
// (courtesy of Arduino forum user *etracer*)
|
||||
asm volatile(
|
||||
"push r18 \n\t"
|
||||
"push r19 \n\t"
|
||||
"push r20 \n\t"
|
||||
"push r21 \n\t"
|
||||
"push r22 \n\t"
|
||||
"push r23 \n\t"
|
||||
"push r26 \n\t"
|
||||
"push r27 \n\t"
|
||||
::);
|
||||
#endif
|
||||
|
||||
uint8_t d = 0;
|
||||
|
||||
// If RX line is high, then we don't see any start bit
|
||||
// so interrupt is probably not for us
|
||||
if (!rx_pin_read()) //Start Bit
|
||||
{
|
||||
// Disable further interrupts during reception, this prevents
|
||||
// triggering another interrupt directly after we return, which can
|
||||
// cause problems at higher baudrates.
|
||||
setRxIntMsk(false);
|
||||
|
||||
// Wait approximately 1/2 of a bit width to "center" the sample
|
||||
tunedDelay(_rx_delay_centering);
|
||||
|
||||
// Read each of the 8 bits
|
||||
for (uint8_t i=8; i > 0; --i)
|
||||
{
|
||||
tunedDelay(_rx_delay_intrabit);
|
||||
d >>= 1;
|
||||
|
||||
if (rx_pin_read())
|
||||
d |= 0x80;
|
||||
}
|
||||
|
||||
if (receivedCommandLength == 0) //check Already Command
|
||||
{
|
||||
//Set Received Data
|
||||
swr_receive_buffer[receiveIndex++] = d;
|
||||
|
||||
//Finded Command
|
||||
if (d == 0x73 && ffCount > 1 && receiveIndex > 6)
|
||||
{
|
||||
receivedCommandLength = receiveIndex;
|
||||
receiveIndex = 0;
|
||||
ffCount = 0;
|
||||
}
|
||||
else if (receiveIndex > _SS_MAX_RX_BUFF)
|
||||
{
|
||||
//Buffer Overflow
|
||||
receiveIndex = 0;
|
||||
ffCount = 0;
|
||||
}
|
||||
else if (d == 0xFF)
|
||||
{
|
||||
ffCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
ffCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// skip the stop bit
|
||||
tunedDelay(_rx_delay_stopbit);
|
||||
|
||||
// Re-enable interrupts when we're sure to be inside the stop bit
|
||||
setRxIntMsk(true);
|
||||
}
|
||||
|
||||
#if GCC_VERSION < 40302
|
||||
// Work-around for avr-gcc 4.3.0 OSX version bug
|
||||
// Restore the registers that the compiler misses
|
||||
asm volatile(
|
||||
"pop r27 \n\t"
|
||||
"pop r26 \n\t"
|
||||
"pop r23 \n\t"
|
||||
"pop r22 \n\t"
|
||||
"pop r21 \n\t"
|
||||
"pop r20 \n\t"
|
||||
"pop r19 \n\t"
|
||||
"pop r18 \n\t"
|
||||
::);
|
||||
#endif
|
||||
}
|
||||
|
||||
ISR(PCINT0_vect)
|
||||
{
|
||||
softSerail_Recv();
|
||||
}
|
||||
|
||||
//================================================================
|
||||
//Public Function from SoftwareSerial.c and modified and create
|
||||
//================================================================
|
||||
// Read data from buffer
|
||||
void SWSerial_Read(uint8_t * receive_cmdBuffer)
|
||||
{
|
||||
for (int i = 0; i < receivedCommandLength; i++)
|
||||
receive_cmdBuffer[i] = swr_receive_buffer[i];
|
||||
}
|
||||
|
||||
void SWSerial_Write(uint8_t b)
|
||||
{
|
||||
volatile uint8_t *reg = _transmitPortRegister;
|
||||
uint8_t oldSREG = SREG;
|
||||
uint16_t delay = _tx_delay;
|
||||
|
||||
cli(); // turn off interrupts for a clean txmit
|
||||
|
||||
// Write the start bit
|
||||
*reg &= transmit_InvMask;
|
||||
|
||||
tunedDelay(delay);
|
||||
|
||||
// Write each of the 8 bits
|
||||
for (uint8_t i = 8; i > 0; --i)
|
||||
{
|
||||
if (b & 1) // choose bit
|
||||
*reg |= transmit_RegMask; // send 1
|
||||
else
|
||||
*reg &= transmit_InvMask; // send 0
|
||||
|
||||
tunedDelay(delay);
|
||||
b >>= 1;
|
||||
}
|
||||
|
||||
// restore pin to natural state
|
||||
*reg |= transmit_RegMask;
|
||||
|
||||
SREG = oldSREG; // turn interrupts back on
|
||||
tunedDelay(_tx_delay);
|
||||
}
|
||||
|
||||
void SWSerial_Print(uint8_t *b)
|
||||
{
|
||||
for (int i = 0; i < PRINT_MAX_LENGTH; i++)
|
||||
{
|
||||
if (b[i] == 0x00)
|
||||
break;
|
||||
else
|
||||
SWSerial_Write(b[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void SWSerial_Begin(long speedBaud)
|
||||
{
|
||||
//INT TX_PIN
|
||||
digitalWrite(TX_PIN, HIGH);
|
||||
pinMode(TX_PIN, OUTPUT);
|
||||
transmit_RegMask = digitalPinToBitMask(TX_PIN); //use Bit 1
|
||||
transmit_InvMask = ~digitalPinToBitMask(TX_PIN); //use Bit 0
|
||||
_transmitPortRegister = portOutputRegister(digitalPinToPort(TX_PIN));
|
||||
|
||||
//INIT RX_PIN
|
||||
pinMode(RX_PIN, INPUT);
|
||||
digitalWrite(RX_PIN, HIGH); // pullup for normal logic!
|
||||
_receiveBitMask = digitalPinToBitMask(RX_PIN);
|
||||
_receivePortRegister = portInputRegister(digitalPinToPort(RX_PIN));
|
||||
|
||||
//Set Values
|
||||
uint16_t bit_delay = (F_CPU / speedBaud) / 4;
|
||||
_tx_delay = subtract_cap(bit_delay, 15 / 4);
|
||||
|
||||
if (digitalPinToPCICR(RX_PIN))
|
||||
{
|
||||
_rx_delay_centering = subtract_cap(bit_delay / 2, (4 + 4 + 75 + 17 - 23) / 4);
|
||||
_rx_delay_intrabit = subtract_cap(bit_delay, 23 / 4);
|
||||
_rx_delay_stopbit = subtract_cap(bit_delay * 3 / 4, (37 + 11) / 4);
|
||||
*digitalPinToPCICR(RX_PIN) |= _BV(digitalPinToPCICRbit(RX_PIN));
|
||||
_pcint_maskreg = digitalPinToPCMSK(RX_PIN);
|
||||
_pcint_maskvalue = _BV(digitalPinToPCMSKbit(RX_PIN));
|
||||
|
||||
tunedDelay(_tx_delay); // if we were low this establishes the end
|
||||
}
|
||||
|
||||
//Start Listen
|
||||
setRxIntMsk(true);
|
||||
}
|
||||
#else
|
||||
void SWSerial_Write(uint8_t b)
|
||||
{
|
||||
Serial.write(b);
|
||||
//Serial.flush();
|
||||
}
|
||||
|
||||
void SWSerial_Print(uint8_t *b)
|
||||
{
|
||||
for (int i = 0; i < PRINT_MAX_LENGTH; i++)
|
||||
{
|
||||
if (b[i] == 0x00)
|
||||
break;
|
||||
else
|
||||
SWSerial_Write(b[i]);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user