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 "LittleFileSystem.h" 00023 00024 // Default network interface object. Don't forget to change the WiFi SSID/password in mbed_app.json if you're using WiFi. 00025 NetworkInterface *net; 00026 00027 // Default block device available on the target board 00028 BlockDevice* bd = BlockDevice::get_default_instance(); 00029 SlicingBlockDevice sd(bd, 0, 2*1024*1024); 00030 00031 #if COMPONENT_SD || COMPONENT_NUSD 00032 // Use FATFileSystem for SD card type blockdevices 00033 FATFileSystem fs("fs"); 00034 #else 00035 // Use LittleFileSystem for non-SD block devices to enable wear leveling and other functions 00036 LittleFileSystem fs("fs"); 00037 #endif 00038 00039 // Default User button for GET example and for resetting the storage 00040 InterruptIn button(BUTTON1); 00041 // Default LED to use for PUT/POST example 00042 DigitalOut led(LED1, 1); 00043 00044 // How often to fetch sensor data (in seconds) 00045 #define SENSORS_POLL_INTERVAL 3.0 00046 00047 // Send all sensor data or just limited (useful for when running out of memory) 00048 #define SEND_ALL_SENSORS 00049 00050 // Sensors related includes and initialization 00051 00052 00053 //static DevI2C devI2c(PB_11,PB_10); 00054 static DigitalOut shutdown_pin(PC_6); 00055 // Temperature reading from microcontroller 00056 AnalogIn adc_temp(ADC_TEMP); 00057 // Voltage reference reading from microcontroller 00058 AnalogIn adc_vref(ADC_VREF); 00059 00060 // Declaring pointers for access to Pelion Client resources outside of main() 00061 MbedCloudClientResource *res_button; 00062 MbedCloudClientResource *res_led; 00063 00064 // Additional resources for sensor readings 00065 #ifdef SEND_ALL_SENSORS 00066 MbedCloudClientResource *res_adc_temp; 00067 MbedCloudClientResource *res_adc_voltage; 00068 #endif /* SEND_ALL_SENSORS */ 00069 00070 // An event queue is a very useful structure to debounce information between contexts (e.g. ISR and normal threads) 00071 // 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 00072 EventQueue eventQueue; 00073 00074 // When the device is registered, this variable will be used to access various useful information, like device ID etc. 00075 static const ConnectorClientEndpointInfo* endpointInfo; 00076 00077 /** 00078 * PUT handler 00079 * @param resource The resource that triggered the callback 00080 * @param newValue Updated value for the resource 00081 */ 00082 void put_callback(MbedCloudClientResource *resource, m2m::String newValue) { 00083 printf("*** PUT received, new value: %s \n", newValue.c_str()); 00084 led = atoi(newValue.c_str()); 00085 } 00086 00087 /** 00088 * POST handler 00089 * @param resource The resource that triggered the callback 00090 * @param buffer If a body was passed to the POST function, this contains the data. 00091 * Note that the buffer is deallocated after leaving this function, so copy it if you need it longer. 00092 * @param size Size of the body 00093 */ 00094 void post_callback(MbedCloudClientResource *resource, const uint8_t *buffer, uint16_t size) { 00095 printf("*** POST received (length %u). Payload: ", size); 00096 for (size_t ix = 0; ix < size; ix++) { 00097 printf("%02x ", buffer[ix]); 00098 } 00099 printf("\n"); 00100 } 00101 00102 /** 00103 * Button function triggered by the physical button press. 00104 */ 00105 void button_press() { 00106 int v = res_button->get_value_int() + 1; 00107 res_button->set_value(v); 00108 printf("*** Button clicked %d times \n", v); 00109 } 00110 00111 /** 00112 * Notification callback handler 00113 * @param resource The resource that triggered the callback 00114 * @param status The delivery status of the notification 00115 */ 00116 void button_callback(MbedCloudClientResource *resource, const NoticationDeliveryStatus status) { 00117 printf("*** Button notification, status %s (%d) \n", MbedCloudClientResource::delivery_status_to_string(status), status); 00118 } 00119 00120 /** 00121 * Registration callback handler 00122 * @param endpoint Information about the registered endpoint such as the name (so you can find it back in portal) 00123 */ 00124 void registered(const ConnectorClientEndpointInfo *endpoint) { 00125 printf("Registered to Pelion Device Management. Endpoint Name: %s\n", endpoint->internal_endpoint_name.c_str()); 00126 endpointInfo = endpoint; 00127 } 00128 00129 /** 00130 * Initialize sensors 00131 */ 00132 void sensors_init() { 00133 00134 printf ("\nSensors configuration:\n"); 00135 // Initialize sensors 00136 00137 // Call sensors enable routines 00138 00139 printf("\n"); ; 00140 } 00141 00142 /** 00143 * Update sensors and report their values. 00144 * This function is called periodically. 00145 */ 00146 void sensors_update() { 00147 float temp3_value, volt_value = 0.0; 00148 00149 temp3_value = adc_temp.read()*100; 00150 volt_value = adc_vref.read(); 00151 00152 printf(" \n"); 00153 printf("ADC temp: %5.4f C, vref: %5.4f V \n", temp3_value, volt_value); 00154 00155 if (endpointInfo) { 00156 #ifdef SEND_ALL_SENSORS 00157 res_adc_temp->set_value(temp3_value); 00158 res_adc_voltage->set_value(volt_value); 00159 #endif /* SEND_ALL_SENSORS */ 00160 } 00161 } 00162 00163 int main(void) { 00164 printf("\nStarting Simple Pelion Device Management Client example\n"); 00165 00166 int storage_status = fs.mount(&sd); 00167 if (storage_status != 0) { 00168 printf("Storage mounting failed.\n"); 00169 } 00170 // If the User button is pressed ons start, then format storage. 00171 bool btn_pressed = (button.read() == MBED_CONF_APP_BUTTON_PRESSED_STATE); 00172 if (btn_pressed) { 00173 printf("User button is pushed on start...\n"); 00174 } 00175 00176 if (storage_status || btn_pressed) { 00177 printf("Formatting the storage...\n"); 00178 int storage_status = StorageHelper::format(&fs, &sd); 00179 if (storage_status != 0) { 00180 printf("ERROR: Failed to reformat the storage (%d).\n", storage_status); 00181 } 00182 } else { 00183 printf("You can hold the user button during boot to format the storage and change the device identity.\n"); 00184 } 00185 00186 sensors_init(); 00187 00188 // Connect to the internet (DHCP is expected to be on) 00189 printf("Connecting to the network using Wifi...\n"); 00190 net = NetworkInterface::get_default_instance(); 00191 00192 nsapi_error_t net_status = -1; 00193 for (int tries = 0; tries < 3; tries++) { 00194 net_status = net->connect(); 00195 if (net_status == NSAPI_ERROR_OK) { 00196 break; 00197 } else { 00198 printf("Unable to connect to network. Retrying...\n"); 00199 } 00200 } 00201 00202 if (net_status != NSAPI_ERROR_OK) { 00203 printf("ERROR: Connecting to the network failed (%d)!\n", net_status); 00204 return -1; 00205 } 00206 00207 printf("Connected to the network successfully. IP address: %s\n", net->get_ip_address()); 00208 00209 printf("Initializing Pelion Device Management Client...\n"); 00210 00211 // SimpleMbedCloudClient handles registering over LwM2M to Pelion DM 00212 SimpleMbedCloudClient client(net, bd, &fs); 00213 int client_status = client.init(); 00214 if (client_status != 0) { 00215 printf("ERROR: Pelion Client initialization failed (%d)\n", client_status); 00216 return -1; 00217 } 00218 00219 // Creating resources, which can be written or read from the cloud 00220 res_button = client.create_resource("3200/0/5501", "Button Count"); 00221 res_button->set_value(0); 00222 res_button->methods(M2MMethod::GET); 00223 res_button->observable(true); 00224 res_button->attach_notification_callback(button_callback); 00225 00226 res_led = client.create_resource("3201/0/5853", "LED State"); 00227 res_led->set_value(1); 00228 res_led->methods(M2MMethod::GET | M2MMethod::PUT); 00229 res_led->attach_put_callback(put_callback); 00230 00231 #ifdef SEND_ALL_SENSORS 00232 // Sensor resources 00233 res_adc_temp = client.create_resource("3303/2/5700", "Temperature ADC (C)"); 00234 res_adc_temp->set_value(0); 00235 res_adc_temp->methods(M2MMethod::GET); 00236 res_adc_temp->observable(true); 00237 00238 res_adc_voltage = client.create_resource("3316/0/5700", "Voltage"); 00239 res_adc_voltage->set_value(0); 00240 res_adc_voltage->methods(M2MMethod::GET); 00241 res_adc_voltage->observable(true); 00242 00243 #endif /* SEND_ALL_SENSORS */ 00244 00245 printf("Initialized Pelion Client. Registering...\n"); 00246 00247 // Callback that fires when registering is complete 00248 client.on_registered(®istered); 00249 00250 // Register with Pelion DM 00251 client.register_and_connect(); 00252 00253 int i = 600; // wait up 60 seconds before attaching sensors and button events 00254 while (i-- > 0 && !client.is_client_registered()) { 00255 wait_ms(100); 00256 } 00257 00258 button.fall(eventQueue.event(&button_press)); 00259 00260 // The timer fires on an interrupt context, but debounces it to the eventqueue, so it's safe to do network operations 00261 Ticker timer; 00262 timer.attach(eventQueue.event(&sensors_update), SENSORS_POLL_INTERVAL); 00263 00264 // You can easily run the eventQueue in a separate thread if required 00265 eventQueue.dispatch_forever(); 00266 } 00267 00268 #endif
Generated on Wed Jul 13 2022 21:27:13 by
1.7.2