add Init version files

This commit is contained in:
phdlee 2018-08-04 11:23:20 +09:00
parent d5db04ff0e
commit 16e173b109
4 changed files with 1750 additions and 0 deletions

362
i2cmeter1/fftfunctions.cpp Normal file
View 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
View 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
View 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
View 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