diff --git a/decoder/decoder.py b/decoder/decoder.py
index fc0868d..2cbc586 100755
--- a/decoder/decoder.py
+++ b/decoder/decoder.py
@@ -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
diff --git a/decoder/html/Telemetry.class.php b/decoder/html/Telemetry.class.php
index 3175247..4c3eee3 100644
--- a/decoder/html/Telemetry.class.php
+++ b/decoder/html/Telemetry.class.php
@@ -1,24 +1,9 @@
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 "$str";
- elseif($type == self::TYPE_STR)
- return $str;
- }*/
}
?>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/decoder/html/Tracker.class.php b/decoder/html/Tracker.class.php
index dcb7ae6..dfd4ffb 100644
--- a/decoder/html/Tracker.class.php
+++ b/decoder/html/Tracker.class.php
@@ -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 {
}
}
?>
+
diff --git a/decoder/html/telemetry.php b/decoder/html/telemetry.php
index 8a9ea90..5fb72ca 100644
--- a/decoder/html/telemetry.php
+++ b/decoder/html/telemetry.php
@@ -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 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))
diff --git a/tracker/software/config.c b/tracker/software/config.c
index c3ca3e3..692cb44 100644
--- a/tracker/software/config.c
+++ b/tracker/software/config.c
@@ -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]);
}
diff --git a/tracker/software/threads/log.c b/tracker/software/threads/log.c
index 2916f5d..1fd2c8b 100644
--- a/tracker/software/threads/log.c
+++ b/tracker/software/threads/log.c
@@ -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 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