/****************************************************************
JI3BNB AX.25 HF PACKET (300baud) DECODE ENGINE <CORE>
ARDUINO MEGA 2560
v1.31 2026.02.21
-- THIS PROGRAM IS IN THE PUBLIC DOMAIN --
/****************************************************************/
//Digital input 19
//Serial output 115200 baud
#include <TimerOne.h>
volatile int pArray[7];
volatile int syncPoint;
volatile bool state_1;
volatile bool state_2;
volatile bool state_3;
volatile bool state_4;
void setup()
{
Timer1.initialize();
Timer1.attachInterrupt(timer_interrupt, 333); //300Baud
Serial.begin(115200);
}
void timer_interrupt(void)
{
static int syncClock;
static bool smplReady;
static int skips;
static byte ones;
static bool fiveOnes;
static byte count8;
static byte buf8;
static int addr;
//save sync points
state_2 = digitalRead(19);
if(state_1 == 0 && state_2 == 1) //rising edge
{
for(int s = 0; s < 7; s++)
{
pArray[s] = pArray[s + 1];
}
pArray[6] = syncClock;
}
//sample and get byte
if(syncClock - syncPoint >= -1 && syncClock - syncPoint <= 1)
{
smplReady = true;
}
else if(syncClock - syncPoint == -9 || syncClock - syncPoint == 9)
{
smplReady = true;
}
else if(smplReady == true)
{
skips++;
if(skips == 5) //go sample now!
{
state_4 = digitalRead(19);
if(state_3 != state_4) //(NRZI) inverted = 0
{
if(fiveOnes == true)
{
//zero insertion
//do nothing
}
else
{
buf8 = buf8 >> 1;
bitWrite(buf8, 7, 0);
Serial.print('0');
count8++;
}
fiveOnes = false;
ones = 0;
}
else //(NRZI) no change = 1
{
buf8 = buf8 >> 1;
bitWrite(buf8, 7, 1);
Serial.print('1');
ones++;
if(ones == 5)
{
fiveOnes = true;
}
else
{
fiveOnes = false;
}
count8++;
if(ones == 6) //flag
{
count8 = 7; //reset position
}
}
if(count8 == 8) //get BYTE now!
{
/*
Serial.print(" ");
if(buf8 < 16)
{
Serial.print('0');
}
Serial.print(buf8, HEX);
*/
if(buf8 != 0x7E && addr < 15) //address field
{
buf8 = buf8 >> 1;
}
Serial.print(" ");
Serial.println((char)buf8);
count8 = 0;
addr++;
if(buf8 == 0x7E) //after flag
{
addr = 1;
}
}
smplReady = false;
skips = 0;
}
}
syncClock++;
if(syncClock > 9)
{
syncClock = 0;
}
state_1 = state_2;
state_3 = state_4;
}
void loop()
{
volatile int tMax;
int sumArray[] = {0,0,0,0,0,0,0,0,0,0};
//find MOST SEEN point
for(int p = 0; p < 7; p++)
{
/*
Serial.print(pArray[p]);
Serial.print(' ');
*/
for(int s = 0; s < 10; s++)
{
if(pArray[p] == s)
{
sumArray[s] += 1;
}
}
}
/*
for(int s = 0; s < 10; s++)
{
Serial.print(sumArray[s]);
Serial.print(' ');
}
*/
tMax = -1;
syncPoint = -1;
for(int s = 0; s < 10; s++)
{
if(sumArray[s] > tMax)
{
tMax = sumArray[s];
syncPoint = s;
}
}
/*
Serial.print("tMax:");
Serial.print(tMax);
Serial.print(' ');
Serial.print("syncPoint:");
Serial.print(syncPoint);
Serial.print(' ');
Serial.println();
*/
delay(1);
}