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.
main.cpp
00001 // ---------------------------------------------------------------------------- 00002 // Copyright 2016-2018 ARM Ltd. 00003 // 00004 // SPDX-License-Identifier: Apache-2.0 00005 // 00006 // Licensed under the Apache License, Version 2.0 (the "License"); 00007 // you may not use this file except in compliance with the License. 00008 // You may obtain a copy of the License at 00009 // 00010 // http://www.apache.org/licenses/LICENSE-2.0 00011 // 00012 // Unless required by applicable law or agreed to in writing, software 00013 // distributed under the License is distributed on an "AS IS" BASIS, 00014 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00015 // See the License for the specific language governing permissions and 00016 // limitations under the License. 00017 // ---------------------------------------------------------------------------- 00018 #ifndef MBED_TEST_MODE 00019 00020 #include "mbed.h" 00021 #include "simple-mbed-cloud-client.h" 00022 #include "FATFileSystem.h" 00023 #include "LittleFileSystem.h" 00024 00025 #include <string> 00026 00027 // Default network interface object. Don't forget to change the WiFi SSID/password in mbed_app.json if you're using WiFi. 00028 NetworkInterface *net = NetworkInterface::get_default_instance(); 00029 00030 // Default block device available on the target board 00031 BlockDevice *bd = BlockDevice::get_default_instance(); 00032 00033 #if COMPONENT_SD || COMPONENT_NUSD 00034 // Use FATFileSystem for SD card type blockdevices 00035 FATFileSystem fs("fs"); 00036 #else 00037 // Use LittleFileSystem for non-SD block devices to enable wear leveling and other functions 00038 LittleFileSystem fs("fs"); 00039 #endif 00040 00041 // Default User button for GET example 00042 InterruptIn button(BUTTON1); 00043 // Default LED to use for PUT/POST example 00044 DigitalOut led(LED1, 0); 00045 00046 // How often to fetch sensor data (in seconds) 00047 #define SENSORS_POLL_INTERVAL 3.0 00048 00049 // Send all sensor data or just limited (useful for when running out of memory) 00050 #define SEND_ALL_SENSORS 00051 00052 // Sensors related includes and initialization 00053 // Temperature reading from microcontroller 00054 AnalogIn adc_temp(ADC_TEMP); 00055 // Voltage reference reading from microcontroller 00056 AnalogIn adc_vref(ADC_VREF); 00057 00058 // Declaring pointers for access to Pelion Device Management Client resources outside of main() 00059 MbedCloudClientResource *res_button; 00060 MbedCloudClientResource *res_pattern_led; 00061 MbedCloudClientResource *res_post; 00062 00063 // Additional resources for sensor readings 00064 #ifdef SEND_ALL_SENSORS 00065 MbedCloudClientResource *res_temperature; 00066 MbedCloudClientResource *res_voltage; 00067 #endif /* SEND_ALL_SENSORS */ 00068 00069 // An event queue is a very useful structure to debounce information between contexts (e.g. ISR and normal threads) 00070 // 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 00071 EventQueue eventQueue; 00072 00073 // When the device is registered, this variable will be used to access various useful information, like device ID etc. 00074 static const ConnectorClientEndpointInfo* endpointInfo; 00075 00076 void pattern_updated(MbedCloudClientResource *resource, m2m::String newValue) { 00077 printf("PUT received, new value: %s\n", newValue.c_str()); 00078 } 00079 00080 void blink() { 00081 led = !led; 00082 } 00083 00084 /** 00085 * POST handler 00086 * @param resource The resource that triggered the callback 00087 * @param buffer If a body was passed to the POST function, this contains the data. 00088 * Note that the buffer is deallocated after leaving this function, so copy it if you need it longer. 00089 * @param size Size of the body 00090 */ 00091 void blink_callback(MbedCloudClientResource *resource, const uint8_t *buffer, uint16_t size) { 00092 printf("POST received. Going to blink LED pattern: %s\n", res_pattern_led->get_value().c_str()); 00093 00094 // Parse the pattern string, and toggle the LED in that pattern 00095 string s = string(res_pattern_led->get_value().c_str()); 00096 size_t i = 0; 00097 size_t pos = s.find(':'); 00098 int total_len = 0; 00099 while (pos != string::npos) { 00100 int len = atoi(s.substr(i, pos - i).c_str()); 00101 00102 mbed_event_queue()->call_in(total_len + len, &blink); 00103 00104 total_len += len; 00105 i = ++pos; 00106 pos = s.find(':', pos); 00107 } 00108 } 00109 00110 /** 00111 * Notification callback handler 00112 * @param resource The resource that triggered the callback 00113 * @param status The delivery status of the notification 00114 */ 00115 void button_callback(MbedCloudClientResource *resource, const NoticationDeliveryStatus status) { 00116 printf("Button notification, status %s (%d)\n", MbedCloudClientResource::delivery_status_to_string(status), status); 00117 } 00118 00119 /** 00120 * Button handler 00121 * This function will be triggered either by a physical button press or by a ticker every 5 seconds (see below) 00122 */ 00123 void button_press() { 00124 int v = res_button->get_value_int() + 1; 00125 res_button->set_value(v); 00126 printf("Button clicked %d times\n", v); 00127 } 00128 00129 /** 00130 * Update sensors and report their values. 00131 * This function is called periodically. 00132 */ 00133 void sensors_update() { 00134 float temp = adc_temp.read()*100; 00135 float vref = adc_vref.read(); 00136 printf("ADC temp: %6.4f C, vref: %6.4f %%\r\n", temp, vref); 00137 if (endpointInfo) { 00138 res_temperature->set_value(temp); 00139 res_voltage->set_value(vref); 00140 } 00141 } 00142 00143 /** 00144 * Registration callback handler 00145 * @param endpoint Information about the registered endpoint such as the name (so you can find it back in portal) 00146 * When the device is registered, this variable will be used to access various useful information, like device ID etc. 00147 */ 00148 void registered(const ConnectorClientEndpointInfo *endpoint) { 00149 printf("Registered to Pelion Device Management. Endpoint Name: %s\n", endpoint->internal_endpoint_name.c_str()); 00150 endpointInfo = endpoint; 00151 } 00152 00153 int main(void) { 00154 printf("\nStarting Simple Pelion Device Management Client example\n"); 00155 00156 int storage_status = fs.mount(bd); 00157 if (storage_status != 0) { 00158 printf("Storage mounting failed.\n"); 00159 } 00160 // If the User button is pressed ons start, then format storage. 00161 bool btn_pressed = (button.read() == MBED_CONF_APP_BUTTON_PRESSED_STATE); 00162 if (btn_pressed) { 00163 printf("User button is pushed on start...\n"); 00164 } 00165 00166 if (storage_status || btn_pressed) { 00167 printf("Formatting the storage...\n"); 00168 int storage_status = StorageHelper::format(&fs, bd); 00169 if (storage_status != 0) { 00170 printf("ERROR: Failed to reformat the storage (%d).\n", storage_status); 00171 } 00172 } else { 00173 printf("You can hold the user button during boot to format the storage and change the device identity.\n"); 00174 } 00175 00176 // Connect to the Internet (DHCP is expected to be on) 00177 printf("Connecting to the network using the default network interface...\n"); 00178 net = NetworkInterface::get_default_instance(); 00179 00180 nsapi_error_t net_status = NSAPI_ERROR_NO_CONNECTION; 00181 while ((net_status = net->connect()) != NSAPI_ERROR_OK) { 00182 printf("Unable to connect to network (%d). Retrying...\n", net_status); 00183 } 00184 00185 printf("Connected to the network successfully. IP address: %s\n", net->get_ip_address()); 00186 00187 printf("Initializing Pelion Device Management Client...\n"); 00188 00189 // SimpleMbedCloudClient handles registering over LwM2M to Pelion Device Management 00190 SimpleMbedCloudClient client(net, bd, &fs); 00191 int client_status = client.init(); 00192 if (client_status != 0) { 00193 printf("Pelion Client initialization failed (%d)\n", client_status); 00194 return -1; 00195 } 00196 00197 // Creating resources, which can be written or read from the cloud 00198 res_button = client.create_resource("3200/0/5501", "Button Count"); 00199 res_button->set_value(0); 00200 res_button->methods(M2MMethod::GET); 00201 res_button->observable(true); 00202 res_button->attach_notification_callback(button_callback); 00203 00204 res_pattern_led = client.create_resource("3201/0/5853", "LED Pattern"); 00205 //res_pattern_led->set_value("500:500:500:500:500:500:500:500"); 00206 res_pattern_led->set_value("100:100:100:100:100:100:100:100"); 00207 res_pattern_led->methods(M2MMethod::GET | M2MMethod::PUT); 00208 res_pattern_led->attach_put_callback(pattern_updated); 00209 00210 res_post = client.create_resource("3201/0/5850", "Blink Action"); 00211 res_post->methods(M2MMethod::POST); 00212 res_post->attach_post_callback(eventQueue.event(&blink_callback)); 00213 00214 // Sensor resources 00215 res_temperature = client.create_resource("3303/0/5700", "Temperature (C)"); 00216 res_temperature->set_value(0); 00217 res_temperature->methods(M2MMethod::GET); 00218 res_temperature->observable(true); 00219 00220 res_voltage = client.create_resource("3316/0/5700", "Voltage"); 00221 res_voltage->set_value(0); 00222 res_voltage->methods(M2MMethod::GET); 00223 res_voltage->observable(true); 00224 00225 printf("Initialized Pelion Device Management Client. Registering...\n"); 00226 00227 // Callback that fires when registering is complete 00228 client.on_registered(®istered); 00229 00230 // Register with Pelion DM 00231 client.register_and_connect(); 00232 00233 // The button fires on an interrupt context, but debounces it to the eventqueue, so it's safe to do network operations 00234 button.fall(eventQueue.event(&button_press)); 00235 printf("Press the user button to increment the LwM2M resource value...\n"); 00236 00237 // The timer fires on an interrupt context, but debounces it to the eventqueue, so it's safe to do network operations 00238 Ticker timer; 00239 timer.attach(eventQueue.event(&sensors_update), SENSORS_POLL_INTERVAL); 00240 00241 // You can easily run the eventQueue in a separate thread if required 00242 eventQueue.dispatch_forever(); 00243 } 00244 00245 #endif /* MBED_TEST_MODE */
Generated on Wed Jul 13 2022 20:07:19 by
1.7.2