Simple Mbed Cloud client application using features of K64F including Wi-Fi and SD Card

Dependencies:   LM75B MMA7660

Committer:
MACRUM
Date:
Wed Jul 04 06:04:43 2018 +0000
Revision:
11:354983151a8e
Parent:
9:9fade4bb2774
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
MarceloSalazar 0:e13a8a944e25 1 // ----------------------------------------------------------------------------
MarceloSalazar 9:9fade4bb2774 2 // Copyright 2016-2018 ARM Ltd.
MarceloSalazar 0:e13a8a944e25 3 //
MarceloSalazar 0:e13a8a944e25 4 // SPDX-License-Identifier: Apache-2.0
MarceloSalazar 0:e13a8a944e25 5 //
MarceloSalazar 0:e13a8a944e25 6 // Licensed under the Apache License, Version 2.0 (the "License");
MarceloSalazar 0:e13a8a944e25 7 // you may not use this file except in compliance with the License.
MarceloSalazar 0:e13a8a944e25 8 // You may obtain a copy of the License at
MarceloSalazar 0:e13a8a944e25 9 //
MarceloSalazar 0:e13a8a944e25 10 // http://www.apache.org/licenses/LICENSE-2.0
MarceloSalazar 0:e13a8a944e25 11 //
MarceloSalazar 0:e13a8a944e25 12 // Unless required by applicable law or agreed to in writing, software
MarceloSalazar 0:e13a8a944e25 13 // distributed under the License is distributed on an "AS IS" BASIS,
MarceloSalazar 0:e13a8a944e25 14 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
MarceloSalazar 0:e13a8a944e25 15 // See the License for the specific language governing permissions and
MarceloSalazar 0:e13a8a944e25 16 // limitations under the License.
MarceloSalazar 0:e13a8a944e25 17 // ----------------------------------------------------------------------------
MarceloSalazar 0:e13a8a944e25 18
MarceloSalazar 1:1ccf36276cd3 19 #include "mbed.h"
MarceloSalazar 0:e13a8a944e25 20 #include "simple-mbed-cloud-client.h"
MarceloSalazar 1:1ccf36276cd3 21 #include "SDBlockDevice.h"
MarceloSalazar 1:1ccf36276cd3 22 #include "FATFileSystem.h"
MACRUM 11:354983151a8e 23 #include "ESP8266Interface.h"
MACRUM 11:354983151a8e 24 #include "MMA7660.h"
MACRUM 11:354983151a8e 25 #include "LM75B.h"
MACRUM 11:354983151a8e 26
MACRUM 11:354983151a8e 27 #define WIFI_SSID "SSID"
MACRUM 11:354983151a8e 28 #define WIFI_PASSWORD "PASSWORD"
MarceloSalazar 1:1ccf36276cd3 29
MarceloSalazar 9:9fade4bb2774 30 // An event queue is a very useful structure to debounce information between contexts (e.g. ISR and normal threads)
MarceloSalazar 9:9fade4bb2774 31 // 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
MarceloSalazar 9:9fade4bb2774 32 EventQueue eventQueue;
MACRUM 11:354983151a8e 33 Thread thread1;
MACRUM 11:354983151a8e 34
MACRUM 11:354983151a8e 35 InterruptIn sw2(SW2);
MACRUM 11:354983151a8e 36 DigitalOut led2(LED2);
MarceloSalazar 0:e13a8a944e25 37
MarceloSalazar 9:9fade4bb2774 38 // Storage implementation definition, currently using SDBlockDevice (SPI flash, DataFlash, and internal flash are also available)
bridadan 5:c18fab181ede 39 SDBlockDevice sd(PTE3, PTE1, PTE2, PTE4);
MarceloSalazar 9:9fade4bb2774 40 FATFileSystem fs("sd", &sd);
MACRUM 11:354983151a8e 41 ESP8266Interface net(D1, D0);
MACRUM 11:354983151a8e 42 LM75B lm75b(I2C_SDA, I2C_SCL); // temperature
MACRUM 11:354983151a8e 43 MMA7660 mma7660(I2C_SDA, I2C_SCL); // accel
MACRUM 11:354983151a8e 44
MACRUM 11:354983151a8e 45 const int NUM_AXIS = 3;
bridadan 5:c18fab181ede 46
MarceloSalazar 9:9fade4bb2774 47 // Declaring pointers for access to Mbed Cloud Client resources outside of main()
MarceloSalazar 9:9fade4bb2774 48 MbedCloudClientResource *button_res;
MarceloSalazar 9:9fade4bb2774 49 MbedCloudClientResource *pattern_res;
MACRUM 11:354983151a8e 50 MbedCloudClientResource *temp_res;
MACRUM 11:354983151a8e 51 MbedCloudClientResource *temp_unit_res;
MACRUM 11:354983151a8e 52 MbedCloudClientResource *accel_res[NUM_AXIS];
MACRUM 11:354983151a8e 53 MbedCloudClientResource *acc_unit_res;
MarceloSalazar 0:e13a8a944e25 54
MACRUM 11:354983151a8e 55 static bool button_pressed = false;
MACRUM 11:354983151a8e 56 static int button_count = 0;
MarceloSalazar 0:e13a8a944e25 57
MACRUM 11:354983151a8e 58 void button_press()
MACRUM 11:354983151a8e 59 {
MACRUM 11:354983151a8e 60 button_pressed = true;
MACRUM 11:354983151a8e 61 ++button_count;
MACRUM 11:354983151a8e 62 button_res->set_value(button_count);
MarceloSalazar 1:1ccf36276cd3 63 }
MarceloSalazar 1:1ccf36276cd3 64
MarceloSalazar 9:9fade4bb2774 65 /**
MarceloSalazar 9:9fade4bb2774 66 * PUT handler
MarceloSalazar 9:9fade4bb2774 67 * @param resource The resource that triggered the callback
MarceloSalazar 9:9fade4bb2774 68 * @param newValue Updated value for the resource
MarceloSalazar 9:9fade4bb2774 69 */
MarceloSalazar 9:9fade4bb2774 70 void pattern_updated(MbedCloudClientResource *resource, m2m::String newValue) {
MarceloSalazar 9:9fade4bb2774 71 printf("PUT received, new value: %s\n", newValue.c_str());
MarceloSalazar 0:e13a8a944e25 72 }
MarceloSalazar 0:e13a8a944e25 73
MarceloSalazar 9:9fade4bb2774 74 /**
MarceloSalazar 9:9fade4bb2774 75 * POST handler
MarceloSalazar 9:9fade4bb2774 76 * @param resource The resource that triggered the callback
MarceloSalazar 9:9fade4bb2774 77 * @param buffer If a body was passed to the POST function, this contains the data.
MarceloSalazar 9:9fade4bb2774 78 * Note that the buffer is deallocated after leaving this function, so copy it if you need it longer.
MarceloSalazar 9:9fade4bb2774 79 * @param size Size of the body
MarceloSalazar 9:9fade4bb2774 80 */
MarceloSalazar 9:9fade4bb2774 81 void blink_callback(MbedCloudClientResource *resource, const uint8_t *buffer, uint16_t size) {
MarceloSalazar 9:9fade4bb2774 82 printf("POST received. Going to blink LED pattern: %s\n", pattern_res->get_value().c_str());
MarceloSalazar 9:9fade4bb2774 83
MarceloSalazar 9:9fade4bb2774 84 static DigitalOut augmentedLed(LED1); // LED that is used for blinking the pattern
MarceloSalazar 0:e13a8a944e25 85
MarceloSalazar 9:9fade4bb2774 86 // Parse the pattern string, and toggle the LED in that pattern
MarceloSalazar 9:9fade4bb2774 87 string s = std::string(pattern_res->get_value().c_str());
MarceloSalazar 9:9fade4bb2774 88 size_t i = 0;
MarceloSalazar 9:9fade4bb2774 89 size_t pos = s.find(':');
MarceloSalazar 9:9fade4bb2774 90 while (pos != string::npos) {
MarceloSalazar 9:9fade4bb2774 91 wait_ms(atoi(s.substr(i, pos - i).c_str()));
MarceloSalazar 9:9fade4bb2774 92 augmentedLed = !augmentedLed;
MarceloSalazar 9:9fade4bb2774 93
MarceloSalazar 9:9fade4bb2774 94 i = ++pos;
MarceloSalazar 9:9fade4bb2774 95 pos = s.find(':', pos);
MarceloSalazar 9:9fade4bb2774 96
MarceloSalazar 9:9fade4bb2774 97 if (pos == string::npos) {
MarceloSalazar 9:9fade4bb2774 98 wait_ms(atoi(s.substr(i, s.length()).c_str()));
MarceloSalazar 9:9fade4bb2774 99 augmentedLed = !augmentedLed;
MarceloSalazar 9:9fade4bb2774 100 }
MarceloSalazar 9:9fade4bb2774 101 }
MarceloSalazar 0:e13a8a944e25 102 }
MarceloSalazar 0:e13a8a944e25 103
MarceloSalazar 9:9fade4bb2774 104 /**
MarceloSalazar 9:9fade4bb2774 105 * Notification callback handler
MarceloSalazar 9:9fade4bb2774 106 * @param resource The resource that triggered the callback
MarceloSalazar 9:9fade4bb2774 107 * @param status The delivery status of the notification
MarceloSalazar 9:9fade4bb2774 108 */
MarceloSalazar 9:9fade4bb2774 109 void button_callback(MbedCloudClientResource *resource, const NoticationDeliveryStatus status) {
MarceloSalazar 9:9fade4bb2774 110 printf("Button notification, status %s (%d)\n", MbedCloudClientResource::delivery_status_to_string(status), status);
MarceloSalazar 9:9fade4bb2774 111 }
MarceloSalazar 1:1ccf36276cd3 112
MACRUM 11:354983151a8e 113 void temp_callback(MbedCloudClientResource *resource, const NoticationDeliveryStatus status)
MACRUM 11:354983151a8e 114 {
MACRUM 11:354983151a8e 115 printf("Temperature notification, status %s (%d)\n", MbedCloudClientResource::delivery_status_to_string(status), status);
MACRUM 11:354983151a8e 116 }
MACRUM 11:354983151a8e 117
MACRUM 11:354983151a8e 118 void accel_callback(MbedCloudClientResource *resource, const NoticationDeliveryStatus status)
MACRUM 11:354983151a8e 119 {
MACRUM 11:354983151a8e 120 printf("Accelerometer notification, status %s (%d)\n", MbedCloudClientResource::delivery_status_to_string(status), status);
MACRUM 11:354983151a8e 121 }
MACRUM 11:354983151a8e 122
MACRUM 11:354983151a8e 123 void measure_sensors()
MACRUM 11:354983151a8e 124 {
MACRUM 11:354983151a8e 125 float temperature, acc[3];
MACRUM 11:354983151a8e 126 const unsigned int buf_size = 20;
MACRUM 11:354983151a8e 127 char buf[buf_size];
MACRUM 11:354983151a8e 128
MACRUM 11:354983151a8e 129 mma7660.readData(acc);
MACRUM 11:354983151a8e 130 for(int i=0; i < NUM_AXIS; i++) {
MACRUM 11:354983151a8e 131 snprintf(buf, buf_size, "%f", acc[i]);
MACRUM 11:354983151a8e 132 accel_res[i]->set_value(buf);
MACRUM 11:354983151a8e 133 }
MACRUM 11:354983151a8e 134 printf("acc: %f,%f,%f\n", acc[0], acc[1], acc[2]);
MACRUM 11:354983151a8e 135
MACRUM 11:354983151a8e 136 temperature = lm75b.read();
MACRUM 11:354983151a8e 137 snprintf(buf, buf_size, "%f", temperature);
MACRUM 11:354983151a8e 138 temp_res->set_value(buf);
MACRUM 11:354983151a8e 139 printf("temp: %s\n", buf);
MACRUM 11:354983151a8e 140 }
MACRUM 11:354983151a8e 141
MarceloSalazar 9:9fade4bb2774 142 /**
MarceloSalazar 9:9fade4bb2774 143 * Registration callback handler
MarceloSalazar 9:9fade4bb2774 144 * @param endpoint Information about the registered endpoint such as the name (so you can find it back in portal)
MarceloSalazar 9:9fade4bb2774 145 */
MarceloSalazar 9:9fade4bb2774 146 void registered(const ConnectorClientEndpointInfo *endpoint) {
MarceloSalazar 9:9fade4bb2774 147 printf("Connected to Mbed Cloud. Endpoint Name: %s\n", endpoint->internal_endpoint_name.c_str());
MarceloSalazar 9:9fade4bb2774 148 }
MarceloSalazar 1:1ccf36276cd3 149
MarceloSalazar 9:9fade4bb2774 150 int main(void) {
MarceloSalazar 9:9fade4bb2774 151 printf("Starting Simple Mbed Cloud Client example\n");
MACRUM 11:354983151a8e 152 printf("Connecting to the network using Wi-Fi...\n");
MarceloSalazar 9:9fade4bb2774 153
MarceloSalazar 9:9fade4bb2774 154 // Connect to the internet (DHCP is expected to be on)
MACRUM 11:354983151a8e 155 nsapi_error_t status = net.connect(WIFI_SSID, WIFI_PASSWORD, NSAPI_SECURITY_WPA2);
MarceloSalazar 9:9fade4bb2774 156
MarceloSalazar 9:9fade4bb2774 157 if (status != 0) {
MarceloSalazar 9:9fade4bb2774 158 printf("Connecting to the network failed %d!\n", status);
MarceloSalazar 1:1ccf36276cd3 159 return -1;
MarceloSalazar 1:1ccf36276cd3 160 }
MarceloSalazar 0:e13a8a944e25 161
MarceloSalazar 9:9fade4bb2774 162 printf("Connected to the network successfully. IP address: %s\n", net.get_ip_address());
MarceloSalazar 1:1ccf36276cd3 163
MarceloSalazar 9:9fade4bb2774 164 // SimpleMbedCloudClient handles registering over LwM2M to Mbed Cloud
MarceloSalazar 9:9fade4bb2774 165 SimpleMbedCloudClient client(&net, &sd, &fs);
MarceloSalazar 9:9fade4bb2774 166 int client_status = client.init();
MarceloSalazar 9:9fade4bb2774 167 if (client_status != 0) {
MarceloSalazar 9:9fade4bb2774 168 printf("Initializing Mbed Cloud Client failed (%d)\n", client_status);
MarceloSalazar 1:1ccf36276cd3 169 return -1;
MarceloSalazar 1:1ccf36276cd3 170 }
MarceloSalazar 1:1ccf36276cd3 171
MarceloSalazar 9:9fade4bb2774 172 // Creating resources, which can be written or read from the cloud
MarceloSalazar 9:9fade4bb2774 173 button_res = client.create_resource("3200/0/5501", "button_count");
MarceloSalazar 9:9fade4bb2774 174 button_res->set_value(0);
MarceloSalazar 9:9fade4bb2774 175 button_res->methods(M2MMethod::GET);
MarceloSalazar 9:9fade4bb2774 176 button_res->observable(true);
MarceloSalazar 9:9fade4bb2774 177 button_res->attach_notification_callback(button_callback);
MarceloSalazar 0:e13a8a944e25 178
MarceloSalazar 9:9fade4bb2774 179 pattern_res = client.create_resource("3201/0/5853", "blink_pattern");
MarceloSalazar 9:9fade4bb2774 180 pattern_res->set_value("500:500:500:500:500:500:500:500");
MarceloSalazar 9:9fade4bb2774 181 pattern_res->methods(M2MMethod::GET | M2MMethod::PUT);
MarceloSalazar 9:9fade4bb2774 182 pattern_res->attach_put_callback(pattern_updated);
MarceloSalazar 0:e13a8a944e25 183
MarceloSalazar 9:9fade4bb2774 184 MbedCloudClientResource *blink_res = client.create_resource("3201/0/5850", "blink_action");
MarceloSalazar 9:9fade4bb2774 185 blink_res->methods(M2MMethod::POST);
MarceloSalazar 9:9fade4bb2774 186 blink_res->attach_post_callback(blink_callback);
MarceloSalazar 9:9fade4bb2774 187
MACRUM 11:354983151a8e 188 temp_res = client.create_resource("3303/0/5700", "temperature");
MACRUM 11:354983151a8e 189 temp_res->set_value("0");
MACRUM 11:354983151a8e 190 temp_res->methods(M2MMethod::GET);
MACRUM 11:354983151a8e 191 temp_res->attach_notification_callback(temp_callback);
MACRUM 11:354983151a8e 192 temp_res->observable(true);
MACRUM 11:354983151a8e 193
MACRUM 11:354983151a8e 194 temp_unit_res = client.create_resource("3303/0/5701", "unit");
MACRUM 11:354983151a8e 195 temp_unit_res->set_value("Cel");
MACRUM 11:354983151a8e 196
MACRUM 11:354983151a8e 197 accel_res[0] = client.create_resource("3313/0/5702", "accel_x");
MACRUM 11:354983151a8e 198 accel_res[1] = client.create_resource("3313/0/5703", "accel_y");
MACRUM 11:354983151a8e 199 accel_res[2] = client.create_resource("3313/0/5704", "accel_z");
MACRUM 11:354983151a8e 200
MACRUM 11:354983151a8e 201 for (int i=0; i < NUM_AXIS; i++) {
MACRUM 11:354983151a8e 202 accel_res[i]->set_value(0);
MACRUM 11:354983151a8e 203 accel_res[i]->methods(M2MMethod::GET);
MACRUM 11:354983151a8e 204 accel_res[i]->attach_notification_callback(accel_callback);
MACRUM 11:354983151a8e 205 accel_res[i]->observable(true);
MACRUM 11:354983151a8e 206 }
MACRUM 11:354983151a8e 207
MACRUM 11:354983151a8e 208 acc_unit_res = client.create_resource("3313/0/5701", "unit");
MACRUM 11:354983151a8e 209 acc_unit_res->set_value("G");
MACRUM 11:354983151a8e 210
MarceloSalazar 9:9fade4bb2774 211 printf("Initialized Mbed Cloud Client. Registering...\n");
MarceloSalazar 0:e13a8a944e25 212
MarceloSalazar 9:9fade4bb2774 213 // Callback that fires when registering is complete
MarceloSalazar 9:9fade4bb2774 214 client.on_registered(&registered);
MarceloSalazar 0:e13a8a944e25 215
MarceloSalazar 9:9fade4bb2774 216 // Register with Mbed Cloud
MarceloSalazar 9:9fade4bb2774 217 client.register_and_connect();
bridadan 6:254a7e7fbef1 218
MACRUM 11:354983151a8e 219 // Setup the button
MACRUM 11:354983151a8e 220 sw2.mode(PullUp);
MACRUM 11:354983151a8e 221
MACRUM 11:354983151a8e 222 // The button fall handler is placed in the event queue so it will run in
MACRUM 11:354983151a8e 223 // thread context instead of ISR context, which allows safely updating the cloud resource
MACRUM 11:354983151a8e 224 sw2.fall(eventQueue.event(&button_press));
MACRUM 11:354983151a8e 225 button_count = 0;
MACRUM 11:354983151a8e 226
bridadan 6:254a7e7fbef1 227 // Placeholder for callback to update local resource when GET comes.
MarceloSalazar 9:9fade4bb2774 228 // The timer fires on an interrupt context, but debounces it to the eventqueue, so it's safe to do network operations
MarceloSalazar 9:9fade4bb2774 229 Ticker timer;
MACRUM 11:354983151a8e 230 timer.attach(eventQueue.event(&measure_sensors), 5.0);
MACRUM 11:354983151a8e 231
MACRUM 11:354983151a8e 232 // Start the event queue in a separate thread so the main thread continues
MACRUM 11:354983151a8e 233 thread1.start(callback(&eventQueue, &EventQueue::dispatch_forever));
MACRUM 11:354983151a8e 234
MACRUM 11:354983151a8e 235 while(1) {
MACRUM 11:354983151a8e 236 wait_ms(100);
MarceloSalazar 1:1ccf36276cd3 237
MACRUM 11:354983151a8e 238 if (button_pressed) {
MACRUM 11:354983151a8e 239 button_pressed = false;
MACRUM 11:354983151a8e 240 printf("button clicked %d times\r\n", button_count);
MACRUM 11:354983151a8e 241 }
MACRUM 11:354983151a8e 242
MACRUM 11:354983151a8e 243 }
MACRUM 11:354983151a8e 244
MarceloSalazar 0:e13a8a944e25 245 }