Last active
April 10, 2024 05:28
-
-
Save ccall48/0391fbada991db2fb4d0a6de0a0dbb5b to your computer and use it in GitHub Desktop.
heltec-wireless-tracker-v1.1-oled
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Heltec Automation LoRaWAN communication example | |
* | |
* Function: | |
* 1. Read the longitude and latitude of GPS and upload it to the LoRaWAN server. | |
* 2. Display the longitude and latitude of GPS on the screen. | |
* | |
* Description: | |
* 1. Communicate using LoRaWAN protocol. | |
* | |
* HelTec AutoMation, Chengdu, China | |
* 成都惠利特自动化科技有限公司 | |
* www.heltec.org | |
* | |
* this project also realess in GitHub: | |
* https://github.com/Heltec-Aaron-Lee/WiFi_Kit_series | |
* | |
* Edited by cory callcott (wdriot.com) [email protected] for working oled | |
* with tracker gps positions. | |
* | |
* */ | |
#include "Arduino.h" | |
#include "LoRaWan_APP.h" | |
#include "HT_st7735.h" | |
#include "HT_TinyGPS++.h" | |
TinyGPSPlus GPS; | |
HT_st7735 st7735; | |
#define VGNSS_CTRL Vext | |
/* OTAA para */ | |
uint8_t devEui[] = { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }; // lsb | |
uint8_t appEui[] = { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }; // lsb | |
uint8_t appKey[] = { 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88 } ; // msb | |
/* ABP para (Use OTAA) */ | |
uint8_t nwkSKey[] = { 0x15, 0xb1, 0xd0, 0xef, 0xa4, 0x63, 0xdf, 0xbe, 0x3d, 0x11, 0x18, 0x1e, 0x1e, 0xc7, 0xda, 0x85 }; | |
uint8_t appSKey[] = { 0xd7, 0x2c, 0x78, 0x75, 0x8c, 0xdc, 0xca, 0xbf, 0x55, 0xee, 0x4a, 0x77, 0x8d, 0x16, 0xef, 0x67 }; | |
uint32_t devAddr = ( uint32_t )0x007e6ae1; | |
#if defined( REGION_EU868 ) | |
/* LoraWan channelsmask, default channels 0-7 sub band 1 */ | |
uint16_t userChannelsMask[6] = { 0x00FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }; | |
int8_t dataRates[6] = {0, 1, 2, 3, 4, 5}; | |
#elif defined( REGION_AU915 ) | |
/* LoraWan channelsmask, default channels 8-15 sub band 2 */ | |
uint16_t userChannelsMask[6] = { 0xFF00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }; | |
int8_t dataRates[6] = {0, 1, 2, 3, 4, 5}; | |
#elif defined( REGION_US915 ) | |
/* LoraWan channelsmask, default channels 8-15 sub band 2 */ | |
uint16_t userChannelsMask[6] = { 0xFF00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }; | |
int8_t dataRates[6] = {0, 1, 2, 3}; | |
#endif | |
uint32_t license[4] = { 0x21701168, 0xAAAEEC0A, 0xFDA9F9D2, 0x0110E29E }; // <- your license here | |
/*LoraWan region, select in arduino IDE tools*/ | |
LoRaMacRegion_t loraWanRegion = ACTIVE_REGION; | |
/*LoraWan Class, Class A and Class C are supported*/ | |
DeviceClass_t loraWanClass = CLASS_A; | |
/*the application data transmission duty cycle. value in [ms].*/ | |
uint32_t appTxDutyCycle = 15000; | |
/*OTAA or ABP*/ | |
bool overTheAirActivation = true; | |
/*ADR enable*/ | |
bool loraWanAdr = true; | |
/* Indicates if the node is sending confirmed or unconfirmed messages */ | |
// bool isTxConfirmed = true; | |
bool isTxConfirmed = false; | |
/* Application port */ | |
uint8_t appPort = 2; | |
/*! | |
Number of trials to transmit the frame, if the LoRaMAC layer did not | |
receive an acknowledgment. The MAC performs a datarate adaptation, | |
according to the LoRaWAN Specification V1.0.2, chapter 18.4, according | |
to the following table: | |
Transmission nb | Data Rate | |
----------------|----------- | |
1 (first) | DR | |
2 | DR | |
3 | max(DR-1,0) | |
4 | max(DR-1,0) | |
5 | max(DR-2,0) | |
6 | max(DR-2,0) | |
7 | max(DR-3,0) | |
8 | max(DR-3,0) | |
Note, that if NbTrials is set to 1 or 2, the MAC will not decrease | |
the datarate, in case the LoRaMAC layer did not receive an acknowledgment | |
*/ | |
//uint8_t confirmedNbTrials = 4; | |
uint8_t confirmedNbTrials = 1; | |
/* Prepares the payload of the frame */ | |
static void prepareTxFrame( uint8_t port ) | |
{ | |
/* | |
appData size is LORAWAN_APP_DATA_MAX_SIZE which is defined in "commiSerial1ioning.h". | |
appDataSize max value is LORAWAN_APP_DATA_MAX_SIZE. | |
if enabled AT, don't modify LORAWAN_APP_DATA_MAX_SIZE, it may cause system hanging or failure. | |
if disabled AT, LORAWAN_APP_DATA_MAX_SIZE can be modified, the max value is reference to lorawan region and SF. | |
for example, if use REGION_CN470, | |
the max value for different DR can be found in MaxPayloadOfDatarateCN470 refer to DataratesCN470 and BandwidthsCN470 in "RegionCN470.h". | |
*/ | |
pinMode(Vext, OUTPUT); | |
digitalWrite(Vext, HIGH); | |
float lat, lon, alt, course, speed, hdop, sats; | |
Serial.println("Waiting for GPS FIX ..."); | |
st7735.st7735_fill_screen(ST7735_BLACK); | |
st7735.st7735_write_str(0, 0, "Device Waking"); | |
st7735.st7735_write_str(0, 40, "Aquiring GPS"); | |
while (!GPS.location.isValid()) | |
{ | |
uint32_t start = millis(); | |
do | |
{ | |
if (Serial1.available()) | |
{ | |
GPS.encode(Serial1.read()); | |
} | |
} while(GPS.charsProcessed() < 10); | |
if ((millis() - start) > 1000) // > 10000) | |
{ | |
Serial.println("No GPS data received: check wiring"); | |
break; | |
} | |
} | |
lat = GPS.location.lat(); // double | |
lon = GPS.location.lng(); // double | |
alt = GPS.altitude.meters(); // double | |
course = GPS.course.deg(); // double | |
speed = GPS.speed.kmph(); // double | |
sats = GPS.satellites.value(); // uint32_t | |
hdop = GPS.hdop.hdop() * 10; // double | |
// pinMode(GPIO0, ANALOG); | |
// uint16_t batteryVoltage = getBatteryVoltage(); | |
unsigned char *puc; | |
appDataSize = 0; | |
puc = (unsigned char *)(&lat); | |
appData[appDataSize++] = puc[0]; | |
appData[appDataSize++] = puc[1]; | |
appData[appDataSize++] = puc[2]; | |
appData[appDataSize++] = puc[3]; | |
puc = (unsigned char *)(&lon); | |
appData[appDataSize++] = puc[0]; | |
appData[appDataSize++] = puc[1]; | |
appData[appDataSize++] = puc[2]; | |
appData[appDataSize++] = puc[3]; | |
puc = (unsigned char *)(&alt); | |
appData[appDataSize++] = puc[0]; | |
appData[appDataSize++] = puc[1]; | |
appData[appDataSize++] = puc[2]; | |
appData[appDataSize++] = puc[3]; | |
// Serial monitor output (baudrate 115200) | |
Serial.print("LAT: "); | |
Serial.print(lat); | |
Serial.print(", LON: "); | |
Serial.print(lon); | |
Serial.print(", ALT: "); | |
Serial.print(alt); | |
Serial.print(", COURSE: "); | |
Serial.print(course); | |
Serial.print(", SPEED: "); | |
Serial.print(speed); | |
Serial.print(", SATS: "); | |
Serial.print(sats); | |
Serial.print(", HDOP: "); | |
Serial.print(hdop); | |
Serial.print("\r\n"); | |
// OLED Display | |
st7735.st7735_fill_screen(ST7735_BLACK); | |
String time_str = "UTC: " + (String)GPS.time.hour() + ":" + (String)GPS.time.minute() + ":" + (String)GPS.time.second(); | |
st7735.st7735_write_str(0, 0, time_str); | |
String latitude = "LAT: " + (String)GPS.location.lat(); | |
st7735.st7735_write_str(0, 20, latitude); | |
String longitude = "LON: " + (String)GPS.location.lng(); | |
st7735.st7735_write_str(0, 40, longitude); | |
String satellites = "SATS: " + (String)GPS.satellites.age(); | |
st7735.st7735_write_str(0, 60, satellites); | |
delay(5000); | |
// digitalWrite(Vext, LOW); // to turn screen off when done ? | |
} | |
void setup() | |
{ | |
Serial1.begin(115200, SERIAL_8N1, 33, 34); | |
Serial.begin(115200); | |
pinMode(Vext, OUTPUT); | |
digitalWrite(Vext, HIGH); | |
Mcu.setlicense(license, 34); | |
st7735.st7735_init(); | |
st7735.st7735_fill_screen(ST7735_BLACK); | |
Mcu.begin(HELTEC_BOARD, SLOW_CLK_TPYE); | |
} | |
void loop() { | |
switch ( deviceState ) | |
{ | |
case DEVICE_STATE_INIT: | |
{ | |
#if(LORAWAN_DEVEUI_AUTO) | |
LoRaWAN.generateDeveuiByChipID(); | |
#endif | |
LoRaWAN.init(loraWanClass,loraWanRegion); | |
// both set join DR and DR when ADR off | |
// LoRaWAN.setDefaultDR(3); | |
LoRaWAN.setDefaultDR(7); // set to SF7 | |
break; | |
} | |
case DEVICE_STATE_JOIN: | |
{ | |
LoRaWAN.join(); | |
st7735.st7735_fill_screen(ST7735_BLACK); | |
st7735.st7735_write_str(0, 0, "WDRIoT Helium"); | |
st7735.st7735_write_str(0, 20, "Mapper..."); | |
st7735.st7735_write_str(0, 60, "OTAA Join >>>"); | |
break; | |
} | |
case DEVICE_STATE_SEND: | |
{ | |
prepareTxFrame( appPort ); | |
st7735.st7735_fill_screen(ST7735_BLACK); | |
st7735.st7735_write_str(0, 0, "send >>>"); | |
LoRaWAN.send(); | |
st7735.st7735_write_str(0, 0, "send >>> ok"); | |
deviceState = DEVICE_STATE_CYCLE; | |
break; | |
} | |
case DEVICE_STATE_CYCLE: | |
{ | |
txDutyCycleTime = appTxDutyCycle + randr( -APP_TX_DUTYCYCLE_RND, APP_TX_DUTYCYCLE_RND ); | |
LoRaWAN.cycle(txDutyCycleTime); | |
deviceState = DEVICE_STATE_SLEEP; | |
break; | |
} | |
case DEVICE_STATE_SLEEP: | |
{ | |
LoRaWAN.sleep(loraWanClass); | |
break; | |
} | |
default: | |
{ | |
deviceState = DEVICE_STATE_INIT; | |
break; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment