Merge pull request #2 from Scobber/master

Add LPP option for GPS data,
This commit is contained in:
Kyle Gabriel 2019-08-23 09:43:47 -04:00 committed by GitHub
commit a2b2d3411d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 192 additions and 130 deletions

View File

@ -26,7 +26,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <Arduino.h> #include <Arduino.h>
#include <lmic.h> #include <lmic.h>
void ttn_register(void (*callback)(uint8_t message)); void ttn_register(void (*callback)(uint8_t message));
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -40,10 +39,11 @@ void ttn_register(void (*callback)(uint8_t message));
// Configuration // Configuration
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
#define USE_CAYENNE
#define DEBUG_PORT Serial // Serial debug port #define DEBUG_PORT Serial // Serial debug port
#define SERIAL_BAUD 115200 // Serial debug baud rate #define SERIAL_BAUD 115200 // Serial debug baud rate
#define SLEEP_BETWEEN_MESSAGES 0 // Do sleep between messages #define SLEEP_BETWEEN_MESSAGES 0 // Do sleep between messages
#define SEND_INTERVAL 30000 // Sleep for these many millis #define SEND_INTERVAL 10000 // Sleep for these many millis
#define MESSAGE_TO_SLEEP_DELAY 5000 // Time after message before going to sleep #define MESSAGE_TO_SLEEP_DELAY 5000 // Time after message before going to sleep
#define LOGO_DELAY 5000 // Time to show logo on first boot #define LOGO_DELAY 5000 // Time to show logo on first boot
#define LORAWAN_PORT 10 // Port the messages will be sent to #define LORAWAN_PORT 10 // Port the messages will be sent to
@ -94,6 +94,7 @@ void ttn_register(void (*callback)(uint8_t message));
#define GPS_RX_PIN 12 #define GPS_RX_PIN 12
#define GPS_TX_PIN 15 #define GPS_TX_PIN 15
#define GPS_BAUDRATE 9600 #define GPS_BAUDRATE 9600
#define USE_GPS 1
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// LoRa SPI // LoRa SPI

View File

@ -62,6 +62,44 @@ static void gps_loop() {
_gps.encode(_serial_gps.read()); _gps.encode(_serial_gps.read());
} }
} }
#ifdef USE_CAYENNE
// CAYENNE DF
void buildPacket(uint8_t txBuffer[11])
{
sprintf(t, "Lat: %f", _gps.location.lat());
Serial.println(t);
sprintf(t, "Lng: %f", _gps.location.lng());
Serial.println(t);
sprintf(t, "Alt: %f", _gps.altitude.meters());
Serial.println(t);
int32_t lat = _gps.location.lat() * 10000;
int32_t lon = _gps.location.lng() * 10000;
int32_t alt = _gps.altitude.meters() * 100;
txBuffer[2] = lat >> 16;
txBuffer[3] = lat >> 8;
txBuffer[4] = lat;
txBuffer[5] = lon >> 16;
txBuffer[6] = lon >> 8;
txBuffer[7] = lon;
txBuffer[8] = alt >> 16;
txBuffer[9] = alt >> 8;
txBuffer[10] = alt;
/*
txBuffer[2] = ( LatitudeBinary >> 16 );// & 0xFF;
txBuffer[3] = ( LatitudeBinary >> 8 );// & 0xFF;
txBuffer[4] = LatitudeBinary;// & 0xFF;
txBuffer[5] = ( LongitudeBinary >> 16 ) & 0xFF;
txBuffer[6] = ( LongitudeBinary >> 8 ) & 0xFF;
txBuffer[7] = LongitudeBinary & 0xFF;
txBuffer[8] = Height >> 16;
txBuffer[9] = Height >> 8;
txBuffer[10] = Height;*/
}
#else
uint8_t txBuffer[9];
void buildPacket(uint8_t txBuffer[9]) void buildPacket(uint8_t txBuffer[9])
{ {
@ -89,3 +127,5 @@ void buildPacket(uint8_t txBuffer[9])
hdopGps = _gps.hdop.value()/10; hdopGps = _gps.hdop.value()/10;
txBuffer[8] = hdopGps & 0xFF; txBuffer[8] = hdopGps & 0xFF;
} }
#endif

View File

@ -6,7 +6,8 @@
// inside the project_config folder. // inside the project_config folder.
// Make sure only one of the following is defined (CFG_us915 or CFG_eu868) // Make sure only one of the following is defined (CFG_us915 or CFG_eu868)
#define CFG_us915 1 #define CFG_au915 1
//#define CFG_au923 1
//#define CFG_eu868 1 //#define CFG_eu868 1
#define CFG_sx1276_radio 1 #define CFG_sx1276_radio 1

View File

@ -1,185 +1,196 @@
/* /*
Main module Main module
# Modified by Kyle T. Gabriel to fix issue with incorrect GPS data for TTNMapper # Modified by Kyle T. Gabriel to fix issue with incorrect GPS data for TTNMapper
Copyright (C) 2018 by Xose Pérez <xose dot perez at gmail dot com> Copyright (C) 2018 by Xose Pérez <xose dot perez at gmail dot com>
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "configuration.h" #include "configuration.h"
#include <rom/rtc.h> #include "rom/rtc.h"
uint8_t txBuffer[9];
// Message counter, stored in RTC memory, survives deep sleep // Message counter, stored in RTC memory, survives deep sleep
RTC_DATA_ATTR uint32_t count = 0; RTC_DATA_ATTR uint32_t count = 0;
// -----------------------------------------------------------------------------
// Submodules
// -----------------------------------------------------------------------------
#include <TinyGPS++.h>
#ifdef USE_CAYENNE
// CAYENNE DF
static uint8_t txBuffer[11] = {0x03, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
#else
uint8_t txBuffer[9];
#endif
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Application // Application
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void send() { void send() {
char buffer[40]; char buffer[40];
snprintf(buffer, sizeof(buffer), "Latitude: %10.6f\n", gps_latitude()); snprintf(buffer, sizeof(buffer), "Latitude: %10.6f\n", gps_latitude());
screen_print(buffer); screen_print(buffer);
snprintf(buffer, sizeof(buffer), "Longitude: %10.6f\n", gps_longitude()); snprintf(buffer, sizeof(buffer), "Longitude: %10.6f\n", gps_longitude());
screen_print(buffer); screen_print(buffer);
snprintf(buffer, sizeof(buffer), "Error: %4.2fm\n", gps_hdop()); snprintf(buffer, sizeof(buffer), "Error: %4.2fm\n", gps_hdop());
screen_print(buffer); screen_print(buffer);
buildPacket(txBuffer); buildPacket(txBuffer);
#if LORAWAN_CONFIRMED_EVERY > 0 #if LORAWAN_CONFIRMED_EVERY > 0
bool confirmed = (count % LORAWAN_CONFIRMED_EVERY == 0); bool confirmed = (count % LORAWAN_CONFIRMED_EVERY == 0);
#else #else
bool confirmed = false; bool confirmed = false;
#endif #endif
ttn_cnt(count); ttn_cnt(count);
ttn_send(txBuffer, sizeof(txBuffer), LORAWAN_PORT, confirmed); ttn_send(txBuffer, sizeof(txBuffer), LORAWAN_PORT, confirmed);
count++; count++;
} }
void sleep() { void sleep() {
#if SLEEP_BETWEEN_MESSAGES #if SLEEP_BETWEEN_MESSAGES
// Show the going to sleep message on the screen // Show the going to sleep message on the screen
char buffer[20]; char buffer[20];
snprintf(buffer, sizeof(buffer), "Sleeping in %3.1fs\n", (MESSAGE_TO_SLEEP_DELAY / 1000.0)); snprintf(buffer, sizeof(buffer), "Sleeping in %3.1fs\n", (MESSAGE_TO_SLEEP_DELAY / 1000.0));
screen_print(buffer); screen_print(buffer);
// Wait for MESSAGE_TO_SLEEP_DELAY millis to sleep // Wait for MESSAGE_TO_SLEEP_DELAY millis to sleep
delay(MESSAGE_TO_SLEEP_DELAY); delay(MESSAGE_TO_SLEEP_DELAY);
// Turn off screen // Turn off screen
screen_off(); screen_off();
// Set the user button to wake the board // Set the user button to wake the board
sleep_interrupt(BUTTON_PIN, LOW); sleep_interrupt(BUTTON_PIN, LOW);
// We sleep for the interval between messages minus the current millis // We sleep for the interval between messages minus the current millis
// this way we distribute the messages evenly every SEND_INTERVAL millis // this way we distribute the messages evenly every SEND_INTERVAL millis
uint32_t sleep_for = (millis() < SEND_INTERVAL) ? SEND_INTERVAL - millis() : SEND_INTERVAL; uint32_t sleep_for = (millis() < SEND_INTERVAL) ? SEND_INTERVAL - millis() : SEND_INTERVAL;
sleep_millis(sleep_for); sleep_millis(sleep_for);
#endif #endif
} }
void callback(uint8_t message) { void callback(uint8_t message) {
if (EV_JOINING == message) screen_print("Joining TTN...\n"); if (EV_JOINING == message) screen_print("Joining TTN...\n");
if (EV_JOINED == message) screen_print("TTN joined!\n"); if (EV_JOINED == message) screen_print("TTN joined!\n");
if (EV_JOIN_FAILED == message) screen_print("TTN join failed\n"); if (EV_JOIN_FAILED == message) screen_print("TTN join failed\n");
if (EV_REJOIN_FAILED == message) screen_print("TTN rejoin failed\n"); if (EV_REJOIN_FAILED == message) screen_print("TTN rejoin failed\n");
if (EV_RESET == message) screen_print("Reset TTN connection\n"); if (EV_RESET == message) screen_print("Reset TTN connection\n");
if (EV_LINK_DEAD == message) screen_print("TTN link dead\n"); if (EV_LINK_DEAD == message) screen_print("TTN link dead\n");
if (EV_ACK == message) screen_print("ACK received\n"); if (EV_ACK == message) screen_print("ACK received\n");
if (EV_PENDING == message) screen_print("Message discarded\n"); if (EV_PENDING == message) screen_print("Message discarded\n");
if (EV_QUEUED == message) screen_print("Message queued\n"); if (EV_QUEUED == message) screen_print("Message queued\n");
if (EV_TXCOMPLETE == message) { if (EV_TXCOMPLETE == message) {
screen_print("Message sent\n"); screen_print("Message sent\n");
sleep(); sleep();
} }
if (EV_RESPONSE == message) { if (EV_RESPONSE == message) {
screen_print("[TTN] Response: "); screen_print("[TTN] Response: ");
size_t len = ttn_response_len(); size_t len = ttn_response_len();
uint8_t data[len]; uint8_t data[len];
ttn_response(data, len); ttn_response(data, len);
char buffer[6]; char buffer[6];
for (uint8_t i=0; i<len; i++) { for (uint8_t i = 0; i < len; i++) {
snprintf(buffer, sizeof(buffer), "%02X", data[i]); snprintf(buffer, sizeof(buffer), "%02X", data[i]);
screen_print(buffer); screen_print(buffer);
}
screen_print("\n");
} }
screen_print("\n");
}
} }
uint32_t get_count() { uint32_t get_count() {
return count; return count;
} }
void setup() { void setup() {
// Debug // Debug
#ifdef DEBUG_PORT #ifdef DEBUG_PORT
DEBUG_PORT.begin(SERIAL_BAUD); DEBUG_PORT.begin(SERIAL_BAUD);
#endif #endif
// Buttons & LED // Buttons & LED
pinMode(BUTTON_PIN, INPUT_PULLUP); pinMode(BUTTON_PIN, INPUT_PULLUP);
pinMode(LED_PIN, OUTPUT); pinMode(LED_PIN, OUTPUT);
// Hello // Hello
DEBUG_MSG(APP_NAME " " APP_VERSION "\n"); DEBUG_MSG(APP_NAME " " APP_VERSION "\n");
// Display // Display
screen_setup(); screen_setup();
// Init GPS // Init GPS
gps_setup(); gps_setup();
// Show logo on first boot // Show logo on first boot
if (0 == count) { if (0 == count) {
screen_print(APP_NAME " " APP_VERSION, 0, 0); screen_print(APP_NAME " " APP_VERSION, 0, 0);
screen_show_logo(); screen_show_logo();
screen_update(); screen_update();
delay(LOGO_DELAY); delay(LOGO_DELAY);
} }
// TTN setup // TTN setup
if (!ttn_setup()) { if (!ttn_setup()) {
screen_print("[ERR] Radio module not found!\n"); screen_print("[ERR] Radio module not found!\n");
delay(MESSAGE_TO_SLEEP_DELAY); delay(MESSAGE_TO_SLEEP_DELAY);
screen_off(); screen_off();
sleep_forever(); sleep_forever();
} }
ttn_register(callback); ttn_register(callback);
ttn_join(); ttn_join();
ttn_sf(LORAWAN_SF); ttn_sf(LORAWAN_SF);
ttn_adr(LORAWAN_ADR); ttn_adr(LORAWAN_ADR);
} }
void loop() { void loop() {
gps_loop(); gps_loop();
ttn_loop(); ttn_loop();
screen_loop(); screen_loop();
// Send every SEND_INTERVAL millis // Send every SEND_INTERVAL millis
static uint32_t last = 0; static uint32_t last = 0;
static bool first = true; static bool first = true;
if (0 == last || millis() - last > SEND_INTERVAL) { if (0 == last || millis() - last > SEND_INTERVAL) {
if (0 < gps_hdop() && gps_hdop() < 50 && gps_latitude() != 0 && gps_longitude() != 0) { if (0 < gps_hdop() && gps_hdop() < 50 && gps_latitude() != 0 && gps_longitude() != 0) {
last = millis(); last = millis();
first = false; first = false;
send(); Serial.println("TRANSMITTING");
} else { send();
if (first) { } else {
screen_print("Waiting GPS lock\n"); if (first) {
first = false; screen_print("Waiting GPS lock\n");
} first = false;
if (millis() > GPS_WAIT_FOR_LOCK) { }
sleep(); if (millis() > GPS_WAIT_FOR_LOCK) {
} sleep();
} }
} }
}
} }

View File

@ -155,6 +155,14 @@ void ttn_join() {
// https://github.com/TheThingsNetwork/gateway-conf/blob/master/US-global_conf.json // https://github.com/TheThingsNetwork/gateway-conf/blob/master/US-global_conf.json
LMIC_selectSubBand(1); LMIC_selectSubBand(1);
#elif defined(CFG_au915)
Serial.println("AU_915");
// NA-US channels 0-71 are configured automatically
// but only one group of 8 should (a subband) should be active
// TTN recommends the second sub band, 1 in a zero based count.
// https://github.com/TheThingsNetwork/gateway-conf/blob/master/US-global_conf.json
LMIC_selectSubBand(1);
#endif #endif
// If using a mono-channel gateway disable all channels // If using a mono-channel gateway disable all channels
@ -210,6 +218,7 @@ void ttn_send(uint8_t * data, uint8_t data_size, uint8_t port, bool confirmed){
// Prepare upstream data transmission at the next possible time. // Prepare upstream data transmission at the next possible time.
// Parameters are port, data, length, confirmed // Parameters are port, data, length, confirmed
LMIC_setTxData2(port, data, data_size, confirmed ? 1 : 0); LMIC_setTxData2(port, data, data_size, confirmed ? 1 : 0);
_ttn_callback(EV_QUEUED); _ttn_callback(EV_QUEUED);