/*************************************************************************************************** Copyright (c) 2015 Thomas Telkamp and Matthijs Kooijman + a little Adaption for the BME280/LoRaDev Demo-Kit by TK 2021 ;-) Permission is hereby granted, free of charge, to anyone obtaining a copy of this document and accompanying files, to do whatever they want with them without any restriction, including, but not limited to, copying, modification and redistribution. NO WARRANTY OF ANY KIND IS PROVIDED. This uses ABP (Activation-by-personalisation), where a DevAddr and Session keys are preconfigured (unlike OTAA, where a DevEUI and application key is configured, while the DevAddr and session keys are assigned/generated in the over-the-air-activation procedure). Note: LoRaWAN per sub-band duty-cycle limitation is enforced (1% in g1, 0.1% in g2), but not the TTN fair usage policy (which is probably violated by this sketch when left running for longer)! To use this sketch, first register your application and device with the things network, to set or generate a DevAddr, NwkSKey and AppSKey. Each device should have their own unique values for these fields. Do not forget to define the radio type correctly in config.h. ------------------------------------------------------------------------------------------------- This sample code has been adapted for Heltec ESP32 LoRa Board. Further information: https://www.aeq-web.com/lorawan-ttn-mit-heltec-esp32-lora-board-abp-mode/ Note: This code example is also compatible with single channel gateways. Currently, only channel 0 is enabled. Further channels can be enabled in the following code below. ***************************************************************************************************/ // Libraries LoRaWAN / SPI / OLED Display #include #include #include #include #include //Libraries for BME280 #include #include //BME280 definition festlegen #define SDA 4 #define SCL 15 TwoWire I2Cone = TwoWire(1); Adafruit_BME280 bme; //Paketzähler ID setzen / Strings festlegen int readingID = 0; int counter = 0; String LoRaMessage = ""; float temperature = 0; float humidity = 0; float pressure = 0; // Zugangsdaten vom TTN / The Things Network // (müssen voher bei generiert worden sein (siehe Wiki).. dann hier unten eintragen) // LoRaWAN Network Session Key (drag and drop als msb ) static const PROGMEM u1_t NWKSKEY[16] = { 0xDC, 0x5D, 0xA2, 0xD6, 0xFB, 0x78, 0x9A, 0x9E, 0xC6, 0x00, 0x9D, 0xBD, 0xA6, 0x5E, 0x6C, 0xE3 }; // LoRaWAN App Session Key (Drag and Drop als msb) static const u1_t PROGMEM APPSKEY[16] = { 0x6E, 0xB3, 0xC4, 0x6F, 0x38, 0x2C, 0xD8, 0xB7, 0x61, 0x89, 0xD1, 0x87, 0xDE, 0xB9, 0x79, 0xB6 }; // LoRaWAN Device Address static const u4_t DEVADDR = 0x260BB744; void startBME(){ delay(1000); I2Cone.begin(SDA, SCL, 100000); bool status1 = bme.begin(0x76, &I2Cone); if (!status1) { Serial.println("Kein BME280 Sensor gefunden!"); while (1); } delay(3000); } // Display passend konfigurieren U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ 15, /* data=*/ 4, /* reset=*/ 16); U8X8_SSD1306_128X64_NONAME_SW_I2C u8x8(15, 4, 16); // Um Grafiken umzuwandeln sollte diese in S/W sein die passende Größe hier 128x64 Pixel haben // und als xbm exportiert werden. static unsigned char TK_OLED_SOURCE_bits[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xaf, 0xaa, 0xba, 0xfa, 0x57, 0x57, 0x55, 0xfd, 0xfa, 0x7f, 0xf5, 0x7f, 0xf5, 0xff, 0x85, 0xfe, 0x07, 0x00, 0x30, 0xf8, 0x07, 0x03, 0x00, 0x70, 0xe0, 0x3f, 0xf0, 0x3f, 0xf0, 0xff, 0x00, 0xf8, 0x07, 0x00, 0x30, 0xf8, 0x07, 0x03, 0x00, 0x70, 0xe0, 0x3f, 0xf0, 0x3f, 0xf0, 0x7f, 0x00, 0xf8, 0x07, 0x00, 0x30, 0xf8, 0x07, 0x03, 0x00, 0x70, 0xc0, 0x3f, 0xf0, 0x1f, 0xf0, 0x3f, 0x00, 0xf8, 0x0f, 0x00, 0x30, 0xf8, 0x07, 0x03, 0x00, 0x70, 0xc0, 0x3f, 0xf0, 0x1f, 0xe0, 0x1f, 0x00, 0xf8, 0xff, 0xc1, 0x3f, 0xf8, 0x07, 0x07, 0x00, 0x78, 0xc0, 0x1f, 0xf0, 0x1f, 0xe0, 0x1f, 0xf8, 0xfe, 0xff, 0xc1, 0x3f, 0xf8, 0x07, 0xff, 0xff, 0x3f, 0x80, 0x1f, 0xe0, 0x0f, 0xc0, 0x1f, 0xfc, 0xff, 0xff, 0xc1, 0x3f, 0xf8, 0x07, 0xff, 0xff, 0x7f, 0x80, 0x0f, 0xe0, 0x0f, 0xc0, 0x1f, 0xf8, 0xff, 0xff, 0xc1, 0x3f, 0xf8, 0x07, 0xff, 0xff, 0x3f, 0x00, 0x0f, 0xe0, 0x0f, 0x80, 0x1f, 0xf8, 0xff, 0xff, 0xc1, 0x3f, 0xf8, 0x07, 0xff, 0xff, 0x7f, 0x00, 0x07, 0xe0, 0x0f, 0x82, 0x1f, 0xe0, 0xff, 0xff, 0xc1, 0x3f, 0x00, 0x00, 0xff, 0xff, 0x3f, 0x00, 0x06, 0xe0, 0x07, 0x83, 0x3f, 0x80, 0xff, 0xff, 0xc1, 0x3f, 0x00, 0x00, 0xff, 0xff, 0x7f, 0x08, 0x86, 0xe0, 0x07, 0x83, 0x3f, 0x00, 0xfe, 0xff, 0xc1, 0x3f, 0x00, 0x00, 0xff, 0xff, 0x3f, 0x08, 0x82, 0xe0, 0x83, 0x07, 0xff, 0x00, 0xfc, 0xff, 0xc1, 0x3f, 0x00, 0x00, 0xff, 0xff, 0x7f, 0x10, 0x82, 0xe0, 0x83, 0x07, 0xff, 0x01, 0xf8, 0xff, 0xc1, 0x3f, 0xd8, 0x06, 0xff, 0xff, 0x3f, 0x18, 0xc0, 0xe0, 0x03, 0x00, 0xff, 0x0f, 0xf8, 0xff, 0xc1, 0x3f, 0xf8, 0x07, 0xff, 0xff, 0x7f, 0x18, 0xc0, 0xe0, 0x01, 0x00, 0xfe, 0x1f, 0xf0, 0xff, 0xc1, 0x3f, 0xf8, 0x07, 0xff, 0xff, 0x3f, 0x30, 0xe0, 0xe0, 0x01, 0x00, 0xfc, 0x3f, 0xf0, 0xff, 0xc1, 0x3f, 0xf8, 0x07, 0xff, 0xff, 0x7f, 0x30, 0xe0, 0xe0, 0x01, 0x00, 0xfc, 0x3f, 0xf0, 0xff, 0xc1, 0x3f, 0xf8, 0x07, 0xaf, 0xaa, 0x3a, 0x78, 0xf0, 0xe0, 0xc0, 0x0f, 0xbc, 0x3f, 0xf0, 0xff, 0xc1, 0x3f, 0xf8, 0x07, 0x03, 0x00, 0x70, 0x78, 0xf0, 0xe0, 0xe0, 0x1f, 0x0c, 0x1e, 0xf0, 0xff, 0xc1, 0x3f, 0xf8, 0x07, 0x03, 0x00, 0x30, 0xf0, 0xfd, 0x60, 0xe0, 0x1f, 0x0c, 0x00, 0xf8, 0xff, 0xc1, 0x3f, 0xf8, 0x07, 0x03, 0x00, 0x30, 0xf8, 0xff, 0x60, 0xf0, 0x3f, 0x08, 0x00, 0xfc, 0xff, 0xc1, 0x3f, 0xf8, 0x07, 0x03, 0x00, 0x30, 0xf8, 0xff, 0x60, 0xf0, 0x3f, 0x08, 0x00, 0xfc, 0xff, 0xc1, 0x3f, 0xf8, 0x07, 0x07, 0x00, 0x38, 0xf8, 0xff, 0x60, 0xf0, 0x3f, 0x30, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xfc, 0xff, 0xff, 0xc1, 0x1f, 0x1c, 0x00, 0xff, 0x00, 0x80, 0x83, 0xff, 0xf0, 0xe1, 0x3f, 0x18, 0xf8, 0xff, 0xff, 0xc3, 0x1f, 0x1c, 0x00, 0xfc, 0x01, 0x80, 0x07, 0xff, 0xe0, 0xc1, 0x7f, 0x58, 0xfa, 0xff, 0xff, 0xc1, 0x0f, 0x1e, 0x00, 0xf8, 0x00, 0x80, 0x03, 0xff, 0xe0, 0x81, 0x3f, 0x58, 0xf2, 0xff, 0xff, 0xc1, 0x07, 0x1e, 0x00, 0xf0, 0x00, 0x80, 0x03, 0xfe, 0xe0, 0x81, 0x3f, 0x18, 0xf8, 0xff, 0xff, 0xc1, 0x03, 0x1f, 0x28, 0xf0, 0x40, 0xd5, 0x03, 0xfe, 0xe0, 0x01, 0x3f, 0x38, 0xfc, 0xff, 0xff, 0xc1, 0x83, 0x1f, 0x7c, 0xf0, 0xe0, 0xff, 0x03, 0xfc, 0xe0, 0x01, 0x3e, 0xf8, 0xff, 0xff, 0xff, 0xc1, 0x81, 0x1f, 0x78, 0xe0, 0xe0, 0xff, 0x03, 0xf8, 0xe0, 0x01, 0x3e, 0xf8, 0xff, 0xff, 0xff, 0xc1, 0xc0, 0x1f, 0x7c, 0xe0, 0xe0, 0xff, 0x03, 0xf0, 0xe0, 0x01, 0x3c, 0xf8, 0xff, 0xff, 0xff, 0x41, 0xe0, 0x1f, 0x78, 0xf0, 0xe0, 0xff, 0x03, 0xf0, 0xe0, 0x01, 0x3c, 0xf8, 0xff, 0xff, 0xff, 0x01, 0xf0, 0x1f, 0x7c, 0xf0, 0xc0, 0xff, 0x03, 0xe0, 0xe0, 0x01, 0x30, 0xf8, 0xff, 0xff, 0xff, 0x01, 0xf8, 0x1f, 0x1c, 0xf0, 0x00, 0xe0, 0x83, 0xe0, 0xe0, 0x01, 0x30, 0xf8, 0xff, 0xff, 0xff, 0x01, 0xf0, 0x1f, 0x00, 0xf8, 0x00, 0xc0, 0x83, 0xc0, 0xe0, 0x41, 0x30, 0xf8, 0xff, 0xff, 0xff, 0x01, 0xe0, 0x1f, 0x00, 0xf8, 0x00, 0xe0, 0x83, 0x81, 0xe0, 0x41, 0x20, 0xf8, 0xff, 0xff, 0xff, 0x01, 0xe0, 0x1f, 0x00, 0xfe, 0x00, 0xe0, 0x83, 0x83, 0xe0, 0xc1, 0x00, 0xf8, 0xff, 0xff, 0xff, 0x81, 0xc0, 0x1f, 0x00, 0xfe, 0xe0, 0xff, 0x83, 0x03, 0xe0, 0xc1, 0x00, 0xf8, 0xff, 0xff, 0xff, 0x81, 0xc0, 0x1f, 0x0c, 0xfc, 0xe0, 0xff, 0x83, 0x07, 0xe0, 0xc1, 0x01, 0xf8, 0xff, 0xff, 0xff, 0xc1, 0x81, 0x1f, 0x08, 0xfc, 0xe0, 0xff, 0x83, 0x0f, 0xe0, 0xc1, 0x03, 0xf8, 0xff, 0xff, 0xff, 0xc1, 0x83, 0x1f, 0x1c, 0xf8, 0xe0, 0xff, 0x83, 0x0f, 0xe0, 0xc1, 0x07, 0xf8, 0xff, 0xff, 0xff, 0xc1, 0x03, 0x1f, 0x18, 0xf8, 0xe0, 0xff, 0x83, 0x1f, 0xe0, 0xc1, 0x07, 0xf8, 0xff, 0xff, 0xff, 0xc1, 0x07, 0x1e, 0x3c, 0xf0, 0xc0, 0xff, 0x83, 0x3f, 0xe0, 0xc1, 0x0f, 0xf8, 0xff, 0xff, 0xff, 0xc1, 0x07, 0x1e, 0x78, 0xf0, 0x00, 0x80, 0x83, 0x3f, 0xe0, 0xc1, 0x1f, 0xf8, 0xff, 0xff, 0xff, 0xc1, 0x0f, 0x1c, 0x7c, 0xe0, 0x00, 0x80, 0x83, 0x7f, 0xe0, 0xc1, 0x1f, 0xf8, 0xff, 0xff, 0xff, 0xc1, 0x1f, 0x1c, 0xf8, 0xc0, 0x00, 0x80, 0x83, 0xff, 0xe0, 0xc1, 0x3f, 0xf8, 0xff, 0xff, 0xff, 0xc1, 0x1f, 0x18, 0xfc, 0xc1, 0x00, 0x80, 0x83, 0xff, 0xe1, 0xc1, 0x3f, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; #define uS_TO_S_FACTOR 1000000 // Umberechnungsfaktor Mikro Sekunden auf Sekunden #define TIME_TO_SLEEP 30 // Dauer des Tiefschlafzustands in Sekunden RTC_DATA_ATTR int bootCount = 0; // These callbacks are only used in over-the-air activation, so they are // left empty here (we cannot leave them out completely unless // DISABLE_JOIN is set in config.h, otherwise the linker will complain). void os_getArtEui (u1_t* buf) { } void os_getDevEui (u1_t* buf) { } void os_getDevKey (u1_t* buf) { } static osjob_t sendjob; // Senden alle 120 Sekunden const unsigned TX_INTERVAL = 60; // LoRa Heltec V2 Pin Map setzen const lmic_pinmap lmic_pins = { .nss = 18, .rxtx = LMIC_UNUSED_PIN, .rst = 14, .dio = {34, 26, 35}, }; void do_send(osjob_t* j) { // Check if there is not a current TX/RX job running if (LMIC.opmode & OP_TXRXPEND) { Serial.println(F("OP_TXRXPEND, not sending")); } else { // Prepare upstream data transmission at the next possible time. startBME(); temperature = bme.readTemperature(); humidity = bme.readHumidity(); pressure = bme.readPressure() / 100.0F; Serial.print("Sending LoRa Packet to TTN Gatway: "); Serial.print("Sending Complete Data: "); //LoRaMessage = String(temperature) + "/" + String(humidity) + "/" + String(pressure); LoRaMessage = String(temperature) + " C" + "| " + String(humidity) +" %" + "| " + String(pressure) + " mB "; Serial.println(LoRaMessage); int test_length = LoRaMessage.length(); uint8_t payload [test_length]; for (int i = 0; i < test_length; i++){ payload[i] = uint8_t (LoRaMessage[i]); } LMIC_setTxData2(1, payload, sizeof(payload)-1, 0); Serial.println(F("Packet queued")); } // Next TX is scheduled after TX_COMPLETE event. } void setup() { u8g2.begin(); u8g2.clearBuffer(); // Internen Display Speicher komplett löschen u8g2.drawXBM(0,0, 128, 64, TK_OLED_SOURCE_bits); u8g2.sendBuffer(); // Inhalt des Speichers direkt auf das Display pushen delay (2000); u8x8.begin(); u8x8.clear(); u8x8.setFont(u8x8_font_chroma48medium8_r); u8x8.drawString(0, 2, "Read: BME280 " ); delay (2000); u8x8.clear(); u8x8.drawString(0, 2, " Push Message to"); u8x8.drawString(0, 3, " TTN Gateway "); delay(1500); u8x8.clear(); u8x8.drawString(0, 4, " & sleep "); u8x8.drawString(0, 6, " ..for 60 sec "); delay (1500); u8x8.clear(); u8x8.begin(); u8x8.setFont(u8x8_font_open_iconic_weather_4x4); u8x8.drawString(0, 2, "A" ); u8x8.setFont(u8x8_font_chroma48medium8_r); u8x8.drawString(4, 3, "Send Data.." ); delay (3000); u8x8.clear(); Serial.begin(115200); SPI.begin(5, 19, 27, 18); //Belegung Heltec LoRa V2 Board Serial.println(F("Booting...")); // LMIC init os_init(); // Reset the MAC state. Session and pending data transfers will be discarded. LMIC_reset(); // Set static session parameters. Instead of dynamically establishing a session // by joining the network, precomputed session parameters are be provided. #ifdef PROGMEM // On AVR, these values are stored in flash and only copied to RAM // once. Copy them to a temporary buffer here, LMIC_setSession will // copy them into a buffer of its own again. uint8_t appskey[sizeof(APPSKEY)]; uint8_t nwkskey[sizeof(NWKSKEY)]; memcpy_P(appskey, APPSKEY, sizeof(APPSKEY)); memcpy_P(nwkskey, NWKSKEY, sizeof(NWKSKEY)); LMIC_setSession (0x1, DEVADDR, nwkskey, appskey); #else // If not running an AVR with PROGMEM, just use the arrays directly LMIC_setSession (0x1, DEVADDR, NWKSKEY, APPSKEY); #endif #if defined(CFG_eu868) // Set up the channels used by the Things Network, which corresponds // to the defaults of most gateways. Without this, only three base // channels from the LoRaWAN specification are used, which certainly // works, so it is good for debugging, but can overload those // frequencies, so be sure to configure the full frequency range of // your network here (unless your network autoconfigures them). // Setting up channels should happen after LMIC_setSession, as that // configures the minimal channel set. // NA-US channels 0-71 are configured automatically LMIC_setupChannel(0, 868100000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band LMIC_setupChannel(1, 868300000, DR_RANGE_MAP(DR_SF12, DR_SF7B), BAND_CENTI); // g-band LMIC_setupChannel(2, 868500000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band LMIC_setupChannel(3, 867100000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band LMIC_setupChannel(4, 867300000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band LMIC_setupChannel(5, 867500000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band LMIC_setupChannel(6, 867700000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band LMIC_setupChannel(7, 867900000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band LMIC_setupChannel(8, 868800000, DR_RANGE_MAP(DR_FSK, DR_FSK), BAND_MILLI); // g2-band //LMIC_disableChannel(0); //Send only at channel 0 LMIC_disableChannel(1); LMIC_disableChannel(2); LMIC_disableChannel(3); LMIC_disableChannel(4); LMIC_disableChannel(5); LMIC_disableChannel(6); LMIC_disableChannel(7); LMIC_disableChannel(8); // TTN defines an additional channel at 869.525Mhz using SF9 for class B // devices' ping slots. LMIC does not have an easy way to define set this // frequency and support for class B is spotty and untested, so this // frequency is not configured here. #elif defined(CFG_us915) // 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 // Disable link check validation LMIC_setLinkCheckMode(0); // TTN uses SF9 for its RX2 window. LMIC.dn2Dr = DR_SF9; // Set data rate and transmit power for uplink (note: txpow seems to be ignored by the library) LMIC_setDrTxpow(DR_SF7, 14); // Start job do_send(&sendjob); } void loop() { os_runloop_once(); } void onEvent (ev_t ev) { Serial.print(os_getTime()); Serial.print(": "); switch (ev) { case EV_SCAN_TIMEOUT: Serial.println(F("EV_SCAN_TIMEOUT")); break; case EV_BEACON_FOUND: Serial.println(F("EV_BEACON_FOUND")); break; case EV_BEACON_MISSED: Serial.println(F("EV_BEACON_MISSED")); break; case EV_BEACON_TRACKED: Serial.println(F("EV_BEACON_TRACKED")); break; case EV_JOINING: Serial.println(F("EV_JOINING")); break; case EV_JOINED: Serial.println(F("EV_JOINED")); break; case EV_RFU1: Serial.println(F("EV_RFU1")); break; case EV_JOIN_FAILED: Serial.println(F("EV_JOIN_FAILED")); break; case EV_REJOIN_FAILED: Serial.println(F("EV_REJOIN_FAILED")); break; case EV_TXCOMPLETE: Serial.println(F("EV_TXCOMPLETE (includes waiting for RX windows)")); if (LMIC.txrxFlags & TXRX_ACK) Serial.println(F("Received ack")); if (LMIC.dataLen) { Serial.println(F("Received ")); Serial.println(LMIC.dataLen); Serial.println(F(" bytes of payload")); } // Schedule next transmission os_setTimedCallback(&sendjob, os_getTime() + sec2osticks(TX_INTERVAL), do_send); break; case EV_LOST_TSYNC: Serial.println(F("EV_LOST_TSYNC")); break; case EV_RESET: Serial.println(F("EV_RESET")); break; case EV_RXCOMPLETE: // data received in ping slot Serial.println(F("EV_RXCOMPLETE")); break; case EV_LINK_DEAD: Serial.println(F("EV_LINK_DEAD")); break; case EV_LINK_ALIVE: Serial.println(F("EV_LINK_ALIVE")); break; default: Serial.println(F("Unknown event")); break; } }