177 lines
3.8 KiB
C++
177 lines
3.8 KiB
C++
#include <Arduino.h>
|
|
#include <avr/sleep.h>
|
|
#include <avr/interrupt.h>
|
|
#include <SPI.h>
|
|
#include <Wire.h>
|
|
#include <LoRaWAN.h>
|
|
|
|
// OLED
|
|
#include <U8x8lib.h>
|
|
U8X8_SSD1306_128X64_NONAME_HW_I2C oled(U8X8_PIN_NONE, PIN_PB0, PIN_PB1);
|
|
|
|
// GPS
|
|
#include <gps.h>
|
|
Gps gps;
|
|
bool hasFix = false;
|
|
bool oldFix = false;
|
|
|
|
// Button Handling
|
|
#include <Button2.h>
|
|
Button2 btn = Button2(PIN_PC2);
|
|
bool adhocsend = false;
|
|
|
|
// Modes for Display Menus and Navigation
|
|
enum Modes {
|
|
M_NORMAL,
|
|
M_SETUP
|
|
};
|
|
|
|
Modes amode = M_NORMAL; // Active Mode
|
|
Modes omode = M_NORMAL; // Previous Mode
|
|
|
|
// LoRa
|
|
#include "config.h" // Contains LoRa ABP Keys
|
|
#define DIO0 PIN_PA4
|
|
#define NSS PIN_PA5
|
|
RFM95 rfm(DIO0, NSS);
|
|
LoRaWAN lora = LoRaWAN(rfm);
|
|
uint16_t Frame_Counter_Tx = 0x0000;
|
|
|
|
// Some Status Variables
|
|
uint8_t interval = 20; // Sending Interval in Settings
|
|
uint8_t packets = 0; // Sent LoRa Packets
|
|
String statusmsg = "";
|
|
|
|
uint8_t loraBuffer[9]; // Lora Data Packet
|
|
uint32_t lastmillis;
|
|
|
|
// Button Handler Function
|
|
void handler(Button2& btn) {
|
|
switch (btn.getClickType()) {
|
|
case SINGLE_CLICK:
|
|
if (amode == M_SETUP) {
|
|
interval = interval += 10;
|
|
if (interval > 40)
|
|
interval = 10;
|
|
} else if (amode == M_NORMAL) {
|
|
statusmsg = "Adhoc Request";
|
|
adhocsend = true;
|
|
}
|
|
break;
|
|
case LONG_CLICK:
|
|
switch (amode) {
|
|
case M_NORMAL:
|
|
amode = M_SETUP;
|
|
break;
|
|
case M_SETUP:
|
|
amode = M_NORMAL;
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Draw the Display
|
|
void updateDisplay() {
|
|
uint16_t buffer[6];
|
|
gps.gdisplay(buffer);
|
|
|
|
oled.home();
|
|
oled.setFont(u8x8_font_victoriabold8_r);
|
|
|
|
if (amode != omode) {
|
|
oled.clear();
|
|
omode = amode;
|
|
}
|
|
|
|
if (amode == M_SETUP) {
|
|
oled.println ("<< SETUP >>");
|
|
oled.println ("");
|
|
oled.print("Interval: ");
|
|
oled.println(interval);
|
|
} else if (amode == M_NORMAL) {
|
|
if (hasFix) {
|
|
if (hasFix != oldFix){
|
|
oled.clear();
|
|
oldFix = hasFix;
|
|
}
|
|
oled.print("HDOP: ");
|
|
oled.println(buffer[0]);
|
|
oled.print("Sats: ");
|
|
oled.print(buffer[1]);
|
|
oled.print("/");
|
|
oled.println(buffer[2]);
|
|
oled.print("Int: ");
|
|
oled.println(interval);
|
|
oled.print("Packet: ");
|
|
oled.println(Frame_Counter_Tx);
|
|
oled.print("Alt: ");
|
|
oled.println(buffer[3]);
|
|
oled.print("Speed: ");
|
|
oled.println(buffer[4]);
|
|
} else {
|
|
if (hasFix != oldFix){
|
|
oled.clear();
|
|
oldFix = hasFix;
|
|
}
|
|
oled.println("NO GPS FIX");
|
|
oled.print("Sats: ");
|
|
oled.print(buffer[1]);
|
|
oled.print("/");
|
|
oled.println(buffer[2]);
|
|
oled.print("Int: ");
|
|
oled.println(interval);
|
|
oled.print("Packet: ");
|
|
oled.println(Frame_Counter_Tx);
|
|
}
|
|
oled.print(statusmsg);
|
|
oled.println(" ");
|
|
}
|
|
}
|
|
|
|
// Setup
|
|
void setup() {
|
|
// GPS Setup
|
|
Serial.begin(9600);
|
|
|
|
// Button
|
|
btn.setLongClickTime(1000);
|
|
btn.setClickHandler(handler);
|
|
btn.setLongClickHandler(handler);
|
|
|
|
// OLED Setup
|
|
Wire.begin();
|
|
Wire.setClock(400000L);
|
|
oled.begin();
|
|
oled.setPowerSave(0);
|
|
oled.setFlipMode(1);
|
|
oled.clear();
|
|
|
|
// Lora Initialization
|
|
rfm.init();
|
|
lora.setKeys(NwkSkey, AppSkey, DevAddr);
|
|
}
|
|
|
|
// Main Loop
|
|
void loop() {
|
|
hasFix = gps.checkGpsFix();
|
|
uint32_t curmillis = millis();
|
|
if (hasFix && (((uint32_t)(curmillis - lastmillis) >= interval*1000) || adhocsend)) {
|
|
if (adhocsend) {
|
|
statusmsg = "Sending (Adhoc)";
|
|
} else {
|
|
statusmsg = "Sending";
|
|
}
|
|
updateDisplay();
|
|
adhocsend = false;
|
|
|
|
gps.buildPacket(loraBuffer);
|
|
lora.Send_Data((unsigned char *)&loraBuffer, sizeof(loraBuffer), Frame_Counter_Tx, SF7BW125, 0x01);
|
|
Frame_Counter_Tx++;
|
|
lastmillis = millis();
|
|
} else {
|
|
updateDisplay();
|
|
}
|
|
statusmsg = "";
|
|
btn.loop();
|
|
} |