Merge branch 'development' of https://github.com/cyberman54/ESP32-Paxcounter into development
This commit is contained in:
commit
ed46e10a9b
@ -31,8 +31,8 @@ typedef struct {
|
|||||||
} mac_t;
|
} mac_t;
|
||||||
|
|
||||||
esp_err_t lora_stack_init();
|
esp_err_t lora_stack_init();
|
||||||
|
void lora_setupForNetwork(bool preJoin);
|
||||||
void lmictask(void *pvParameters);
|
void lmictask(void *pvParameters);
|
||||||
void onEvent(ev_t ev);
|
|
||||||
void gen_lora_deveui(uint8_t *pdeveui);
|
void gen_lora_deveui(uint8_t *pdeveui);
|
||||||
void RevBytes(unsigned char *b, size_t c);
|
void RevBytes(unsigned char *b, size_t c);
|
||||||
void get_hard_deveui(uint8_t *pdeveui);
|
void get_hard_deveui(uint8_t *pdeveui);
|
||||||
@ -43,6 +43,7 @@ void showLoraKeys(void);
|
|||||||
void lora_send(void *pvParameters);
|
void lora_send(void *pvParameters);
|
||||||
void lora_enqueuedata(MessageBuffer_t *message);
|
void lora_enqueuedata(MessageBuffer_t *message);
|
||||||
void lora_queuereset(void);
|
void lora_queuereset(void);
|
||||||
|
void myEventCallback(void *pUserData, ev_t ev);
|
||||||
void myRxCallback(void *pUserData, uint8_t port, const uint8_t *pMsg,
|
void myRxCallback(void *pUserData, uint8_t port, const uint8_t *pMsg,
|
||||||
size_t nMsg);
|
size_t nMsg);
|
||||||
void myTxCallback(void *pUserData, int fSuccess);
|
void myTxCallback(void *pUserData, int fSuccess);
|
||||||
|
@ -15,7 +15,7 @@ esp_err_t err;
|
|||||||
|
|
||||||
// populate cfg vars with factory settings
|
// populate cfg vars with factory settings
|
||||||
void defaultConfig() {
|
void defaultConfig() {
|
||||||
cfg.loradr = LORADRDEFAULT; // 0-15, lora datarate, see pacounter.conf
|
cfg.loradr = LORADRDEFAULT; // 0-15, lora datarate, see paxcounter.conf
|
||||||
cfg.txpower = LORATXPOWDEFAULT; // 0-15, lora tx power
|
cfg.txpower = LORATXPOWDEFAULT; // 0-15, lora tx power
|
||||||
cfg.adrmode = 1; // 0=disabled, 1=enabled
|
cfg.adrmode = 1; // 0=disabled, 1=enabled
|
||||||
cfg.screensaver = 0; // 0=disabled, 1=enabled
|
cfg.screensaver = 0; // 0=disabled, 1=enabled
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
// use interrupts only if LORA_IRQ and LORA_DIO are connected to interrupt
|
// use interrupts only if LORA_IRQ and LORA_DIO are connected to interrupt
|
||||||
// capable GPIO pins on your board, if not disable interrupts
|
// capable GPIO pins on your board, if not disable interrupts
|
||||||
//#define LMIC_USE_INTERRUPTS 1
|
#define LMIC_USE_INTERRUPTS 1
|
||||||
|
|
||||||
// time sync via LoRaWAN network, note: not supported by TTNv2
|
// time sync via LoRaWAN network, note: not supported by TTNv2
|
||||||
// #define LMIC_ENABLE_DeviceTimeReq 1
|
// #define LMIC_ENABLE_DeviceTimeReq 1
|
||||||
@ -28,14 +28,14 @@
|
|||||||
// so consuming more power. You may sharpen (reduce) this value if you are
|
// so consuming more power. You may sharpen (reduce) this value if you are
|
||||||
// limited on battery.
|
// limited on battery.
|
||||||
// ATTN: VALUES > 7 WILL CAUSE RECEPTION AND JOIN PROBLEMS WITH HIGH SF RATES
|
// ATTN: VALUES > 7 WILL CAUSE RECEPTION AND JOIN PROBLEMS WITH HIGH SF RATES
|
||||||
#define CLOCK_ERROR_PROCENTAGE 7
|
//#define CLOCK_ERROR_PROCENTAGE 5
|
||||||
|
|
||||||
// Set this to 1 to enable some basic debug output (using printf) about
|
// Set this to 1 to enable some basic debug output (using printf) about
|
||||||
// RF settings used during transmission and reception. Set to 2 to
|
// RF settings used during transmission and reception. Set to 2 to
|
||||||
// enable more verbose output. Make sure that printf is actually
|
// enable more verbose output. Make sure that printf is actually
|
||||||
// configured (e.g. on AVR it is not by default), otherwise using it can
|
// configured (e.g. on AVR it is not by default), otherwise using it can
|
||||||
// cause crashing.
|
// cause crashing.
|
||||||
#define LMIC_DEBUG_LEVEL 0
|
//#define LMIC_DEBUG_LEVEL 1
|
||||||
|
|
||||||
// Enable this to allow using printf() to print to the given serial port
|
// Enable this to allow using printf() to print to the given serial port
|
||||||
// (or any other Print object). This can be easy for debugging. The
|
// (or any other Print object). This can be easy for debugging. The
|
||||||
|
292
src/lorawan.cpp
292
src/lorawan.cpp
@ -75,6 +75,39 @@ const lmic_pinmap lmic_pins = {
|
|||||||
.spi_freq = 0,
|
.spi_freq = 0,
|
||||||
.pConfig = &myHalConfig};
|
.pConfig = &myHalConfig};
|
||||||
|
|
||||||
|
void lora_setupForNetwork(bool preJoin) {
|
||||||
|
|
||||||
|
if (preJoin) {
|
||||||
|
|
||||||
|
#if CFG_LMIC_US_like
|
||||||
|
// in the US, with TTN, it saves join time if we start on subband 1
|
||||||
|
// (channels 8-15). This will get overridden after the join by
|
||||||
|
// parameters from the network. If working with other networks or in
|
||||||
|
// other regions, this will need to be changed.
|
||||||
|
LMIC_selectSubBand(1);
|
||||||
|
#elif CFG_LMIC_EU_like
|
||||||
|
// setting for TheThingsNetwork
|
||||||
|
// TTN uses SF9, not SF12, for RX2 window
|
||||||
|
LMIC.dn2Dr = EU868_DR_SF9;
|
||||||
|
// Disable link check validation
|
||||||
|
LMIC_setLinkCheckMode(0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// set data rate adaptation according to saved setting
|
||||||
|
LMIC_setAdrMode(cfg.adrmode);
|
||||||
|
// set data rate and transmit power to stored device values if no ADR
|
||||||
|
if (!cfg.adrmode)
|
||||||
|
LMIC_setDrTxpow(assertDR(cfg.loradr), cfg.txpower);
|
||||||
|
// show current devaddr
|
||||||
|
ESP_LOGI(TAG, "DEVaddr: %08X", LMIC.devaddr);
|
||||||
|
ESP_LOGI(TAG, "Radio parameters: %s / %s / %s",
|
||||||
|
getSfName(updr2rps(LMIC.datarate)),
|
||||||
|
getBwName(updr2rps(LMIC.datarate)),
|
||||||
|
getCrName(updr2rps(LMIC.datarate)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// DevEUI generator using devices's MAC address
|
// DevEUI generator using devices's MAC address
|
||||||
void gen_lora_deveui(uint8_t *pdeveui) {
|
void gen_lora_deveui(uint8_t *pdeveui) {
|
||||||
uint8_t *p = pdeveui, dmac[6];
|
uint8_t *p = pdeveui, dmac[6];
|
||||||
@ -204,117 +237,6 @@ void showLoraKeys(void) {
|
|||||||
|
|
||||||
#endif // VERBOSE
|
#endif // VERBOSE
|
||||||
|
|
||||||
void onEvent(ev_t ev) {
|
|
||||||
char buff[24] = "";
|
|
||||||
|
|
||||||
switch (ev) {
|
|
||||||
|
|
||||||
case EV_SCAN_TIMEOUT:
|
|
||||||
strcpy_P(buff, PSTR("SCAN TIMEOUT"));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EV_BEACON_FOUND:
|
|
||||||
strcpy_P(buff, PSTR("BEACON FOUND"));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EV_BEACON_MISSED:
|
|
||||||
strcpy_P(buff, PSTR("BEACON MISSED"));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EV_BEACON_TRACKED:
|
|
||||||
strcpy_P(buff, PSTR("BEACON TRACKED"));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EV_JOINING:
|
|
||||||
strcpy_P(buff, PSTR("JOINING"));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EV_JOINED:
|
|
||||||
strcpy_P(buff, PSTR("JOINED"));
|
|
||||||
// set data rate adaptation according to saved setting
|
|
||||||
LMIC_setAdrMode(cfg.adrmode);
|
|
||||||
// set data rate and transmit power to defaults only if we have no ADR
|
|
||||||
if (!cfg.adrmode)
|
|
||||||
LMIC_setDrTxpow(assertDR(cfg.loradr), cfg.txpower);
|
|
||||||
// show current devaddr
|
|
||||||
ESP_LOGI(TAG, "DEVaddr=%08X", LMIC.devaddr);
|
|
||||||
ESP_LOGI(TAG, "Radio parameters %s / %s / %s",
|
|
||||||
getSfName(updr2rps(LMIC.datarate)),
|
|
||||||
getBwName(updr2rps(LMIC.datarate)),
|
|
||||||
getCrName(updr2rps(LMIC.datarate)));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EV_RFU1:
|
|
||||||
strcpy_P(buff, PSTR("RFU1"));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EV_JOIN_FAILED:
|
|
||||||
strcpy_P(buff, PSTR("JOIN FAILED"));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EV_REJOIN_FAILED:
|
|
||||||
strcpy_P(buff, PSTR("REJOIN FAILED"));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EV_TXCOMPLETE:
|
|
||||||
strcpy_P(buff, PSTR("TX COMPLETE"));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EV_LOST_TSYNC:
|
|
||||||
strcpy_P(buff, PSTR("LOST TSYNC"));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EV_RESET:
|
|
||||||
strcpy_P(buff, PSTR("RESET"));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EV_RXCOMPLETE:
|
|
||||||
// data received in ping slot
|
|
||||||
strcpy_P(buff, PSTR("RX COMPLETE"));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EV_LINK_DEAD:
|
|
||||||
strcpy_P(buff, PSTR("LINK DEAD"));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EV_LINK_ALIVE:
|
|
||||||
strcpy_P(buff, PSTR("LINK_ALIVE"));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EV_SCAN_FOUND:
|
|
||||||
strcpy_P(buff, PSTR("SCAN FOUND"));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EV_TXSTART:
|
|
||||||
if (!(LMIC.opmode & OP_JOINING)) {
|
|
||||||
strcpy_P(buff, PSTR("TX START"));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EV_TXCANCELED:
|
|
||||||
strcpy_P(buff, PSTR("TX CANCELLED"));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EV_RXSTART:
|
|
||||||
strcpy_P(buff, PSTR("RX START"));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EV_JOIN_TXCOMPLETE:
|
|
||||||
strcpy_P(buff, PSTR("JOIN WAIT"));
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
sprintf_P(buff, PSTR("LMIC EV %d"), ev);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Log & Display if asked
|
|
||||||
if (*buff) {
|
|
||||||
ESP_LOGI(TAG, "%s", buff);
|
|
||||||
sprintf(lmic_event_msg, buff);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// LMIC send task
|
// LMIC send task
|
||||||
void lora_send(void *pvParameters) {
|
void lora_send(void *pvParameters) {
|
||||||
configASSERT(((uint32_t)pvParameters) == 1); // FreeRTOS check
|
configASSERT(((uint32_t)pvParameters) == 1); // FreeRTOS check
|
||||||
@ -324,9 +246,9 @@ void lora_send(void *pvParameters) {
|
|||||||
while (1) {
|
while (1) {
|
||||||
|
|
||||||
// postpone until we are joined if we are not
|
// postpone until we are joined if we are not
|
||||||
while (!LMIC.devaddr) {
|
// while (!LMIC.devaddr) {
|
||||||
vTaskDelay(pdMS_TO_TICKS(500));
|
// vTaskDelay(pdMS_TO_TICKS(500));
|
||||||
}
|
//}
|
||||||
|
|
||||||
// fetch next or wait for payload to send from queue
|
// fetch next or wait for payload to send from queue
|
||||||
if (xQueueReceive(LoraSendQueue, &SendBuffer, portMAX_DELAY) != pdTRUE) {
|
if (xQueueReceive(LoraSendQueue, &SendBuffer, portMAX_DELAY) != pdTRUE) {
|
||||||
@ -337,7 +259,8 @@ void lora_send(void *pvParameters) {
|
|||||||
// attempt to transmit payload
|
// attempt to transmit payload
|
||||||
else {
|
else {
|
||||||
|
|
||||||
switch (LMIC_sendWithCallback_strict(
|
// switch (LMIC_sendWithCallback_strict(
|
||||||
|
switch (LMIC_sendWithCallback(
|
||||||
SendBuffer.MessagePort, SendBuffer.Message, SendBuffer.MessageSize,
|
SendBuffer.MessagePort, SendBuffer.Message, SendBuffer.MessageSize,
|
||||||
(cfg.countermode & 0x02), myTxCallback, NULL)) {
|
(cfg.countermode & 0x02), myTxCallback, NULL)) {
|
||||||
|
|
||||||
@ -351,7 +274,8 @@ void lora_send(void *pvParameters) {
|
|||||||
lora_enqueuedata(&SendBuffer); // re-enqueue the undelivered message
|
lora_enqueuedata(&SendBuffer); // re-enqueue the undelivered message
|
||||||
break;
|
break;
|
||||||
case LMIC_ERROR_TX_TOO_LARGE: // message size exceeds LMIC buffer size
|
case LMIC_ERROR_TX_TOO_LARGE: // message size exceeds LMIC buffer size
|
||||||
case LMIC_ERROR_TX_NOT_FEASIBLE: // message too large for current datarate
|
case LMIC_ERROR_TX_NOT_FEASIBLE: // message too large for current
|
||||||
|
// datarate
|
||||||
ESP_LOGI(TAG,
|
ESP_LOGI(TAG,
|
||||||
"Message too large to send, message not sent and deleted");
|
"Message too large to send, message not sent and deleted");
|
||||||
// we need some kind of error handling here -> to be done
|
// we need some kind of error handling here -> to be done
|
||||||
@ -385,9 +309,9 @@ esp_err_t lora_stack_init() {
|
|||||||
&lmicTask, // task handle
|
&lmicTask, // task handle
|
||||||
1); // CPU core
|
1); // CPU core
|
||||||
|
|
||||||
if (!LMIC_startJoining()) { // start joining
|
// start join
|
||||||
|
if (!LMIC_startJoining())
|
||||||
ESP_LOGI(TAG, "Already joined");
|
ESP_LOGI(TAG, "Already joined");
|
||||||
}
|
|
||||||
|
|
||||||
// start lmic send task
|
// start lmic send task
|
||||||
xTaskCreatePinnedToCore(lora_send, // task function
|
xTaskCreatePinnedToCore(lora_send, // task function
|
||||||
@ -480,41 +404,137 @@ finish:
|
|||||||
|
|
||||||
// LMIC lorawan stack task
|
// LMIC lorawan stack task
|
||||||
void lmictask(void *pvParameters) {
|
void lmictask(void *pvParameters) {
|
||||||
configASSERT(((uint32_t)pvParameters) == 1); // FreeRTOS check
|
configASSERT(((uint32_t)pvParameters) == 1);
|
||||||
|
|
||||||
|
// setup LMIC stack
|
||||||
os_init(); // initialize lmic run-time environment
|
os_init(); // initialize lmic run-time environment
|
||||||
LMIC_reset(); // initialize lmic MAC
|
|
||||||
|
|
||||||
// pre-join settings
|
// register a callback for downlink messages and lmic events.
|
||||||
LMIC_setDrTxpow(assertDR(LORADRDEFAULT), LORATXPOWDEFAULT);
|
// We aren't trying to write reentrant code, so pUserData is NULL.
|
||||||
LMIC_setLinkCheckMode(0);
|
// LMIC_reset() doesn't affect callbacks, so we can do this first.
|
||||||
|
LMIC_registerRxMessageCb(myRxCallback, NULL);
|
||||||
|
LMIC_registerEventCb(myEventCallback, NULL);
|
||||||
|
|
||||||
|
// Reset the MAC state. Session and pending data transfers will be
|
||||||
|
// discarded.
|
||||||
|
LMIC_reset();
|
||||||
|
|
||||||
// This tells LMIC to make the receive windows bigger, in case your clock is
|
// This tells LMIC to make the receive windows bigger, in case your clock is
|
||||||
// faster or slower. This causes the transceiver to be earlier switched on,
|
// faster or slower. This causes the transceiver to be earlier switched on,
|
||||||
// so consuming more power. You may sharpen (reduce) CLOCK_ERROR_PERCENTAGE
|
// so consuming more power. You may sharpen (reduce) CLOCK_ERROR_PERCENTAGE
|
||||||
// in src/lmic_config.h if you are limited on battery.
|
// in src/lmic_config.h if you are limited on battery.
|
||||||
#ifdef CLOCK_ERROR_PROCENTAGE
|
#ifdef CLOCK_ERROR_PROCENTAGE
|
||||||
LMIC_setClockError(MAX_CLOCK_ERROR * CLOCK_ERROR_PROCENTAGE / 100);
|
LMIC_setClockError(CLOCK_ERROR_PROCENTAGE * MAX_CLOCK_ERROR / 100);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CFG_LMIC_US_like
|
|
||||||
// in the US, with TTN, it saves join time if we start on subband 1
|
|
||||||
// (channels 8-15). This will get overridden after the join by parameters
|
|
||||||
// from the network. If working with other networks or in other regions,
|
|
||||||
// this will need to be changed.
|
|
||||||
LMIC_selectSubBand(1);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// register a callback for downlink messages. We aren't trying to write
|
|
||||||
// reentrant code, so pUserData is NULL.
|
|
||||||
LMIC_registerRxMessageCb(myRxCallback, NULL);
|
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
os_runloop_once(); // execute lmic scheduled jobs and events
|
os_runloop_once(); // execute lmic scheduled jobs and events
|
||||||
delay(2); // yield to CPU
|
delay(2); // yield to CPU
|
||||||
}
|
}
|
||||||
} // lmictask
|
} // lmictask
|
||||||
|
|
||||||
|
// lmic event handler
|
||||||
|
void myEventCallback(void *pUserData, ev_t ev) {
|
||||||
|
char buff[24] = "";
|
||||||
|
|
||||||
|
switch (ev) {
|
||||||
|
|
||||||
|
case EV_SCAN_TIMEOUT:
|
||||||
|
strcpy_P(buff, PSTR("SCAN TIMEOUT"));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EV_BEACON_FOUND:
|
||||||
|
strcpy_P(buff, PSTR("BEACON FOUND"));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EV_BEACON_MISSED:
|
||||||
|
strcpy_P(buff, PSTR("BEACON MISSED"));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EV_BEACON_TRACKED:
|
||||||
|
strcpy_P(buff, PSTR("BEACON TRACKED"));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EV_JOINING:
|
||||||
|
strcpy_P(buff, PSTR("JOINING"));
|
||||||
|
// do the network-specific setup prior to join.
|
||||||
|
lora_setupForNetwork(true);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EV_JOINED:
|
||||||
|
strcpy_P(buff, PSTR("JOINED"));
|
||||||
|
// do the after join network-specific setup.
|
||||||
|
lora_setupForNetwork(false);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EV_RFU1:
|
||||||
|
strcpy_P(buff, PSTR("RFU1"));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EV_JOIN_FAILED:
|
||||||
|
strcpy_P(buff, PSTR("JOIN FAILED"));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EV_REJOIN_FAILED:
|
||||||
|
strcpy_P(buff, PSTR("REJOIN FAILED"));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EV_TXCOMPLETE:
|
||||||
|
strcpy_P(buff, PSTR("TX COMPLETE"));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EV_LOST_TSYNC:
|
||||||
|
strcpy_P(buff, PSTR("LOST TSYNC"));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EV_RESET:
|
||||||
|
strcpy_P(buff, PSTR("RESET"));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EV_RXCOMPLETE:
|
||||||
|
strcpy_P(buff, PSTR("RX COMPLETE"));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EV_LINK_DEAD:
|
||||||
|
strcpy_P(buff, PSTR("LINK DEAD"));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EV_LINK_ALIVE:
|
||||||
|
strcpy_P(buff, PSTR("LINK_ALIVE"));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EV_SCAN_FOUND:
|
||||||
|
strcpy_P(buff, PSTR("SCAN FOUND"));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EV_TXSTART:
|
||||||
|
strcpy_P(buff, PSTR("TX START"));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EV_TXCANCELED:
|
||||||
|
strcpy_P(buff, PSTR("TX CANCELLED"));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EV_RXSTART:
|
||||||
|
strcpy_P(buff, PSTR("RX START"));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EV_JOIN_TXCOMPLETE:
|
||||||
|
strcpy_P(buff, PSTR("JOIN WAIT"));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
sprintf_P(buff, PSTR("LMIC EV %d"), ev);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Log & Display if asked
|
||||||
|
if (*buff) {
|
||||||
|
ESP_LOGD(TAG, "%s", buff);
|
||||||
|
sprintf(lmic_event_msg, buff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// receive message handler
|
// receive message handler
|
||||||
void myRxCallback(void *pUserData, uint8_t port, const uint8_t *pMsg,
|
void myRxCallback(void *pUserData, uint8_t port, const uint8_t *pMsg,
|
||||||
size_t nMsg) {
|
size_t nMsg) {
|
||||||
|
Loading…
Reference in New Issue
Block a user