This is an example application based on Mbed-OS LoRaWAN protocol APIs. The Mbed-OS LoRaWAN stack implementation is compliant with LoRaWAN v1.0.2 specification.
Dependencies: Lorawan_Version_0_1
Dependents: Lorawan_Version_0_1
Diff: main.cpp
- Revision:
- 66:a11c79073f1f
- Parent:
- 65:3061ea235a0c
- Child:
- 67:7bb75ed97500
--- a/main.cpp Sat Jan 11 11:35:11 2020 +0000 +++ b/main.cpp Tue Jan 14 13:48:39 2020 +0000 @@ -14,91 +14,392 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -#include "mbed.h" -#include "Lora.h" -#include "Fahrrad.h" +#include <stdio.h> + +#include "Watchdog.h" +#include "lorawan/LoRaWANInterface.h" +#include "lorawan/system/lorawan_data_structures.h" +#include "events/EventQueue.h" + +// Application helpers +#include "DummySensor.h" #include "trace_helper.h" -#include <stdio.h> +#include "lora_radio_helper.h" + +#include <mbed.h> #include "mbed_stats.h" +#include "Watchdog.h" + +using namespace events; + +// Max payload size can be LORAMAC_PHY_MAXPAYLOAD. +uint8_t tx_buffer[13]; +uint8_t rx_buffer[13]; + float Home_Longitude; float Home_Latitude; + float Home_Distance; float Home_Distance_max; bool GPS_activ,LORA_activ,AtHome; + + + +DigitalOut GPSenable(PC_6); int LiveTick; + bool IsLoading; AnalogIn LadeSpannung(PB_0); // 1/11 der gleichgerichteten Spannung am Dynamo -struct TX_Position -{ -uint8_t TX_Precode; -uint8_t TX_Zeitstempel[sizeof(float)]; -uint8_t TX_Longitude[sizeof(float)]; -uint8_t TX_Latitude[sizeof(float)]; -}; +/* + * Sets up an application dependent transmission timer in ms. Used only when Duty Cycling is off for testing + */ +#define TX_TIMER 100000 + +/** + * Maximum number of events for the event queue. + * 10 is the safe number for the stack events, however, if application + * also uses the queue for whatever purposes, this number should be increased. + */ +#define MAX_NUMBER_OF_EVENTS 10 + +/** + * Maximum number of retries for CONFIRMED messages before giving up + */ +#define CONFIRMED_MSG_RETRY_COUNTER 3 -DigitalOut led(LED2); + DigitalOut led(LED2); + +#include "Fahrrad.h" + +/** +* This event queue is the global event queue for both the +* application and stack. To conserve memory, the stack is designed to run +* in the same thread as the application and the application is responsible for +* providing an event queue to the stack that will be used for ISR deferment as +* well as application information event queuing. +*/ +static EventQueue ev_queue(MAX_NUMBER_OF_EVENTS *EVENTS_EVENT_SIZE); + +static void send_message(); -//Livetick Warteschlange Events -static EventQueue ev_queue(10 *EVENTS_EVENT_SIZE); +/** + * Event handler. + * + * This will be passed to the LoRaWAN stack to queue events for the + * application which in turn drive the application. + */ +static void lora_event_handler(lorawan_event_t event); + + +static void send_Position_to_Lora(uint8_t OptCode,GPS_Position current_pos); + + +/** + * Constructing Mbed LoRaWANInterface and passing it the radio object from lora_radio_helper. + */ +static LoRaWANInterface lorawan(radio); + +/** + * Application specific callbacks + */ +static lorawan_app_callbacks_t callbacks; + static void LifeTicker() { - + Watchdog &watchdog = Watchdog::get_instance(); + Watchdog::get_instance().kick(); // kick the Watchdog before the timeout + LiveTick=LiveTick+1; - printf("\n\t\t---LiveTick--- [%i]\n\n", LiveTick); - printf("Ladewert: %3.3f%%\n", LadeSpannung.read()*100.0f); - -//if(LadeSpannung.read() > 0.05f) { -// if (not IsLoading) {Licht_hell();} -// IsLoading = 1; -// } else { -// if (IsLoading) {ev_queue.call_in(3000, Licht_dunkel);} -// IsLoading = 0; -// } + printf("\n[LiveTick] --- [%i]\n\n", LiveTick); + + mbed_stats_cpu_t stats; + mbed_stats_cpu_get(&stats); + printf("[SYSTEM] Uptime: %llu ", stats.uptime / 1000); + printf("Idle: %llu ", stats.idle_time / 1000); + printf("Sleep: %llu ", stats.sleep_time / 1000); + printf("Deep: %llu\n", stats.deep_sleep_time / 1000); + + + printf("[SYSTEM] Ladewert: %3.3f%%\n", LadeSpannung.read()*100.0f); + if(LadeSpannung.read() > 0.05f) { + if (not IsLoading) {Licht_hell();} + IsLoading = 1; + } else { + if (IsLoading) {ev_queue.call_in(3000, Licht_dunkel);} + IsLoading = 0; + } + + + GPS_Position current_pos; + + if(LiveTick>10 && LiveTick<<15){ + GPSenable=1;} + else + { + current_pos = GPS_aktiv(); + if(LORA_activ) { - printf("\n\tLORA Connected\n"); + printf("\n[LORA] Connected\n"); + send_Position_to_Lora(0x11, current_pos); } else { - printf("\n\tKein LORA Signal\n"); + printf("\n[LORA] not Connected\n"); } + } - ev_queue.call(GPS_aktiv); + + + + + + + + + // ev_queue.call_in(5000, LifeTicker); - - - mbed_stats_cpu_t stats; - mbed_stats_cpu_get(&stats); - printf("Uptime: %llu ", stats.uptime / 1000); - printf("Sleep time: %llu ", stats.sleep_time / 1000); - printf("Deep Sleep: %llu\n", stats.deep_sleep_time / 1000); - } + + + +/** + * Entry point for application + */ int main(void) { - printf("----- MAIN() ------"); - + Watchdog &watchdog = Watchdog::get_instance(); + + watchdog.start(30000); + uint32_t watchdog_timeout = watchdog.get_timeout(); + printf("Watchdog initialized to %lu ms.\r\n", watchdog_timeout); + + + ev_queue.call_every(15000,LifeTicker); + // setup tracing setup_trace(); - Lora_init(); + //Starte_Fahrrad_Eventmanager(); //schonmal die Fahrrad Events Initialisieren falls wir hier auch ohne lorawan empfang was machen wollen + + + // Initialize LoRaWAN stack + if (lorawan.initialize(&ev_queue) != LORAWAN_STATUS_OK) { + printf("\r\n LoRa initialization failed! \r\n"); + return -1; + } + + printf("\r\n Mbed LoRaWANStack initialized \r\n"); + + // prepare application callbacks + callbacks.events = mbed::callback(lora_event_handler); + lorawan.add_app_callbacks(&callbacks); + + // Set number of retries in case of CONFIRMED messages + if (lorawan.set_confirmed_msg_retries(CONFIRMED_MSG_RETRY_COUNTER) + != LORAWAN_STATUS_OK) { + printf("\r\n set_confirmed_msg_retries failed! \r\n\r\n"); + return -1; + } + + printf("\r\n CONFIRMED message retries : %d \r\n", + CONFIRMED_MSG_RETRY_COUNTER); + + // Enable adaptive data rate + if (lorawan.enable_adaptive_datarate() != LORAWAN_STATUS_OK) { + printf("\r\n enable_adaptive_datarate failed! \r\n"); + return -1; + } + + printf("\r\n Adaptive data rate (ADR) - Enabled \r\n"); + + // stores the status of a call to LoRaWAN protocol + lorawan_status_t retcode; + retcode = lorawan.connect(); + if (retcode == LORAWAN_STATUS_OK || + retcode == LORAWAN_STATUS_CONNECT_IN_PROGRESS) { + } else { + printf("\r\n Connection error, code = %d \r\n", retcode); + return -1; + } + + printf("\r\n Connection - In Progress ...\r\n"); + + // make your event queue dispatching events forever + ev_queue.dispatch_forever(); - ev_queue.call_every(5000,LifeTicker); + return 0; +} + + +static void send_Position_to_Lora(uint8_t OptCode,GPS_Position current_pos) +{ + + //1Byte Opcode 0x01 + //4Byte Timestemp + //4Byte Longitude + //4Byte Latitude + + uint8_t tmpbytes[sizeof(float)]; + + tx_buffer[0] = OptCode; + + *((float *)tmpbytes) = current_pos.Zeitstempel; + tx_buffer[1] = tmpbytes[0]; + tx_buffer[2] = tmpbytes[1]; + tx_buffer[3] = tmpbytes[2]; + tx_buffer[4] = tmpbytes[3]; + + *((float *)tmpbytes) = current_pos.Longitude; + tx_buffer[5] = tmpbytes[0]; + tx_buffer[6] = tmpbytes[1]; + tx_buffer[7] = tmpbytes[2]; + tx_buffer[8] = tmpbytes[3]; + + *((float *)tmpbytes) = current_pos.Latitude; + tx_buffer[9] = tmpbytes[0]; + tx_buffer[10] = tmpbytes[1]; + tx_buffer[11] = tmpbytes[2]; + tx_buffer[12] = tmpbytes[3]; + + printf("\tSend Message:%02X:%02X%02X%02X%02X:%02X%02X%02X%02X:%02X%02X%02X%02X \n", + tx_buffer[0], + tx_buffer[1],tx_buffer[2],tx_buffer[3],tx_buffer[4], + tx_buffer[5],tx_buffer[6],tx_buffer[7],tx_buffer[8], + tx_buffer[9],tx_buffer[10],tx_buffer[11],tx_buffer[12]); + send_message(); +} + +/** + * Sends a message to the Network Server + */ +static void send_message() +{ - //Starte_Fahrrad_Eventmanager(); //schonmal die Fahrrad Events Initialisieren falls wir hier auch ohne lorawan empfang was machen wollen + uint16_t packet_len; + int16_t retcode; + packet_len = sizeof(tx_buffer); + + retcode = lorawan.send(MBED_CONF_LORA_APP_PORT, tx_buffer, packet_len, + MSG_UNCONFIRMED_FLAG); + + if (retcode < 0) { + retcode == LORAWAN_STATUS_WOULD_BLOCK ? printf("send - WOULD BLOCK\r\n") + : printf("\r\n send() - Error code %d \r\n", retcode); + + if (retcode == LORAWAN_STATUS_WOULD_BLOCK) { + //retry in 3 seconds + if (MBED_CONF_LORA_DUTY_CYCLE_ON) { + ev_queue.call_in(3000, send_message); + } + } + return; + } + + printf("\r\n %d bytes scheduled for transmission \r\n", retcode); + memset(tx_buffer, 0, sizeof(tx_buffer)); +} + +/** + * Receive a message from the Network Server + */ +static void receive_message() +{ + uint8_t port; + int flags; + int16_t retcode = lorawan.receive(rx_buffer, sizeof(rx_buffer), port, flags); + + if (retcode < 0) { + printf("\r\n receive() - Error code %d \r\n", retcode); + return; + } + + printf(" RX Data on port %u (%d bytes): ", port, retcode); + for (uint8_t i = 0; i < retcode; i++) { + printf("%02x ", rx_buffer[i]); + } + + if (rx_buffer[0] == 0xa0) Licht_aus(); + if (rx_buffer[0] == 0xa1)Licht_an(); + if (rx_buffer[0] == 0xb1) Blinken_ein(); + if (rx_buffer[0] == 0xb0) Blinken_aus() ; + + + + if (rx_buffer[0] == 0xc1)GPS_anfordern(); + + printf("\r\n"); + + memset(rx_buffer, 0, sizeof(rx_buffer)); +} - return 0; +/** + * Event handler + */ +static void lora_event_handler(lorawan_event_t event) +{ + switch (event) { + case CONNECTED: + LORA_activ=1; + printf("\r\n Connection - Successful \r\n"); + + //ev_queue.call_every(5000, send_message); + + + break; + case DISCONNECTED: + ev_queue.break_dispatch(); + printf("\r\n Disconnected Successfully \r\n"); + break; + case TX_DONE: + printf("\r\n Message Sent to Network Server \r\n"); + if (MBED_CONF_LORA_DUTY_CYCLE_ON) { + //send_message(); + } + break; + case TX_TIMEOUT: + + LORA_activ=0; + case TX_ERROR: + case TX_CRYPTO_ERROR: + case TX_SCHEDULING_ERROR: + printf("\r\n Transmission Error - EventCode = %d \r\n", event); + // try again + if (MBED_CONF_LORA_DUTY_CYCLE_ON) { + send_message(); + } + break; + case RX_DONE: + printf("\r\n Received message from Network Server \r\n"); + receive_message(); + break; + case RX_TIMEOUT: + case RX_ERROR: + printf("\r\n Error in reception - Code = %d \r\n", event); + break; + case JOIN_FAILURE: + printf("\r\n OTAA Failed - Check Keys \r\n"); + break; + case UPLINK_REQUIRED: + printf("\r\n Uplink required by NS \r\n"); + if (MBED_CONF_LORA_DUTY_CYCLE_ON) { + send_message(); + } + break; + default: + MBED_ASSERT("Unknown Event"); + } } +// EOF