- Merged dbgon and dbgoff command to debug

- Fixed error in SOI-not-found flag in debug.c
- Added camera-command command (for testing different camera options while watching the livestream)
- Fixed table header in readLog USB command
- Added last-image-id to track-point struct (which is also logged), SSDV transmission will start with next ID on STM32 reset.
  This has been done while habhub alway mixes up different images with the same image id.
- Added thread (module) configuration printout on USB debug
- Added GPS_LOG and GPS_OFF flag
- Changed tracking manager initialization strategy:
  Tracking Manager runs all time and also logs when there is no new GPS fix
  Tracking Manager logs images ID
  Tracking Manager doesnt switch on GPS unless there is a position thread running (in order to save energy when position is not sent out)
Implemented several flags in decoder2.py
Added script command.c which sends camera registers via USB to the OV5640.
Develop
Sven Steudte 2017-09-11 06:45:19 +02:00
rodzic e9cff81fa4
commit 37180ab892
16 zmienionych plików z 206 dodań i 152 usunięć

18
decoder/command.py 100644
Wyświetl plik

@ -0,0 +1,18 @@
#!/usr/bin/python
import serial,os,re,sys
import pygame
from pygame.locals import *
import pygame.time
from cStringIO import StringIO
try:
ser = serial.Serial(port='/dev/ttyACM1')
except:
sys.stderr.write('Error: Could not open serial port\n')
sys.exit(1)
ser.write('\r\n')
ser.write('command '+str(int(sys.argv[1], 16))+' '+str(int(sys.argv[2], 16))+'\r\n')
ser.close()

Wyświetl plik

@ -40,8 +40,15 @@ while True:
print line.strip()
continue
i += 1
if int(size) == 0:
ser.write('picture\r\n')
continue
imgbuf = ser.read(int(size))
for event in pygame.event.get():
if event.type == QUIT:
exit(0)
@ -61,6 +68,11 @@ while True:
screen.blit(textsurface,(0,0))
pygame.display.flip()
pygame.display.update(displaygroup.draw(screen))
f = open('data/data'+str(i)+'.jpg','wb')
f.write(imgbuf)
f.close()
except Exception as e:
print str(e)
textsurface = myfont.render('Error %s' % (e), False, (255, 100, 100))
@ -69,7 +81,6 @@ while True:
pygame.display.update(displaygroup.draw(screen))
ser.write('picture\r\n')
i += 1

16
decoder/empty.py 100644
Wyświetl plik

@ -0,0 +1,16 @@
#!/usr/bin/python
import serial,os,re,sys
import pygame
from pygame.locals import *
import pygame.time
from cStringIO import StringIO
try:
ser = serial.Serial(port='/dev/ttyACM1')
except:
sys.stderr.write('Error: Could not open serial port\n')
sys.exit(1)
while True:
ser.read(1)

Wyświetl plik

@ -463,7 +463,7 @@ void start_user_modules(void)
config[4].ssdv_conf.ram_size = sizeof(ssdv_buffer); // Buffer size
config[4].ssdv_conf.res = RES_VGA; // Resolution VGA
config[4].ssdv_conf.quality = 4; // Image quality
//start_image_thread(&config[4]);
start_image_thread(&config[4]);
// Module IMAGE, SSDV 2m 2FSK
config[5].power = 127; // Transmission Power

Wyświetl plik

@ -5,6 +5,7 @@
#include "config.h"
#include "image.h"
#include "tracking.h"
#include "pi2c.h"
const SerialConfig uart_config =
{
@ -18,23 +19,19 @@ mutex_t trace_mtx; // Used internal to synchronize multiple chprintf in debug.h
bool debug_on_usb = false;
void debugOnUSB_Off(BaseSequentialStream *chp, int argc, char *argv[])
void debugOnUSB(BaseSequentialStream *chp, int argc, char *argv[])
{
(void)chp;
(void)argc;
(void)argv;
debug_on_usb = false;
if(argc < 1)
{
chprintf(chp, "Argument missing!\r\n");
chprintf(chp, "Argument 1: 1 for switch on, 0 for switch off!\r\n");
return;
}
debug_on_usb = atoi(argv[0]);
}
void debugOnUSB_On(BaseSequentialStream *chp, int argc, char *argv[])
{
(void)chp;
(void)argc;
(void)argv;
debug_on_usb = true;
}
static uint8_t usb_buffer[96*1024] __attribute__((aligned(32))); // USB image buffer
static uint8_t usb_buffer[64*1024] __attribute__((aligned(32))); // USB image buffer
void printPicture(BaseSequentialStream *chp, int argc, char *argv[])
{
(void)argc;
@ -67,8 +64,8 @@ void printPicture(BaseSequentialStream *chp, int argc, char *argv[])
}
if(!start_detected)
{
TRACE_USB("DATA > image,jpeg,0");
TRACE_USB("DATA > error,no SOI flag found");
TRACE_USB("DATA > image/jpeg,0");
TRACE_USB("DATA > text/trace,no SOI flag found");
}
} else { // No camera found
@ -79,16 +76,11 @@ void printPicture(BaseSequentialStream *chp, int argc, char *argv[])
}
}
trackPoint_t* getLogBuffer(uint16_t id)
void command2Camera(BaseSequentialStream *chp, int argc, char *argv[])
{
if(sizeof(trackPoint_t)*id < LOG_SECTOR_SIZE-sizeof(trackPoint_t))
{
return (trackPoint_t*)(LOG_FLASH_ADDR1 + id * sizeof(trackPoint_t));
} else if((id-(LOG_SECTOR_SIZE/sizeof(trackPoint_t)))*sizeof(trackPoint_t) < LOG_SECTOR_SIZE-sizeof(trackPoint_t)) {
return (trackPoint_t*)(LOG_FLASH_ADDR2 + (id-(LOG_SECTOR_SIZE/sizeof(trackPoint_t))) * sizeof(trackPoint_t));
} else { // Outside of memory address allocation
return NULL;
}
(void)chp;
(void)argc;
I2C_write8_16bitreg(0x3C, atoi(argv[0]), atoi(argv[1]));
}
void readLog(BaseSequentialStream *chp, int argc, char *argv[])
@ -96,17 +88,19 @@ void readLog(BaseSequentialStream *chp, int argc, char *argv[])
(void)argc;
(void)argv;
chprintf(chp, "id,date,time,lat,lon,alt,sats,ttff,vbat,vsol,vsub,pbat,rbat,press,temp,hum,idimg\r\n");
trackPoint_t *tp;
for(uint16_t i=0; (tp = getLogBuffer(i)) != NULL; i++)
if(tp->id != 0xFFFFFFFF)
{
chprintf( chp,
"%d,%04d-%02d-%02d,%02d:%02d:%02d,%d.%05d,%d.%05d,%d,%d,%d,%d.%03d,%d.%03d,%d.%03d,%d,%d,%d.%01d,%2d.%02d,%2d.%01d\r\n",
"%d,%04d-%02d-%02d,%02d:%02d:%02d,%d.%05d,%d.%05d,%d,%d,%d,%d.%03d,%d.%03d,%d.%03d,%d,%d,%d.%01d,%2d.%02d,%2d.%01d,%d\r\n",
tp->id,tp->time.year, tp->time.month, tp->time.day, tp->time.hour, tp->time.minute, tp->time.day,
tp->gps_lat/10000000, (tp->gps_lat > 0 ? 1:-1)*(tp->gps_lat/100)%100000, tp->gps_lon/10000000, (tp->gps_lon > 0 ? 1:-1)*(tp->gps_lon/100)%100000, tp->gps_alt,
tp->gps_sats, tp->gps_ttff,
tp->adc_vbat/1000, (tp->adc_vbat%1000), tp->adc_vsol/1000, (tp->adc_vsol%1000), tp->adc_vusb/1000, (tp->adc_vusb%1000), tp->adc_pbat, tp->adc_rbat,
tp->air_press/10, tp->air_press%10, tp->air_temp/100, tp->air_temp%100, tp->air_hum/10, tp->air_hum%10
tp->air_press/10, tp->air_press%10, tp->air_temp/100, tp->air_temp%100, tp->air_hum/10, tp->air_hum%10, tp->id_image
);
}
}
@ -117,6 +111,7 @@ void printConfig(BaseSequentialStream *chp, int argc, char *argv[])
{
chprintf(chp, "Argument missing!\r\n");
chprintf(chp, "Argument 1: Id of config!\r\n");
return;
}
uint8_t id = atoi(argv[0]);
@ -125,9 +120,14 @@ void printConfig(BaseSequentialStream *chp, int argc, char *argv[])
chprintf(chp, "Power: %d\r\n", config[id].power);
if(config[id].frequency.type == FREQ_STATIC) {
chprintf(chp, "Frequency: %d Hz\r\n", config[id].frequency.hz);
uint32_t freq = config[id].frequency.hz;
if((freq/1000)*1000 == freq)
chprintf(chp, "Frequency: %d.%03d MHz\r\n", freq/1000000, (freq%1000000)/1000);
else
chprintf(chp, "Frequency: %d.%03d MHz\r\n", freq/1000000, (freq%1000000));
} else {
chprintf(chp, "Frequency: APRS region dependent (currently %d Hz\r\n", getFrequency(&config[id].frequency));
uint32_t freq = getFrequency(&config[id].frequency);
chprintf(chp, "Frequency: APRS region dependent (currently %d.%03d MHz)\r\n", freq/1000000, (freq%1000000)/1000);
}
chprintf(chp, "Protocol: %d\r\n", config[id].protocol);

Wyświetl plik

@ -104,11 +104,11 @@ extern bool debug_on_usb;
TRACE_INFO("%-4s > Current time: %02d-%02d-%02d %02d:%02d:%02d:%03d", thd, dbgtime.year, dbgtime.month, dbgtime.day, dbgtime.hour, dbgtime.minute, dbgtime.second, dbgtime.millisecond); \
}
void debugOnUSB_Off(BaseSequentialStream *chp, int argc, char *argv[]);
void debugOnUSB_On(BaseSequentialStream *chp, int argc, char *argv[]);
void debugOnUSB(BaseSequentialStream *chp, int argc, char *argv[]);
void printConfig(BaseSequentialStream *chp, int argc, char *argv[]);
void printPicture(BaseSequentialStream *chp, int argc, char *argv[]);
void readLog(BaseSequentialStream *chp, int argc, char *argv[]);
void command2Camera(BaseSequentialStream *chp, int argc, char *argv[]);
#endif

Wyświetl plik

@ -27,11 +27,11 @@ static const struct regval_list OV5640YUV_Sensor_Dvp_Init[] =
{ 0x4051, 0x8f },
{ 0x3008, 0x42 },
{ 0x3103, 0x03 },
{ 0x3103, 0x03 },
{ 0x3017, 0x7f },
{ 0x3018, 0xff },
{ 0x302c, 0x02 },
{ 0x3108, 0x21 },
{ 0x3108, 0x21 }, // PCLK root divider [5:4]
{ 0x3630, 0x2e },//2e
{ 0x3632, 0xe2 },
{ 0x3633, 0x23 },//23
@ -92,12 +92,12 @@ static const struct regval_list OV5640YUV_Sensor_Dvp_Init[] =
{ 0x3814, 0x31 },
{ 0x3815, 0x31 },
{ 0x3034, 0x1a },
{ 0x3035, 0x11 }, //15fps
{ 0x3036, 0x46 },
{ 0x3037, 0x14 },
{ 0x3038, 0x00 },
{ 0x3039, 0x00 },
{ 0x3034, 0x1a }, // PLL charge pump control [7:4]
{ 0x3035, 0x11 }, // System clock divider [7:4]
{ 0x3036, 0x46 }, // PLL multiplier [7:0]
{ 0x3037, 0x14 }, // PLL root divider [4], PLL pre-divider [3:0]
{ 0x3038, 0x00 }, // System control registers (changing not recommended)
{ 0x3039, 0x00 }, // PLL bypass [7]
{ 0x380c, 0x07 },
{ 0x380d, 0x68 },
@ -802,7 +802,6 @@ void set6MHz(void)
*/
static bool analyze_image(uint8_t *image, uint32_t image_len)
{
return true;
ssdv_t ssdv;
uint8_t pkt[SSDV_PKT_SIZE];
uint8_t *b;
@ -851,7 +850,7 @@ static bool analyze_image(uint8_t *image, uint32_t image_len)
*/
uint32_t OV5640_Snapshot2RAM(uint8_t* buffer, uint32_t size, resolution_t res, bool enableJpegValidation)
{
uint8_t cntr = 5;
uint8_t cntr = 10;
bool status;
bool jpegValid;
uint32_t size_sampled;

Wyświetl plik

@ -8,16 +8,16 @@
#include "shell.h"
static const ShellCommand commands[] = {
{"dbgon", debugOnUSB_On},
{"dbgoff", debugOnUSB_Off},
{"debug", debugOnUSB},
{"picture", printPicture},
{"log", readLog},
// {"printconfig", printConfig}, FIXME: This feature is faulty at the moment
{"config", printConfig},
{"command", command2Camera},
{NULL, NULL}
};
static const ShellConfig shell_cfg = {
(BaseSequentialStream *)&SDU1,
(BaseSequentialStream*)&SDU1,
commands
};
@ -30,7 +30,7 @@ int main(void) {
// Voltage switching (1.8V <=> 3.0V)
#if ACTIVATE_USB || ACTIVATE_3V
boost_voltage(true); // Ramp up voltage to 3V
boost_voltage(true); // Ramp up voltage to 3V
chThdSleepMilliseconds(100);
#endif
@ -54,9 +54,8 @@ int main(void) {
start_essential_threads(); // Startup required modules (tracking managemer, watchdog)
start_user_modules(); // Startup optional modules (eg. POSITION, LOG, ...)
// Print time every 10 sec
while(true) {
if (SDU1.config->usbp->state == USB_ACTIVE) {
if(SDU1.config->usbp->state == USB_ACTIVE) {
thread_t *shelltp = chThdCreateFromHeap(NULL, THD_WORKING_AREA_SIZE(512), "shell", NORMALPRIO+1, shellThread, (void*)&shell_cfg);
chThdWait(shelltp);
}

Wyświetl plik

@ -125,6 +125,11 @@ uint32_t aprs_encode_position(uint8_t* message, mod_t mod, const aprs_conf_t *co
chsnprintf(temp, sizeof(temp), "%d", ++loss_of_gps_counter);
ax25_send_string(&packet, temp);
} else if(trackPoint->gps_lock == GPS_LOG) { // GPS position from log (because the tracker has been just switched on)
ax25_send_string(&packet, " GPS FROM LOG");
loss_of_gps_counter = 0;
} else {
loss_of_gps_counter = 0;
}

Wyświetl plik

@ -305,45 +305,48 @@ void shutdownRadio(void)
uint32_t getAPRSRegionFrequency(void) {
trackPoint_t *point = getLastTrackPoint();
uint32_t freq = 0; // Position unknown
// Position unknown
if(point == NULL || (point->gps_lat == 0 && point->gps_lon == 0))
return 0;
// America 144.390 MHz
if(isPointInAmerica(point->gps_lat, point->gps_lon))
freq = APRS_FREQ_AMERICA;
return APRS_FREQ_AMERICA;
// China 144.640 MHz
if(isPointInChina(point->gps_lat, point->gps_lon))
freq = APRS_FREQ_CHINA;
return APRS_FREQ_CHINA;
// Japan 144.660 MHz
if(isPointInJapan(point->gps_lat, point->gps_lon))
freq = APRS_FREQ_JAPAN;
return APRS_FREQ_JAPAN;
// Southkorea 144.620 MHz
if(isPointInSouthkorea(point->gps_lat, point->gps_lon))
freq = APRS_FREQ_SOUTHKOREA;
return APRS_FREQ_SOUTHKOREA;
// Southkorea 144.620 MHz
if(isPointInSoutheastAsia(point->gps_lat, point->gps_lon))
freq = APRS_FREQ_SOUTHEASTASIA;
return APRS_FREQ_SOUTHEASTASIA;
// Australia 145.175 MHz
if(isPointInAustralia(point->gps_lat, point->gps_lon))
freq = APRS_FREQ_AUSTRALIA;
return APRS_FREQ_AUSTRALIA;
// Australia 144.575 MHz
if(isPointInNewZealand(point->gps_lat, point->gps_lon))
freq = APRS_FREQ_NEWZEALAND;
return APRS_FREQ_NEWZEALAND;
// Argentina/Paraguay/Uruguay 144.930 MHz
if(isPointInArgentina(point->gps_lat, point->gps_lon))
freq = APRS_FREQ_ARGENTINA;
return APRS_FREQ_ARGENTINA;
// Brazil 145.575 MHz
if(isPointInBrazil(point->gps_lat, point->gps_lon))
freq = APRS_FREQ_BRAZIL;
return APRS_FREQ_BRAZIL;
return freq;
// For the rest of the world 144.800 MHz
return 144800000;
}
/**
@ -420,7 +423,7 @@ uint32_t getFrequency(freq_conf_t *config)
switch(config->type) {
case FREQ_APRS_REGION:; // Dynamic frequency (determined by GPS position)
uint32_t freq = getAPRSRegionFrequency();
if(!freq) // Use default frequency (if freq is not set = position unknown)
if(!freq) // Use default frequency (if freq is 0 = position unknown)
return config->hz;
return freq;

Wyświetl plik

@ -273,7 +273,7 @@ const uint8_t noCameraFound[4071] = {
0xBD, 0xC0, 0x20, 0x00, 0x01, 0xFF, 0xD9
};
static uint8_t gimage_id; // Global image ID (for all image threads)
uint8_t gimage_id; // Global image ID (for all image threads)
mutex_t camera_mtx;
bool camera_mtx_init = false;

Wyświetl plik

@ -7,6 +7,7 @@
void start_image_thread(module_conf_t *conf);
bool takePicture(ssdv_conf_t *conf, bool enableJpegValidation);
extern mutex_t camera_mtx;
extern uint8_t gimage_id;
#endif

Wyświetl plik

@ -213,7 +213,7 @@ void start_position_thread(module_conf_t *conf)
if(conf->init_delay) chThdSleepMilliseconds(conf->init_delay);
// Start tracking manager (if not running yet)
init_tracking_manager();
init_tracking_manager(true);
// Start position thread
TRACE_INFO("POS > Startup position thread");

Wyświetl plik

@ -1,11 +1,9 @@
#include "ch.h"
#include "hal.h"
#include "debug.h"
#include "threads.h"
#include "tracking.h"
#include "watchdog.h"
#include "image.h"
#include "pi2c.h"
#include "pac1720.h"
@ -15,9 +13,8 @@ void start_essential_threads(void) {
// Init watchdog
init_watchdog();
// Initialize essential mutex's
// Initialize tracking manager (without GPS, GPS is initialized if needed by position thread)
init_tracking_manager(false);
pi2cInit(); // Initialize I2C
pac1720_init(); // Initialize current measurement

Wyświetl plik

@ -3,7 +3,6 @@
#include "tracking.h"
#include "debug.h"
#include "ptime.h"
#include "config.h"
#include "ublox.h"
#include "bme280.h"
@ -12,12 +11,14 @@
#include "radio.h"
#include "flash.h"
#include "watchdog.h"
#include "image.h"
static trackPoint_t trackPoints[2];
static trackPoint_t* lastTrackPoint;
static systime_t nextLogEntryTimer;
static module_conf_t trac_conf = {.name = "TRAC"}; // Fake config needed for watchdog tracking
static bool threadStarted = false;
static bool tracking_useGPS = false;
/**
* Returns most recent track point witch is complete.
@ -27,73 +28,48 @@ trackPoint_t* getLastTrackPoint(void)
return lastTrackPoint;
}
/**
* Returns next free log entry address in memory. Returns 0 if all cells are
* filled with data
*/
static uint32_t getNextFreeLogAddress(void)
trackPoint_t* getLogBuffer(uint16_t id)
{
// Search in flash sector 10
for(uint32_t address = LOG_FLASH_ADDR1; address < LOG_FLASH_ADDR1+LOG_SECTOR_SIZE; address += sizeof(trackPoint_t))
if(sizeof(trackPoint_t)*id < LOG_SECTOR_SIZE-sizeof(trackPoint_t))
{
trackPoint_t pt;
flashRead(address, (char*)&pt, sizeof(trackPoint_t));
if(pt.id == 0xFFFFFFFF)
return address;
return (trackPoint_t*)(LOG_FLASH_ADDR1 + id * sizeof(trackPoint_t));
} else if((id-(LOG_SECTOR_SIZE/sizeof(trackPoint_t)))*sizeof(trackPoint_t) < LOG_SECTOR_SIZE-sizeof(trackPoint_t)) {
return (trackPoint_t*)(LOG_FLASH_ADDR2 + (id-(LOG_SECTOR_SIZE/sizeof(trackPoint_t))) * sizeof(trackPoint_t));
} else { // Outside of memory address allocation
return NULL;
}
// Search in flash sector 11
for(uint32_t address = LOG_FLASH_ADDR2; address < LOG_FLASH_ADDR2+LOG_SECTOR_SIZE; address += sizeof(trackPoint_t))
{
trackPoint_t pt;
flashRead(address, (char*)&pt, sizeof(trackPoint_t));
if(pt.id == 0xFFFFFFFF)
return address;
}
return 0;
}
/**
* Returns next free log entry address in memory. Returns 0 if all cells are
* filled with data
*/
static bool getLastLog(trackPoint_t* last)
static trackPoint_t* getNextFreeLogAddress(void)
{
TRACE_INFO("TRAC > Read last track point from flash memory");
trackPoint_t* tp;
for(uint16_t i=0; (tp = getLogBuffer(i)) != NULL; i++)
if(tp->id == 0xFFFFFFFF)
return tp;
uint64_t last_time = 0;
uint32_t last_address = 0;
return NULL;
}
// Search in flash sector 10
for(uint32_t address = LOG_FLASH_ADDR1; address < LOG_FLASH_ADDR1+LOG_SECTOR_SIZE; address += sizeof(trackPoint_t))
{
trackPoint_t pt;
flashRead(address, (char*)&pt, sizeof(trackPoint_t));
if(pt.id != 0xFFFFFFFF && date2UnixTimestamp(pt.time) >= last_time) {
last_address = address;
last_time = date2UnixTimestamp(pt.time);
}
}
// Search in flash sector 11
for(uint32_t address = LOG_FLASH_ADDR2; address < LOG_FLASH_ADDR2+LOG_SECTOR_SIZE; address += sizeof(trackPoint_t))
{
trackPoint_t pt;
flashRead(address, (char*)&pt, sizeof(trackPoint_t));
if(pt.id != 0xFFFFFFFF && date2UnixTimestamp(pt.time) >= last_time) {
last_address = address;
last_time = date2UnixTimestamp(pt.time);
}
}
if(last_address) {
flashRead(last_address, (char*)last, sizeof(trackPoint_t));
TRACE_INFO("TRAC > Found track point in flash memory ID=%d", last->id);
return true;
} else {
TRACE_INFO("TRAC > No track point found in flash memory");
return false;
/**
* Returns next free log entry address in memory. Returns 0 if all cells are
* filled with data
*/
static trackPoint_t* getLastLog(void)
{
trackPoint_t* last = NULL;
trackPoint_t* tp;
for(uint16_t i=0; (tp = getLogBuffer(i)) != NULL; i++) {
if(tp->id == 0xFFFFFFFF)
return last; // Found last entry
last = tp;
}
if(last->id != 0xFFFFFFFF)
return last; // All memory entries are use, so the very last one must be the most recent one.
return NULL; // There is no log entry in memory
}
/**
@ -119,13 +95,13 @@ static void eraseOldestLogData(void)
static void writeLogTrackPoint(trackPoint_t* tp)
{
// Get address to write on
uint32_t address = getNextFreeLogAddress();
if(!address) // Memory completly used, erase oldest data
trackPoint_t* address = getNextFreeLogAddress();
if(address == NULL) // Memory completly used, erase oldest data
{
eraseOldestLogData();
address = getNextFreeLogAddress();
}
if(!address) // Something went wront at erasing the memory
if(address == NULL) // Something went wront at erasing the memory
{
TRACE_ERROR("TRAC > Erasing flash failed");
return;
@ -133,12 +109,12 @@ static void writeLogTrackPoint(trackPoint_t* tp)
// Write data into flash
TRACE_INFO("TRAC > Flash write (ADDR=%08x)", address);
flashSectorBegin(flashSectorAt(address));
flashWrite(address, (char*)tp, sizeof(trackPoint_t));
flashSectorEnd(flashSectorAt(address));
flashSectorBegin(flashSectorAt((uint32_t)address));
flashWrite((uint32_t)address, (char*)tp, sizeof(trackPoint_t));
flashSectorEnd(flashSectorAt((uint32_t)address));
// Verify
if(flashCompare(address, (char*)tp, sizeof(trackPoint_t)))
if(flashCompare((uint32_t)address, (char*)tp, sizeof(trackPoint_t)))
TRACE_INFO("TRAC > Flash write OK")
else
TRACE_ERROR("TRAC > Flash write failed");
@ -172,20 +148,25 @@ THD_FUNCTION(trackingThread, arg) {
lastTrackPoint->time.minute = rtc.minute;
lastTrackPoint->time.second = rtc.second;
// Get last GPS fix from memory
trackPoint_t lastLogPoint;
if(getLastLog(&lastLogPoint)) { // If there has been stored a trackpoint, then get the last know GPS fix
lastTrackPoint->gps_lat = lastLogPoint.gps_lat;
lastTrackPoint->gps_lon = lastLogPoint.gps_lon;
lastTrackPoint->gps_alt = lastLogPoint.gps_alt;
// Get last tracking point from memory
TRACE_INFO("TRAC > Read last track point from flash memory");
trackPoint_t* lastLogPoint = getLastLog();
if(lastLogPoint != NULL) { // If there has been stored a trackpoint, then get the last know GPS fix
TRACE_INFO("TRAC > Found track point in flash memory ID=%d", lastLogPoint->id);
lastTrackPoint->gps_lat = lastLogPoint->gps_lat;
lastTrackPoint->gps_lon = lastLogPoint->gps_lon;
lastTrackPoint->gps_alt = lastLogPoint->gps_alt;
} else {
TRACE_INFO("TRAC > No track point found in flash memory");
}
lastTrackPoint->gps_lock = GPS_LOSS; // But tell the user that there is no current lock nor any GPS sats locked
lastTrackPoint->gps_lock = GPS_LOG; // Tell other threads that it has been taken from log
lastTrackPoint->gps_sats = 0;
lastTrackPoint->gps_ttff = 0;
// Debug last stored GPS position
if(lastLogPoint.id != 0xFFFFFFFF) {
if(lastLogPoint != NULL) {
TRACE_INFO(
"TRAC > Last GPS position (from memory)\r\n"
"%s Latitude: %d.%07ddeg\r\n"
@ -220,6 +201,14 @@ THD_FUNCTION(trackingThread, arg) {
lastTrackPoint->air_temp = 0;
}
/*
* Get last image ID. This is important because Habhub does mix up different
* images with the same it. So it is good to use a new image ID when the
* tracker has been reset.
*/
if(lastLogPoint != NULL)
gimage_id = lastLogPoint->id_image;
systime_t time = chVTGetSystemTimeX();
while(true)
{
@ -232,9 +221,9 @@ THD_FUNCTION(trackingThread, arg) {
// Search for GPS satellites
gpsFix_t gpsFix = {{0,0,0,0,0,0,0},0,0,0,0,0};
// Switch on GPS is enough power is available
// Switch on GPS is enough power is available and GPS is needed by any position thread
uint16_t batt = getBatteryVoltageMV();
if(batt >= gps_on_vbat)
if(batt >= gps_on_vbat && tracking_useGPS)
{
// Switch on GPS
GPS_Init();
@ -304,8 +293,11 @@ THD_FUNCTION(trackingThread, arg) {
tp->gps_lon = ltp->gps_lon;
tp->gps_alt = ltp->gps_alt;
// Mark GPS loss (or low batt)
tp->gps_lock = batt < gps_off_vbat ? GPS_LOWBATT : GPS_LOSS;
// Mark GPS loss (or low batt, GPS switch off)
if(tracking_useGPS)
tp->gps_lock = batt < gps_off_vbat ? GPS_LOWBATT : GPS_LOSS;
else
tp->gps_lock = GPS_OFF;
tp->gps_sats = 0;
}
@ -335,23 +327,26 @@ THD_FUNCTION(trackingThread, arg) {
tp->air_temp = 0;
}
// Set last time ID
tp->id_image = gimage_id;
// Trace data
TRACE_INFO( "TRAC > New tracking point available (ID=%d)\r\n"
"%s Time %04d-%02d-%02d %02d:%02d:%02d\r\n"
"%s Pos %d.%05d %d.%05d Alt %dm\r\n"
"%s Sats %d TTFF %dsec\r\n"
"%s ADC Vbat=%d.%03dV Vsol=%d.%03dV VUSB=%d.%03dV Pbat=%dmW Rbat=%dmOhm\r\n"
"%s AIR p=%6d.%01dPa T=%2d.%02ddegC phi=%2d.%01d%%",
"%s AIR p=%6d.%01dPa T=%2d.%02ddegC phi=%2d.%01d%% ImageID=%d",
tp->id,
TRACE_TAB, tp->time.year, tp->time.month, tp->time.day, tp->time.hour, tp->time.minute, tp->time.day,
TRACE_TAB, tp->gps_lat/10000000, (tp->gps_lat > 0 ? 1:-1)*(tp->gps_lat/100)%100000, tp->gps_lon/10000000, (tp->gps_lon > 0 ? 1:-1)*(tp->gps_lon/100)%100000, tp->gps_alt,
TRACE_TAB, tp->gps_sats, tp->gps_ttff,
TRACE_TAB, tp->adc_vbat/1000, (tp->adc_vbat%1000), tp->adc_vsol/1000, (tp->adc_vsol%1000), tp->adc_vusb/1000, (tp->adc_vusb%1000), tp->adc_pbat, tp->adc_rbat,
TRACE_TAB, tp->air_press/10, tp->air_press%10, tp->air_temp/100, tp->air_temp%100, tp->air_hum/10, tp->air_hum%10
TRACE_TAB, tp->air_press/10, tp->air_press%10, tp->air_temp/100, tp->air_temp%100, tp->air_hum/10, tp->air_hum%10, tp->id_image
);
// Append logging (timeout)
if(nextLogEntryTimer <= chVTGetSystemTimeX() && isGPSLocked(&gpsFix))
if(nextLogEntryTimer <= chVTGetSystemTimeX())
{
writeLogTrackPoint(tp);
nextLogEntryTimer += log_cycle_time;
@ -365,8 +360,11 @@ THD_FUNCTION(trackingThread, arg) {
}
}
void init_tracking_manager(void)
void init_tracking_manager(bool useGPS)
{
if(useGPS)
tracking_useGPS = true;
if(!threadStarted)
{
threadStarted = true;

Wyświetl plik

@ -5,16 +5,20 @@
#include "hal.h"
#include "ptime.h"
#define GPS_LOCKED 0 /* GPS is locked and could aquire a fix */
#define GPS_LOSS 1 /* GPS was switched on all time but it couln't aquire a fix */
#define GPS_LOWBATT 2 /* GPS was switched on but had to be switched off prematurely while the battery is almost empty (or is too cold) */
typedef enum {
GPS_LOCKED, // GPS is locked and could aquire a fix
GPS_LOSS, // GPS was switched on all time but it couln't aquire a fix
GPS_LOWBATT, // GPS was switched on but had to be switched off prematurely while the battery is almost empty (or is too cold)
GPS_LOG, // The tracker has been just switched on and the position has been taken from the log
GPS_OFF, // There is no active position thread so the GPS was never switched on (in oder to save power)
} gpsLock_t;
typedef struct {
uint32_t id; // Serial ID
ptime_t time; // GPS time
// GPS
uint8_t gps_lock; // 0: locked, 1: GPS loss, 2: low power (switched off)
gpsLock_t gps_lock; // 0: locked, 1: GPS loss, 2: low power (switched off), 3: taken from log, 4: GPS switch off permanently
int32_t gps_lat; // Latitude in °*10^7
int32_t gps_lon; // Longitude in °*10^7
int32_t gps_alt; // Altitude in meter
@ -32,12 +36,15 @@ typedef struct {
uint32_t air_press; // Airpressure in Pa*10 (in 0.1Pa)
uint16_t air_hum; // Rel. humidity in %*10 (in 0.1%)
int16_t air_temp; // Temperature in degC*100 (in 0.01°C)
int8_t id_image; // Last image ID (this is important because it will set the image counter at reset so the last image wont get overwritten with the same image ID)
} trackPoint_t;
void waitForNewTrackPoint(void);
trackPoint_t* getLastTrackPoint(void);
void getNextLogTrackPoint(trackPoint_t* log);
void init_tracking_manager(void);
void init_tracking_manager(bool useGPS);
trackPoint_t* getLogBuffer(uint16_t id);
#endif