Toyomasa Watarai / Mbed OS mbed-cloud-connect-example-esp8266

Fork of mbed-cloud-connect-example-ethernet by NXP

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

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 
00019 #include "mbed.h"
00020 #include "simple-mbed-cloud-client.h"
00021 #include "SDBlockDevice.h"
00022 #include "FATFileSystem.h"
00023 #include "ESP8266Interface.h"
00024 #include "MMA7660.h"
00025 #include "LM75B.h"
00026 
00027 #define WIFI_SSID "SSID"
00028 #define WIFI_PSWD "PASSWORD"
00029 
00030 // An event queue is a very useful structure to debounce information between contexts (e.g. ISR and normal threads)
00031 // 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
00032 EventQueue eventQueue;
00033 Thread thread1;
00034 
00035 // Storage implementation definition, currently using SDBlockDevice (SPI flash, DataFlash, and internal flash are also available)
00036 /* K64 & K66 */
00037 InterruptIn sw2(SW2);
00038 DigitalOut led2(LED2);
00039 
00040 SDBlockDevice sd(PTE3, PTE1, PTE2, PTE4);
00041 FATFileSystem fs("sd", &sd);
00042 ESP8266Interface net(D1, D0);
00043 LM75B lm75b(I2C_SDA, I2C_SCL);     // temperature
00044 MMA7660 mma7660(I2C_SDA, I2C_SCL); // accel
00045 
00046 const int NUM_AXIS = 3;
00047 
00048 // Declaring pointers for access to Mbed Cloud Client resources outside of main()
00049 MbedCloudClientResource *button_res;
00050 MbedCloudClientResource *pattern_res;
00051 MbedCloudClientResource *temp_res;
00052 MbedCloudClientResource *temp_unit_res;    
00053 MbedCloudClientResource *accel_res[NUM_AXIS];
00054 MbedCloudClientResource *acc_unit_res;
00055 
00056 static bool button_pressed = false;
00057 static int button_count = 0;
00058 
00059 void button_press()
00060 {
00061     button_pressed = true;
00062     ++button_count;
00063     button_res->set_value(button_count);
00064 }
00065 
00066 /**
00067  * PUT handler
00068  * @param resource The resource that triggered the callback
00069  * @param newValue Updated value for the resource
00070  */
00071 void pattern_updated(MbedCloudClientResource *resource, m2m::String newValue)
00072 {
00073     printf("PUT received, new value: %s\n", newValue.c_str());
00074 }
00075 
00076 /**
00077  * POST handler
00078  * @param resource The resource that triggered the callback
00079  * @param buffer If a body was passed to the POST function, this contains the data.
00080  *               Note that the buffer is deallocated after leaving this function, so copy it if you need it longer.
00081  * @param size Size of the body
00082  */
00083 void blink_callback(MbedCloudClientResource *resource, const uint8_t *buffer, uint16_t size)
00084 {
00085     printf("POST received. Going to blink LED pattern: %s\n", pattern_res->get_value().c_str());
00086 
00087     static DigitalOut augmentedLed(LED1); // LED that is used for blinking the pattern
00088 
00089     // Parse the pattern string, and toggle the LED in that pattern
00090     string s = std::string(pattern_res->get_value().c_str());
00091     size_t i = 0;
00092     size_t pos = s.find(':');
00093     while (pos != string::npos) {
00094         wait_ms(atoi(s.substr(i, pos - i).c_str()));
00095         augmentedLed = !augmentedLed;
00096 
00097         i = ++pos;
00098         pos = s.find(':', pos);
00099 
00100         if (pos == string::npos) {
00101             wait_ms(atoi(s.substr(i, s.length()).c_str()));
00102             augmentedLed = !augmentedLed;
00103         }
00104     }
00105 }
00106 
00107 /**
00108  * Notification callback handler
00109  * @param resource The resource that triggered the callback
00110  * @param status The delivery status of the notification
00111  */
00112 void button_callback(MbedCloudClientResource *resource, const NoticationDeliveryStatus status)
00113 {
00114     printf("Button notification, status %s (%d)\n", MbedCloudClientResource::delivery_status_to_string(status), status);
00115 }
00116 
00117 void temp_callback(MbedCloudClientResource *resource, const NoticationDeliveryStatus status)
00118 {
00119     printf("Temperature notification, status %s (%d)\n", MbedCloudClientResource::delivery_status_to_string(status), status);
00120 }
00121 
00122 void accel_callback(MbedCloudClientResource *resource, const NoticationDeliveryStatus status)
00123 {
00124     printf("Accelerometer notification, status %s (%d)\n", MbedCloudClientResource::delivery_status_to_string(status), status);
00125 }
00126 
00127 void measure_sensors()
00128 {
00129     float temperature, acc[3];
00130     const unsigned int buf_size = 20;
00131     char buf[buf_size];
00132 
00133     mma7660.readData(acc);
00134     for(int i=0; i < NUM_AXIS; i++) {
00135         snprintf(buf, buf_size, "%f", acc[i]);
00136         accel_res[i]->set_value(buf);
00137     }
00138     printf("acc: %f,%f,%f\n", acc[0], acc[1], acc[2]);
00139 
00140     temperature = lm75b.read();
00141     snprintf(buf, buf_size, "%f", temperature);
00142     temp_res->set_value(buf);
00143     printf("temp: %s\n", buf);
00144 }
00145 
00146 /**
00147  * Registration callback handler
00148  * @param endpoint Information about the registered endpoint such as the name (so you can find it back in portal)
00149  */
00150 void registered(const ConnectorClientEndpointInfo *endpoint)
00151 {
00152     printf("Connected to Mbed Cloud. Endpoint Name: %s\n", endpoint->internal_endpoint_name.c_str());
00153 }
00154 
00155 int main(void)
00156 {
00157     printf("Starting Simple Mbed Cloud Client example\n");
00158     printf("Connecting to the network using Wi-Fi...\n");
00159 
00160     // Connect to the internet (DHCP is expected to be on)
00161     nsapi_error_t status = net.connect(WIFI_SSID, WIFI_PSWD, NSAPI_SECURITY_WPA_WPA2);
00162 
00163     if (status != 0) {
00164         printf("Connecting to the network failed %d!\n", status);
00165         return -1;
00166     }
00167 
00168     printf("Connected to the network successfully. IP address: %s\n", net.get_ip_address());
00169 
00170     // SimpleMbedCloudClient handles registering over LwM2M to Mbed Cloud
00171     SimpleMbedCloudClient client(&net, &sd, &fs);
00172     int client_status = client.init();
00173     if (client_status != 0) {
00174         printf("Initializing Mbed Cloud Client failed (%d)\n", client_status);
00175         return -1;
00176     }
00177 
00178     // Creating resources, which can be written or read from the cloud
00179     button_res = client.create_resource("3200/0/5501", "button_count");
00180     button_res->set_value(0);
00181     button_res->methods(M2MMethod::GET);
00182     button_res->observable(true);
00183     button_res->attach_notification_callback(button_callback);
00184 
00185     pattern_res = client.create_resource("3201/0/5853", "blink_pattern");
00186     pattern_res->set_value("500:500:500:500:500:500:500:500");
00187     pattern_res->methods(M2MMethod::GET | M2MMethod::PUT);
00188     pattern_res->attach_put_callback(pattern_updated);
00189 
00190     MbedCloudClientResource *blink_res = client.create_resource("3201/0/5850", "blink_action");
00191     blink_res->methods(M2MMethod::POST);
00192     blink_res->attach_post_callback(blink_callback);
00193     
00194     temp_res = client.create_resource("3303/0/5700", "temperature");
00195     temp_res->set_value("0");
00196     temp_res->methods(M2MMethod::GET);
00197     temp_res->attach_notification_callback(temp_callback);
00198     temp_res->observable(true);
00199 
00200     temp_unit_res = client.create_resource("3303/0/5701", "unit");
00201     temp_unit_res->set_value("Cel");
00202     
00203     accel_res[0] = client.create_resource("3313/0/5702", "accel_x");
00204     accel_res[1] = client.create_resource("3313/0/5703", "accel_y");
00205     accel_res[2] = client.create_resource("3313/0/5704", "accel_z");
00206 
00207     for (int i=0; i < NUM_AXIS; i++) {
00208         accel_res[i]->set_value(0);
00209         accel_res[i]->methods(M2MMethod::GET);
00210         accel_res[i]->attach_notification_callback(accel_callback);
00211         accel_res[i]->observable(true);
00212     }
00213 
00214     acc_unit_res = client.create_resource("3313/0/5701", "unit");
00215     acc_unit_res->set_value("G");
00216     
00217     printf("Initialized Mbed Cloud Client. Registering...\n");
00218 
00219     // Callback that fires when registering is complete
00220     client.on_registered(&registered);
00221 
00222     // Register with Mbed Cloud
00223     client.register_and_connect();
00224 
00225     // Setup the button
00226     sw2.mode(PullUp);
00227 
00228     // The button fall handler is placed in the event queue so it will run in
00229     // thread context instead of ISR context, which allows safely updating the cloud resource
00230     sw2.fall(eventQueue.event(&button_press));
00231     button_count = 0;
00232 
00233     // Placeholder for callback to update local resource when GET comes.
00234     // The timer fires on an interrupt context, but debounces it to the eventqueue, so it's safe to do network operations
00235     Ticker timer;
00236     timer.attach(eventQueue.event(&measure_sensors), 5.0);
00237 
00238     // Start the event queue in a separate thread so the main thread continues
00239     thread1.start(callback(&eventQueue, &EventQueue::dispatch_forever));
00240 
00241     while(1) {
00242         wait_ms(100);
00243 
00244         if (button_pressed) {
00245             button_pressed = false;
00246             printf("button clicked %d times\r\n", button_count);
00247         }
00248 
00249     }
00250 }