From c02f43044fc8595076f6997a22fe8674dbce2907 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Thu, 18 May 2023 15:49:22 +0200 Subject: Start encoding aprs434 compressed messages --- tracker-stm32/src/main.ino | 79 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 72 insertions(+), 7 deletions(-) diff --git a/tracker-stm32/src/main.ino b/tracker-stm32/src/main.ino index da82e01..ed1d570 100644 --- a/tracker-stm32/src/main.ino +++ b/tracker-stm32/src/main.ino @@ -4,9 +4,15 @@ #include #include -File myFile; +constexpr char *CALLSIGN = "HB9EGM"; +constexpr int SSID = 12; +constexpr char SYMBOL_TABLE_IDENTIFIER = '/'; +constexpr char SYMBOL_CODE_BICYCLE = 'b'; +#if 0 +File myFile; constexpr int SD_CS = 17; +#endif // SX1278 has the following connections: // NSS pin: PD14 (Arduino 10) @@ -18,8 +24,39 @@ SFE_UBLOX_GNSS gnss; long lastGnssPoll = 0; long lastPositionReport = 0; -constexpr size_t POSITION_REPORT_LEN = 32; -char positionReport[POSITION_REPORT_LEN+1]; + +constexpr size_t MAX_REPORT_LEN = 32; +size_t report_len = 0; +uint8_t report[MAX_REPORT_LEN]; + +const char* digits = " 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-./?@"; + +#define callsign_int_t uint32_t +callsign_int_t encodeCallsign(const char *callsign) { + // Encode CCCC according to aprs434.github.io/code/codec.cpp + const int b = 37; + + callsign_int_t result; + callsign_int_t weight; + int i, j, k, ch; + + result = 0, weight = 1; + for (i = j = strlen(callsign); i > 0; i--) { // iterate over input string + ch = toupper(callsign[i-1]); + for (k = 0; k < strlen(digits); k++) { // lookup char index + if (digits[k] == ch) { + break; + } + } + if (k == strlen(digits)) // ignore if ch not found in digits + continue; + result = result + ((k) * weight); + weight = weight * b; + } + + return result; // result can be pow(42,51)! +} + static char letterize(int x) { return (char) x + 65; @@ -54,13 +91,14 @@ void setup() { Serial.begin(9600); pinMode(LED_BUILTIN, OUTPUT); +#if 0 pinMode(SD_CS, OUTPUT); if (!SD.begin(SD_CS)) { Serial.println("SD init failed!"); return; } - +#endif Wire.begin(); @@ -175,12 +213,39 @@ void loop() digitalWrite(LED_BUILTIN, HIGH); - ssize_t len = snprintf(positionReport, POSITION_REPORT_LEN, "HB9EGM %s", locator); + // Encode LoRa message according to aprs434.github.io + const uint32_t callsign_EEEE = encodeCallsign(CALLSIGN); + + report_len = 0; + // Callsign encoded as CCCC + report[report_len++] = (callsign_EEEE >> 24) & 0xFF; + report[report_len++] = (callsign_EEEE >> 16) & 0xFF; + report[report_len++] = (callsign_EEEE >> 8) & 0xFF; + report[report_len++] = callsign_EEEE & 0xFF; + + // D SSID Path Code and Data Type Code + + const int date_type_code = 0; // compressed geolocation + const int path_code = 2; // metropolitan mobile + report[report_len++] = SSID * 16 + path_code * 4 + date_type_code; + + // / Symbol Table Identifier + report[report_len++] = SYMBOL_TABLE_IDENTIFIER; +#warn "TODO longitude and latitude" + // XXXX Base91 Longitude + // YYYY Base91 Latitude + // $ Symbol Code + report[report_len++] = SYMBOL_CODE_BICYCLE; + // cs Course and Speed Serial.print(F("TX: ")); - Serial.print(positionReport); + // This is the old custom report I used before adopting aprs434.github.io, + // it is just callsign SPACE locator sent as ASCII + Serial.print(CALLSIGN); + Serial.print(" "); + Serial.println(locator); - int state = radio.transmit(positionReport, len); + int state = radio.transmit(report, report_len); if (state == RADIOLIB_ERR_NONE) { Serial.print(F(" RFM OK Datarate: ")); -- cgit v1.2.3