Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Revision 61:9a84b5964019, committed 2020-05-04
- Comitter:
- dudmuck
- Date:
- Mon May 04 03:05:28 2020 +0000
- Parent:
- 60:b951e344a9fc
- Commit message:
- add cayenne option
Changed in this revision
--- a/main.cpp Wed Apr 08 22:33:12 2020 +0000 +++ b/main.cpp Mon May 04 03:05:28 2020 +0000 @@ -14,6 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#ifndef MBED_CONF_APP_CAYENNE + #include <stdio.h> #include "lorawan/LoRaWANInterface.h" @@ -268,3 +270,4 @@ } // EOF +#endif /* MBED_CONF_APP_CAYENNE */ \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main_cayenne.cpp Mon May 04 03:05:28 2020 +0000 @@ -0,0 +1,362 @@ +/** + * Copyright (c) 2017, Arm Limited and affiliates. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifdef MBED_CONF_APP_CAYENNE + +#include <stdio.h> + +#include "lorawan/LoRaWANInterface.h" +#include "lorawan/system/lorawan_data_structures.h" +#include "events/EventQueue.h" + +// Application helpers +#include "trace_helper.h" +#include "lora_radio_helper.h" +#include "mbed.h" + +using namespace events; + +// Max payload size can be LORAMAC_PHY_MAXPAYLOAD. +// This example only communicates with much shorter messages (<30 bytes). +// If longer messages are used, these buffers must be changed accordingly. +uint8_t tx_buffer[30]; +uint8_t rx_buffer[30]; + +/* + * Sets up an application dependent transmission timer in ms. Used only when Duty Cycling is off for testing + */ +#define TX_TIMER 10000 + +/** + * 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 + +/* https://developers.mydevices.com/cayenne/docs/lora/#lora-cayenne-low-power-payload-reference-implementation-cayenne-lpp-cc-constants-definitions + */ + +#define LPP_DIGITAL_INPUT 0 // 1 byte +#define LPP_DIGITAL_OUTPUT 1 // 1 byte +#define LPP_ANALOG_INPUT 2 // 2 bytes, 0.01 signed +#define LPP_ANALOG_OUTPUT 3 // 2 bytes, 0.01 signed +#define LPP_LUMINOSITY 101 // 2 bytes, 1 lux unsigned +#define LPP_PRESENCE 102 // 1 byte, 1 +#define LPP_TEMPERATURE 103 // 2 bytes, 0.1°C signed +#define LPP_RELATIVE_HUMIDITY 104 // 1 byte, 0.5% unsigned +#define LPP_ACCELEROMETER 113 // 2 bytes per axis, 0.001G +#define LPP_BAROMETRIC_PRESSURE 115 // 2 bytes 0.1 hPa Unsigned +#define LPP_GYROMETER 134 // 2 bytes per axis, 0.01 °/s +#define LPP_GPS 136 // 3 byte lon/lat 0.0001 °, 3 bytes alt 0.01m + + +// Data ID + Data Type + Data Size +#define LPP_DIGITAL_INPUT_SIZE 3 +#define LPP_DIGITAL_OUTPUT_SIZE 3 +#define LPP_ANALOG_INPUT_SIZE 4 +#define LPP_ANALOG_OUTPUT_SIZE 4 +#define LPP_LUMINOSITY_SIZE 4 +#define LPP_PRESENCE_SIZE 3 +#define LPP_TEMPERATURE_SIZE 4 +#define LPP_RELATIVE_HUMIDITY_SIZE 3 +#define LPP_ACCELEROMETER_SIZE 8 +#define LPP_BAROMETRIC_PRESSURE_SIZE 4 +#define LPP_GYROMETER_SIZE 8 + +#define CAYENNE_CH_DOUT 2 +#define CAYENNE_CH_AOUT 3 +#define CAYENNE_CH_TEMP 0 +#ifdef MBED_CONF_APP_ANALOG_IN_PIN + AnalogIn a_in(MBED_CONF_APP_ANALOG_IN_PIN); + #define CAYENNE_CH_ANALOG_IN 1 +#endif + +#ifdef MBED_CONF_APP_DIGITAL_OUT_PIN + DigitalOut dig_out(MBED_CONF_APP_DIGITAL_OUT_PIN); +#endif /* MBED_CONF_APP_DIGITAL_OUT_PIN */ +#ifdef MBED_CONF_APP_ANALOG_OUT_PIN + PwmOut pwm(MBED_CONF_APP_ANALOG_OUT_PIN); +#endif /* MBED_CONF_APP_ANALOG_OUT_PIN */ + +volatile int cayenne_ack_ch; + + +/** +* 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); + +/** + * 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); + +/** + * 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; + +/** + * Entry point for application + */ +int main(void) +{ + // setup tracing + setup_trace(); + + // stores the status of a call to LoRaWAN protocol + lorawan_status_t retcode; + + // 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"); + + 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(); + + return 0; +} + +/** + * Sends a message to the Network Server + */ +static void send_message() +{ + uint16_t packet_len = 0; + int16_t retcode; + int32_t sensor_value; + + if (cayenne_ack_ch != -1) { + switch (cayenne_ack_ch) { + tx_buffer[packet_len++] = cayenne_ack_ch; +#ifdef MBED_CONF_APP_DIGITAL_OUT_PIN + case CAYENNE_CH_DOUT: + tx_buffer[packet_len++] = LPP_DIGITAL_OUTPUT; + tx_buffer[packet_len++] = dig_out.read(); + printf("digitalOut-ack%u\r\n", dig_out.read()); + break; +#endif /* MBED_CONF_APP_DIGITAL_OUT_PIN */ +#ifdef MBED_CONF_APP_ANALOG_OUT_PIN + case CAYENNE_CH_AOUT: + tx_buffer[packet_len++] = LPP_ANALOG_OUTPUT; + { + uint16_t u16 = pwm.read() * 100; + tx_buffer[packet_len++] = u16 >> 8; + tx_buffer[packet_len++] = u16; + printf("pwmAck:%x\r\n", u16); + } + break; +#endif /* MBED_CONF_APP_ANALOG_OUT_PIN */ + } + cayenne_ack_ch = -1; + } + +#ifdef MBED_CONF_APP_ANALOG_IN_PIN + { + uint16_t rot, u16 = a_in.read_u16(); + float f = u16 / 198.6; // scale 65535/3.3 to 0.01v per bit + tx_buffer[packet_len++] = CAYENNE_CH_ANALOG_IN; + tx_buffer[packet_len++] = LPP_ANALOG_INPUT; + rot = (uint16_t) f; + tx_buffer[packet_len++] = rot >> 8; + tx_buffer[packet_len++] = rot; + printf("analog_in:%u -> %04x\r\n", u16, rot); + } +#endif /* MBED_CONF_APP_ANALOG_IN_PIN */ + + 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]); + } + printf("\r\n"); + + { + unsigned n; + for (n = 0; n < retcode; n += 4) { + uint16_t val = rx_buffer[n+1] << 8; + val += rx_buffer[n+2]; + cayenne_ack_ch = rx_buffer[n]; + switch (rx_buffer[n]) { + case CAYENNE_CH_DOUT: + #ifdef MBED_CONF_APP_DIGITAL_OUT_PIN + dig_out.write(val); + printf("digitalOut write%u\r\n", val); + #endif /* MBED_CONF_APP_DIGITAL_OUT_PIN */ + break; + case CAYENNE_CH_AOUT: + #ifdef MBED_CONF_APP_ANALOG_OUT_PIN + pwm.write(val / 100.0); + printf("PWM-write_%x\r\n", val); + #endif /* MBED_CONF_APP_ANALOG_OUT_PIN */ + break; + default: + break; + } + } + } + + memset(rx_buffer, 0, sizeof(rx_buffer)); +} + +/** + * Event handler + */ +static void lora_event_handler(lorawan_event_t event) +{ + switch (event) { + case CONNECTED: + cayenne_ack_ch = -1; + printf("\r\n Connection - Successful \r\n"); + if (MBED_CONF_LORA_DUTY_CYCLE_ON) { + send_message(); + } else { + ev_queue.call_every(TX_TIMER, 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: + 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 +#endif /* MBED_CONF_APP_CAYENNE */ \ No newline at end of file
--- a/mbed-os.lib Wed Apr 08 22:33:12 2020 +0000 +++ b/mbed-os.lib Mon May 04 03:05:28 2020 +0000 @@ -1,1 +1,1 @@ -https://github.com/ARMmbed/mbed-os/#b6e5a0a8afa34dec9dae8963778aebce0c82a54b +https://github.com/ARMmbed/mbed-os/#b6370b4c37f3d4665ed1cdcb1afea85396bba1b3
--- a/mbed_app.json Wed Apr 08 22:33:12 2020 +0000 +++ b/mbed_app.json Mon May 04 03:05:28 2020 +0000 @@ -1,5 +1,6 @@ { "config": { + "lora-radio": { "help": "Which radio to use (options: SX1272,SX1276)", "value": "SX1276" @@ -23,7 +24,23 @@ "lora-rxctl": { "value": "NC" }, "lora-ant-switch": { "value": "NC" }, "lora-pwr-amp-ctl": { "value": "NC" }, - "lora-tcxo": { "value": "NC" } + "lora-tcxo": { "value": "NC" }, + "_cayenne": { + "help": "compile main_cayenne.cpp instead of main.cpp", + "value": 1 + }, + "_analog_in_pin": { + "help": "PA_0, PA_4, PA_5", + "value": "" + }, + "_analog_out_pin": { + "help": "PA_0, PB_5, PB_10, PB_11", + "value": "" + }, + "_digital_out_pin": { + "help": "", + "value": "" + } }, "target_overrides": { "*": { @@ -241,4 +258,5 @@ } }, "macros": ["MBEDTLS_USER_CONFIG_FILE=\"mbedtls_lora_config.h\""] + } \ No newline at end of file