This repo contains a code example of sending LoRa message that will be relayed by the Things Network to the ThingSpeak Channel of the project
main.cpp@0:490b5d248e91, 2020-11-22 (annotated)
- Committer:
- nsejim
- Date:
- Sun Nov 22 12:16:19 2020 +0000
- Revision:
- 0:490b5d248e91
Code example of sending LoRa message to Things Network gateway and be relayed to the associated ThingSpeak channel
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
nsejim | 0:490b5d248e91 | 1 | #include "mbed.h" // Include the library of Mbed |
nsejim | 0:490b5d248e91 | 2 | #include "LoRaWANInterface.h" |
nsejim | 0:490b5d248e91 | 3 | #include "SX1276_LoRaRadio.h" |
nsejim | 0:490b5d248e91 | 4 | |
nsejim | 0:490b5d248e91 | 5 | |
nsejim | 0:490b5d248e91 | 6 | /* |
nsejim | 0:490b5d248e91 | 7 | Send LoRa message to a the group project Thingspeak channel |
nsejim | 0:490b5d248e91 | 8 | https://thingspeak.com/channels/1234574/feed.json |
nsejim | 0:490b5d248e91 | 9 | */ |
nsejim | 0:490b5d248e91 | 10 | |
nsejim | 0:490b5d248e91 | 11 | // The port we're sending and receiving on |
nsejim | 0:490b5d248e91 | 12 | #define MBED_CONF_LORA_APP_PORT 1 |
nsejim | 0:490b5d248e91 | 13 | |
nsejim | 0:490b5d248e91 | 14 | InterruptIn send_data_button(p6); |
nsejim | 0:490b5d248e91 | 15 | |
nsejim | 0:490b5d248e91 | 16 | // Device credentials, register device as OTAA in The Things Network and copy credentials here |
nsejim | 0:490b5d248e91 | 17 | static uint8_t DEV_EUI[] = { 0x18, 0x11, 0x20, 0x20, 0x18, 0x11, 0x20, 0x20 }; |
nsejim | 0:490b5d248e91 | 18 | static uint8_t APP_EUI[] = { 0x70, 0xB3, 0xD5, 0x7E, 0xD0, 0x03, 0x84, 0x15 }; |
nsejim | 0:490b5d248e91 | 19 | static uint8_t APP_KEY[] = { 0x76, 0x8B, 0xD9, 0x68, 0xA9, 0x4C, 0xC0, 0xF6, 0x52, 0x20, 0x48, 0x7C, 0x00, 0xE6, 0x0D, 0x3C }; |
nsejim | 0:490b5d248e91 | 20 | |
nsejim | 0:490b5d248e91 | 21 | |
nsejim | 0:490b5d248e91 | 22 | // Peripherals (LoRa radio, temperature sensor and button) |
nsejim | 0:490b5d248e91 | 23 | SX1276_LoRaRadio radio(D11, D12, D13, D10, A0, D2, D3, D4, D5, D8, D9, NC, NC, NC, NC, A4, NC, NC); |
nsejim | 0:490b5d248e91 | 24 | |
nsejim | 0:490b5d248e91 | 25 | // EventQueue is required to dispatch events around |
nsejim | 0:490b5d248e91 | 26 | static EventQueue ev_queue; |
nsejim | 0:490b5d248e91 | 27 | // Constructing Mbed LoRaWANInterface and passing it down the radio object. |
nsejim | 0:490b5d248e91 | 28 | static LoRaWANInterface lorawan(radio); |
nsejim | 0:490b5d248e91 | 29 | // Application specific callbacks |
nsejim | 0:490b5d248e91 | 30 | static lorawan_app_callbacks_t callbacks; |
nsejim | 0:490b5d248e91 | 31 | // LoRaWAN stack event handler |
nsejim | 0:490b5d248e91 | 32 | static void lora_event_handler(lorawan_event_t event); |
nsejim | 0:490b5d248e91 | 33 | |
nsejim | 0:490b5d248e91 | 34 | // Send a message over LoRaWAN |
nsejim | 0:490b5d248e91 | 35 | static void send_message(char *device, long int start, long int end, int topic) { |
nsejim | 0:490b5d248e91 | 36 | uint8_t tx_buffer[50] = { 0 }; |
nsejim | 0:490b5d248e91 | 37 | // Sending strings over LoRaWAN is not recommended |
nsejim | 0:490b5d248e91 | 38 | sprintf((char*) tx_buffer, "{\"device\":\"%s\",\"start\":%ld,\"end\":%ld,\"topic\":%d}", device, start, end, topic); |
nsejim | 0:490b5d248e91 | 39 | int packet_len = strlen((char*) tx_buffer); |
nsejim | 0:490b5d248e91 | 40 | printf("Sending %d bytes: \"%s\"\n", packet_len, tx_buffer); |
nsejim | 0:490b5d248e91 | 41 | int16_t retcode = lorawan.send(MBED_CONF_LORA_APP_PORT, tx_buffer, packet_len, MSG_UNCONFIRMED_FLAG); |
nsejim | 0:490b5d248e91 | 42 | // for some reason send() returns -1... I cannot find out why, the stack returns the right number. I feel that this is some weird Emscripten quirk |
nsejim | 0:490b5d248e91 | 43 | if (retcode < 0) { |
nsejim | 0:490b5d248e91 | 44 | retcode == LORAWAN_STATUS_WOULD_BLOCK ? printf("send - duty cycle violation\n") |
nsejim | 0:490b5d248e91 | 45 | : printf("send() - Error code %d\n", retcode); |
nsejim | 0:490b5d248e91 | 46 | return; |
nsejim | 0:490b5d248e91 | 47 | } |
nsejim | 0:490b5d248e91 | 48 | printf("%d bytes scheduled for transmission\n", retcode); |
nsejim | 0:490b5d248e91 | 49 | } |
nsejim | 0:490b5d248e91 | 50 | |
nsejim | 0:490b5d248e91 | 51 | int initialize_lora() { |
nsejim | 0:490b5d248e91 | 52 | if (DEV_EUI[0] == 0x0 && DEV_EUI[1] == 0x0 && DEV_EUI[2] == 0x0 && DEV_EUI[3] == 0x0 && DEV_EUI[4] == 0x0 && DEV_EUI[5] == 0x0 && DEV_EUI[6] == 0x0 && DEV_EUI[7] == 0x0) { |
nsejim | 0:490b5d248e91 | 53 | printf("Set your LoRaWAN credentials first!\n"); |
nsejim | 0:490b5d248e91 | 54 | return -1; |
nsejim | 0:490b5d248e91 | 55 | } |
nsejim | 0:490b5d248e91 | 56 | if (lorawan.initialize(&ev_queue) != LORAWAN_STATUS_OK) { |
nsejim | 0:490b5d248e91 | 57 | printf("LoRa initialization failed!\n"); |
nsejim | 0:490b5d248e91 | 58 | return -1; |
nsejim | 0:490b5d248e91 | 59 | } |
nsejim | 0:490b5d248e91 | 60 | // prepare application callbacks |
nsejim | 0:490b5d248e91 | 61 | callbacks.events = mbed::callback(lora_event_handler); |
nsejim | 0:490b5d248e91 | 62 | lorawan.add_app_callbacks(&callbacks); |
nsejim | 0:490b5d248e91 | 63 | // Disable adaptive data rating |
nsejim | 0:490b5d248e91 | 64 | if (lorawan.disable_adaptive_datarate() != LORAWAN_STATUS_OK) { |
nsejim | 0:490b5d248e91 | 65 | printf("disable_adaptive_datarate failed!\n"); |
nsejim | 0:490b5d248e91 | 66 | return -1; |
nsejim | 0:490b5d248e91 | 67 | } |
nsejim | 0:490b5d248e91 | 68 | lorawan.set_datarate(5); // SF7BW125 |
nsejim | 0:490b5d248e91 | 69 | lorawan_connect_t connect_params; |
nsejim | 0:490b5d248e91 | 70 | connect_params.connect_type = LORAWAN_CONNECTION_OTAA; |
nsejim | 0:490b5d248e91 | 71 | connect_params.connection_u.otaa.dev_eui = DEV_EUI; |
nsejim | 0:490b5d248e91 | 72 | connect_params.connection_u.otaa.app_eui = APP_EUI; |
nsejim | 0:490b5d248e91 | 73 | connect_params.connection_u.otaa.app_key = APP_KEY; |
nsejim | 0:490b5d248e91 | 74 | connect_params.connection_u.otaa.nb_trials = 3; |
nsejim | 0:490b5d248e91 | 75 | |
nsejim | 0:490b5d248e91 | 76 | lorawan_status_t retcode = lorawan.connect(connect_params); |
nsejim | 0:490b5d248e91 | 77 | |
nsejim | 0:490b5d248e91 | 78 | if (retcode == LORAWAN_STATUS_OK || |
nsejim | 0:490b5d248e91 | 79 | retcode == LORAWAN_STATUS_CONNECT_IN_PROGRESS) { |
nsejim | 0:490b5d248e91 | 80 | } else { |
nsejim | 0:490b5d248e91 | 81 | printf("Connection error, code = %d\n", retcode); |
nsejim | 0:490b5d248e91 | 82 | return -1; |
nsejim | 0:490b5d248e91 | 83 | } |
nsejim | 0:490b5d248e91 | 84 | |
nsejim | 0:490b5d248e91 | 85 | printf("LoRa Connection - In Progress ...\r\n"); |
nsejim | 0:490b5d248e91 | 86 | // make your event queue dispatching events forever |
nsejim | 0:490b5d248e91 | 87 | ev_queue.dispatch_forever(); |
nsejim | 0:490b5d248e91 | 88 | return 0; |
nsejim | 0:490b5d248e91 | 89 | } |
nsejim | 0:490b5d248e91 | 90 | |
nsejim | 0:490b5d248e91 | 91 | void send_data_button_isr() { |
nsejim | 0:490b5d248e91 | 92 | |
nsejim | 0:490b5d248e91 | 93 | char device[] = "MyDevice"; |
nsejim | 0:490b5d248e91 | 94 | int topic = 3; // topic identifier |
nsejim | 0:490b5d248e91 | 95 | long int start = 1606037871; // start reading |
nsejim | 0:490b5d248e91 | 96 | long int end = 1606038051; // end reading |
nsejim | 0:490b5d248e91 | 97 | |
nsejim | 0:490b5d248e91 | 98 | send_message(device, start, end, topic); |
nsejim | 0:490b5d248e91 | 99 | } |
nsejim | 0:490b5d248e91 | 100 | |
nsejim | 0:490b5d248e91 | 101 | int main() { |
nsejim | 0:490b5d248e91 | 102 | send_data_button.rise(ev_queue.event(&send_data_button_isr)); // Registering an ISR for button click |
nsejim | 0:490b5d248e91 | 103 | initialize_lora(); |
nsejim | 0:490b5d248e91 | 104 | } |
nsejim | 0:490b5d248e91 | 105 | |
nsejim | 0:490b5d248e91 | 106 | // Event handler |
nsejim | 0:490b5d248e91 | 107 | static void lora_event_handler(lorawan_event_t event) { |
nsejim | 0:490b5d248e91 | 108 | switch (event) { |
nsejim | 0:490b5d248e91 | 109 | case CONNECTED: |
nsejim | 0:490b5d248e91 | 110 | printf("LoRA Connection - Successful\n"); |
nsejim | 0:490b5d248e91 | 111 | break; |
nsejim | 0:490b5d248e91 | 112 | case DISCONNECTED: |
nsejim | 0:490b5d248e91 | 113 | ev_queue.break_dispatch(); |
nsejim | 0:490b5d248e91 | 114 | printf("LoRa Disconnected Successfully\n"); |
nsejim | 0:490b5d248e91 | 115 | break; |
nsejim | 0:490b5d248e91 | 116 | case TX_DONE: |
nsejim | 0:490b5d248e91 | 117 | printf("Message Sent to Network Server\n"); |
nsejim | 0:490b5d248e91 | 118 | break; |
nsejim | 0:490b5d248e91 | 119 | case TX_TIMEOUT: |
nsejim | 0:490b5d248e91 | 120 | case TX_ERROR: |
nsejim | 0:490b5d248e91 | 121 | case TX_CRYPTO_ERROR: |
nsejim | 0:490b5d248e91 | 122 | case TX_SCHEDULING_ERROR: |
nsejim | 0:490b5d248e91 | 123 | printf("Transmission Error - EventCode = %d\n", event); |
nsejim | 0:490b5d248e91 | 124 | break; |
nsejim | 0:490b5d248e91 | 125 | case JOIN_FAILURE: |
nsejim | 0:490b5d248e91 | 126 | printf("OTAA Failed - Check Keys\n"); |
nsejim | 0:490b5d248e91 | 127 | break; |
nsejim | 0:490b5d248e91 | 128 | default: |
nsejim | 0:490b5d248e91 | 129 | MBED_ASSERT("Unknown Event"); |
nsejim | 0:490b5d248e91 | 130 | } |
nsejim | 0:490b5d248e91 | 131 | } |
nsejim | 0:490b5d248e91 | 132 | |
nsejim | 0:490b5d248e91 | 133 |