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.
Dependencies: mbed Socket lwip-eth lwip-sys lwip
Fork of 6_songs-from-the-cloud by
main.cpp
00001 /* 00002 * Copyright (c) 2015 ARM Limited. All rights reserved. 00003 * SPDX-License-Identifier: Apache-2.0 00004 * Licensed under the Apache License, Version 2.0 (the License); you may 00005 * not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an AS IS BASIS, WITHOUT 00012 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #include "mbed.h" // this tells us to load mbed OS related functions 00018 #include "tones.h" // list of all the tones and their frequencies 00019 #include "simpleclient.h" 00020 #include <string> 00021 #include <sstream> 00022 #include <vector> 00023 00024 Serial output(USBTX, USBRX); 00025 00026 PwmOut buzzer(D3); // our buzzer is a PWM output (pulse-width modulation) 00027 00028 static int BPM = 35; 00029 00030 EthernetInterface eth; 00031 00032 // These are example resource values for the Device Object 00033 struct MbedClientDevice device = { 00034 "Manufacturer_String", // Manufacturer 00035 "Type_String", // Type 00036 "ModelNumber_String", // ModelNumber 00037 "SerialNumber_String" // SerialNumber 00038 }; 00039 00040 // Instantiate the class which implements LWM2M Client API (from simpleclient.h) 00041 MbedClient mbed_client(device); 00042 00043 // this is our function that plays a tone. 00044 // Takes in a tone frequency, and after duration (in ms.) we stop playing again 00045 static void playTone(int tone, int duration) { 00046 00047 buzzer.period_us(1000000/tone); //period in us 00048 buzzer.write(0.10f); // 10% duty cycle, otherwise it's too loud 00049 wait_us(1000*duration/2); //play for half the length 00050 buzzer.write(0.0f); 00051 wait_us(1000*duration/2); //silence for half the length 00052 00053 } 00054 00055 static void play_song(std::vector<int>* melody, std::vector<int>* duration) { 00056 00057 output.printf("play_song\n\r"); 00058 for (int i = 0; i < melody->size(); i++) { 00059 int tone = melody->at(0); 00060 // BPM is quarter notes per minute, so length in milliseconds is: 00061 int length = static_cast<int>(static_cast<float>(1000 / duration->at(0)) * (60000.0f / static_cast<float>(BPM * 1000))); 00062 00063 // printf("tone %d, length %d, duration %d\r\n", tone, length, duration->at(0)); 00064 00065 if (melody->at(i) != 0) { 00066 playTone(melody->at(i), length); 00067 } 00068 else { 00069 buzzer = 0.0f; 00070 wait_ms(length); 00071 } 00072 } 00073 } 00074 00075 00076 /* 00077 * The buzzer contains two properties (notes, duration) and a function (play). 00078 * When the function play_song_from_cloud is executed, the notes and duration patterns are read, 00079 * and the song will be played. 00080 */ 00081 class BuzzerResource { 00082 public: 00083 BuzzerResource() { 00084 // create ObjectID with metadata tag of 'buzzer', which is not defined by the LWM2M standard but we can use it for this demo 00085 buzzer_object = M2MInterfaceFactory::create_object("buzzer"); 00086 M2MObjectInstance* buzzer_inst = buzzer_object->create_object_instance(); 00087 00088 // notes resource 00089 M2MResource* notes_res = buzzer_inst->create_dynamic_resource("notes", "", 00090 M2MResourceInstance::STRING, true); //observable 00091 00092 // read and write 00093 notes_res->set_operation(M2MBase::GET_PUT_ALLOWED); 00094 00095 // set initial pattern 00096 char notes_buffer[100]; 00097 int notes_size = sprintf(notes_buffer,"262:277"); 00098 00099 notes_res->set_value((const uint8_t*)notes_buffer, 00100 (uint32_t)notes_size); 00101 00102 // duration resource 00103 M2MResource* duration_res = buzzer_inst->create_dynamic_resource("duration", "", 00104 M2MResourceInstance::STRING, true); //observable 00105 00106 duration_res->set_operation(M2MBase::GET_PUT_ALLOWED); 00107 00108 // set initial pattern 00109 char dur_buffer[100]; 00110 int dur_size = sprintf(dur_buffer,"4:4"); 00111 00112 duration_res->set_value((const uint8_t*)dur_buffer, 00113 (uint32_t)dur_size); 00114 00115 // play resource 00116 M2MResource* play_res = buzzer_inst->create_dynamic_resource("play", "", 00117 M2MResourceInstance::STRING, false); //not observable 00118 00119 play_res->set_operation(M2MBase::POST_ALLOWED); 00120 00121 play_res->set_execute_function(execute_callback (this, &BuzzerResource::play_song_cloud)); 00122 00123 00124 } 00125 00126 M2MObject* get_object() { 00127 return buzzer_object; 00128 } 00129 00130 /*TODO - move the actual call to play_song_cloud to the main function, to avoid 00131 running it in interrupt context. Use a flag or semaphore set by the callback and checked for 00132 in the main function */ 00133 00134 void play_song_cloud(void *) { 00135 00136 output.printf("play song cloud triggered!\r\n"); 00137 00138 // read the object storing resources 'notes' and 'duration' 00139 M2MObjectInstance* inst = buzzer_object->object_instance(); 00140 00141 M2MResource* n_res = inst->resource("notes"); 00142 00143 // values in mbed Client are all buffers, and we need a vector of int's 00144 uint8_t* n_buffIn = NULL; 00145 uint32_t n_sizeIn; 00146 n_res->get_value(n_buffIn, n_sizeIn); 00147 00148 output.printf("notes = %s\n\r",n_buffIn); 00149 00150 std::stringstream notesPattern((char*)n_buffIn, n_sizeIn); 00151 00152 std::vector<int>* notes = new std::vector<int>; 00153 { 00154 std::string n_item; 00155 while (std::getline(notesPattern, n_item, ':')) { 00156 notes->push_back(atoi((const char*)n_item.c_str())); 00157 } 00158 } 00159 00160 M2MResource* d_res = inst->resource("duration"); 00161 00162 // values in mbed Client are all buffers, and we need a vector of int's 00163 uint8_t* d_buffIn = NULL; 00164 uint32_t d_sizeIn; 00165 00166 d_res->get_value(d_buffIn, d_sizeIn); 00167 00168 output.printf("durations = %s\n\r",d_buffIn); 00169 00170 //TODO: investigate why passing in d_sizeIn causes it to think there are always 0 durations 00171 //std::stringstream durationPattern((char*)d_buffIn, d_sizeIn); 00172 std::stringstream durationPattern((char*)d_buffIn, 100); 00173 00174 std::vector<int>* durations = new std::vector<int>; 00175 { 00176 std::string d_item; 00177 while (std::getline(durationPattern, d_item, ':')) { 00178 durations->push_back(atoi((const char*)d_item.c_str())); 00179 } 00180 } 00181 00182 if (notes->size() != durations->size()) { 00183 output.printf("Notes and duration have different sizes (%d vs %d), abort!\r\n", notes->size(), durations->size()); 00184 return; 00185 } 00186 00187 play_song(notes, durations); 00188 } 00189 00190 private: 00191 M2MObject* buzzer_object; 00192 00193 00194 }; 00195 00196 // Entry point to the program 00197 int main() { 00198 00199 green = 1; // turn green off 00200 00201 // This sets up the network interface configuration which will be used 00202 // by LWM2M Client API to communicate with mbed Device server. 00203 eth.init(); //Use DHCP 00204 eth.connect(); 00205 00206 output.printf("[ETH] IP address %s\r\n", eth.getIPAddress()); 00207 output.printf("[ETH] Device name %s\r\n", MBED_ENDPOINT_NAME); 00208 00209 // Create LWM2M Client API interface to manage register and unregister 00210 mbed_client.create_interface(); 00211 00212 // Create resource for interactions between the device and server 00213 BuzzerResource * buzzer_resource = new BuzzerResource(); 00214 00215 // Create LWM2M server object specifying mbed device server 00216 // information. 00217 M2MSecurity* register_object = mbed_client.create_register_object(); 00218 00219 // Add all the objects that you would like to register 00220 // into the list and pass the list for register API. 00221 M2MObjectList object_list; 00222 object_list.push_back(buzzer_resource->get_object()); 00223 00224 mbed_client.set_register_object(register_object); 00225 00226 // Register with mbed Device Connector 00227 mbed_client.test_register(register_object, object_list); 00228 00229 //TODO: should check for play command received and play song from main 00230 // to avoid doing too much in interrupt context. 00231 00232 while (true) { 00233 00234 wait_ms(25000); //wait 25 seconds 00235 output.printf("Updating registration\n\r"); 00236 mbed_client.test_update_register(); //update registration 00237 00238 } 00239 00240 } 00241
Generated on Tue Jul 12 2022 12:47:48 by
1.7.2
