From 5a7003d621feacd22921156b7cfe9d095217b69b Mon Sep 17 00:00:00 2001 From: sessionm21 Date: Sun, 19 Apr 2020 04:07:23 +0100 Subject: [PATCH] send coordinates over lorawan --- .clang | 17 ++++ .ctags | 6 ++ .gitmodules | 3 + Makefile | 28 +++++- collar.cpp | 272 ++++++++++++++++++++++++++++++++------------------ prototest.cpp | 141 ++++++++++++++++++++++++++ 6 files changed, 366 insertions(+), 101 deletions(-) create mode 100644 .clang create mode 100644 .ctags create mode 100644 prototest.cpp diff --git a/.clang b/.clang new file mode 100644 index 0000000..931ce9f --- /dev/null +++ b/.clang @@ -0,0 +1,17 @@ +-Datmega328p +-Dmega328p +-DF_CPU=16000000L +-DARDUINO=200 +-DARDUINO_AVR_NANO +-DARDUINO_ARCH_AVR +-D__AVR_ATmega328P +-std=c++11 +-I./external/ArduinoCore-avr/libraries/SPI/src +-I./external/ArduinoCore-avr/cores/arduino +-I./external/ArduinoCore-avr/variants/eightanaloginputs +-I./libraries/arduino-LoRa/src +-I./libraries/TinyGPSPlus/src +-I./libraries/TinyLoRa +-I./external/nanopb +-I./protobuf +-I./external/ArduinoCore-avr/libraries/SoftwareSerial/src diff --git a/.ctags b/.ctags new file mode 100644 index 0000000..61fff66 --- /dev/null +++ b/.ctags @@ -0,0 +1,6 @@ +--recurse=yes +--exclude=.git +--exclude=vendor/* +--exclude=node_modules/* +--exclude=db/* +--exclude=log/* diff --git a/.gitmodules b/.gitmodules index a01553f..feca297 100644 --- a/.gitmodules +++ b/.gitmodules @@ -13,3 +13,6 @@ [submodule "libraries/TinyGPSPlus"] path = libraries/TinyGPSPlus url = https://github.com/mikalhart/TinyGPSPlus.git +[submodule "libraries/arduino-lmic"] + path = libraries/arduino-lmic + url = https://github.com/mcci-catena/arduino-lmic.git diff --git a/Makefile b/Makefile index cfb2654..4aa8562 100644 --- a/Makefile +++ b/Makefile @@ -31,6 +31,7 @@ INC_DIRS?=-I./$(ARDUINO_DIR)/libraries/SPI/src\ -I./$(ARDUINO_DIR)/variants/eightanaloginputs\ -I./libraries/arduino-LoRa/src\ -I./libraries/TinyGPSPlus/src\ + -I./libraries/TinyLoRa\ -I./$(NANOPB_DIR)\ -I./protobuf\ -I./$(ARDUINO_DIR)/libraries/SoftwareSerial/src/ @@ -46,19 +47,26 @@ SRC_FILES?=./$(ARDUINO_DIR)/cores/arduino/main.cpp\ ./$(ARDUINO_DIR)/cores/arduino/HardwareSerial1.cpp\ ./$(ARDUINO_DIR)/cores/arduino/HardwareSerial2.cpp\ ./$(ARDUINO_DIR)/cores/arduino/HardwareSerial3.cpp\ - ./$(ARDUINO_DIR)/libraries/SPI/src/SPI.cpp\ ./$(ARDUINO_DIR)/cores/arduino/WString.cpp\ ./$(ARDUINO_DIR)/cores/arduino/Print.cpp\ ./$(ARDUINO_DIR)/cores/arduino/Stream.cpp\ ./$(ARDUINO_DIR)/cores/arduino/new.cpp\ ./$(ARDUINO_DIR)/cores/arduino/abi.cpp\ ./$(ARDUINO_DIR)/libraries/SoftwareSerial/src/SoftwareSerial.cpp\ + ./$(ARDUINO_DIR)/libraries/SPI/src/SPI.cpp\ ./libraries/arduino-LoRa/src/LoRa.cpp\ ./libraries/TinyGPSPlus/src/TinyGPS++.cpp\ + ./libraries/TinyLoRa/TinyLoRa.cpp\ ./$(NANOPB_DIR)/pb_encode.c\ ./$(NANOPB_DIR)/pb_decode.c\ ./$(NANOPB_DIR)/pb_common.c\ - ./gateway/message.pb.c + ./protobuf/gateway/message.pb.c + +SRC_FILES_COMMON?=\ + ./$(NANOPB_DIR)/pb_encode.c\ + ./$(NANOPB_DIR)/pb_decode.c\ + ./$(NANOPB_DIR)/pb_common.c\ + ./protobuf/gateway/message.pb.c build: $(OUT)$(NAME) @@ -66,21 +74,31 @@ $(OUT)$(NAME): $(OUT)$(NAME).elf $(OBJCOPY) -R .eeprom -O ihex $(OUT)$(NAME).elf $(OUT)$(NAME).hex $(OUT)eep.hex: $(OUT)$(NAME).elf $(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O ihex $(OUT)$(NAME).elf $(OUT)eep.hex -$(OUT)$(NAME).elf: protobuf bin +$(OUT)$(NAME).elf: protobufg bin $(CC) $(CFLAGS) -o $(OUT)$(NAME).elf collar.cpp $(INC_DIRS) $(SRC_FILES) -protobuf: +test: + g++ -o $(OUT)test prototest.cpp $(INC_DIRS) $(SRC_FILES_COMMON) + $(OUT)test + +protobufg: mkdir -p protobuf/gateway python3 external/nanopb/generator/nanopb_generator.py gateway/message.proto -D protobuf bin: mkdir bin -flash: +flash: $(OUT)$(NAME) avrdude -v -patmega328p -carduino -P/dev/ttyUSB0 -b115200 -D -Uflash:w:$(OUT)$(NAME).hex:i +run: flash + screen /dev/ttyUSB0 + +start: flash + systemctl start lora-gateway-bridge loraserver stop: avrdude -v -patmega328p -carduino -P/dev/ttyUSB0 -b115200 -D -Uflash:w:nothing.hex:i + systemctl stop lora-gateway-bridge loraserver clean: rm -r protobuf diff --git a/collar.cpp b/collar.cpp index 889c4fe..caab6fa 100644 --- a/collar.cpp +++ b/collar.cpp @@ -1,131 +1,211 @@ +// Hello LoRa - ABP TTN Packet Sender (Multi-Channel) +// Tutorial Link: https://learn.adafruit.com/the-things-network-for-feather/using-a-feather-32u4 +// +// Adafruit invests time and resources providing this open source code. +// Please support Adafruit and open source hardware by purchasing +// products from Adafruit! +// +// Copyright 2015, 2016 Ideetron B.V. +// +// Modified by Brent Rubell for Adafruit Industries, 2018 +/************************** Configuration ***********************************/ +#include #include -#include -#include -#include +#include "gateway/message.pb.h" #include "pb_common.h" #include "pb.h" #include "pb_encode.h" +#include "pb_decode.h" #include "gateway/message.pb.h" -unsigned long previousMillis = 0; -const long interval = 5000; -float lat = 0; -float lng = 0; +// Visit your thethingsnetwork.org device console +// to create an account, or if you need your session keys. -bool sending = false; +// Network Session Key (MSB) +uint8_t NwkSkey[16] = {0x52, 0x92, 0xC0, 0x72, 0x2D, 0x3C, 0x55, 0x5E, 0xE4, 0xB9, 0x9E, 0x9B, 0x88, 0x66, 0x47, 0xF1}; -TinyGPSPlus gps; +// Application Session Key (MSB) +uint8_t AppSkey[16] = {0xC4, 0x30, 0xEF, 0x56, 0x4F, 0x6D, 0xA2, 0x56, 0x1F, 0x15, 0x2F, 0xB8, 0x62, 0xC7, 0xCA, 0xC2}; -SoftwareSerial ss(6, 7); +// Device Address (MSB) +uint8_t DevAddr[4] = {0x26, 0x02, 0x12, 0xB6}; -typedef struct lora_status_s { - int sleep; -} lora_status_t; +/************************** Example Begins Here ***********************************/ +// Data Packet to Send to TTN +unsigned char loraData[50] = {"hello LoRa"}; -static lora_status_t lora_status; +// How many times data transfer should occur, in seconds +const unsigned int sendInterval = 30; -void transmitLora() { - // Encode as protobuf packet - if (lat && lng) { - uint8_t buffer[50] = {0}; - Fenceless_CollarResponse m = Fenceless_CollarResponse_init_zero; - pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer)); - m.loc.x = lat; - m.loc.y = lng; +// Pinout for Adafruit Feather 32u4 LoRa +TinyLoRa lora = TinyLoRa(2, 10, 9); - int status = pb_encode(&stream, Fenceless_CollarResponse_fields, &m); +// Pinout for Adafruit Feather M0 LoRa +//TinyLoRa lora = TinyLoRa(3, 8, 4); - if (!status) { - Serial.println("Failed to encode"); +const uint8_t N_POLY_MAX=100; +float polyx[N_POLY_MAX]; +float polyy[N_POLY_MAX]; +int n_poly=0; +int push_vert(float x, float y) { + if(n_poly>N_POLY_MAX) + return 0; + polyx[n_poly]=x; + polyy[n_poly]=y; + n_poly++; + return 1; +} +void clear_verts() { + n_poly=0; +} +int pnpoly(int nvert, float *vertx, float *verty, float testx, float testy) +{ //from stack overflow + int i, j, c = 0; + for (i = 0, j = nvert-1; i < nvert; j = i++) { + if ( ((verty[i]>testy) != (verty[j]>testy)) && + (testx < (vertx[j]-vertx[i]) * (testy-verty[i]) / (verty[j]-verty[i]) + vertx[i]) ) + c = !c; + } + return c; +} +int check_bounds(float x, float y) { + return pnpoly(n_poly, polyx, polyy, x, y); +} +bool Fenceless_Coordinates_callback(pb_istream_t *stream, const pb_field_iter_t *field, void **arg) { + Serial.println("Called"); + while(stream->bytes_left) { + Fenceless_Coordinate m = Fenceless_Coordinate_init_zero; + if(!pb_decode(stream, Fenceless_Coordinate_fields, &m)) { + return false; } - - Serial.print("Sending packet Lat / Long: "); - Serial.println(lat); - Serial.println(lng); - - // send packet - - LoRa.beginPacket(); - LoRa.print((char *) buffer); - LoRa.endPacket(); - + push_vert(m.x,m.y); + return true; } } -void updateGPS() { - // Gather GPS data - if (gps.location.isValid()) { - lat = gps.location.lat(); - lng = gps.location.lng(); - } else { - lat = 0; - lng = 0; +void import_protobuf(uint8_t *protobuffer, uint32_t size) { + Fenceless_Coordinates m; + pb_istream_t stream = pb_istream_from_buffer(protobuffer, size); + int status = pb_decode(&stream, Fenceless_Coordinates_fields, &m); + if(!status){ + Serial.println("Failed to decode"); + } + clear_verts(); + switch(m.isr) { + case 10: + push_vert(m.coord9.x, m.coord9.y); + case 9: + push_vert(m.coord8.x, m.coord8.y); + case 8: + push_vert(m.coord7.x, m.coord7.y); + case 7: + push_vert(m.coord6.x, m.coord6.y); + case 6: + push_vert(m.coord5.x, m.coord5.y); + case 5: + push_vert(m.coord4.x, m.coord4.y); + case 4: + push_vert(m.coord3.x, m.coord3.y); + case 3: + push_vert(m.coord2.x, m.coord2.y); + push_vert(m.coord1.x, m.coord1.y); + push_vert(m.coord0.x, m.coord0.y); } } -ISR(TIMER1_OVF_vect) { - // handle timer overflow interrupt at 1 per second - updateGPS(); - if(!gps.location.isValid()) { - Serial.println("Seeking GPS"); +bool Fenceless_Coordinates_encode(pb_ostream_t *stream, const pb_field_iter_t *field, void * const * arg) { + Serial.println("Encode called"); + return false; + Fenceless_Coordinate c = *(Fenceless_Coordinate*)field->pData; + if(!pb_encode_tag_for_field(stream, field)) { + return false; } - if(sending && gps.location.isValid()) { - if(lora_status.sleep) { - } - transmitLora(); + return pb_encode(stream, Fenceless_Coordinate_fields, field); +} +void test() { + Serial.println("Testing protobuf"); + uint8_t buffer[100] = {0}; + Fenceless_Coordinates m = Fenceless_Coordinates_init_zero; + pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer)); + int status = pb_encode(&stream, Fenceless_Coordinates_fields, &m); + if(!status){ + Serial.println("Failed to encode"); } + import_protobuf(buffer, sizeof(buffer)); } -void initialize_timer() { - TCCR1A = 0; - TCCR1B = 0; - TCNT1 = 34286; // timer preload - TCCR1B |= (1< 0) { - gps.encode(ss.read()); - } - /* Lora data recieved */ - int packetSize = LoRa.parsePacket(); - if (packetSize) { - Serial.print("Received Packet: "); - while (LoRa.available()) { - Serial.print((char) LoRa.read()); - } - Serial.println(); +void loop() +{ + Serial.println("Sending LoRa Data..."); + lora.sendData(loraData, sizeof(loraData), lora.frameCounter); + // Optionally set the Frame Port (1 to 255) + // uint8_t framePort = 1; + // lora.sendData(loraData, sizeof(loraData), lora.frameCounter, framePort); + Serial.print("Frame Counter: ");Serial.println(lora.frameCounter); + lora.frameCounter++; + + // blink LED to indicate packet sent + digitalWrite(LED_BUILTIN, HIGH); + delay(1000); + digitalWrite(LED_BUILTIN, LOW); + + Serial.println("delaying..."); + + if(recieved) { + Serial.println("Recieved something"); + } else { + Serial.println("Nothing yet"); } + delay(sendInterval * 1000); } diff --git a/prototest.cpp b/prototest.cpp new file mode 100644 index 0000000..defdfda --- /dev/null +++ b/prototest.cpp @@ -0,0 +1,141 @@ +#include +#include + +#include "pb_common.h" +#include "pb.h" +#include "pb_encode.h" +#include "pb_decode.h" + +#include "gateway/message.pb.h" + +/* + * Try to get repeating element to work with nanopb + * for coordinates + */ +using namespace std; +void print_buffer(uint8_t *buffer, int size) { + for(int i=0;iarray_size); + // bool eof; + // uint32_t tag; + // pb_wire_type_t t = PB_WT_STRING; + // pb_decode_tag(stream, &t, &tag, &eof); + // Fenceless_Coordinate coord; + // int err = pb_decode(stream, Fenceless_Coordinate_fields, &coord); + // assert(err); + // printf("%d %d", coord.x,coord.y); + + // return false; + //}; + //stream0 = pb_istream_from_buffer(buffer, stream.bytes_written); + //err = pb_decode(&stream0, Fenceless_Coordinates_fields, &coords0); + //assert(err); + return 0; +}