oh man i have not used code blocks in forever, my code is nicely formatted on Arduino IDE, is the format the same? or did you meant blockquote? just gonna try my luck first
#include “LoRaWan_APP.h”
#include “HT_SSD1306Wire.h”
#include “Arduino.h”
// OLED Display Configuration
#ifdef WIRELESS_STICK_V3
static SSD1306Wire display(0x3c, 500000, SDA_OLED, SCL_OLED, GEOMETRY_64_32, RST_OLED);
#else
static SSD1306Wire display(0x3c, 500000, SDA_OLED, SCL_OLED, GEOMETRY_128_64, RST_OLED);
#endif
// Device Configuration
const String TAG_ID = “MT1”; // Maintenance Tag ID
// OTAA Parameters
uint8_t devEui[] = { 0x3A, 0x43, 0xCA, 0x48, 0x00, 0x00, 0xBC, 0x6A };
uint8_t appEui[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
uint8_t appKey[] = { 0x74, 0xD6, 0x6E, 0x63, 0x45, 0x82, 0x48, 0x27, 0xFE, 0xC5, 0xB7, 0x70, 0xBA, 0x2B, 0x50, 0x45 };
// ABP Parameters (required by library but not used in OTAA mode)
uint8_t nwkSKey[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
uint8_t appSKey[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
uint32_t devAddr = ( uint32_t )0x00000000;
// LoRaWAN Configuration
uint16_t userChannelsMask[6]={ 0x00FF,0x0000,0x0000,0x0000,0x0000,0x0000 };
LoRaMacRegion_t loraWanRegion = LORAMAC_REGION_AS923; // Singapore frequency plan
DeviceClass_t loraWanClass = CLASS_A;
bool overTheAirActivation = true;
bool loraWanAdr = false; // Disable ADR for more stable connection
bool isTxConfirmed = false; // Changed to unconfirmed messages
uint8_t appPort = 85; // Changed to match the port being used in transmissions
uint8_t confirmedNbTrials = 4; // Reduced retries
uint32_t appTxDutyCycle = 30000; // Increased to 30 seconds for better stability
// Panic Button Configuration
const int PRG_BUTTON_PIN = 0; // GPIO0 on Heltec board
unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 50;
int lastButtonState = HIGH;
int buttonState;
unsigned long lastPanicTime = 0;
const unsigned long PANIC_COOLDOWN = 10000; // 10 second cooldown
bool isPanicMode = false;
unsigned long lastTransmitTime = 0;
// Display Functions
void VextON(void) {
pinMode(Vext, OUTPUT);
digitalWrite(Vext, LOW);
}
void displayStatus(const String& status, const String& detail) {
display.clear();
display.setTextAlignment(TEXT_ALIGN_LEFT);
display.setFont(ArialMT_Plain_16);
display.drawString(0, 0, status);
display.setFont(ArialMT_Plain_10);
display.drawString(0, 20, detail);
display.drawString(0, 35, "Tag ID: " + TAG_ID);
display.display();
}
void downLinkDataHandle(McpsIndication_t *mcpsIndication) {
Serial.printf("Received downlink: %s, RXSIZE %d, PORT %d, DATA: ", mcpsIndication->RxSlot?"RXWIN2":"RXWIN1", mcpsIndication->BufferSize, mcpsIndication->Port);
for(uint8_t i=0; i<mcpsIndication->BufferSize; i++) {
Serial.printf("%02X", mcpsIndication->Buffer[i]);
}
Serial.println();
}
void joinCallback(void) {
Serial.println("Join success!");
deviceState = DEVICE_STATE_SEND;
}
void prepareTxFrame(uint8_t port, bool isPanic) {
appDataSize = 4;
appData[0] = isPanic ? 0xFF : 0x00;
appData[1] = TAG_ID.charAt(0);
appData[2] = TAG_ID.charAt(1);
appData[3] = TAG_ID.charAt(2);
String msgType = isPanic ? "PANIC ALERT" : "Heartbeat";
Serial.println("\n--- Transmitting Message ---");
Serial.printf("Type: %s\n", msgType.c_str());
Serial.printf("Tag ID: %c%c%c\n", appData[1], appData[2], appData[3]);
Serial.print("Raw Payload (hex): ");
for(uint8_t i = 0; i < appDataSize; i++) {
Serial.printf("%02X ", appData[i]);
}
Serial.println("\n------------------------");
}
void setup() {
Serial.begin(115200);
while (!Serial);
VextON();
delay(100);
display.init();
display.clear();
display.display();
pinMode(PRG_BUTTON_PIN, INPUT_PULLUP);
buttonState = digitalRead(PRG_BUTTON_PIN);
lastButtonState = buttonState;
// Initialize LoRaWAN with AS923 configuration
Mcu.begin(HELTEC_BOARD, SLOW_CLK_TPYE);
LoRaWAN.init(loraWanClass, loraWanRegion);
LoRaWAN.setDefaultDR(1); // Changed to DR1 for better range
displayStatus("Joining", "Network...");
deviceState = DEVICE_STATE_JOIN;
}
void loop() {
unsigned long currentTime = millis();
bool flag = false;
if (deviceState == DEVICE_STATE_JOIN && flag == false) {
Serial.println("Attempting to join network...");
LoRaWAN.join();
delay(5000);
if (deviceState != DEVICE_STATE_JOIN) {
Serial.println("Join successful!");
displayStatus("Connected", "Network OK");
delay(1000);
LoRaWAN.setDefaultDR(1); // Keep at DR1 for better stability
deviceState = DEVICE_STATE_SEND;
lastTransmitTime = currentTime; // Initialize timing
} else {
Serial.println("Join failed, retrying...");
displayStatus("Joining", "Retrying...");
}
flag = true;
}
// Button handling with debounce
int reading = digitalRead(PRG_BUTTON_PIN);
if (reading != lastButtonState) {
lastDebounceTime = currentTime;
}
if ((currentTime - lastDebounceTime) > debounceDelay) {
if (reading != buttonState) {
buttonState = reading;
if (buttonState == LOW) {
if (!isPanicMode) {
isPanicMode = true;
isTxConfirmed = true;
confirmedNbTrials = 8;
displayStatus("PANIC MODE", "Alert Active!");
prepareTxFrame(appPort, true);
deviceState = DEVICE_STATE_SEND;
lastTransmitTime = currentTime - appTxDutyCycle; // Force immediate send
lastPanicTime = currentTime;
}
}
}
}
lastButtonState = reading;
if (currentTime - lastTransmitTime >= appTxDutyCycle) {
switch(deviceState) {
case DEVICE_STATE_SEND: {
prepareTxFrame(appPort, isPanicMode);
LoRaWAN.send();
Serial.println("Uplink sent");
lastTransmitTime = currentTime;
deviceState = DEVICE_STATE_CYCLE;
break;
}
case DEVICE_STATE_CYCLE: {
LoRaWAN.cycle(appTxDutyCycle);
deviceState = DEVICE_STATE_SLEEP;
break;
}
case DEVICE_STATE_SLEEP: {
LoRaWAN.sleep(loraWanClass);
if (isPanicMode && (currentTime - lastPanicTime >= PANIC_COOLDOWN)) {
isPanicMode = false;
isTxConfirmed = false;
confirmedNbTrials = 4;
displayStatus("Normal Mode", "Monitoring...");
}
deviceState = DEVICE_STATE_SEND;
break;
}
default:
deviceState = DEVICE_STATE_SEND;
break;
}
}
}