Skip to content

Commit

Permalink
Bugfixes APRS/OGNTP/RF - Flarm features
Browse files Browse the repository at this point in the history
  • Loading branch information
roema committed Nov 3, 2020
1 parent fab85df commit b49c3b5
Show file tree
Hide file tree
Showing 9 changed files with 205 additions and 38 deletions.
9 changes: 8 additions & 1 deletion ognbase/APRS.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,14 @@ void OGN_APRS_Export()
APRS_AIRC.callsign = String(Container[i].addr, HEX);
APRS_AIRC.callsign.toUpperCase();
APRS_AIRC.rec_callsign = ogn_callsign;
APRS_AIRC.timestamp = zeroPadding(String(hour()), 2) + zeroPadding(String(minute()), 2) + zeroPadding(String(second()), 2) + "h";

//APRS_AIRC.timestamp = zeroPadding(String(hour()), 2) + zeroPadding(String(minute()), 2) + zeroPadding(String(second()), 2) + "h";

// TBD need to use Container[i].timestamp instead of hour(), minute(), second()
// actually, need to make sure Container[i].timestamp is based on SlotTime not current time due slot-2 time extension
//converting Container[i].timestamp to hour minutes seconds
time_t receive_time = Container[i].timestamp;
APRS_AIRC.timestamp = zeroPadding(String(hour(receive_time)), 2) + zeroPadding(String(minute(receive_time)), 2) + zeroPadding(String(second(receive_time)), 2) + "h";

/*Latitude*/
APRS_AIRC.lat_deg = String(int(LAT));
Expand Down
3 changes: 2 additions & 1 deletion ognbase/Protocol_OGNTP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,8 @@ size_t ogntp_encode(void* pkt, ufo_t* this_aircraft)

ogn_tx_pkt.Packet.Position.AcftType = (int16_t) this_aircraft->aircraft_type;
ogn_tx_pkt.Packet.Position.Stealth = (int16_t) this_aircraft->stealth;
ogn_tx_pkt.Packet.Position.Time = second();
// ogn_tx_pkt.Packet.Position.Time = second();
ogn_tx_pkt.Packet.Position.Time = this_aircraft->timestamp % 60;

ogn_tx_pkt.Packet.Whiten();
ogn_tx_pkt.calcFEC();
Expand Down
185 changes: 161 additions & 24 deletions ognbase/RF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
#include "Log.h"
#endif /* LOGGER_IS_ENABLED */

#define DEBUG 1 // Nick to see messages

byte RxBuffer[MAX_PKT_SIZE];

unsigned long TxTimeMarker = 0;
Expand Down Expand Up @@ -307,6 +309,21 @@ byte RF_setup(void)
return RF_IC_NONE;
}

#define DELAY_PPS_GPSTIME 200 // approx msec between PPS and time in NMEA sentence
#define SLOT1_START 400 // slot1 start msec after PPS
#define SLOT1_ADVANCE 100 // advance slot1 to mid of dead time between slots
#define SLOT2_START 800 // slot2 start msec after PPS
#define SLOT_DURATION 400 // slot msec duration

extern int status_LED; // LEDHelper

static long TimeReference = 0; // Hop reference timing
static long TimeReference_2 = 0;
static long Now_millis = 0;
static long prev_TimeCommit = 0;
uint8_t Slot = 0;
time_t slotTime = 0;

void RF_SetChannel(void)
{
tmElements_t tm;
Expand All @@ -323,6 +340,7 @@ void RF_SetChannel(void)
case SOFTRF_MODE_GROUND:
case SOFTRF_MODE_NORMAL:
default:
/*
unsigned long pps_btime_ms = SoC->get_PPS_TimeMarker();
unsigned long time_corr_pos = 0;
unsigned long time_corr_neg = 0;
Expand All @@ -334,7 +352,7 @@ void RF_SetChannel(void)
time_corr_neg = (lastCommitTime - pps_btime_ms) % 1000;
else
time_corr_neg = 1000 - ((pps_btime_ms - lastCommitTime) % 1000);
time_corr_pos = 400; /* 400 ms after PPS for V6, 350 ms - for OGNTP */
time_corr_pos = 400; // 400 ms after PPS for V6, 350 ms - for OGNTP
}
int yr = gnss.date.year();
Expand All @@ -353,15 +371,109 @@ void RF_SetChannel(void)
break;
}
uint8_t Slot = 0; /* only #0 "400ms" timeslot is currently in use */
uint8_t Slot = 0; // only #0 "400ms" timeslot is currently in use
uint8_t OGN = (settings->rf_protocol == RF_PROTOCOL_OGNTP ? 1 : 0);
/* FANET uses 868.2 MHz. Bandwidth is 250kHz */
if (settings->rf_protocol == RF_PROTOCOL_FANET)
/ FANET uses 868.2 MHz. Bandwidth is 250kHz
if (settings->rf_protocol == RF_PROTOCOL_FANET) {
Slot = 0;
}
uint8_t chan = RF_FreqPlan.getChannel(Time, Slot, OGN);
*/
unsigned long pps_btime_ms = SoC->get_PPS_TimeMarker();
// unsigned long time_corr_pos = 0;
unsigned long time_corr_neg = 0;
unsigned long timeAge = 0;
unsigned long lastCommitTime = (Now_millis = millis()) - (timeAge = gnss.time.age());

// HOP Testing - NMEA sentence time commit
//Serial.printf("Commit: %d, %d, %d\r\n", lastCommitTime, prev_TimeCommit, pps_btime_ms);

// Time could be in GGA or RMC. For consistency must pick only first one
// problem is that the second commit is 450 msec after the first or only 550 before next !
// not needed if PPS is available
if (lastCommitTime - prev_TimeCommit < 500) {
lastCommitTime = prev_TimeCommit;
timeAge = Now_millis - lastCommitTime;
} else {
prev_TimeCommit = lastCommitTime;
}

// if PPS available, reference time is PPS relative for accuracy
if (pps_btime_ms) {
// calculate delta time from millis() to PPS reference
if (pps_btime_ms <= lastCommitTime) {
time_corr_neg = (lastCommitTime - pps_btime_ms) % 1000;
} else {
time_corr_neg = 1000 - ((pps_btime_ms - lastCommitTime) % 1000);
}
} else { // no PPS, approximate reference delay
time_corr_neg = DELAY_PPS_GPSTIME;
}

// only frequency hop with legacy and OGN protocols
switch (settings->rf_protocol) {
case RF_PROTOCOL_LEGACY:
case RF_PROTOCOL_OGNTP:
if ((Now_millis - TimeReference) >= 1000) {
if (pps_btime_ms) {
TimeReference = pps_btime_ms +SLOT1_START -SLOT1_ADVANCE -0; // allow for latency ?
} else {
TimeReference = lastCommitTime -time_corr_neg +SLOT1_START -SLOT1_ADVANCE;
}
Slot = 0;
if ((Now_millis - TimeReference) >= 1000) { // has PPS stopped ?
TxTimeMarker = Now_millis; // if so no Tx
return;
} else {
TxTimeMarker = TimeReference;
}
TxRandomValue = SoC->random(0, SLOT_DURATION -10) +SLOT1_ADVANCE; // allow some margin
} else {
if ((Now_millis - TimeReference_2) >= 1000) {
TimeReference_2 = TimeReference +SLOT_DURATION +SLOT1_ADVANCE;
Slot = 1;
TxTimeMarker = TimeReference_2;
TxRandomValue = SoC->random(10, SLOT_DURATION -0); // allow some margin
} else {
return;
}
}
break;
default:
/* FANET uses 868.2 MHz. Bandwidth is 250kHz */
Slot = 0;
break;
}

// HOP Testing - slot timing 400 and 800 msec after PPS
//Serial.printf("Timing: %d, %d, %d, %d, %d, %d, %d\r\n", Now_millis, pps_btime_ms, timeAge, time_corr_neg, TimeReference, TxRandomValue, Slot);

// latest time from GPS
int yr = gnss.date.year();
if( yr > 99)
yr = yr - 1970;
else
yr += 30;
tm.Year = yr;
tm.Month = gnss.date.month();
tm.Day = gnss.date.day();
tm.Hour = gnss.time.hour();
tm.Minute = gnss.time.minute();
tm.Second = gnss.time.second();

// time right now is:
slotTime = Time = makeTime(tm) + (timeAge + time_corr_neg)/ 1000;
break;
}

uint8_t OGN = (settings->rf_protocol == RF_PROTOCOL_OGNTP ? 1 : 0);

uint8_t chan = RF_FreqPlan.getChannel(Time, Slot, OGN);

// HOP Testing - time and channel
//Serial.printf("Time: %d, %d\r\n", Time,chan);
#if DEBUG
Serial.print("Plan: ");
Serial.println(RF_FreqPlan.Plan);
Expand All @@ -373,49 +485,55 @@ void RF_SetChannel(void)
Serial.println(chan);
#endif

if (RF_ready && rf_chip)
if (RF_ready && rf_chip) {
rf_chip->channel(chan);
}
}

void RF_loop()
{
if (!RF_ready)
{
if (RF_FreqPlan.Plan == RF_BAND_AUTO)
{
if (ThisAircraft.latitude || ThisAircraft.longitude)
{
if (!RF_ready) {
if (RF_FreqPlan.Plan == RF_BAND_AUTO) {
if (ThisAircraft.latitude || ThisAircraft.longitude) {
RF_FreqPlan.setPlan((int32_t)(ThisAircraft.latitude * 600000),
(int32_t)(ThisAircraft.longitude * 600000));
RF_ready = true;
}
}
else
} else {
RF_ready = true;
}
}

if (RF_ready)
if (RF_ready) {
RF_SetChannel();
}
}

size_t RF_Encode(ufo_t* fop)
{
size_t size = 0;
if (RF_ready && protocol_encode)
{
if (settings->txpower == RF_TX_POWER_OFF)
if (RF_ready && protocol_encode) {
if (settings->txpower == RF_TX_POWER_OFF) {
return size;

if ((millis() - TxTimeMarker) > TxRandomValue)
size = (*protocol_encode)((void *) &TxBuffer[0], fop);
}

if ((millis() - TxTimeMarker) > TxRandomValue) {
switch (settings->rf_protocol) {
case RF_PROTOCOL_LEGACY:
case RF_PROTOCOL_OGNTP:
fop->timestamp = slotTime;
break;
}
size = (*protocol_encode)((void *) &TxBuffer[0], fop);
}
}
return size;
}

bool RF_Transmit(size_t size, bool wait)
{
if (RF_ready && rf_chip && (size > 0))
{
if (RF_ready && rf_chip && (size > 0)){
RF_tx_size = size;

if (settings->txpower == RF_TX_POWER_OFF)
Expand All @@ -437,7 +555,7 @@ bool RF_Transmit(size_t size, bool wait)
}
tx_packets_counter++;
RF_tx_size = 0;

/*
TxRandomValue = (
#if !defined(EXCLUDE_SX12XX)
LMIC.protocol ?
Expand All @@ -446,7 +564,26 @@ bool RF_Transmit(size_t size, bool wait)
SoC->random(LEGACY_TX_INTERVAL_MIN, LEGACY_TX_INTERVAL_MAX));
TxTimeMarker = millis();

*/
switch (settings->rf_protocol) {
case RF_PROTOCOL_LEGACY:
case RF_PROTOCOL_OGNTP:
TxRandomValue = 2000; // HOP - stop any re-trigger for now until next channel change
TxTimeMarker = millis();
break;
default:
TxRandomValue = (
#if !defined(EXCLUDE_SX12XX)
LMIC.protocol ?
SoC->random(LMIC.protocol->tx_interval_min, LMIC.protocol->tx_interval_max) :
#endif
SoC->random(LEGACY_TX_INTERVAL_MIN, LEGACY_TX_INTERVAL_MAX));
TxTimeMarker = millis();
break;
}

// HOP testing - transmit time
//Serial.printf("Tx: %d, %d, %d\r\n", millis(), TxTimeMarker, TxRandomValue);
return true;
}
}
Expand Down
2 changes: 1 addition & 1 deletion ognbase/SoftRF.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
#include <raspi/raspi.h>
#endif /* RASPBERRY_PI */

#define SOFTRF_FIRMWARE_VERSION "0.0.4"
#define SOFTRF_FIRMWARE_VERSION "0.0.5"
#define SOFTRF_IDENT "OGNB-"

#define ENTRY_EXPIRATION_TIME 10 /* seconds */
Expand Down
16 changes: 13 additions & 3 deletions ognbase/Traffic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,12 +154,16 @@ void ParseData()
StdOut.println(RF_last_rssi);
}


if (protocol_decode && (*protocol_decode)((void *) RxBuffer, &ThisAircraft, &fo))
{
int i;

fo.rssi = RF_last_rssi;

for (int i=0; i < MAX_TRACKING_OBJECTS; i++) {
// for debugging
Serial.printf("Pkt: %06x\r\n", fo.addr);

for (i=0; i < MAX_TRACKING_OBJECTS; i++) {
if (Container[i].addr == fo.addr)
{
Container[i] = fo;
Expand All @@ -173,7 +177,13 @@ void ParseData()
break;
}
}
}
// detect and delete double IDs - Caz Yokoyama fix
while (++i < MAX_TRACKING_OBJECTS) {
if (Container[i].addr == fo.addr) {
Container[i] = EmptyFO;
}
}
}
}

void Traffic_setup()
Expand Down
10 changes: 7 additions & 3 deletions ognbase/Web.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,15 @@ AsyncWebSocketClient* globalClient = NULL;

size_t content_len;

static const char upload_html[] PROGMEM = "<div class = 'upload'>\
static const char upload_html[] PROGMEM = "<html>\
<head>\
<meta http-equiv='Content-Type' content='text/html; charset=utf-8'>\
</head>\
<div class = 'upload'>\
<form method = 'POST' action = '/doUpload' enctype='multipart/form-data'>\
<input type='file' name='data'/><input type='submit' name='upload' value='Upload' title = 'Upload Files'>\
</form></div>";
</form></div>\
</html>";


void onWsEvent(AsyncWebSocket* server, AsyncWebSocketClient* client, AwsEventType type, void* arg, uint8_t* data, size_t len)
Expand Down Expand Up @@ -533,6 +538,5 @@ void Web_loop(void)
values += "_";
values += largest_range;
globalClient->text(values);
delay(1000);
}
}
2 changes: 1 addition & 1 deletion ognbase/data/index.html
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>OGN Groundstation</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="data:,">
<link rel="stylesheet" type="text/css" href="style.css">
<script type = "text/javascript">
Expand Down
2 changes: 1 addition & 1 deletion ognbase/data/update.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<html>
<head>
<meta name='viewport' content='width=device-width, initial-scale=1'>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>Firmware update</title>
</head>
<body>
Expand Down
Loading

0 comments on commit b49c3b5

Please sign in to comment.