kopia lustrzana https://github.com/DL7AD/pecanpico9
Implemented Log packets for the last protocol changes
rodzic
c745ef50c9
commit
955c33a2f8
|
@ -1,7 +1,6 @@
|
|||
#!/usr/bin/python3
|
||||
|
||||
import serial,re,io
|
||||
import base91
|
||||
import sys
|
||||
import argparse
|
||||
import telnetlib
|
||||
|
@ -63,7 +62,8 @@ sqlite.cursor().execute("""
|
|||
si4464_temp INTEGER,
|
||||
|
||||
sys_time INTEGER,
|
||||
sys_error INTEGER
|
||||
sys_error INTEGER,
|
||||
PRIMARY KEY (call,reset,id,time)
|
||||
)
|
||||
""")
|
||||
sqlite.cursor().execute("""
|
||||
|
@ -104,20 +104,18 @@ def received_data(data):
|
|||
|
||||
if pos: # Position packet (with comment and telementry)
|
||||
|
||||
posi = pos.group(3)
|
||||
comm = pos.group(4)
|
||||
tel = pos.group(5)
|
||||
position.insert_position(sqlite, call, posi, comm, tel)
|
||||
position.insert_position(sqlite, call, comm, 'pos')
|
||||
|
||||
elif dat: # Data packet
|
||||
|
||||
typ = dat.group(3)
|
||||
data = base91.decode(dat.group(4)) # Decode Base91
|
||||
data = dat.group(4)
|
||||
|
||||
if typ is 'I': # Image packet
|
||||
image.insert_image(sqlite, rxer, call, data)
|
||||
elif typ is 'L': # Log packet
|
||||
position.insert_log(sqlite, call, data)
|
||||
position.insert_position(sqlite, call, data, 'log')
|
||||
|
||||
if args.device == 'I': # Source APRS-IS
|
||||
|
||||
|
|
|
@ -1,24 +1,9 @@
|
|||
<?php
|
||||
class Telemetry {
|
||||
|
||||
/*const TYPE_INT = 0; // Integer
|
||||
const TYPE_STR = 1; // String
|
||||
const TYPE_HTML = 2; // HTML
|
||||
|
||||
const LOC_INT = 0; // Internal
|
||||
const LOC_EXT = 1; // External
|
||||
|
||||
const LOC_INT1 = 0; // Internal 1
|
||||
const LOC_EXT1 = 1; // External 1
|
||||
const LOC_EXT2 = 2; // External 2
|
||||
|
||||
const COL_GREEN = "#008000";
|
||||
const COL_ORANGE = "#CC6600";
|
||||
const COL_RED = "#FF0000";*/
|
||||
|
||||
function __construct($sqlResult) {
|
||||
$this->reset = $sqlResult['reset'];
|
||||
$this->id = $sqlResult['id'];
|
||||
$this->org = $sqlResult['org'];
|
||||
|
||||
$this->rxtime = $sqlResult['rxtime'];
|
||||
|
||||
|
@ -68,101 +53,6 @@ class Telemetry {
|
|||
$this->err_bme280_e2 = ($this->sys_error >> 10) & 0x1;
|
||||
|
||||
}
|
||||
/*function getOV9655Error($type) {
|
||||
$error = ($this->sys_error >> 4) & 0x3;
|
||||
if($type == self::TYPE_INT)
|
||||
return $error;
|
||||
|
||||
switch($error) {
|
||||
case 0: return $this->colorize($type, self::COL_GREEN, "OK");
|
||||
case 1: return $this->colorize($type, self::COL_RED, "I2C Error - Camera not found");
|
||||
case 2: return $this->colorize($type, self::COL_RED, "DMA abort - last buffer segment");
|
||||
case 3: return $this->colorize($type, self::COL_RED, "DMA FIFO error");
|
||||
case 4: return $this->colorize($type, self::COL_RED, "DMA stream transfer error");
|
||||
case 5: return $this->colorize($type, self::COL_RED, "DMA direct mode error");
|
||||
}
|
||||
}
|
||||
function getGPSStatus($type) {
|
||||
if($type == self::TYPE_INT)
|
||||
return $this->gps_lock;
|
||||
|
||||
switch($this->gps_lock) {
|
||||
case 0: return $this->colorize($type, self::COL_GREEN, "GPS locked");
|
||||
case 1: return $this->colorize($type, self::COL_GREEN, "GPS locked - kept switched on");
|
||||
case 2: return $this->colorize($type, self::COL_RED, "GPS loss");
|
||||
case 3: return $this->colorize($type, self::COL_ORANGE, "Low Batt before switched on");
|
||||
case 4: return $this->colorize($type, self::COL_ORANGE, "Low Batt while switched on");
|
||||
case 5: return $this->colorize($type, self::COL_GREEN, "Data from memory");
|
||||
case 6: return $this->colorize($type, self::COL_RED, "GPS communication error");
|
||||
}
|
||||
}
|
||||
function getEVA7MError($type) {
|
||||
$error = ($this->sys_error >> 2) & 0x1;
|
||||
if($type == self::TYPE_INT)
|
||||
return $error;
|
||||
|
||||
switch($error) {
|
||||
case 0: return $this->colorize($type, self::COL_GREEN, "OK");
|
||||
case 1: return $this->colorize($type, self::COL_RED, "Fail");
|
||||
}
|
||||
}
|
||||
function getI2cError($loc, $type) {
|
||||
$error = $loc == self::LOC_INT ? $this->sys_error & 0x1 : ($this->sys_error >> 1) & 0x1;
|
||||
if($type == self::TYPE_INT)
|
||||
return $error;
|
||||
|
||||
switch($error) {
|
||||
case 0: return $this->colorize($type, self::COL_GREEN, "OK");
|
||||
case 1: return $this->colorize($type, self::COL_RED, "Fail");
|
||||
}
|
||||
}
|
||||
function getPAC1720Error($type) {
|
||||
$error = ($this->sys_error >> 3) & 0x1;
|
||||
if($type == self::TYPE_INT)
|
||||
return $error;
|
||||
|
||||
switch($error) {
|
||||
case 0: return $this->colorize($type, self::COL_GREEN, "OK");
|
||||
case 1: return $this->colorize($type, self::COL_RED, "Fail");
|
||||
}
|
||||
}
|
||||
function getBME280Error($type, $loc) {
|
||||
switch($loc) {
|
||||
case self::LOC_INT1: $error = ($this->sys_error >> 7) & 0x1; break;
|
||||
case self::LOC_EXT1: $error = ($this->sys_error >> 8) & 0x1; break;
|
||||
case self::LOC_EXT2: $error = ($this->sys_error >> 9) & 0x1; break;
|
||||
}
|
||||
if($type == self::TYPE_INT)
|
||||
return $error;
|
||||
|
||||
switch($error) {
|
||||
case 0: return $this->colorize($type, self::COL_GREEN, "OK");
|
||||
case 1: return $this->colorize($type, self::COL_RED, "Fail");
|
||||
}
|
||||
}
|
||||
|
||||
private function colorize($type, $color, $str) {
|
||||
if($type == self::TYPE_HTML)
|
||||
return "<font color=\"$color\">$str</font>";
|
||||
elseif($type == self::TYPE_STR)
|
||||
return $str;
|
||||
}*/
|
||||
}
|
||||
?>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -84,7 +84,20 @@ class Tracker {
|
|||
if($from - $to > 64281600)
|
||||
$from = $from + 64281600; // Max. 744 days (2 non leap years + 14 weeks)
|
||||
|
||||
$stmt = Database::getInstance()->prepare("SELECT * FROM position WHERE :from <= rxtime AND rxtime <= :to AND call = :call ORDER BY rxtime ASC");
|
||||
$stmt = Database::getInstance()->prepare("
|
||||
SELECT *
|
||||
FROM position
|
||||
WHERE (
|
||||
:from <= rxtime
|
||||
AND rxtime <= :to
|
||||
AND org = 'pos'
|
||||
) OR (
|
||||
:from <= gps_time
|
||||
AND gps_time <= :to
|
||||
AND org = 'log'
|
||||
) AND call = :call
|
||||
ORDER BY rxtime ASC
|
||||
");
|
||||
$stmt->bindValue(':call', $this->call, SQLITE3_TEXT);
|
||||
$stmt->bindValue(':from', $from, SQLITE3_INTEGER);
|
||||
$stmt->bindValue(':to', $to, SQLITE3_INTEGER);
|
||||
|
@ -131,3 +144,4 @@ class Tracker {
|
|||
}
|
||||
}
|
||||
?>
|
||||
|
||||
|
|
|
@ -187,11 +187,10 @@ function loadRecentData() {
|
|||
$('#act_pos').text(time_format(json['lastActivity']['pos']));
|
||||
$('#act_img').text(time_format(json['lastActivity']['img']));
|
||||
|
||||
// TODO: Remove old entries
|
||||
|
||||
// Update charts if there is new data or at a timeout of 300 seconds
|
||||
if(tel.length > 0 || json['time']-lastChartUpdate > 300) {
|
||||
|
||||
// Add new rows
|
||||
var time = json['time'];
|
||||
xAxis.minValue = new Date((time-<?=$range?>)*1000),
|
||||
xAxis.maxValue = new Date(time*1000),
|
||||
|
@ -210,7 +209,7 @@ function loadRecentData() {
|
|||
dataLight.addRow([null,null]);
|
||||
}
|
||||
|
||||
var time = new Date(data['rxtime']*1000);
|
||||
var time = new Date(data['org'] == 'pos' ? data['rxtime']*1000 : data['gps_time']*1000);
|
||||
dataBattery.addRow([time, data['adc_vbat'], data['pac_vbat'], data['pac_pbat']/10]);
|
||||
dataSolar.addRow([time, data['adc_vsol'], data['pac_vsol'], data['pac_psol']/10]);
|
||||
dataTemp.addRow([time, data['sen_i1_temp']/100, data['sen_e1_temp']/100, data['sen_e2_temp']/100, data['stm32_temp']/100, data['si4464_temp']/100]);
|
||||
|
@ -220,6 +219,19 @@ function loadRecentData() {
|
|||
last = data['rxtime'];
|
||||
});
|
||||
|
||||
// Remove old rows
|
||||
var removeTime = new Date((time-<?=$range?>)*1000);
|
||||
for(var c=0; c<dataBattery.getNumberOfColumns(); c++) {
|
||||
if(dataBattery.getValue(c, 0) < removeTime) {
|
||||
dataBattery.removeRow(c);
|
||||
dataSolar.removeRow(c);
|
||||
dataTemp.removeRow(c);
|
||||
dataGPS.removeRow(c);
|
||||
dataLight.removeRow(c);
|
||||
}
|
||||
}
|
||||
|
||||
// Update charts
|
||||
batteryChart.draw(dataBattery, voltageOptions);
|
||||
solarChart.draw(dataSolar, voltageOptions);
|
||||
tempChart.draw(dataTemp, tempOptions);
|
||||
|
|
|
@ -2,11 +2,11 @@ import binascii
|
|||
import urllib.request
|
||||
import urllib.error
|
||||
from datetime import datetime
|
||||
from position import decode_position
|
||||
from subprocess import *
|
||||
import time
|
||||
import threading
|
||||
from shutil import copyfile
|
||||
import base91
|
||||
|
||||
def decode_callsign(code):
|
||||
callsign = ''
|
||||
|
@ -59,9 +59,10 @@ def imgproc():
|
|||
time.sleep(1)
|
||||
|
||||
w = time.time()
|
||||
def insert_image(sqlite, receiver, call, data):
|
||||
def insert_image(sqlite, receiver, call, data_b91):
|
||||
global imageProcessor,imageData,w
|
||||
|
||||
data = base91.decode(data_b91)
|
||||
if len(data) != 174:
|
||||
return # APRS message has invalid type or length (or both)
|
||||
|
||||
|
@ -106,7 +107,7 @@ def insert_image(sqlite, receiver, call, data):
|
|||
_id = 0
|
||||
|
||||
# Debug
|
||||
print('Received image packet %d Packet %d ServerID %d' % (imageID, packetID, _id))
|
||||
print('Received image packet Call=%s ImageID=%d PacketID=%d ServerID=%d' % (call, imageID, packetID, _id))
|
||||
|
||||
# Insert into database
|
||||
cur.execute("""
|
||||
|
|
|
@ -3,72 +3,7 @@ import sqlite3
|
|||
import base91
|
||||
import struct
|
||||
|
||||
def insert_log(sqlite, call, data):
|
||||
|
||||
if len(data)/10*10 != len(data): # Is not multiple of 8 bytes
|
||||
return # APRS message sampled too short
|
||||
|
||||
for i in range(int(len(data)/10)):
|
||||
tim = (data[i*10+3] << 24) | (data[i*10+2] << 16) | (data[i*10+1] << 8) | data[i*10+0]
|
||||
lat = (data[i*10+5] << 8) | data[i*10+4]
|
||||
lon = (data[i*10+7] << 8) | data[i*10+6]
|
||||
alt = (data[i*10+9] << 8) | data[i*10+8]
|
||||
|
||||
lat = float(lat * 180) / 65536 - 90
|
||||
lon = float(lon * 360) / 65536 - 180
|
||||
|
||||
tim_stringified = datetime.utcfromtimestamp(tim).strftime("%Y-%m-%d %H:%M:%S")
|
||||
try:
|
||||
sqlite.cursor().execute("INSERT OR FAIL INTO position (call,time,org,lat,lon,alt,isnew) VALUES (?,?,'log',?,?,?,1)", (call, tim, lat, lon, alt))
|
||||
print("Decoded log from %s time %s => lat=%06.3f lon=%07.3f alt=%05d" % (call, tim_stringified, lat, lon, alt))
|
||||
except sqlite3.IntegrityError:
|
||||
print("Decoded log from %s time %s => lat=%06.3f lon=%07.3f alt=%05d already in db" % (call, tim_stringified, lat, lon, alt))
|
||||
|
||||
sqlite.commit()
|
||||
|
||||
def decode_position(posi, tel):
|
||||
# Decode latitude
|
||||
y3 = ord(posi[1]) - 33
|
||||
y2 = ord(posi[2]) - 33
|
||||
y1 = ord(posi[3]) - 33
|
||||
y0 = ord(posi[4]) - 33
|
||||
ye = y0 + y1*91 + y2*8281 + y3*753571
|
||||
y = -ye / 380926.0 + 90
|
||||
|
||||
# Decode longitude
|
||||
x3 = ord(posi[5]) - 33
|
||||
x2 = ord(posi[6]) - 33
|
||||
x1 = ord(posi[7]) - 33
|
||||
x0 = ord(posi[8]) - 33
|
||||
xe = x0 + x1*91 + x2*8281 + x3*753571
|
||||
x = xe / 190463.0 - 180
|
||||
|
||||
# Decode altitude
|
||||
z1 = ord(posi[10]) - 33
|
||||
z0 = ord(posi[11]) - 33
|
||||
ze = z0 + z1*91
|
||||
z = pow(1.002, ze) / 3.281
|
||||
|
||||
# Time
|
||||
timd = datetime.now(timezone.utc)
|
||||
|
||||
# Decode GPS Fix Type
|
||||
isnew = ((ord(posi[12])-33) >> 5) & 0x1
|
||||
|
||||
# Decode telemetry
|
||||
teld = [0]*6
|
||||
if tel != None:
|
||||
for i in range(6):
|
||||
t1 = ord(tel[i*2+0]) - 33
|
||||
t0 = ord(tel[i*2+1]) - 33
|
||||
teld.append(t0 + t1*91)
|
||||
|
||||
return timd,x,y,z,teld,isnew
|
||||
|
||||
def insert_position(sqlite, call, posi, comm, tel): #sqlite, call, data
|
||||
# Decode position
|
||||
timd,x,y,z,teld,isnew = decode_position(posi, tel)
|
||||
|
||||
def insert_position(sqlite, call, comm, typ):
|
||||
# Decode comment
|
||||
data = base91.decode(comm)
|
||||
(adc_vsol,adc_vbat,pac_vsol,pac_vbat,pac_pbat,pac_psol,light_intensity,
|
||||
|
@ -78,36 +13,14 @@ def insert_position(sqlite, call, posi, comm, tel): #sqlite, call, data
|
|||
si4464_temp,reset,_id,gps_time,sys_time,sys_error) = struct.unpack('HHHHhhHBBBBHiiIIIhhhBBBBhhHIIII', data[:72])
|
||||
|
||||
# Insert
|
||||
rxtime = int(datetime.now(timezone.utc).timestamp())
|
||||
sqlite.cursor().execute(
|
||||
"""INSERT INTO position (call,rxtime,org,adc_vsol,adc_vbat,pac_vsol,pac_vbat,pac_pbat,pac_psol,light_intensity,gps_lock,gps_sats,gps_ttff,gps_pdop,gps_alt,gps_lat,gps_lon,sen_i1_press,sen_e1_press,sen_e2_press,sen_i1_temp,sen_e1_temp,sen_e2_temp,sen_i1_hum,sen_e1_hum,sen_e2_hum,sys_error,stm32_temp,si4464_temp,reset,id,sys_time,gps_time)
|
||||
VALUES (?,?,'pos',?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)""",
|
||||
(call,int(timd.timestamp()), adc_vsol,adc_vbat,pac_vsol,pac_vbat,pac_pbat,pac_psol,light_intensity,gps_lock,gps_sats,gps_ttff,gps_pdop,gps_alt,gps_lat,gps_lon,sen_i1_press,sen_e1_press,sen_e2_press,sen_i1_temp,sen_e1_temp,sen_e2_temp,sen_i1_hum,sen_e1_hum,sen_e2_hum,sys_error,stm32_temp,si4464_temp,reset,_id,sys_time,gps_time)
|
||||
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)""",
|
||||
(call,rxtime,typ,adc_vsol,adc_vbat,pac_vsol,pac_vbat,pac_pbat,pac_psol,light_intensity,gps_lock,gps_sats,gps_ttff,gps_pdop,gps_alt,gps_lat,gps_lon,sen_i1_press,sen_e1_press,sen_e2_press,sen_i1_temp,sen_e1_temp,sen_e2_temp,sen_i1_hum,sen_e1_hum,sen_e2_hum,sys_error,stm32_temp,si4464_temp,reset,_id,sys_time,gps_time)
|
||||
)
|
||||
sqlite.commit()
|
||||
|
||||
# Debug
|
||||
tim_stringified = timd.strftime("%Y-%m-%d %H:%M:%S")
|
||||
print("Decoded position from %s time %s => lat=%f lon=%f alt=%d new=%d comment=%s, sequ=%d tel=[%d,%d,%d,%d,%d]"
|
||||
% (call, tim_stringified, y, x, int(z), isnew, comm, teld[0], teld[1], teld[2], teld[3], teld[4], teld[5]))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
print('Received %s packet packet Call=%s Reset=%d ID=%d' % (typ, call, reset, _id))
|
||||
|
||||
|
|
|
@ -386,10 +386,10 @@ void start_user_modules(void)
|
|||
config[0].frequency.hz = 144800000; // Default frequency 144.800 MHz
|
||||
config[0].trigger.type = TRIG_NEW_POINT; // Transmit when tracking manager samples new tracking point
|
||||
chsnprintf(config[0].aprs_conf.callsign, 16, "DL7AD"); // APRS Callsign
|
||||
config[0].aprs_conf.ssid = 13; // APRS SSID
|
||||
config[0].aprs_conf.ssid = 15; // APRS SSID
|
||||
config[0].aprs_conf.symbol = SYM_BALLOON; // APRS Symbol
|
||||
chsnprintf(config[0].aprs_conf.path, 16, "WIDE1-1"); // APRS Path
|
||||
config[0].aprs_conf.preamble = 300; // APRS Preamble (300ms)
|
||||
config[0].aprs_conf.preamble = 200; // APRS Preamble (200ms)
|
||||
config[0].aprs_conf.tel[0] = TEL_VBAT; // APRS Telemetry parameter 1: Battery voltage
|
||||
config[0].aprs_conf.tel[1] = TEL_VSOL; // APRS Telemetry parameter 2: Solar voltage
|
||||
config[0].aprs_conf.tel[2] = TEL_PBAT; // APRS Telemetry parameter 3: Battery charge/discharge power
|
||||
|
@ -398,7 +398,7 @@ void start_user_modules(void)
|
|||
config[0].aprs_conf.tel_enc = TRUE; // Transmit Telemetry encoding information activated
|
||||
config[0].aprs_conf.tel_enc_cycle = 3600; // Transmit Telemetry encoding information every 3600sec
|
||||
chsnprintf(config[0].aprs_conf.tel_comment, 30, "http://ssdv.habhub.org/DL7AD");// Telemetry comment
|
||||
//start_position_thread(&config[0]);
|
||||
start_position_thread(&config[0]);
|
||||
|
||||
// Module POSITION, UKHAS 2m 2FSK
|
||||
config[1].power = 127; // Transmission Power
|
||||
|
@ -440,7 +440,7 @@ void start_user_modules(void)
|
|||
config[3].trigger.type = TRIG_CONTINUOUSLY; // Transmit continuously
|
||||
chsnprintf(config[3].aprs_conf.callsign, 16, "DL7AD"); // APRS Callsign
|
||||
config[3].aprs_conf.ssid = 14; // APRS SSID
|
||||
config[3].aprs_conf.preamble = 300; // APRS Preamble (300ms)
|
||||
config[3].aprs_conf.preamble = 200; // APRS Preamble (200ms)
|
||||
config[3].ssdv_conf.ram_buffer = ssdv_buffer; // Camera buffer
|
||||
config[3].ssdv_conf.ram_size = sizeof(ssdv_buffer); // Buffer size
|
||||
config[3].ssdv_conf.res = RES_QVGA; // Resolution QVGA
|
||||
|
@ -473,8 +473,8 @@ void start_user_modules(void)
|
|||
config[5].fsk_conf.bits = 8; // 8bit
|
||||
config[5].fsk_conf.stopbits = 2; // 2 Stopbits
|
||||
config[5].fsk_conf.predelay = 3000; // Preamble (1000ms)
|
||||
config[5].fsk_conf.baud = 300; // Baudrate (600baud)
|
||||
config[5].fsk_conf.shift = 425; // Frequency shift (1000Hz)
|
||||
config[5].fsk_conf.baud = 600; // Baudrate (600baud)
|
||||
config[5].fsk_conf.shift = 425; // Frequency shift (1000Hz)
|
||||
chsnprintf(config[5].ssdv_conf.callsign, 7, "DL7AD"); // SSDV Callsign
|
||||
config[5].ssdv_conf.ram_buffer = ssdv_buffer; // Camera buffer
|
||||
config[5].ssdv_conf.ram_size = sizeof(ssdv_buffer); // Buffer size
|
||||
|
@ -492,11 +492,10 @@ void start_user_modules(void)
|
|||
config[6].frequency.hz = 144800000; // Default frequency 144.800 MHz
|
||||
config[6].init_delay = 5000; // Module startup delay (5 seconds)
|
||||
config[6].trigger.type = TRIG_TIMEOUT; // Periodic cycling (every 180 seconds)
|
||||
config[6].trigger.timeout = 60; // Timeout 180 sec
|
||||
config[6].trigger.timeout = 60; // Timeout 60 sec
|
||||
chsnprintf(config[6].aprs_conf.callsign, 16, "DL7AD"); // APRS Callsign
|
||||
config[6].aprs_conf.ssid = 13; // APRS SSID
|
||||
chsnprintf(config[6].aprs_conf.path, 16, "WIDE1-1"); // APRS Path
|
||||
config[6].aprs_conf.preamble = 300; // APRS Preamble (300ms)
|
||||
//start_logging_thread(&config[6]);
|
||||
config[6].aprs_conf.ssid = 15; // APRS SSID
|
||||
config[6].aprs_conf.preamble = 200; // APRS Preamble (200ms)
|
||||
start_logging_thread(&config[6]);
|
||||
}
|
||||
|
||||
|
|
|
@ -147,32 +147,7 @@ THD_FUNCTION(logThread, arg)
|
|||
if(!p_sleep(&conf->sleep_conf))
|
||||
{
|
||||
// Get log from memory
|
||||
|
||||
uint16_t pkt[80]; // 16 PositionPoints each 10 bytes
|
||||
uint8_t pkt_base91[BASE91LEN(160)];
|
||||
for(uint16_t t=0; t<sizeof(pkt_base91); t++) pkt_base91[t] = 0; // Deleting buffer
|
||||
|
||||
TRACE_INFO("LOG > Encode 16 log points")
|
||||
|
||||
for(uint8_t i=0; i<16; i++)
|
||||
{
|
||||
trackPoint_t log;
|
||||
getNextLogTrackPoint(&log);
|
||||
|
||||
TRACE_INFO("id=%d time=%d lat=%d lon=%d alt=%d", log.id, log.gps_time, log.gps_lat, log.gps_lon, log.gps_alt);
|
||||
int64_t lat = (int64_t)log.gps_lat + (int64_t)900000000 + 13733;
|
||||
lat <<= 16;
|
||||
lat /= 1800000000;
|
||||
int64_t lon = (int64_t)log.gps_lon + (int64_t)1800000000 + 27466;
|
||||
lon <<= 16;
|
||||
lon /= 3600000000;
|
||||
|
||||
pkt[i*5+0] = log.gps_time & 0xFFFF;
|
||||
pkt[i*5+1] = log.gps_time >> 16;
|
||||
pkt[i*5+2] = lat; // Latitude (get full 16bit resolution over 180°)
|
||||
pkt[i*5+3] = lon; // Longitude (get full 16bit resolution over 360°)
|
||||
pkt[i*5+4] = log.gps_alt; // Altitude in meters (cut off first two MSB bytes)
|
||||
}
|
||||
trackPoint_t log;
|
||||
|
||||
// Encode radio message
|
||||
radioMSG_t msg;
|
||||
|
@ -188,14 +163,19 @@ THD_FUNCTION(logThread, arg)
|
|||
msg.afsk_conf = &(conf->afsk_conf);
|
||||
msg.gfsk_conf = &(conf->gfsk_conf);
|
||||
|
||||
ax25_t ax25_handle;
|
||||
|
||||
// Encode Base91
|
||||
base91_encode((uint8_t*)pkt, pkt_base91, sizeof(pkt));
|
||||
uint8_t pkt_base91[BASE91LEN(sizeof(log))];
|
||||
|
||||
// Encode and transmit log packet
|
||||
ax25_t ax25_handle;
|
||||
aprs_encode_init(&ax25_handle, buffer, sizeof(buffer), msg.mod);
|
||||
aprs_encode_data_packet(&ax25_handle, 'L', &conf->aprs_conf, pkt_base91, strlen((char*)pkt_base91)); // Encode packet
|
||||
|
||||
for(uint8_t i=0; i<2; i++) { // Transmit two log packets
|
||||
getNextLogTrackPoint(&log);
|
||||
base91_encode((uint8_t*)&log, pkt_base91, sizeof(log));
|
||||
aprs_encode_data_packet(&ax25_handle, 'L', &conf->aprs_conf, pkt_base91, strlen((char*)pkt_base91)); // Encode packet
|
||||
}
|
||||
|
||||
msg.bin_len = aprs_encode_finalize(&ax25_handle);
|
||||
|
||||
// Transmit packet
|
||||
|
|
Ładowanie…
Reference in New Issue