kopia lustrzana https://github.com/markqvist/LibAPRS
Various bugfixes
rodzic
687066ca7a
commit
2c9f5fd070
|
@ -1,5 +1,6 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "AFSK.h"
|
#include "AFSK.h"
|
||||||
|
#include "Arduino.h"
|
||||||
|
|
||||||
extern unsigned long custom_preamble;
|
extern unsigned long custom_preamble;
|
||||||
extern unsigned long custom_tail;
|
extern unsigned long custom_tail;
|
||||||
|
@ -465,7 +466,7 @@ ISR(ADC_vect) {
|
||||||
}
|
}
|
||||||
|
|
||||||
poll_timer++;
|
poll_timer++;
|
||||||
if (poll_timer > 4) {
|
if (poll_timer > 3) {
|
||||||
poll_timer = 0;
|
poll_timer = 0;
|
||||||
APRS_poll();
|
APRS_poll();
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,7 +58,6 @@ void APRS_poll(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void APRS_setCallsign(char *call, int ssid) {
|
void APRS_setCallsign(char *call, int ssid) {
|
||||||
Serial.println("Setting to: ");
|
|
||||||
memset(CALL, 0, 7);
|
memset(CALL, 0, 7);
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (i < 6 && call[i] != 0) {
|
while (i < 6 && call[i] != 0) {
|
||||||
|
@ -171,23 +170,22 @@ void APRS_setDirectivity(int s) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void APRS_printSettings() {
|
void APRS_printSettings() {
|
||||||
Serial.println("LibAPRS Settings:");
|
Serial.println(F("LibAPRS Settings:"));
|
||||||
Serial.print("Callsign: "); Serial.print(CALL); Serial.print("-"); Serial.println(CALL_SSID);
|
Serial.print(F("Callsign: ")); Serial.print(CALL); Serial.print(F("-")); Serial.println(CALL_SSID);
|
||||||
Serial.print("Destination: "); Serial.print(DST); Serial.print("-"); Serial.println(DST_SSID);
|
Serial.print(F("Destination: ")); Serial.print(DST); Serial.print(F("-")); Serial.println(DST_SSID);
|
||||||
Serial.print("Path1: "); Serial.print(PATH1); Serial.print("-"); Serial.println(PATH1_SSID);
|
Serial.print(F("Path1: ")); Serial.print(PATH1); Serial.print(F("-")); Serial.println(PATH1_SSID);
|
||||||
Serial.print("Path2: "); Serial.print(PATH2); Serial.print("-"); Serial.println(PATH2_SSID);
|
Serial.print(F("Path2: ")); Serial.print(PATH2); Serial.print(F("-")); Serial.println(PATH2_SSID);
|
||||||
Serial.print("Message dst: "); if (message_recip[0] == 0) { Serial.println("N/A"); } else { Serial.print(message_recip); Serial.print("-"); Serial.println(message_recip_ssid); }
|
Serial.print(F("Message dst: ")); if (message_recip[0] == 0) { Serial.println(F("N/A")); } else { Serial.print(message_recip); Serial.print(F("-")); Serial.println(message_recip_ssid); }
|
||||||
Serial.print("TX Preamble: "); Serial.println(custom_preamble);
|
Serial.print(F("TX Preamble: ")); Serial.println(custom_preamble);
|
||||||
Serial.print("TX Tail: "); Serial.println(custom_tail);
|
Serial.print(F("TX Tail: ")); Serial.println(custom_tail);
|
||||||
Serial.print("Symbol table: "); if (symbolTable = '/') { Serial.println("Normal"); } else { Serial.println("Alternate"); }
|
Serial.print(F("Symbol table: ")); if (symbolTable = '/') { Serial.println(F("Normal")); } else { Serial.println(F("Alternate")); }
|
||||||
Serial.print("Symbol: "); Serial.println(symbol);
|
Serial.print(F("Symbol: ")); Serial.println(symbol);
|
||||||
Serial.print("Power: "); if (power < 10) { Serial.println(power); } else { Serial.println("N/A"); }
|
Serial.print(F("Power: ")); if (power < 10) { Serial.println(power); } else { Serial.println(F("N/A")); }
|
||||||
Serial.print("Height: "); if (height < 10) { Serial.println(height); } else { Serial.println("N/A"); }
|
Serial.print(F("Height: ")); if (height < 10) { Serial.println(height); } else { Serial.println(F("N/A")); }
|
||||||
Serial.print("Gain: "); if (gain < 10) { Serial.println(gain); } else { Serial.println("N/A"); }
|
Serial.print(F("Gain: ")); if (gain < 10) { Serial.println(gain); } else { Serial.println(F("N/A")); }
|
||||||
Serial.print("Directivity: "); if (directivity < 10) { Serial.println(directivity); } else { Serial.println("N/A"); }
|
Serial.print(F("Directivity: ")); if (directivity < 10) { Serial.println(directivity); } else { Serial.println(F("N/A")); }
|
||||||
Serial.print("Latitude: "); if (latitude[0] != 0) { Serial.println(latitude); } else { Serial.println("N/A"); }
|
Serial.print(F("Latitude: ")); if (latitude[0] != 0) { Serial.println(latitude); } else { Serial.println(F("N/A")); }
|
||||||
Serial.print("Longtitude: "); if (longtitude[0] != 0) { Serial.println(longtitude); } else { Serial.println("N/A"); }
|
Serial.print(F("Longtitude: ")); if (longtitude[0] != 0) { Serial.println(longtitude); } else { Serial.println(F("N/A")); }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void APRS_sendPkt(void *_buffer, size_t length) {
|
void APRS_sendPkt(void *_buffer, size_t length) {
|
||||||
|
@ -214,6 +212,7 @@ void APRS_sendPkt(void *_buffer, size_t length) {
|
||||||
ax25_sendVia(&AX25, path, countof(path), buffer, length);
|
ax25_sendVia(&AX25, path, countof(path), buffer, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Dynamic RAM usage of this function is 30 bytes
|
||||||
void APRS_sendLoc(void *_buffer, size_t length) {
|
void APRS_sendLoc(void *_buffer, size_t length) {
|
||||||
size_t payloadLength = 20+length;
|
size_t payloadLength = 20+length;
|
||||||
bool usePHG = false;
|
bool usePHG = false;
|
||||||
|
@ -250,6 +249,7 @@ void APRS_sendLoc(void *_buffer, size_t length) {
|
||||||
free(packet);
|
free(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Dynamic RAM usage of this function is 18 bytes
|
||||||
void APRS_sendMsg(void *_buffer, size_t length) {
|
void APRS_sendMsg(void *_buffer, size_t length) {
|
||||||
if (length > 67) length = 67;
|
if (length > 67) length = 67;
|
||||||
size_t payloadLength = 11+length+4;
|
size_t payloadLength = 11+length+4;
|
||||||
|
@ -299,11 +299,44 @@ void APRS_sendMsg(void *_buffer, size_t length) {
|
||||||
packet[14+length] = n+48;
|
packet[14+length] = n+48;
|
||||||
|
|
||||||
APRS_sendPkt(packet, payloadLength);
|
APRS_sendPkt(packet, payloadLength);
|
||||||
|
|
||||||
free(packet);
|
free(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
void APRS_msgRetry() {
|
void APRS_msgRetry() {
|
||||||
message_seq--;
|
message_seq--;
|
||||||
APRS_sendMsg(lastMessage, lastMessageLen);
|
APRS_sendMsg(lastMessage, lastMessageLen);
|
||||||
|
}
|
||||||
|
|
||||||
|
// For getting free memory, from:
|
||||||
|
// http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1213583720/15
|
||||||
|
|
||||||
|
extern unsigned int __heap_start;
|
||||||
|
extern void *__brkval;
|
||||||
|
|
||||||
|
struct __freelist {
|
||||||
|
size_t sz;
|
||||||
|
struct __freelist *nx;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct __freelist *__flp;
|
||||||
|
|
||||||
|
int freeListSize() {
|
||||||
|
struct __freelist* current;
|
||||||
|
int total = 0;
|
||||||
|
for (current = __flp; current; current = current->nx) {
|
||||||
|
total += 2; /* Add two bytes for the memory block's header */
|
||||||
|
total += (int) current->sz;
|
||||||
|
}
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
|
int freeMemory() {
|
||||||
|
int free_memory;
|
||||||
|
if ((int)__brkval == 0) {
|
||||||
|
free_memory = ((int)&free_memory) - ((int)&__heap_start);
|
||||||
|
} else {
|
||||||
|
free_memory = ((int)&free_memory) - ((int)__brkval);
|
||||||
|
free_memory += freeListSize();
|
||||||
|
}
|
||||||
|
return free_memory;
|
||||||
}
|
}
|
|
@ -34,4 +34,6 @@ void APRS_sendLoc(void *_buffer, size_t length);
|
||||||
void APRS_sendMsg(void *_buffer, size_t length);
|
void APRS_sendMsg(void *_buffer, size_t length);
|
||||||
void APRS_msgRetry();
|
void APRS_msgRetry();
|
||||||
|
|
||||||
void APRS_printSettings();
|
void APRS_printSettings();
|
||||||
|
|
||||||
|
int freeMemory();
|
||||||
|
|
|
@ -18,15 +18,46 @@
|
||||||
// You always need to include this function. It will
|
// You always need to include this function. It will
|
||||||
// get called by the library every time a packet is
|
// get called by the library every time a packet is
|
||||||
// received, so you can process incoming packets.
|
// received, so you can process incoming packets.
|
||||||
|
//
|
||||||
|
// IMPORTANT! This function is called from within an
|
||||||
|
// interrupt. That means that you should only do things
|
||||||
|
// here that are FAST. Don't print out info directly
|
||||||
|
// from this function, instead set a flag and print it
|
||||||
|
// from your main loop, like this:
|
||||||
|
|
||||||
|
boolean gotPacket = false;
|
||||||
|
AX25Msg incomingPacket;
|
||||||
|
uint8_t *packetData;
|
||||||
void aprs_msg_callback(struct AX25Msg *msg) {
|
void aprs_msg_callback(struct AX25Msg *msg) {
|
||||||
Serial.print("Received APRS packet. Data: ");
|
// If we already have a packet waiting to be
|
||||||
for (int i = 0; i < msg->len; i++) { Serial.write(msg->info[i]); }
|
// processed, we must drop the new one.
|
||||||
Serial.println("");
|
if (!gotPacket) {
|
||||||
|
// Set flag to indicate we got a packet
|
||||||
|
gotPacket = true;
|
||||||
|
|
||||||
|
// The memory referenced as *msg is volatile
|
||||||
|
// and we need to copy all the data to a
|
||||||
|
// local variable for later processing.
|
||||||
|
memcpy(&incomingPacket, msg, sizeof(AX25Msg));
|
||||||
|
|
||||||
|
// We need to allocate a new buffer for the
|
||||||
|
// data payload of the packet. First we check
|
||||||
|
// if there is enough free RAM.
|
||||||
|
if (freeMemory() > msg->len) {
|
||||||
|
packetData = (uint8_t*)malloc(msg->len);
|
||||||
|
memcpy(packetData, msg->info, msg->len);
|
||||||
|
incomingPacket.info = packetData;
|
||||||
|
} else {
|
||||||
|
// We did not have enough free RAM to receive
|
||||||
|
// this packet, so we drop it.
|
||||||
|
gotPacket = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
// Set up serial port
|
// Set up serial port
|
||||||
Serial.begin(9600);
|
Serial.begin(115200);
|
||||||
|
|
||||||
// Initialise APRS library - This starts the modem
|
// Initialise APRS library - This starts the modem
|
||||||
APRS_init();
|
APRS_init();
|
||||||
|
@ -36,25 +67,26 @@ void setup() {
|
||||||
|
|
||||||
// You don't need to set the destination identifier, but
|
// You don't need to set the destination identifier, but
|
||||||
// if you want to, this is how you do it:
|
// if you want to, this is how you do it:
|
||||||
APRS_setDestination("APZMDM", 0);
|
// APRS_setDestination("APZMDM", 0);
|
||||||
|
|
||||||
// Path parameters are set to sensible values by
|
// Path parameters are set to sensible values by
|
||||||
// default, but this is how you can configure them:
|
// default, but this is how you can configure them:
|
||||||
APRS_setPath1("WIDE1", 1);
|
// APRS_setPath1("WIDE1", 1);
|
||||||
APRS_setPath2("WIDE2", 2);
|
// APRS_setPath2("WIDE2", 2);
|
||||||
|
|
||||||
// You can define preamble and tail like this:
|
// You can define preamble and tail like this:
|
||||||
APRS_setPreamble(350);
|
// APRS_setPreamble(350);
|
||||||
APRS_setTail(50);
|
// APRS_setTail(50);
|
||||||
|
|
||||||
// You can use the normal or alternate symbol table:
|
// You can use the normal or alternate symbol table:
|
||||||
APRS_useAlternateSymbolTable(false);
|
// APRS_useAlternateSymbolTable(false);
|
||||||
|
|
||||||
// And set what symbol you want to use:
|
// And set what symbol you want to use:
|
||||||
APRS_setSymbol('n');
|
// APRS_setSymbol('n');
|
||||||
|
|
||||||
// We can print out all the settings
|
// We can print out all the settings
|
||||||
APRS_printSettings();
|
APRS_printSettings();
|
||||||
|
Serial.print(F("Free RAM: ")); Serial.println(freeMemory());
|
||||||
}
|
}
|
||||||
|
|
||||||
void locationUpdateExample() {
|
void locationUpdateExample() {
|
||||||
|
@ -79,7 +111,7 @@ void locationUpdateExample() {
|
||||||
char *comment = "LibAPRS location update";
|
char *comment = "LibAPRS location update";
|
||||||
|
|
||||||
// And send the update
|
// And send the update
|
||||||
APRS_sendLoc(comment, sizeof(comment));
|
APRS_sendLoc(comment, strlen(comment));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,19 +120,44 @@ void messageExample() {
|
||||||
APRS_setMessageDestination("AA3BBB", 0);
|
APRS_setMessageDestination("AA3BBB", 0);
|
||||||
|
|
||||||
// And define a string to send
|
// And define a string to send
|
||||||
char *message = "Hi there! This is a message";
|
char *message = "Hi there! This is a message.";
|
||||||
APRS_sendMsg(message, sizeof(message));
|
APRS_sendMsg(message, strlen(message));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Here's a function to process incoming packets
|
||||||
|
// Remember to call this function often, so you
|
||||||
|
// won't miss any packets due to one already
|
||||||
|
// waiting to be processed
|
||||||
|
void processPacket() {
|
||||||
|
if (gotPacket) {
|
||||||
|
gotPacket = false;
|
||||||
|
Serial.print(F("Received APRS packet. Data: "));
|
||||||
|
for (int i = 0; i < incomingPacket.len; i++) {
|
||||||
|
Serial.write(incomingPacket.info[i]);
|
||||||
|
}
|
||||||
|
Serial.println("");
|
||||||
|
|
||||||
|
// Remeber to free memory for our buffer!
|
||||||
|
free(packetData);
|
||||||
|
|
||||||
|
// You can print out the amount of free
|
||||||
|
// RAM to check you don't have any memory
|
||||||
|
// leaks
|
||||||
|
// Serial.print(F("Free RAM: ")); Serial.println(freeMemory());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean whichExample = false;
|
||||||
void loop() {
|
void loop() {
|
||||||
delay(2000);
|
delay(2000);
|
||||||
locationUpdateExample();
|
|
||||||
|
|
||||||
delay(2000);
|
|
||||||
messageExample();
|
|
||||||
|
|
||||||
// Just for fun we print out the settings
|
processPacket();
|
||||||
APRS_printSettings();
|
if (whichExample) {
|
||||||
|
locationUpdateExample();
|
||||||
|
} else {
|
||||||
|
messageExample();
|
||||||
|
}
|
||||||
|
whichExample ^= true;
|
||||||
|
|
||||||
}
|
}
|
|
@ -17,4 +17,8 @@ See the example included in the library for info on how to use it!
|
||||||
- Ability to send raw packets
|
- Ability to send raw packets
|
||||||
- Support for settings APRS symbols
|
- Support for settings APRS symbols
|
||||||
- Support for power/height/gain info in location updates
|
- Support for power/height/gain info in location updates
|
||||||
- Can run with open squelch
|
- Can run with open squelch
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
Place the "LibAPRS" folder (the one in the same folder as this readme file) inside your Arduino "libraries" folder. That's all!
|
Ładowanie…
Reference in New Issue