Generic Pelion Device Management example for various U-blox-based boards.

Dependencies:   ublox-at-cellular-interface ublox-cellular-base

DEPRECATED

This example application is not maintained and not recommended. It uses an old version of Mbed OS, Pelion DM, and Arm toolchain. It doesn't work with Mbed Studio.

Please use: https://os.mbed.com/teams/mbed-os-examples/code/mbed-os-example-pelion/

This example is known to work great on the following platforms:

For Odin-W2 please go to Repository link

Follow the Quick-Start instructions: https://cloud.mbed.com/quick-start

UBLOX_C030_U201

UBLOX_C030_R412M

Example functionality

This example showcases the following device functionality:

  • On user button click, increment Pelion LWM2M button resource.
  • Allow the user to change the state of the board LED from Pelion LWM2M led_state resource and PUT request.
  • (currently disabled) Read ADC temperature and ADC vref, and report them as Pelion LWM2M resources.

Use this example with Mbed CLI

1. Import the application into your desktop:

mbed import https://os.mbed.com/teams/ublox/code/pelion-example-common

cd pelion-example-common

2. Install the CLOUD_SDK_API_KEY

mbed config -G CLOUD_SDK_API_KEY <PELION_DM_API_KEY>

For instructions on how to generate your API key, please see the documentation.

3. Initialize firmware credentials (done once per repository). You can use the following command:

mbed dm init -d "<your company name in Pelion DM>" --model-name "<product model identifier>" -q --force

If above command do not work for your Mbed CLI, please consider upgrading Mbed CLI to version 1.8.x or above.

4. Compile and program:

mbed compile -t <toolchain> -m <TARGET_BOARD>

(supported toolchains : GCC_ARM / ARM / IAR)

Committer:
screamer
Date:
Wed Mar 27 18:57:20 2019 +0000
Revision:
7:230af466efc4
Parent:
6:2fb5057c0e42
Child:
10:4c2ed226f5a8
Imporve inline documentation
Update to Mbed OS 5.11.5 and PDMC 2.2.1

Who changed what in which revision?

UserRevisionLine numberNew contents of line
screamer 0:a076a1bbe630 1 // ----------------------------------------------------------------------------
screamer 0:a076a1bbe630 2 // Copyright 2016-2018 ARM Ltd.
screamer 0:a076a1bbe630 3 //
screamer 0:a076a1bbe630 4 // SPDX-License-Identifier: Apache-2.0
screamer 0:a076a1bbe630 5 //
screamer 0:a076a1bbe630 6 // Licensed under the Apache License, Version 2.0 (the "License");
screamer 0:a076a1bbe630 7 // you may not use this file except in compliance with the License.
screamer 0:a076a1bbe630 8 // You may obtain a copy of the License at
screamer 0:a076a1bbe630 9 //
screamer 0:a076a1bbe630 10 // http://www.apache.org/licenses/LICENSE-2.0
screamer 0:a076a1bbe630 11 //
screamer 0:a076a1bbe630 12 // Unless required by applicable law or agreed to in writing, software
screamer 0:a076a1bbe630 13 // distributed under the License is distributed on an "AS IS" BASIS,
screamer 0:a076a1bbe630 14 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
screamer 0:a076a1bbe630 15 // See the License for the specific language governing permissions and
screamer 0:a076a1bbe630 16 // limitations under the License.
screamer 0:a076a1bbe630 17 // ----------------------------------------------------------------------------
screamer 0:a076a1bbe630 18 #ifndef MBED_TEST_MODE
screamer 0:a076a1bbe630 19
screamer 0:a076a1bbe630 20 #include "mbed.h"
screamer 0:a076a1bbe630 21 #include "simple-mbed-cloud-client.h"
screamer 0:a076a1bbe630 22 #include "FATFileSystem.h"
screamer 0:a076a1bbe630 23 #include "LittleFileSystem.h"
screamer 0:a076a1bbe630 24
screamer 3:3b2db67b206e 25 // Default network interface object. Don't forget to change the WiFi SSID/password in mbed_app.json if you're using WiFi.
screamer 0:a076a1bbe630 26 NetworkInterface *net = NetworkInterface::get_default_instance();
screamer 0:a076a1bbe630 27
screamer 3:3b2db67b206e 28 // Default block device available on the target board
screamer 0:a076a1bbe630 29 BlockDevice *bd = BlockDevice::get_default_instance();
screamer 3:3b2db67b206e 30
screamer 3:3b2db67b206e 31 #if COMPONENT_SD || COMPONENT_NUSD
screamer 3:3b2db67b206e 32 // Use FATFileSystem for SD card type blockdevices
screamer 7:230af466efc4 33 FATFileSystem fs("fs");
screamer 3:3b2db67b206e 34 #else
screamer 3:3b2db67b206e 35 // Use LittleFileSystem for non-SD block devices to enable wear leveling and other functions
screamer 7:230af466efc4 36 LittleFileSystem fs("fs");
screamer 3:3b2db67b206e 37 #endif
screamer 3:3b2db67b206e 38
screamer 7:230af466efc4 39 // Default User button for GET example
screamer 6:2fb5057c0e42 40 InterruptIn button(BUTTON1);
screamer 0:a076a1bbe630 41 // Default LED to use for PUT/POST example
screamer 7:230af466efc4 42 DigitalOut led(LED1, 0);
screamer 1:a50c1e691ff1 43
screamer 6:2fb5057c0e42 44 // Declaring pointers for access to Pelion Device Management Client resources outside of main()
screamer 7:230af466efc4 45 MbedCloudClientResource *res_button;
screamer 7:230af466efc4 46 MbedCloudClientResource *res_led;
screamer 7:230af466efc4 47 MbedCloudClientResource *res_post;
screamer 0:a076a1bbe630 48
screamer 6:2fb5057c0e42 49 // An event queue is a very useful structure to debounce information between contexts (e.g. ISR and normal threads)
screamer 6:2fb5057c0e42 50 // This is great because things such as network operations are illegal in ISR, so updating a resource in a button's fall() function is not allowed
screamer 6:2fb5057c0e42 51 EventQueue eventQueue;
screamer 0:a076a1bbe630 52
screamer 7:230af466efc4 53 // When the device is registered, this variable will be used to access various useful information, like device ID etc.
screamer 7:230af466efc4 54 static const ConnectorClientEndpointInfo* endpointInfo;
screamer 7:230af466efc4 55
screamer 0:a076a1bbe630 56 /**
screamer 6:2fb5057c0e42 57 * PUT handler - sets the value of the built-in LED
screamer 0:a076a1bbe630 58 * @param resource The resource that triggered the callback
screamer 0:a076a1bbe630 59 * @param newValue Updated value for the resource
screamer 0:a076a1bbe630 60 */
screamer 6:2fb5057c0e42 61 void put_callback(MbedCloudClientResource *resource, m2m::String newValue) {
screamer 7:230af466efc4 62 printf("*** PUT received, new value: %s \n", newValue.c_str());
screamer 0:a076a1bbe630 63 led = atoi(newValue.c_str());
screamer 0:a076a1bbe630 64 }
screamer 0:a076a1bbe630 65
screamer 0:a076a1bbe630 66 /**
screamer 6:2fb5057c0e42 67 * POST handler - prints the content of the payload
screamer 0:a076a1bbe630 68 * @param resource The resource that triggered the callback
screamer 0:a076a1bbe630 69 * @param buffer If a body was passed to the POST function, this contains the data.
screamer 0:a076a1bbe630 70 * Note that the buffer is deallocated after leaving this function, so copy it if you need it longer.
screamer 0:a076a1bbe630 71 * @param size Size of the body
screamer 0:a076a1bbe630 72 */
screamer 6:2fb5057c0e42 73 void post_callback(MbedCloudClientResource *resource, const uint8_t *buffer, uint16_t size) {
screamer 7:230af466efc4 74 printf("*** POST received (length %u). Payload: ", size);
screamer 6:2fb5057c0e42 75 for (size_t ix = 0; ix < size; ix++) {
screamer 6:2fb5057c0e42 76 printf("%02x ", buffer[ix]);
screamer 6:2fb5057c0e42 77 }
screamer 6:2fb5057c0e42 78 printf("\n");
screamer 0:a076a1bbe630 79 }
screamer 0:a076a1bbe630 80
screamer 0:a076a1bbe630 81 /**
screamer 6:2fb5057c0e42 82 * Button handler
screamer 6:2fb5057c0e42 83 * This function will be triggered either by a physical button press or by a ticker every 5 seconds (see below)
screamer 0:a076a1bbe630 84 */
screamer 0:a076a1bbe630 85 void button_press() {
screamer 7:230af466efc4 86 int v = res_button->get_value_int() + 1;
screamer 7:230af466efc4 87 res_button->set_value(v);
screamer 7:230af466efc4 88 printf("*** Button clicked %d times \n", v);
screamer 0:a076a1bbe630 89 }
screamer 0:a076a1bbe630 90
screamer 0:a076a1bbe630 91 /**
screamer 0:a076a1bbe630 92 * Notification callback handler
screamer 0:a076a1bbe630 93 * @param resource The resource that triggered the callback
screamer 0:a076a1bbe630 94 * @param status The delivery status of the notification
screamer 0:a076a1bbe630 95 */
screamer 0:a076a1bbe630 96 void button_callback(MbedCloudClientResource *resource, const NoticationDeliveryStatus status) {
screamer 7:230af466efc4 97 printf("*** Button notification, status %s (%d) \n", MbedCloudClientResource::delivery_status_to_string(status), status);
screamer 0:a076a1bbe630 98 }
screamer 0:a076a1bbe630 99
screamer 0:a076a1bbe630 100 /**
screamer 0:a076a1bbe630 101 * Registration callback handler
screamer 0:a076a1bbe630 102 * @param endpoint Information about the registered endpoint such as the name (so you can find it back in portal)
screamer 0:a076a1bbe630 103 */
screamer 0:a076a1bbe630 104 void registered(const ConnectorClientEndpointInfo *endpoint) {
screamer 3:3b2db67b206e 105 printf("Registered to Pelion Device Management. Endpoint Name: %s\n", endpoint->internal_endpoint_name.c_str());
screamer 7:230af466efc4 106 endpointInfo = endpoint;
screamer 0:a076a1bbe630 107 }
screamer 0:a076a1bbe630 108
screamer 0:a076a1bbe630 109 int main(void) {
screamer 3:3b2db67b206e 110 printf("\nStarting Simple Pelion Device Management Client example\n");
screamer 0:a076a1bbe630 111
screamer 7:230af466efc4 112 int storage_status = fs.mount(bd);
screamer 7:230af466efc4 113 if (storage_status != 0) {
screamer 7:230af466efc4 114 printf("Storage mounting failed.\n");
screamer 7:230af466efc4 115 }
screamer 0:a076a1bbe630 116 // If the User button is pressed ons start, then format storage.
screamer 7:230af466efc4 117 bool btn_pressed = (button.read() == MBED_CONF_APP_BUTTON_PRESSED_STATE);
screamer 7:230af466efc4 118 if (btn_pressed) {
screamer 7:230af466efc4 119 printf("User button is pushed on start...\n");
screamer 7:230af466efc4 120 }
screamer 7:230af466efc4 121
screamer 7:230af466efc4 122 if (storage_status || btn_pressed) {
screamer 7:230af466efc4 123 printf("Formatting the storage...\n");
screamer 6:2fb5057c0e42 124 int storage_status = StorageHelper::format(&fs, bd);
screamer 0:a076a1bbe630 125 if (storage_status != 0) {
screamer 0:a076a1bbe630 126 printf("ERROR: Failed to reformat the storage (%d).\n", storage_status);
screamer 0:a076a1bbe630 127 }
screamer 3:3b2db67b206e 128 } else {
screamer 3:3b2db67b206e 129 printf("You can hold the user button during boot to format the storage and change the device identity.\n");
screamer 0:a076a1bbe630 130 }
screamer 0:a076a1bbe630 131
screamer 6:2fb5057c0e42 132 // Connect to the Internet (DHCP is expected to be on)
screamer 6:2fb5057c0e42 133 printf("Connecting to the network using the default network interface...\n");
screamer 0:a076a1bbe630 134 net = NetworkInterface::get_default_instance();
screamer 0:a076a1bbe630 135
screamer 6:2fb5057c0e42 136 nsapi_error_t net_status = NSAPI_ERROR_NO_CONNECTION;
screamer 6:2fb5057c0e42 137 while ((net_status = net->connect()) != NSAPI_ERROR_OK) {
screamer 6:2fb5057c0e42 138 printf("Unable to connect to network (%d). Retrying...\n", net_status);
screamer 0:a076a1bbe630 139 }
screamer 0:a076a1bbe630 140
screamer 0:a076a1bbe630 141 printf("Connected to the network successfully. IP address: %s\n", net->get_ip_address());
screamer 0:a076a1bbe630 142
screamer 6:2fb5057c0e42 143 printf("Initializing Pelion Device Management Client...\n");
screamer 6:2fb5057c0e42 144
screamer 6:2fb5057c0e42 145 // SimpleMbedCloudClient handles registering over LwM2M to Pelion Device Management
screamer 0:a076a1bbe630 146 SimpleMbedCloudClient client(net, bd, &fs);
screamer 0:a076a1bbe630 147 int client_status = client.init();
screamer 0:a076a1bbe630 148 if (client_status != 0) {
screamer 6:2fb5057c0e42 149 printf("Pelion Client initialization failed (%d)\n", client_status);
screamer 0:a076a1bbe630 150 return -1;
screamer 0:a076a1bbe630 151 }
screamer 0:a076a1bbe630 152
screamer 0:a076a1bbe630 153 // Creating resources, which can be written or read from the cloud
screamer 7:230af466efc4 154 res_button = client.create_resource("3200/0/5501", "Button Count");
screamer 7:230af466efc4 155 res_button->set_value(0);
screamer 7:230af466efc4 156 res_button->methods(M2MMethod::GET);
screamer 7:230af466efc4 157 res_button->observable(true);
screamer 7:230af466efc4 158 res_button->attach_notification_callback(button_callback);
screamer 0:a076a1bbe630 159
screamer 7:230af466efc4 160 res_led = client.create_resource("3201/0/5853", "LED State");
screamer 7:230af466efc4 161 res_led->set_value(led.read());
screamer 7:230af466efc4 162 res_led->methods(M2MMethod::GET | M2MMethod::PUT);
screamer 7:230af466efc4 163 res_led->attach_put_callback(put_callback);
screamer 0:a076a1bbe630 164
screamer 7:230af466efc4 165 res_post = client.create_resource("3300/0/5605", "Execute Function");
screamer 7:230af466efc4 166 res_post->methods(M2MMethod::POST);
screamer 7:230af466efc4 167 res_post->attach_post_callback(post_callback);
screamer 0:a076a1bbe630 168
screamer 6:2fb5057c0e42 169 printf("Initialized Pelion Device Management Client. Registering...\n");
screamer 0:a076a1bbe630 170
screamer 0:a076a1bbe630 171 // Callback that fires when registering is complete
screamer 0:a076a1bbe630 172 client.on_registered(&registered);
screamer 0:a076a1bbe630 173
screamer 0:a076a1bbe630 174 // Register with Pelion DM
screamer 0:a076a1bbe630 175 client.register_and_connect();
screamer 0:a076a1bbe630 176
screamer 6:2fb5057c0e42 177 // The button fires on an interrupt context, but debounces it to the eventqueue, so it's safe to do network operations
screamer 0:a076a1bbe630 178 button.fall(eventQueue.event(&button_press));
screamer 3:3b2db67b206e 179 printf("Press the user button to increment the LwM2M resource value...\n");
screamer 0:a076a1bbe630 180
screamer 0:a076a1bbe630 181 // You can easily run the eventQueue in a separate thread if required
screamer 0:a076a1bbe630 182 eventQueue.dispatch_forever();
screamer 0:a076a1bbe630 183 }
screamer 6:2fb5057c0e42 184
screamer 6:2fb5057c0e42 185 #endif /* MBED_TEST_MODE */