kopia lustrzana https://github.com/bristol-seds/pico-tracker
Added aprs variable frequency, location functions for aprs
rodzic
c7c2d09c4a
commit
532e4847be
|
@ -130,6 +130,7 @@
|
|||
*/
|
||||
#define TELEMETRY_FREQUENCY 434600000
|
||||
#define TELEMETRY_INTERVAL 30
|
||||
#define APRS_INTERVAL 180
|
||||
|
||||
/**
|
||||
* Watchdog Timer
|
||||
|
|
|
@ -25,7 +25,13 @@
|
|||
#ifndef LOCATION_H
|
||||
#define LOCATION_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
bool latlon_in_aprs_zone(int32_t aprs_zone, int32_t aprs_zone_outline, float lon, float lat);
|
||||
|
||||
bool aprs_location_tx_allow(void);
|
||||
int32_t aprs_location_frequency(void);
|
||||
|
||||
void aprs_location_update(float lon, float lat);
|
||||
|
||||
#endif /* LOCATION_H */
|
||||
|
|
|
@ -47,6 +47,7 @@ char telemetry_string[TELEMETRY_STRING_MAX];
|
|||
int telemetry_active(void);
|
||||
int telemetry_start(enum telemetry_t type, int32_t length);
|
||||
int telemetry_start_rsid(rsid_code_t rsid);
|
||||
void telemetry_aprs_set_frequency(int32_t frequency);
|
||||
void telemetry_stop(void);
|
||||
float telemetry_si_temperature(void);
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "samd20.h"
|
||||
#include "geofence_aprs.h"
|
||||
|
||||
int32_t current_aprs_zone = -2, current_aprs_zone_outline = -2;
|
||||
|
||||
#define polyX(i) (poly[(i*2)+0])
|
||||
#define polyY(i) (poly[(i*2)+1])
|
||||
|
@ -47,7 +48,7 @@
|
|||
* Note that division by zero is avoided because the division is
|
||||
* protected by the "if" clause which surrounds it.
|
||||
*/
|
||||
bool point_in_polygon(int32_t* poly, uint32_t points, int32_t x, int32_t y) {
|
||||
bool point_in_polygon(const int32_t* poly, uint32_t points, int32_t x, int32_t y) {
|
||||
|
||||
uint32_t i, j = points-1;
|
||||
bool oddNodes = false;
|
||||
|
@ -70,7 +71,7 @@ bool point_in_polygon(int32_t* poly, uint32_t points, int32_t x, int32_t y) {
|
|||
/**
|
||||
* Returns if a latitude and longitude is in a polygon
|
||||
*/
|
||||
bool latlon_in_polygon(int32_t* poly, uint32_t points, float lon, float lat) {
|
||||
bool latlon_in_polygon(const int32_t* poly, uint32_t points, float lon, float lat) {
|
||||
|
||||
int32_t x = (int32_t)round(lon * 1000 * 1000); // longitude: µdegrees
|
||||
int32_t y = (int32_t)round(lat * 1000 * 1000); // latitude: µdegrees
|
||||
|
@ -80,8 +81,6 @@ bool latlon_in_polygon(int32_t* poly, uint32_t points, float lon, float lat) {
|
|||
|
||||
|
||||
|
||||
int32_t current_aprs_zone, current_aprs_zone_outline;
|
||||
|
||||
/**
|
||||
* Returns if a latitude and longitude is in a given aprs zone outline
|
||||
*/
|
||||
|
@ -92,27 +91,64 @@ bool latlon_in_aprs_zone(int32_t aprs_zone, int32_t aprs_zone_outline, float lon
|
|||
lon, lat);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns if aprs should be transmitted in the current zone
|
||||
*/
|
||||
bool aprs_location_tx_allow(void) {
|
||||
|
||||
/* Not in any zone, or in a zone other than Alpha */
|
||||
return (current_aprs_zone == -1) || (current_aprs_zone > 0);
|
||||
}
|
||||
/**
|
||||
* Returns the aprs frequency in the current zone.
|
||||
*
|
||||
* Where aprs is not allowed this function is unspecified
|
||||
*/
|
||||
int32_t aprs_location_frequency(void) {
|
||||
|
||||
if (current_aprs_zone >= 0) {
|
||||
return aprs_zones[current_aprs_zone].frequency;
|
||||
}
|
||||
|
||||
return 144800000;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Updates the aprs location based on the current lat/lon
|
||||
*/
|
||||
void update_aprs_location(float lon, float lat) {
|
||||
void aprs_location_update(float lon, float lat) {
|
||||
|
||||
uint32_t z, outline;
|
||||
|
||||
/* Were we in an aprs zone last time? */
|
||||
if (current_aprs_zone >= 0 && current_aprs_zone_outline >= 0) {
|
||||
|
||||
|
||||
if (0) {
|
||||
|
||||
/* Are we still in the same outline? */
|
||||
|
||||
if (1) { /* Still in outline */
|
||||
/* Are we still in the outline? */
|
||||
if (latlon_in_aprs_zone(current_aprs_zone,
|
||||
current_aprs_zone_outline,
|
||||
lon, lat)) { /* Still in outline */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Find which aprs zone we are in and save it */
|
||||
}
|
||||
for (z = 0; z < 12; z++) { /* For each zone */
|
||||
|
||||
void aprs_location_init(float lon, float lat) {
|
||||
current_aprs_zone = -1; current_aprs_zone_outline = -1;
|
||||
update_aprs_location(lon, lat);
|
||||
for (outline = 0; outline < sizeof(aprs_zones[z].outline_lengths); outline++) {
|
||||
|
||||
if (latlon_in_aprs_zone(z, outline, lon, lat)) { /* If we're in this zone */
|
||||
|
||||
/* Record the current zone */
|
||||
current_aprs_zone = z;
|
||||
current_aprs_zone_outline = outline;
|
||||
|
||||
return; /* Go home. We return the first zone we match */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* We're not in a zone */
|
||||
current_aprs_zone = -1;
|
||||
}
|
||||
|
|
|
@ -44,6 +44,8 @@
|
|||
#include "timer.h"
|
||||
#include "contestia.h"
|
||||
#include "rsid.h"
|
||||
#include "aprs.h"
|
||||
#include "location.h"
|
||||
#include "si_trx.h"
|
||||
#include "si_trx_defs.h"
|
||||
#include "analogue.h"
|
||||
|
@ -236,9 +238,35 @@ void output_telemetry_string(enum telemetry_t type)
|
|||
while (telemetry_active()) {
|
||||
system_sleep();
|
||||
}
|
||||
}
|
||||
|
||||
/* Pips */
|
||||
telemetry_start(TELEMETRY_PIPS, 0xFFFF);
|
||||
void aprs_telemetry(void) {
|
||||
|
||||
if (!gps_is_locked()) return; /* Don't bother with no GPS */
|
||||
|
||||
struct ubx_nav_posllh pos = gps_get_nav_posllh();
|
||||
float lat = (float)pos.payload.lat / 10000000.0;
|
||||
float lon = (float)pos.payload.lon / 10000000.0;
|
||||
uint32_t altitude = pos.payload.height / 1000;
|
||||
|
||||
/* Update location */
|
||||
aprs_location_update(lon, lat);
|
||||
|
||||
/* aprs okay here? */
|
||||
if (aprs_location_tx_allow()) {
|
||||
|
||||
/* Set location */
|
||||
aprs_set_location(lat, lon, altitude);
|
||||
|
||||
/* Set frequency */
|
||||
telemetry_aprs_set_frequency(aprs_location_frequency());
|
||||
|
||||
/* Transmit packet and wait */
|
||||
telemetry_start(TELEMETRY_APRS, 0xFFFF);
|
||||
while (telemetry_active()) {
|
||||
system_sleep();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -304,10 +332,30 @@ void xosc_measure_callback(uint32_t result)
|
|||
_xosc_error = result - XOSC_FREQUENCY;
|
||||
}
|
||||
|
||||
uint32_t telemetry_interval_count = TELEMETRY_INTERVAL;
|
||||
uint32_t aprs_interval_count = 0;
|
||||
uint8_t telemetry_trigger_flag = 0;
|
||||
uint8_t aprs_trigger_flag = 0;
|
||||
|
||||
/**
|
||||
* Called by the timer at 1Hz
|
||||
*/
|
||||
void timepulse_callback(uint32_t sequence)
|
||||
{
|
||||
telemetry_trigger_flag = 1;
|
||||
telemetry_interval_count++;
|
||||
aprs_interval_count++;
|
||||
|
||||
/* Runs at the rate of telemetry packets */
|
||||
if (telemetry_interval_count >= TELEMETRY_INTERVAL) {
|
||||
telemetry_interval_count = 0;
|
||||
telemetry_trigger_flag = 1;
|
||||
}
|
||||
|
||||
/* Runs at the rate of aprs packets */
|
||||
if (aprs_interval_count >= APRS_INTERVAL) {
|
||||
aprs_interval_count = 0;
|
||||
aprs_trigger_flag = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -323,16 +371,6 @@ int main(void)
|
|||
led_on();
|
||||
|
||||
|
||||
/* while (1) { */
|
||||
/* telemetry_start(TELEMETRY_APRS, 0xFFFF); */
|
||||
|
||||
/* while (telemetry_active()) { */
|
||||
/* system_sleep(); */
|
||||
/* } */
|
||||
|
||||
/* for (int i = 0; i < 1000*1000; i++); */
|
||||
/* } */
|
||||
|
||||
|
||||
while (1) {
|
||||
/* Sleep wait for next telemetry */
|
||||
|
@ -355,6 +393,17 @@ int main(void)
|
|||
TELEMETRY_CONTESTIA :
|
||||
TELEMETRY_RTTY);
|
||||
|
||||
|
||||
/* Maybe aprs? */
|
||||
if (aprs_trigger_flag) {
|
||||
aprs_telemetry();
|
||||
}
|
||||
aprs_trigger_flag = 0;
|
||||
|
||||
|
||||
/* Pips */
|
||||
telemetry_start(TELEMETRY_PIPS, 0xFFFF);
|
||||
|
||||
/* Measure XOSC against gps timepulse */
|
||||
measure_xosc(XOSC_MEASURE_TIMEPULSE, xosc_measure_callback);
|
||||
}
|
||||
|
|
|
@ -118,7 +118,10 @@ uint8_t radio_on = 0;
|
|||
* Temperature
|
||||
*/
|
||||
float _si_temperature = 128.0;
|
||||
|
||||
/**
|
||||
* APRS frequency
|
||||
*/
|
||||
int32_t _aprs_frequency = 0;
|
||||
|
||||
/**
|
||||
* Returns 1 if we're currently outputting.
|
||||
|
@ -187,6 +190,13 @@ int telemetry_start_rsid(rsid_code_t rsid) {
|
|||
return 1; /* Already active */
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Setter for the APRS frequency
|
||||
*/
|
||||
void telemetry_aprs_set_frequency(int32_t frequency) {
|
||||
_aprs_frequency = frequency;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops the ongoing telemetry at the earliest possible moment (end of
|
||||
* symbol / block).
|
||||
|
@ -310,8 +320,14 @@ void telemetry_tick(void) {
|
|||
/* APRS: We use pwm to control gpio1 */
|
||||
aprs_start();
|
||||
|
||||
si_trx_on(SI_MODEM_MOD_TYPE_2GFSK, 144888000, 400);
|
||||
radio_on = 1;
|
||||
// if (_aprs_frequency) { TODO configurable frequency
|
||||
// si_trx_on(SI_MODEM_MOD_TYPE_2GFSK, _aprs_frequency, 400);
|
||||
// radio_on = 1;
|
||||
// }
|
||||
|
||||
si_trx_on(SI_MODEM_MOD_TYPE_2GFSK, 144800000, 400);
|
||||
radio_on = 1;
|
||||
|
||||
}
|
||||
|
||||
if (!aprs_tick()) {
|
||||
|
|
|
@ -32,7 +32,6 @@
|
|||
#include "system/interrupt.h"
|
||||
|
||||
uint32_t gps_timepulse_count = 0;
|
||||
uint32_t telemetry_interval_count = TELEMETRY_INTERVAL;
|
||||
uint32_t timepulse_sequence = 0;
|
||||
|
||||
timepulse_callback_t _timer_callback;
|
||||
|
@ -89,15 +88,9 @@ void EIC_Handler(void) {
|
|||
if (gps_timepulse_count >= GPS_TIMEPULSE_FREQ) {
|
||||
gps_timepulse_count = 0;
|
||||
|
||||
telemetry_interval_count++;
|
||||
/* Runs at the rate of telemetry packets */
|
||||
if (telemetry_interval_count >= TELEMETRY_INTERVAL) {
|
||||
telemetry_interval_count = 0;
|
||||
|
||||
/* Make the callback if we have one */
|
||||
if (_timer_callback) {
|
||||
_timer_callback(timepulse_sequence++);
|
||||
}
|
||||
/* Make the callback if we have one */
|
||||
if (_timer_callback) {
|
||||
_timer_callback(timepulse_sequence++);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Ładowanie…
Reference in New Issue