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:
Fri Dec 21 02:13:03 2018 +0000
Revision:
1:ddb04b438959
Parent:
0:91c16b1711c2
Child:
2:aadfd874279d
Add Wio LED control

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 1:ddb04b438959 23 #include "Wio_LED.h"
MACRUM 0:91c16b1711c2 24
MACRUM 0:91c16b1711c2 25 // An event queue is a very useful structure to debounce information between contexts (e.g. ISR and normal threads)
MACRUM 0:91c16b1711c2 26 // 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 27 EventQueue eventQueue;
MACRUM 0:91c16b1711c2 28
MACRUM 0:91c16b1711c2 29 #if defined(TARGET_WIO_3G)
MACRUM 0:91c16b1711c2 30 DigitalOut SD_POWER(PA_15, 1);
MACRUM 0:91c16b1711c2 31 #endif
MACRUM 0:91c16b1711c2 32
MACRUM 0:91c16b1711c2 33 // Default block device
MACRUM 0:91c16b1711c2 34 BlockDevice* bd = BlockDevice::get_default_instance();
MACRUM 0:91c16b1711c2 35 FATFileSystem fs("sd", bd);
MACRUM 0:91c16b1711c2 36
MACRUM 0:91c16b1711c2 37 // Default network interface object
MACRUM 0:91c16b1711c2 38 CellularBase *net;
MACRUM 0:91c16b1711c2 39
MACRUM 0:91c16b1711c2 40 // Declaring pointers for access to Mbed Cloud Client resources outside of main()
MACRUM 0:91c16b1711c2 41 MbedCloudClientResource *button_res;
MACRUM 0:91c16b1711c2 42 MbedCloudClientResource *pattern_res;
MACRUM 0:91c16b1711c2 43
MACRUM 0:91c16b1711c2 44 // 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 45 void fake_button_press() {
MACRUM 0:91c16b1711c2 46 int v = button_res->get_value_int() + 1;
MACRUM 0:91c16b1711c2 47
MACRUM 0:91c16b1711c2 48 button_res->set_value(v);
MACRUM 0:91c16b1711c2 49
MACRUM 0:91c16b1711c2 50 printf("Simulated button clicked %d times\n", v);
MACRUM 0:91c16b1711c2 51 }
MACRUM 0:91c16b1711c2 52
MACRUM 0:91c16b1711c2 53 /**
MACRUM 0:91c16b1711c2 54 * PUT handler
MACRUM 0:91c16b1711c2 55 * @param resource The resource that triggered the callback
MACRUM 0:91c16b1711c2 56 * @param newValue Updated value for the resource
MACRUM 0:91c16b1711c2 57 */
MACRUM 0:91c16b1711c2 58 void pattern_updated(MbedCloudClientResource *resource, m2m::String newValue) {
MACRUM 0:91c16b1711c2 59 printf("PUT received, new value: %s\n", newValue.c_str());
MACRUM 0:91c16b1711c2 60 }
MACRUM 0:91c16b1711c2 61
MACRUM 0:91c16b1711c2 62 /**
MACRUM 0:91c16b1711c2 63 * POST handler
MACRUM 0:91c16b1711c2 64 * @param resource The resource that triggered the callback
MACRUM 0:91c16b1711c2 65 * @param buffer If a body was passed to the POST function, this contains the data.
MACRUM 0:91c16b1711c2 66 * Note that the buffer is deallocated after leaving this function, so copy it if you need it longer.
MACRUM 0:91c16b1711c2 67 * @param size Size of the body
MACRUM 0:91c16b1711c2 68 */
MACRUM 0:91c16b1711c2 69 void blink_callback(MbedCloudClientResource *resource, const uint8_t *buffer, uint16_t size) {
MACRUM 0:91c16b1711c2 70 printf("POST received. Going to blink LED pattern: %s\n", pattern_res->get_value().c_str());
MACRUM 0:91c16b1711c2 71
MACRUM 1:ddb04b438959 72 // static DigitalOut augmentedLed(LED1); // LED that is used for blinking the pattern
MACRUM 1:ddb04b438959 73 static int led = 0;
MACRUM 0:91c16b1711c2 74
MACRUM 0:91c16b1711c2 75 // Parse the pattern string, and toggle the LED in that pattern
MACRUM 0:91c16b1711c2 76 string s = std::string(pattern_res->get_value().c_str());
MACRUM 0:91c16b1711c2 77 size_t i = 0;
MACRUM 0:91c16b1711c2 78 size_t pos = s.find(':');
MACRUM 0:91c16b1711c2 79 while (pos != string::npos) {
MACRUM 0:91c16b1711c2 80 wait_ms(atoi(s.substr(i, pos - i).c_str()));
MACRUM 1:ddb04b438959 81 led = !led;
MACRUM 1:ddb04b438959 82 if (led) {
MACRUM 1:ddb04b438959 83 setcolor(WS2812_RED);
MACRUM 1:ddb04b438959 84 }
MACRUM 1:ddb04b438959 85 else {
MACRUM 1:ddb04b438959 86 setcolor(WS2812_BLACK);
MACRUM 1:ddb04b438959 87 }
MACRUM 0:91c16b1711c2 88
MACRUM 0:91c16b1711c2 89 i = ++pos;
MACRUM 0:91c16b1711c2 90 pos = s.find(':', pos);
MACRUM 0:91c16b1711c2 91
MACRUM 0:91c16b1711c2 92 if (pos == string::npos) {
MACRUM 0:91c16b1711c2 93 wait_ms(atoi(s.substr(i, s.length()).c_str()));
MACRUM 1:ddb04b438959 94 led = !led;
MACRUM 1:ddb04b438959 95 if (led) {
MACRUM 1:ddb04b438959 96 setcolor(WS2812_RED);
MACRUM 1:ddb04b438959 97 }
MACRUM 1:ddb04b438959 98 else {
MACRUM 1:ddb04b438959 99 setcolor(WS2812_BLACK);
MACRUM 1:ddb04b438959 100 }
MACRUM 0:91c16b1711c2 101 }
MACRUM 0:91c16b1711c2 102 }
MACRUM 0:91c16b1711c2 103 }
MACRUM 0:91c16b1711c2 104
MACRUM 0:91c16b1711c2 105 /**
MACRUM 0:91c16b1711c2 106 * Notification callback handler
MACRUM 0:91c16b1711c2 107 * @param resource The resource that triggered the callback
MACRUM 0:91c16b1711c2 108 * @param status The delivery status of the notification
MACRUM 0:91c16b1711c2 109 */
MACRUM 0:91c16b1711c2 110 void button_callback(MbedCloudClientResource *resource, const NoticationDeliveryStatus status) {
MACRUM 0:91c16b1711c2 111 printf("Button notification, status %s (%d)\n", MbedCloudClientResource::delivery_status_to_string(status), status);
MACRUM 0:91c16b1711c2 112 }
MACRUM 0:91c16b1711c2 113
MACRUM 0:91c16b1711c2 114 /**
MACRUM 0:91c16b1711c2 115 * Registration callback handler
MACRUM 0:91c16b1711c2 116 * @param endpoint Information about the registered endpoint such as the name (so you can find it back in portal)
MACRUM 0:91c16b1711c2 117 */
MACRUM 0:91c16b1711c2 118 void registered(const ConnectorClientEndpointInfo *endpoint) {
MACRUM 0:91c16b1711c2 119 printf("Connected to Pelion Device Management. Endpoint Name: %s\n", endpoint->internal_endpoint_name.c_str());
MACRUM 0:91c16b1711c2 120 }
MACRUM 0:91c16b1711c2 121
MACRUM 0:91c16b1711c2 122 int main(void) {
MACRUM 0:91c16b1711c2 123 printf("Starting Simple Pelion Device Management Client example\n");
MACRUM 0:91c16b1711c2 124 printf("Connecting to the network...\n");
MACRUM 0:91c16b1711c2 125
MACRUM 0:91c16b1711c2 126 net = CellularBase::get_default_instance();
MACRUM 0:91c16b1711c2 127
MACRUM 0:91c16b1711c2 128 /* Set Pin code for SIM card */
MACRUM 0:91c16b1711c2 129 net->set_sim_pin(MBED_CONF_APP_SIM_PIN_CODE);
MACRUM 0:91c16b1711c2 130
MACRUM 0:91c16b1711c2 131 /* Set network credentials here, e.g., APN */
MACRUM 0:91c16b1711c2 132 net->set_credentials(MBED_CONF_APP_APN, MBED_CONF_APP_USERNAME, MBED_CONF_APP_PASSWORD);
MACRUM 0:91c16b1711c2 133
MACRUM 0:91c16b1711c2 134 nsapi_error_t status = net->connect();
MACRUM 0:91c16b1711c2 135
MACRUM 0:91c16b1711c2 136 if (status != NSAPI_ERROR_OK) {
MACRUM 0:91c16b1711c2 137 printf("Connecting to the network failed %d!\n", status);
MACRUM 0:91c16b1711c2 138 return -1;
MACRUM 0:91c16b1711c2 139 }
MACRUM 0:91c16b1711c2 140
MACRUM 0:91c16b1711c2 141 printf("Connected to the network successfully. IP address: %s\n", net->get_ip_address());
MACRUM 0:91c16b1711c2 142
MACRUM 0:91c16b1711c2 143 // SimpleMbedCloudClient handles registering over LwM2M to Mbed Cloud
MACRUM 0:91c16b1711c2 144 SimpleMbedCloudClient client(net, bd, &fs);
MACRUM 0:91c16b1711c2 145 int client_status = client.init();
MACRUM 0:91c16b1711c2 146 if (client_status != 0) {
MACRUM 0:91c16b1711c2 147 printf("Pelion Client initialization failed (%d)\n", client_status);
MACRUM 0:91c16b1711c2 148 return -1;
MACRUM 0:91c16b1711c2 149 }
MACRUM 0:91c16b1711c2 150
MACRUM 0:91c16b1711c2 151 // Creating resources, which can be written or read from the cloud
MACRUM 0:91c16b1711c2 152 button_res = client.create_resource("3200/0/5501", "button_count");
MACRUM 0:91c16b1711c2 153 button_res->set_value(0);
MACRUM 0:91c16b1711c2 154 button_res->methods(M2MMethod::GET);
MACRUM 0:91c16b1711c2 155 button_res->observable(true);
MACRUM 0:91c16b1711c2 156 button_res->attach_notification_callback(button_callback);
MACRUM 0:91c16b1711c2 157
MACRUM 0:91c16b1711c2 158 pattern_res = client.create_resource("3201/0/5853", "blink_pattern");
MACRUM 0:91c16b1711c2 159 pattern_res->set_value("500:500:500:500:500:500:500:500");
MACRUM 0:91c16b1711c2 160 pattern_res->methods(M2MMethod::GET | M2MMethod::PUT);
MACRUM 0:91c16b1711c2 161 pattern_res->attach_put_callback(pattern_updated);
MACRUM 0:91c16b1711c2 162
MACRUM 0:91c16b1711c2 163 MbedCloudClientResource *blink_res = client.create_resource("3201/0/5850", "blink_action");
MACRUM 0:91c16b1711c2 164 blink_res->methods(M2MMethod::POST);
MACRUM 0:91c16b1711c2 165 blink_res->attach_post_callback(blink_callback);
MACRUM 0:91c16b1711c2 166
MACRUM 0:91c16b1711c2 167 printf("Initialized Pelion Client. Registering...\n");
MACRUM 0:91c16b1711c2 168
MACRUM 0:91c16b1711c2 169 // Callback that fires when registering is complete
MACRUM 0:91c16b1711c2 170 client.on_registered(&registered);
MACRUM 0:91c16b1711c2 171
MACRUM 0:91c16b1711c2 172 // Register with Mbed Cloud
MACRUM 0:91c16b1711c2 173 client.register_and_connect();
MACRUM 0:91c16b1711c2 174
MACRUM 0:91c16b1711c2 175 // Placeholder for callback to update local resource when GET comes.
MACRUM 0:91c16b1711c2 176 // The timer fires on an interrupt context, but debounces it to the eventqueue, so it's safe to do network operations
MACRUM 0:91c16b1711c2 177 Ticker timer;
MACRUM 0:91c16b1711c2 178 timer.attach(eventQueue.event(&fake_button_press), 5.0);
MACRUM 0:91c16b1711c2 179
MACRUM 0:91c16b1711c2 180 // You can easily run the eventQueue in a separate thread if required
MACRUM 0:91c16b1711c2 181 eventQueue.dispatch_forever();
MACRUM 0:91c16b1711c2 182 }
MACRUM 0:91c16b1711c2 183 #endif