Specific Pelion ready example using features of Seeed Wio boards including cellular and SD Card

Dependencies:   WS2812 PixelArray

Fork of simple-mbed-cloud-example-wio_3g by Toyomasa Watarai

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:
Seeed Wio 3G and Seeed Wio LTE-M1/NB1(BG96) over cellular and using SD card.

https://os.mbed.com/media/cache/platforms/Wio_3G.png.250x250_q85.png

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

Example functionality

This example showcases the following device functionality:

  • Allow the user to change the state of the board LED from Pelion LWM2M led_state resource and PUT request.

Instructions to use this program with mbed CLI

1. Import the application into your desktop:

mbed import https://os.mbed.com/teams/Seeed/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.9.x or above.

  • Set APN name, username and password in the mbed_app.json.

            "nsapi.default-cellular-plmn"      : "\"00000\"",
            "nsapi.default-cellular-sim-pin"   : "\"0000\"",
            "nsapi.default-cellular-apn"       : "\"apn\"",
            "nsapi.default-cellular-username"  : "\"username\"",
            "nsapi.default-cellular-password"  : "\"password\""

Information

For the Wio LTE-M1/NB1(BG96) target, PLMN (Public land mobile network) should be specified to get quick connection to the network. This is usually found first 5 digit from your SIM card IMSI (International Mobile Subscriber Identity) number. e.g. 44052

4. Compile and program:

mbed compile -t <toolchain> -m WIO_3G

(supported toolchains : GCC_ARM / ARM / IAR)

Troubleshooting

  • Make sure the fields nsapi.default-cellular-sim-pin, nsapi.default-cellular-apn, nsapi.default-cellular-username and nsapi.default-cellular-password from the mbed_app.json file are filled in correctly. The correct values should appear in the user manual in the details of the SIM card.
  • Enable trace flag to have access to debug information "mbed-trace.enable": true.
  • Try both TCP and UDP socket types.
  • Try both "lwip.ppp-enabled": true and "lwip.ppp-enabled": false.
  • The modem and network may only support IPv6 in which case "lwip.ipv6-enabled": true shall be defined.
  • The SIM and modem must have compatible cellular technology (3G, 4G, NB-IoT, ...) supported and cellular network available.
Committer:
MACRUM
Date:
Sat Nov 10 20:27:36 2018 +0900
Revision:
0:91c16b1711c2
Child:
1:ddb04b438959
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
MACRUM 0:91c16b1711c2 1 // ----------------------------------------------------------------------------
MACRUM 0:91c16b1711c2 2 // Copyright 2016-2018 ARM Ltd.
MACRUM 0:91c16b1711c2 3 //
MACRUM 0:91c16b1711c2 4 // SPDX-License-Identifier: Apache-2.0
MACRUM 0:91c16b1711c2 5 //
MACRUM 0:91c16b1711c2 6 // Licensed under the Apache License, Version 2.0 (the "License");
MACRUM 0:91c16b1711c2 7 // you may not use this file except in compliance with the License.
MACRUM 0:91c16b1711c2 8 // You may obtain a copy of the License at
MACRUM 0:91c16b1711c2 9 //
MACRUM 0:91c16b1711c2 10 // http://www.apache.org/licenses/LICENSE-2.0
MACRUM 0:91c16b1711c2 11 //
MACRUM 0:91c16b1711c2 12 // Unless required by applicable law or agreed to in writing, software
MACRUM 0:91c16b1711c2 13 // distributed under the License is distributed on an "AS IS" BASIS,
MACRUM 0:91c16b1711c2 14 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
MACRUM 0:91c16b1711c2 15 // See the License for the specific language governing permissions and
MACRUM 0:91c16b1711c2 16 // limitations under the License.
MACRUM 0:91c16b1711c2 17 // ----------------------------------------------------------------------------
MACRUM 0:91c16b1711c2 18 #ifndef MBED_TEST_MODE
MACRUM 0:91c16b1711c2 19
MACRUM 0:91c16b1711c2 20 #include "mbed.h"
MACRUM 0:91c16b1711c2 21 #include "simple-mbed-cloud-client.h"
MACRUM 0:91c16b1711c2 22 #include "FATFileSystem.h"
MACRUM 0:91c16b1711c2 23
MACRUM 0:91c16b1711c2 24 // An event queue is a very useful structure to debounce information between contexts (e.g. ISR and normal threads)
MACRUM 0:91c16b1711c2 25 // 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
MACRUM 0:91c16b1711c2 26 EventQueue eventQueue;
MACRUM 0:91c16b1711c2 27
MACRUM 0:91c16b1711c2 28 #if defined(TARGET_WIO_3G)
MACRUM 0:91c16b1711c2 29 DigitalOut SD_POWER(PA_15, 1);
MACRUM 0:91c16b1711c2 30 #endif
MACRUM 0:91c16b1711c2 31
MACRUM 0:91c16b1711c2 32 // Default block device
MACRUM 0:91c16b1711c2 33 BlockDevice* bd = BlockDevice::get_default_instance();
MACRUM 0:91c16b1711c2 34 FATFileSystem fs("sd", bd);
MACRUM 0:91c16b1711c2 35
MACRUM 0:91c16b1711c2 36 // Default network interface object
MACRUM 0:91c16b1711c2 37 CellularBase *net;
MACRUM 0:91c16b1711c2 38
MACRUM 0:91c16b1711c2 39 // Declaring pointers for access to Mbed Cloud Client resources outside of main()
MACRUM 0:91c16b1711c2 40 MbedCloudClientResource *button_res;
MACRUM 0:91c16b1711c2 41 MbedCloudClientResource *pattern_res;
MACRUM 0:91c16b1711c2 42
MACRUM 0:91c16b1711c2 43 // This function gets triggered by the timer. It's easy to replace it by an InterruptIn and fall() mode on a real button
MACRUM 0:91c16b1711c2 44 void fake_button_press() {
MACRUM 0:91c16b1711c2 45 int v = button_res->get_value_int() + 1;
MACRUM 0:91c16b1711c2 46
MACRUM 0:91c16b1711c2 47 button_res->set_value(v);
MACRUM 0:91c16b1711c2 48
MACRUM 0:91c16b1711c2 49 printf("Simulated button clicked %d times\n", v);
MACRUM 0:91c16b1711c2 50 }
MACRUM 0:91c16b1711c2 51
MACRUM 0:91c16b1711c2 52 /**
MACRUM 0:91c16b1711c2 53 * PUT handler
MACRUM 0:91c16b1711c2 54 * @param resource The resource that triggered the callback
MACRUM 0:91c16b1711c2 55 * @param newValue Updated value for the resource
MACRUM 0:91c16b1711c2 56 */
MACRUM 0:91c16b1711c2 57 void pattern_updated(MbedCloudClientResource *resource, m2m::String newValue) {
MACRUM 0:91c16b1711c2 58 printf("PUT received, new value: %s\n", newValue.c_str());
MACRUM 0:91c16b1711c2 59 }
MACRUM 0:91c16b1711c2 60
MACRUM 0:91c16b1711c2 61 /**
MACRUM 0:91c16b1711c2 62 * POST handler
MACRUM 0:91c16b1711c2 63 * @param resource The resource that triggered the callback
MACRUM 0:91c16b1711c2 64 * @param buffer If a body was passed to the POST function, this contains the data.
MACRUM 0:91c16b1711c2 65 * Note that the buffer is deallocated after leaving this function, so copy it if you need it longer.
MACRUM 0:91c16b1711c2 66 * @param size Size of the body
MACRUM 0:91c16b1711c2 67 */
MACRUM 0:91c16b1711c2 68 void blink_callback(MbedCloudClientResource *resource, const uint8_t *buffer, uint16_t size) {
MACRUM 0:91c16b1711c2 69 printf("POST received. Going to blink LED pattern: %s\n", pattern_res->get_value().c_str());
MACRUM 0:91c16b1711c2 70
MACRUM 0:91c16b1711c2 71 static DigitalOut augmentedLed(LED1); // LED that is used for blinking the pattern
MACRUM 0:91c16b1711c2 72
MACRUM 0:91c16b1711c2 73 // Parse the pattern string, and toggle the LED in that pattern
MACRUM 0:91c16b1711c2 74 string s = std::string(pattern_res->get_value().c_str());
MACRUM 0:91c16b1711c2 75 size_t i = 0;
MACRUM 0:91c16b1711c2 76 size_t pos = s.find(':');
MACRUM 0:91c16b1711c2 77 while (pos != string::npos) {
MACRUM 0:91c16b1711c2 78 wait_ms(atoi(s.substr(i, pos - i).c_str()));
MACRUM 0:91c16b1711c2 79 augmentedLed = !augmentedLed;
MACRUM 0:91c16b1711c2 80
MACRUM 0:91c16b1711c2 81 i = ++pos;
MACRUM 0:91c16b1711c2 82 pos = s.find(':', pos);
MACRUM 0:91c16b1711c2 83
MACRUM 0:91c16b1711c2 84 if (pos == string::npos) {
MACRUM 0:91c16b1711c2 85 wait_ms(atoi(s.substr(i, s.length()).c_str()));
MACRUM 0:91c16b1711c2 86 augmentedLed = !augmentedLed;
MACRUM 0:91c16b1711c2 87 }
MACRUM 0:91c16b1711c2 88 }
MACRUM 0:91c16b1711c2 89 }
MACRUM 0:91c16b1711c2 90
MACRUM 0:91c16b1711c2 91 /**
MACRUM 0:91c16b1711c2 92 * Notification callback handler
MACRUM 0:91c16b1711c2 93 * @param resource The resource that triggered the callback
MACRUM 0:91c16b1711c2 94 * @param status The delivery status of the notification
MACRUM 0:91c16b1711c2 95 */
MACRUM 0:91c16b1711c2 96 void button_callback(MbedCloudClientResource *resource, const NoticationDeliveryStatus status) {
MACRUM 0:91c16b1711c2 97 printf("Button notification, status %s (%d)\n", MbedCloudClientResource::delivery_status_to_string(status), status);
MACRUM 0:91c16b1711c2 98 }
MACRUM 0:91c16b1711c2 99
MACRUM 0:91c16b1711c2 100 /**
MACRUM 0:91c16b1711c2 101 * Registration callback handler
MACRUM 0:91c16b1711c2 102 * @param endpoint Information about the registered endpoint such as the name (so you can find it back in portal)
MACRUM 0:91c16b1711c2 103 */
MACRUM 0:91c16b1711c2 104 void registered(const ConnectorClientEndpointInfo *endpoint) {
MACRUM 0:91c16b1711c2 105 printf("Connected to Pelion Device Management. Endpoint Name: %s\n", endpoint->internal_endpoint_name.c_str());
MACRUM 0:91c16b1711c2 106 }
MACRUM 0:91c16b1711c2 107
MACRUM 0:91c16b1711c2 108 int main(void) {
MACRUM 0:91c16b1711c2 109 printf("Starting Simple Pelion Device Management Client example\n");
MACRUM 0:91c16b1711c2 110 printf("Connecting to the network...\n");
MACRUM 0:91c16b1711c2 111
MACRUM 0:91c16b1711c2 112 net = CellularBase::get_default_instance();
MACRUM 0:91c16b1711c2 113
MACRUM 0:91c16b1711c2 114 /* Set Pin code for SIM card */
MACRUM 0:91c16b1711c2 115 net->set_sim_pin(MBED_CONF_APP_SIM_PIN_CODE);
MACRUM 0:91c16b1711c2 116
MACRUM 0:91c16b1711c2 117 /* Set network credentials here, e.g., APN */
MACRUM 0:91c16b1711c2 118 net->set_credentials(MBED_CONF_APP_APN, MBED_CONF_APP_USERNAME, MBED_CONF_APP_PASSWORD);
MACRUM 0:91c16b1711c2 119
MACRUM 0:91c16b1711c2 120 nsapi_error_t status = net->connect();
MACRUM 0:91c16b1711c2 121
MACRUM 0:91c16b1711c2 122 if (status != NSAPI_ERROR_OK) {
MACRUM 0:91c16b1711c2 123 printf("Connecting to the network failed %d!\n", status);
MACRUM 0:91c16b1711c2 124 return -1;
MACRUM 0:91c16b1711c2 125 }
MACRUM 0:91c16b1711c2 126
MACRUM 0:91c16b1711c2 127 printf("Connected to the network successfully. IP address: %s\n", net->get_ip_address());
MACRUM 0:91c16b1711c2 128
MACRUM 0:91c16b1711c2 129 // SimpleMbedCloudClient handles registering over LwM2M to Mbed Cloud
MACRUM 0:91c16b1711c2 130 SimpleMbedCloudClient client(net, bd, &fs);
MACRUM 0:91c16b1711c2 131 int client_status = client.init();
MACRUM 0:91c16b1711c2 132 if (client_status != 0) {
MACRUM 0:91c16b1711c2 133 printf("Pelion Client initialization failed (%d)\n", client_status);
MACRUM 0:91c16b1711c2 134 return -1;
MACRUM 0:91c16b1711c2 135 }
MACRUM 0:91c16b1711c2 136
MACRUM 0:91c16b1711c2 137 // Creating resources, which can be written or read from the cloud
MACRUM 0:91c16b1711c2 138 button_res = client.create_resource("3200/0/5501", "button_count");
MACRUM 0:91c16b1711c2 139 button_res->set_value(0);
MACRUM 0:91c16b1711c2 140 button_res->methods(M2MMethod::GET);
MACRUM 0:91c16b1711c2 141 button_res->observable(true);
MACRUM 0:91c16b1711c2 142 button_res->attach_notification_callback(button_callback);
MACRUM 0:91c16b1711c2 143
MACRUM 0:91c16b1711c2 144 pattern_res = client.create_resource("3201/0/5853", "blink_pattern");
MACRUM 0:91c16b1711c2 145 pattern_res->set_value("500:500:500:500:500:500:500:500");
MACRUM 0:91c16b1711c2 146 pattern_res->methods(M2MMethod::GET | M2MMethod::PUT);
MACRUM 0:91c16b1711c2 147 pattern_res->attach_put_callback(pattern_updated);
MACRUM 0:91c16b1711c2 148
MACRUM 0:91c16b1711c2 149 MbedCloudClientResource *blink_res = client.create_resource("3201/0/5850", "blink_action");
MACRUM 0:91c16b1711c2 150 blink_res->methods(M2MMethod::POST);
MACRUM 0:91c16b1711c2 151 blink_res->attach_post_callback(blink_callback);
MACRUM 0:91c16b1711c2 152
MACRUM 0:91c16b1711c2 153 printf("Initialized Pelion Client. Registering...\n");
MACRUM 0:91c16b1711c2 154
MACRUM 0:91c16b1711c2 155 // Callback that fires when registering is complete
MACRUM 0:91c16b1711c2 156 client.on_registered(&registered);
MACRUM 0:91c16b1711c2 157
MACRUM 0:91c16b1711c2 158 // Register with Mbed Cloud
MACRUM 0:91c16b1711c2 159 client.register_and_connect();
MACRUM 0:91c16b1711c2 160
MACRUM 0:91c16b1711c2 161 // Placeholder for callback to update local resource when GET comes.
MACRUM 0:91c16b1711c2 162 // The timer fires on an interrupt context, but debounces it to the eventqueue, so it's safe to do network operations
MACRUM 0:91c16b1711c2 163 Ticker timer;
MACRUM 0:91c16b1711c2 164 timer.attach(eventQueue.event(&fake_button_press), 5.0);
MACRUM 0:91c16b1711c2 165
MACRUM 0:91c16b1711c2 166 // You can easily run the eventQueue in a separate thread if required
MACRUM 0:91c16b1711c2 167 eventQueue.dispatch_forever();
MACRUM 0:91c16b1711c2 168 }
MACRUM 0:91c16b1711c2 169 #endif