Ram Gandikota / Mbed OS ABCD
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #include "utils.hpp"
00003 #include "stdio.h"
00004 
00005 #include "EthernetInterface.h"
00006 #include "frdm_client.hpp"
00007 
00008 #include "metronome.hpp"
00009 
00010 
00011 
00012 #define IOT_ENABLED
00013 
00014 namespace active_low
00015 {
00016   const bool on = false;
00017   const bool off = true;
00018 }
00019 
00020 RawSerial pc(USBTX, USBRX);
00021 
00022 DigitalOut g_led_red(LED1);
00023 DigitalOut g_led_green(LED2);
00024 DigitalOut g_led_blue(LED3);
00025 
00026 InterruptIn g_button_mode(SW3);
00027 InterruptIn g_button_tap(SW2);
00028 
00029 size_t prev_bpm =0,max_bpm=0, min_bpm=INT_MAX;
00030 bool min_changed = 0, max_changed =0, bpm_changed =0;
00031 uint8_t* buffIn = NULL;
00032 uint32_t sizeIn;
00033 
00034 Semaphore updates(0);
00035 
00036 Ticker status_ticker;
00037 void blinky(){
00038   
00039   g_led_green = !g_led_green;
00040   
00041   }
00042 metronome metronome_object;
00043 
00044 
00045 void metronome::start_timing(){
00046       m_timing = true;
00047       m_beat_count = 0;
00048       m_timer.start();
00049            
00050   }
00051   
00052 void metronome::stop_timing(){
00053       
00054       m_timing = false;
00055       m_timer.stop();
00056     size_t curr_bpm=0;
00057       curr_bpm = metronome_object.get_bpm();
00058       pc.printf("BPM:- %d",curr_bpm);
00059       bpm_changed = 1;
00060       if(curr_bpm < min_bpm){
00061             min_bpm = curr_bpm;
00062             min_changed =1;
00063         }
00064       if(curr_bpm > max_bpm){
00065           max_bpm = curr_bpm;
00066           max_changed = 1;
00067         }
00068       if (curr_bpm == 0){
00069           g_led_green = active_low::off;
00070         }else{
00071           //pc.printf("Blinky Call");
00072           size_t tempo = 60/curr_bpm;
00073           status_ticker.attach(blinky,tempo);
00074           }      
00075 }   
00076 void metronome::tap(){
00077       
00078       m_beats[m_beat_count++] = m_timer.read_us();
00079       pc.printf("%d\n",m_timer.read_us());
00080       
00081     
00082 } 
00083 size_t metronome::get_bpm() const {
00084      int i=0;
00085      size_t bpm=0;
00086      if(m_beat_count < 4){
00087          return prev_bpm;
00088       }else{          
00089             for(i=0;i<m_beat_count-1;i++){
00090                bpm = bpm + m_beats[i+1]-m_beats[i];
00091               } 
00092             bpm = (size_t) bpm/(m_beat_count-1);
00093             prev_bpm = (bpm * 0.00006);
00094             pc.printf("BPM Calc:- %d",prev_bpm);
00095             return prev_bpm;
00096         }
00097 } 
00098 
00099 void on_mode()
00100 {
00101   
00102   if(metronome_object.is_timing()){
00103         //Go to play mode
00104         //printf("playmode");
00105         g_led_red = active_low::off;
00106         g_led_green = active_low::on;
00107         metronome_object.stop_timing();
00108                 
00109 }else{
00110        //Go to learn mode
00111       // printf("learnmode");
00112        g_led_green = active_low::off;
00113        g_led_red = active_low::on;
00114        status_ticker.detach();
00115        metronome_object.start_timing();
00116 
00117       }
00118 }
00119 
00120 void on_tap()
00121 {
00122     // Receive a tempo tap
00123     if(metronome_object.is_timing()){
00124           metronome_object.tap();
00125       }    
00126 }
00127 
00128 
00129 /*Frequency Class  and related resources*/
00130 class FreqResource {
00131 public:
00132     FreqResource() {
00133         
00134 //        M2MObject* freq_object;
00135         freq_object = M2MInterfaceFactory::create_object("3318");
00136         M2MObjectInstance* freq_inst = freq_object->create_object_instance();
00137 
00138 
00139 // Why is it blinking only 4 time? - Ram
00140         // there's not really an execute LWM2M ID that matches... hmm...
00141         M2MResource* setValue_res = freq_inst->create_dynamic_resource("5900", "Set Value",
00142             M2MResourceInstance::FLOAT, true);
00143         // we allow executing a function here...
00144         setValue_res->set_operation(M2MBase::GET_PUT_ALLOWED);
00145         //setValue_res->set_value_updated_function(value_updated_callback2(this, &FreqResource::handle_put_bpm));
00146         setValue_res->set_execute_function(execute_callback (this, &FreqResource::handle_put_bpm));
00147         // Completion of execute function can take a time, that's why delayed response is used
00148         setValue_res->set_delayed_response(true);
00149         
00150         //Max BPM
00151          M2MResource* maxBPM_res = freq_inst->create_dynamic_resource("5602", "Max BPM",
00152             M2MResourceInstance::FLOAT, true);
00153             
00154         // we allow executing a function here...
00155         maxBPM_res->set_operation(M2MBase::GET_ALLOWED);
00156     
00157         // Completion of execute function can take a time, that's why delayed response is used
00158        // maxBPM_res->set_delayed_response(true);
00159         
00160         //Min BPM
00161          M2MResource* minBPM_res = freq_inst->create_dynamic_resource("5601", "Min BPM",
00162             M2MResourceInstance::FLOAT, true);
00163         // we allow executing a function here...
00164         minBPM_res->set_operation(M2MBase::GET_ALLOWED);
00165     
00166         // Completion of execute function can take a time, that's why delayed response is used
00167         //minBPM_res->set_delayed_response(true);
00168         
00169         //Reset Min/Max
00170          M2MResource* resetBPM_res = freq_inst->create_dynamic_resource("5605", "Reset Min/Max BPM",
00171             M2MResourceInstance::STRING, true);
00172         // we allow executing a function here...
00173         resetBPM_res->set_operation(M2MBase::POST_ALLOWED);        
00174         resetBPM_res->set_execute_function(execute_callback (this, &FreqResource::handle_reset_minMax_bpm));
00175         // Completion of execute function can take a time, that's why delayed response is used
00176         resetBPM_res->set_delayed_response(true);
00177         
00178         //Units
00179          M2MResource* unitsBPM_res = freq_inst->create_dynamic_resource("5701", "Units",
00180             M2MResourceInstance::STRING, true);
00181         // we allow executing a function here...
00182         unitsBPM_res->set_operation(M2MBase::GET_ALLOWED);
00183         // Completion of execute function can take a time, that's why delayed response is used
00184         //unitsBPM_res->set_delayed_response(true);
00185         unitsBPM_res->set_value((uint8_t*)"BPM",3);
00186     }
00187     
00188 
00189     ~FreqResource() {
00190         
00191     }
00192 
00193    void handle_put_bpm(void *argument){
00194         
00195         status_ticker.detach();
00196         M2MObjectInstance* inst = freq_object->object_instance();
00197         M2MResource* setValue_res = inst->resource("5900");
00198 
00199         // values in mbed Client are all buffers, and we need a vector of int's
00200         setValue_res->get_value(buffIn, sizeIn);
00201         
00202         int temp=0;
00203             for(int i=0;i<sizeIn;i++){
00204             temp=temp*10+(int)buffIn[i]-48;
00205             }
00206         prev_bpm=temp;
00207             
00208       if(prev_bpm < min_bpm)
00209       {
00210             min_bpm = prev_bpm;
00211             min_changed =1;
00212         }
00213       if(prev_bpm > max_bpm)
00214       {
00215           max_bpm = prev_bpm;
00216           max_changed = 1;
00217         }
00218         size_t tempo = 60/prev_bpm;
00219         status_ticker.attach(blinky,tempo);
00220           
00221         bpm_changed = 1; 
00222    }
00223    
00224    void handle_set_bpm(){
00225        
00226       M2MObjectInstance* inst = freq_object->object_instance();
00227         M2MResource* setValue_res = inst->resource("5900");
00228         
00229         char buffer[20];
00230         int size = sprintf(buffer,"%d",prev_bpm);
00231         setValue_res->set_value((uint8_t*)buffer, size);
00232       
00233       }
00234       
00235     void handle_set_min_bpm(){
00236       //Send a notification
00237       M2MObjectInstance* inst = freq_object->object_instance();
00238         M2MResource* minBPM_res = inst->resource("5601");
00239         pc.printf("%d",min_bpm);
00240         char buffer[20];
00241         int size = sprintf(buffer,"%d",min_bpm);
00242         minBPM_res->set_value((uint8_t*)buffer, size);
00243        
00244       
00245       }
00246     void handle_set_max_bpm(){
00247       //Send a notification
00248       M2MObjectInstance* inst = freq_object->object_instance();
00249         M2MResource* maxBPM_res = inst->resource("5602");
00250         
00251         char buffer[20];
00252         int size = sprintf(buffer,"%d",max_bpm);
00253         maxBPM_res->set_value((uint8_t*)buffer, size);
00254        
00255       
00256       }
00257     
00258     void handle_reset_minMax_bpm(void *argument){
00259       //Handle request to reset the min_max values to zero and 1000000 each
00260            
00261          M2MObjectInstance* inst = freq_object->object_instance();
00262          M2MResource* minBPM_res = inst->resource("5601");
00263          M2MResource* maxBPM_res = inst->resource("5602");
00264 
00265                minBPM_res->set_value(0);
00266                maxBPM_res->set_value(0);               
00267           }       
00268       
00269     M2MObject* get_object() {
00270         return freq_object;
00271     }
00272 
00273 private:
00274     M2MObject* freq_object;
00275 };
00276 
00277 int main()
00278 {
00279   // Seed the RNG for networking purposes
00280     unsigned seed = utils::entropy_seed();
00281     srand(seed);
00282 
00283   // LEDs are active LOW - true/1 means off, false/0 means on
00284   // Use the constants for easier reading
00285     g_led_red = active_low::off;
00286     g_led_green = active_low::off;
00287     g_led_blue = active_low::off;
00288     
00289 
00290   // Button falling edge is on push (rising is on release)
00291     g_button_mode.fall(&on_mode);
00292     g_button_tap.fall(&on_tap);
00293 
00294 #ifdef IOT_ENABLED
00295   // Turn on the blue LED until connected to the network
00296    // g_led_blue = active_low::off;
00297 
00298 
00299   // Need to be connected with Ethernet cable for success
00300     EthernetInterface ethernet;
00301     if (ethernet.connect() != 0)
00302         return 1;
00303 
00304   // Pair with the device connector
00305     frdm_client client("coap://api.connector.mbed.com:5684", &ethernet);
00306     if (client.get_state() == frdm_client::state::error)
00307         return 1;
00308 
00309   // The REST endpoints for this device
00310   // Add your own M2MObjects to this list with push_back before client.connect()
00311     M2MObjectList objects;
00312     
00313     //Frequency device definition and instance definition
00314     FreqResource freq_resource;         
00315 
00316     M2MDevice* device = frdm_client::make_device();
00317     objects.push_back(device);
00318     objects.push_back(freq_resource.get_object());
00319     
00320   // Publish the RESTful endpoints
00321     client.connect(objects);
00322 
00323   // Connect complete; turn off blue LED forever
00324     //g_led_blue = active_low::on;
00325     
00326 #endif
00327 
00328     while (true)
00329     {
00330       //updates.wait(25000);
00331 #ifdef IOT_ENABLED
00332         if (client.get_state() == frdm_client::state::error)
00333             break;
00334 #endif
00335 
00336         // Insert any code that must be run continuously here
00337         if(bpm_changed){
00338            bpm_changed = 0;
00339            freq_resource.handle_set_bpm();
00340           }
00341           
00342         if(min_changed) {
00343            min_changed = 0;
00344             freq_resource.handle_set_min_bpm();
00345         }
00346         if(max_changed) {
00347            max_changed = 0;
00348             freq_resource.handle_set_max_bpm();
00349         }
00350         
00351     }
00352 
00353 #ifdef IOT_ENABLED
00354     client.disconnect();
00355 #endif
00356     return 1;
00357 }