Audio Reactive Infinity Mirror
Dependencies: mbed-dsp mbed-rtos mbed
Infinity Mirror Project Page https://developer.mbed.org/users/mgolino/notebook/infinity-mirror/
Revision 0:85385a11b2da, committed 2015-12-12
- Comitter:
- mgolino
- Date:
- Sat Dec 12 01:22:30 2015 +0000
- Commit message:
- Audio Reactive Infinity Mirror
Changed in this revision
diff -r 000000000000 -r 85385a11b2da MCP23S17.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MCP23S17.lib Sat Dec 12 01:22:30 2015 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/stjo2809/code/MCP23S17/#f93b811965d8
diff -r 000000000000 -r 85385a11b2da arm_const_structs.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/arm_const_structs.h Sat Dec 12 01:22:30 2015 +0000 @@ -0,0 +1,86 @@ +/* ---------------------------------------------------------------------- +* Copyright (C) 2010-2013 ARM Limited. All rights reserved. +* +* $Date: 17. January 2013 +* $Revision: V1.4.1 +* +* Project: CMSIS DSP Library +* Title: arm_const_structs.h +* +* Description: This file has constant structs that are initialized for +* user convenience. For example, some can be given as +* arguments to the arm_cfft_f32() function. +* +* Target Processor: Cortex-M4/Cortex-M3 +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* - Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* - Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in +* the documentation and/or other materials provided with the +* distribution. +* - Neither the name of ARM LIMITED nor the names of its contributors +* may be used to endorse or promote products derived from this +* software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +* -------------------------------------------------------------------- */ + +#ifndef _ARM_CONST_STRUCTS_H +#define _ARM_CONST_STRUCTS_H + +#include "arm_math.h" +#include "arm_common_tables.h" + + const arm_cfft_instance_f32 arm_cfft_sR_f32_len16 = { + 16, twiddleCoef_16, armBitRevIndexTable16, ARMBITREVINDEXTABLE__16_TABLE_LENGTH + }; + + const arm_cfft_instance_f32 arm_cfft_sR_f32_len32 = { + 32, twiddleCoef_32, armBitRevIndexTable32, ARMBITREVINDEXTABLE__32_TABLE_LENGTH + }; + + const arm_cfft_instance_f32 arm_cfft_sR_f32_len64 = { + 64, twiddleCoef_64, armBitRevIndexTable64, ARMBITREVINDEXTABLE__64_TABLE_LENGTH + }; + + const arm_cfft_instance_f32 arm_cfft_sR_f32_len128 = { + 128, twiddleCoef_128, armBitRevIndexTable128, ARMBITREVINDEXTABLE_128_TABLE_LENGTH + }; + + const arm_cfft_instance_f32 arm_cfft_sR_f32_len256 = { + 256, twiddleCoef_256, armBitRevIndexTable256, ARMBITREVINDEXTABLE_256_TABLE_LENGTH + }; + + const arm_cfft_instance_f32 arm_cfft_sR_f32_len512 = { + 512, twiddleCoef_512, armBitRevIndexTable512, ARMBITREVINDEXTABLE_512_TABLE_LENGTH + }; + + const arm_cfft_instance_f32 arm_cfft_sR_f32_len1024 = { + 1024, twiddleCoef_1024, armBitRevIndexTable1024, ARMBITREVINDEXTABLE1024_TABLE_LENGTH + }; + + const arm_cfft_instance_f32 arm_cfft_sR_f32_len2048 = { + 2048, twiddleCoef_2048, armBitRevIndexTable2048, ARMBITREVINDEXTABLE2048_TABLE_LENGTH + }; + + const arm_cfft_instance_f32 arm_cfft_sR_f32_len4096 = { + 4096, twiddleCoef_4096, armBitRevIndexTable4096, ARMBITREVINDEXTABLE4096_TABLE_LENGTH + }; + +#endif +
diff -r 000000000000 -r 85385a11b2da ble_mini.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ble_mini.h Sat Dec 12 01:22:30 2015 +0000 @@ -0,0 +1,16 @@ +#ifndef _BLE_MINI_H +#define _BLE_MINI_H +#include "mbed.h" +//Command List +//valid port:1,2,3,4 +#define BLE_CONNECTED 0x00 +#define LIGHTS_OFF_SWITCH 0x01 +#define IR_SWITCH 0x02 +#define MIC_SWITCH 0x03 +#define AUX_SWITCH 0x04 +#define MANUAL_SWITCH 0x05 +#define STROBE_SPEED 0x06 +#define COLOR_SELECT 0x07 + +#endif +
diff -r 000000000000 -r 85385a11b2da fftstuff.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/fftstuff.cpp Sat Dec 12 01:22:30 2015 +0000 @@ -0,0 +1,312 @@ +#include "fftstuff.h" +#include <iostream> + +AnalogIn mic(p15); +AnalogIn aux(p20); +bool auxControl = false; +bool micControl = false; +float redColor, greenColor, blueColor; +// Integers used to cycle LED colors +int rIdx = 0; +int gIdx = 1; +int bIdx = 2; +Serial pc2(USBTX, USBRX); +PwmOut grled(p23); +PwmOut rrled(p22); +PwmOut brled(p21); +Ticker counter; +int i = 0; +int flipCount = 0; +//////////////////////////////////////////////////////////////////////////////// +// CONFIGURATION +// These values alter the behavior of the audio reaction. +//////////////////////////////////////////////////////////////////////////////// +int SLOWDOWN = 0; // Create an optical delay in spectrumLoop - useful when only one RGB led is used. + // Only active when nonzero. + // A value >= 1000 and <= 1000 + PIXEL_COUNT fixes the output to a single frequency + // window = a single color. +int SAMPLE_RATE_HZ = 6000; // Sample rate of the audio in hertz +float SPECTRUM_MIN_DB = 30.0; // Audio intensity (in decibels) that maps to low LED brightness => sensitive to quiet +float SPECTRUM_MAX_DB = 100.0; // Audio intensity (in decibels) that maps to high LED brightness => sensitive to loud +const int FFT_SIZE = 32; // Size of the FFT +const int PIXEL_COUNT = 3; // Number of pixels (1)R, (2)G, & (3)B for LED strip +// END CONFIGURATION + +//////////////////////////////////////////////////////////////////////////////// +// INTERNAL STATE +// These shouldn't be modified unless you know what you're doing. +//////////////////////////////////////////////////////////////////////////////// +const static arm_cfft_instance_f32 *S; +Ticker samplingTimer; +float samples[FFT_SIZE*2]; +float magnitudes[FFT_SIZE]; +int sampleCounter = 0; +float frequencyWindow[PIXEL_COUNT+1]; +float hues[PIXEL_COUNT]; +// END INTERNAL STATE + +//////////////////////////////////////////////////////////////////////////////// +// SAMPLING FUNCTIONS +//////////////////////////////////////////////////////////////////////////////// +// Read from the ADC and store the sample data +void samplingCallback() +{ + i++; + if(auxControl) { // Read aux input (pin 20) + samples[sampleCounter] = (1023 * aux) - 511.0f; + } + else if(micControl) { // Read mic input (pin 15) + samples[sampleCounter] = (1023 * mic) - 511.0f; + } + // Complex FFT functions require a coefficient for the imaginary part of the input. + // Since we only have real data, set this coefficient to zero. + samples[sampleCounter+1] = 0.0; + // Update sample buffer position and stop after the buffer is filled + sampleCounter += 2; + if (sampleCounter >= FFT_SIZE*2) { + samplingTimer.detach(); + } +} // End samplingCallBack + +// Begin sampling audio +void samplingBegin() +{ + // Reset sample buffer position and start callback at necessary rate. + sampleCounter = 0; + samplingTimer.attach_us(&samplingCallback, 1000000/SAMPLE_RATE_HZ); +} + +// Check if sampling is done before performing FFT +bool samplingIsDone() +{ + return sampleCounter >= FFT_SIZE*2; +} // End samplingIsDone +// END SAMPLING FUNCTIONS + +//////////////////////////////////////////////////////////////////////////////// +// FFT FUNCTIONS +// Used for performing FFT on audio signal +///////////////////////////////////////////////////////////////////////////////// +// Initialize FFT Size +void initFFT() +{ + switch (FFT_SIZE) { // Call appropriate FFT + case 16: + S = & arm_cfft_sR_f32_len16; + break; + case 32: + S = & arm_cfft_sR_f32_len32; + break; + case 64: + S = & arm_cfft_sR_f32_len64; + break; + case 128: + S = & arm_cfft_sR_f32_len128; + break; + case 256: + S = & arm_cfft_sR_f32_len256; + break; + case 512: + S = & arm_cfft_sR_f32_len512; + break; + case 1024: + S = & arm_cfft_sR_f32_len1024; + break; + case 2048: + S = & arm_cfft_sR_f32_len2048; + break; + case 4096: + S = & arm_cfft_sR_f32_len4096; + break; + } +} // End initFFT + +// Setup the frequency windowing size given sampling rate +void spectrumSetup() +{ + // Set the frequency window values by evenly dividing the possible frequency + float windowSize = (SAMPLE_RATE_HZ / 2.0) / float(PIXEL_COUNT); + for (int i = 0; i < PIXEL_COUNT+1; ++i) { + frequencyWindow[i] = i*windowSize; + } +} // End spectrumSetup + +// Convert a frequency to the appropriate FFT bin it will fall within +int frequencyToBin(float frequency) +{ + float binFrequency = float(SAMPLE_RATE_HZ) / float(FFT_SIZE); + return int(frequency / binFrequency); +} + +// Compute the average magnitude of a target frequency window vs. all other frequencies +void windowMean(float* magnitudes, int lowBin, int highBin, float* windowMean, float* otherMean) +{ + *windowMean = 0; + *otherMean = 0; + // Notice the first magnitude bin is skipped because it represents the average power of the signal + for (int i = 1; i < FFT_SIZE/2; ++i) { + // Sum values + if (i >= lowBin && i <= highBin) { + *windowMean += magnitudes[i]; + } else { + *otherMean += magnitudes[i]; + } + } + // Average values + *windowMean /= (highBin - lowBin) + 1; + *otherMean /= (FFT_SIZE / 2 - (highBin - lowBin)); +} + +// Update LED RGB values based on intensity of frequency window +void spectrumLoop() +{ + + // Update each LED color based on the audio intensity of each frequency window + float max = 0.0f; + static int SLrpt = 0; + static int SLpixcnt = 0; + int SLpixend = 0; + float intensity, otherMean; + if(SLOWDOWN != 0) + { + if(SLOWDOWN >= 1000) + { + if(SLOWDOWN <= (1000 + PIXEL_COUNT-1)) + { + SLpixcnt = SLOWDOWN - 1000; + SLrpt = 0; + SLpixend = SLpixcnt + 1; + } + else + SLOWDOWN = 0; + } + else + { + SLrpt++; + if (SLrpt >= SLOWDOWN) + { + SLrpt = 0; + SLpixcnt = SLpixcnt < PIXEL_COUNT-1 ? ++SLpixcnt : 0; + } + SLpixend = SLpixcnt + 1; + } + } + else + { + SLpixcnt = 0; + SLrpt = 0; + SLpixend = PIXEL_COUNT; + } + + for (int i = SLpixcnt; i < SLpixend; ++i) { + windowMean(magnitudes, + frequencyToBin(frequencyWindow[i]), + frequencyToBin(frequencyWindow[i+1]), + &intensity, + &otherMean); + // Convert intensity to decibels. + intensity = 20.0*log10(intensity); + //pc2.printf("INTENSITY1: %f\n\r", intensity); + // Scale the intensity and clamp between 0 and 1.0. + intensity -= SPECTRUM_MIN_DB; + //intensity = intensity < 0.0 ? 0.0 : intensity; + intensity /= (SPECTRUM_MAX_DB-SPECTRUM_MIN_DB); + intensity = intensity > 1.0 ? 1.0 : intensity; + //pc2.printf("INTENSITY2: %f\n\r", intensity); + + + if(intensity > max){ + max = intensity; + } + + + hues[i]=intensity; + } + //cout << "AUX VALUE" << mic << "\n\r" << endl; + //cout << "/n HUES: " << hues[0] << " " << hues[1] << " " << hues[2] << "\n\r" << endl; + redColor= hues[rIdx]; + greenColor= hues[gIdx]; + blueColor= hues[bIdx]; + + //pc2.printf("writing colors\n\r"); + //pc2.printf("!!!red %f, green %f, blue %f!!!\n\n\n\r", redColor, greenColor, blueColor); + rrled = hues[rIdx]/max; + grled= hues[gIdx]/max; + brled= hues[bIdx]/max; + // possible add Threading to make this function wait rather than SLOWDOWN +} + +//////////////////////////////////////////////////////////////////////////////// +// TIMING THREADS +//////////////////////////////////////////////////////////////////////////////// +// Cycle given frequency window controlling an LED color +////***************************************** +void flip() // add input argument for FFT processing +{ + rIdx++; + gIdx++; + bIdx++; + if(rIdx > 2){ + rIdx = 0; + } + if(gIdx > 2){ + gIdx = 0; + } + if(bIdx > 2){ + bIdx = 0; + } + // 4s wait time +} +////***************************************** + +void runFFT(bool input, float colors[]) +{ + //counter.attach(&flip, 4.0); + // Initialize frequency window size + spectrumSetup(); + //pc2.printf("hi"); + if (input == true){ + micControl = true; + auxControl = false; + } + else{ + micControl = false; + auxControl = true; + } + + + // Begin sampling audio + samplingBegin(); + //pc2.printf("sampling began\n"); + // Init arm_ccft_32 + initFFT(); + + //6000 HZ = check back for readable every 1/2 second + i = 0; + while(i< 3000){ + if (samplingIsDone()) { + // Run FFT on sample data. + arm_cfft_f32(S, samples, 0, 1); + // Calculate magnitude of complex numbers output by the FFT. + arm_cmplx_mag_f32(samples, magnitudes, FFT_SIZE); + spectrumLoop(); + // Restart audio sampling. + samplingBegin(); + } + } + + colors[0] = redColor; + colors[1] = greenColor; + colors[2] = blueColor; + flipCount++; + //shift colors around every 4 seconds + if (flipCount >= 8){ + flipCount = 0; + flip(); + } + + +} +// END FFT FUNCTIONS + +
diff -r 000000000000 -r 85385a11b2da fftstuff.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/fftstuff.h Sat Dec 12 01:22:30 2015 +0000 @@ -0,0 +1,6 @@ +#include "rtos.h" +#include "arm_math.h" +#include "arm_const_structs.h" +#include "mbed.h" + +void runFFT(bool input, float colors[3]);
diff -r 000000000000 -r 85385a11b2da main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Sat Dec 12 01:22:30 2015 +0000 @@ -0,0 +1,252 @@ +// ECE 4180 Final Project +// Fall 2015 +// Matthew Ashcraft 4th year EE +// Matthew Golino 5th year CE +// +// Bluetooth Controlled Audio Reactive Infinity Mirror + +#include "mbed.h" +#include "ble_mini.h" +#include <iostream> +#include "fftstuff.h" + +//////////////////////////////////////////////////////////////////////////////// +// MBED PIN DESIGNATION +// DO NOT change unless accompanying hardware is altered +//////////////////////////////////////////////////////////////////////////////// +// Analog +//AnalogIn mic(p15); // Analog input for the microphone +//AnalogIn aux(p20); // Analog input for the DC offset aux cable input +// PWM outputs for RGB LEDs +PwmOut gled(p23); +PwmOut rled(p22); +PwmOut bled(p21); +// Serial Interface for Mbed to PC +Serial pc(USBTX, USBRX); +// Serial Interface for Bluetooth Module to Mbed +Serial device(p9,p10); +// END MBED PIN DESIGNATION + +//////////////////////////////////////////////////////////////////////////////// +// GLOBAL VARIABLES +// Variables used across multiple functions, simpler than passing to functions +//////////////////////////////////////////////////////////////////////////////// + +char buf[4]; // Char buffer for bluetooth commands +// Boolean flags for audio sampling +bool AuxIn = false; +bool MicIn = false; +bool inputSelect = false; //false = aux --- true = mic +// Float variable used to write to LED PWM outputs +float redVal = -1; +float greenVal = -1; +float blueVal = -1; +// Float used to "save" previous values for manual writing +float redHold = -1; +float greenHold = -1; +float blueHold = -1; +//strobe values +float strobeVal = -1; +float strobeHold = 0; +// END GLOBAL VARIABLES + + +//////////////////////////////////////////////////////////////////////////////// +// LED WRITING FUNCTIONS +//////////////////////////////////////////////////////////////////////////////// +// Write stored RGB values to PWM outputs +void writeColors(float redVal, float greenVal, float blueVal, float strobeVal) +{ + if (strobeVal > 0) { + rled = 0; + gled = 0; + bled = 0; + wait(strobeVal); + } + if ((redVal >= 0) || (greenVal >= 0) || (blueVal >= 0)) { + rled = redVal; + gled = greenVal; + bled = blueVal; + } +} +// END LED WRITING FUNCTIONS + +int main() { + // Initialize frequency window size + // Set BLE mini baud rate + device.baud(57600); + // Floats used to "hold" RGB values +// float redHold = -1; +// float greenHold = -1; +// float blueHold = -1; + // Floats used to set and "hold" strobe setting + + while(1) { + if(device.readable()) { + // Read in Bluetooth commands + for(int i = 0; i < 4; i++){ + buf[i]=device.getc(); + pc.printf("%x ",buf[i]); + } + pc.printf("\n\r"); + pc.printf("done\n"); + + // Check cases for all different switch options based on buf[0]; + char whichInput = buf[0]; + // Check for Bluetooth Connectivity + if(whichInput == BLE_CONNECTED){ + pc.printf("case0\n\n"); + //pretty lights for connect + rled = 255; + wait(0.25); + rled=0; + gled=255; + wait(0.25); + gled=0; + bled=255; + wait(0.25); + bled=0; + } + else if(whichInput == LIGHTS_OFF_SWITCH){ // Manually turn off lights + pc.printf("Turning All Lights Off\n\n"); + strobeVal = -1; + if(buf[1]==0x01){ + redVal = 0.0f; + greenVal = 0.0f; + blueVal = 0.0f; + } + else if(buf[1]==0x00){ + redVal = -1.0f; + greenVal = -1.0f; + blueVal = -1.0f; + } + } + else if(whichInput == IR_SWITCH){ // React to IR remote + pc.printf("Listening to IR Remote\n\n"); + strobeVal = -1; + //TBD + + + } + + else if(whichInput == MIC_SWITCH){ // React to microphone audio input + pc.printf("Listening to Microphone for FFT\n\n"); + strobeVal = -1; + if(buf[1]==0x00){ //switched off + redVal = 0; + greenVal = 0; + blueVal = 0; + } + else if (buf[1]==0x01){ //switched on + //MicIn = true; //FALSE = MIC CONTROLS -- REMEMBER TO FIX IN CODE + inputSelect = true; + float colors[3] = {0.0f,0.0f,0.0f}; + + while(!device.readable()){ // done to improve speed => bypass long if statement + runFFT(inputSelect, colors); + redVal = colors[0]; + greenVal = colors[1]; + blueVal = colors[2];; + writeColors(redVal, greenVal, blueVal, strobeVal); + } + } + redVal = -1; + greenVal = -1; + blueVal = -1; + } + else if(whichInput == AUX_SWITCH){ // React to aux cable audio input + pc.printf("Listening to Aux for FFT\n\n"); + strobeVal = -1; + if(buf[1]==0x00){ //switched off + redVal = 0; + greenVal = 0; + blueVal = 0; + } + else if (buf[1]==0x01){ //switched on + inputSelect = false; + float colors[3] = {0.0f,0.0f,0.0f}; + + while(!device.readable()){ // done to improve speed => bypass long if statement + runFFT(inputSelect, colors); + redVal = colors[0]; + greenVal = colors[1]; + blueVal = colors[2];; + writeColors(redVal, greenVal, blueVal, strobeVal); + } + } + redVal = -1; + greenVal = -1; + blueVal = -1; + } + else if(whichInput == MANUAL_SWITCH){ // Manual color control + pc.printf("Colors are Being Controlled Manually\n\n"); + strobeVal = strobeHold; + if ((redVal < 0) && (redHold < 0)){ + redVal = 128.0f/255; + greenVal = 128.0f/255; + blueVal = 128.0f/255; + } + else{ + redVal = redHold; + greenVal = greenHold; + blueVal = blueHold; + } + + if(buf[1] == 0x00){ + redVal = -1; + greenVal = -1; + blueVal = -1; + } + } + else if(whichInput == STROBE_SPEED){ // Strobe feature for manual control + pc.printf("Strobe Speed Changed\n\n"); + float strobeSpeed = buf[1]; // Value 0-255 to be used in determining strobe speed + //determine how to control strobe + //pc.printf("Strobe rate: %f", strobeSpeed); + strobeVal = 0.35 - (strobeSpeed*0.35/255); + if(strobeSpeed == 0){ + strobeVal=0; + } + strobeHold = strobeVal; + } + else if(whichInput == COLOR_SELECT){ + pc.printf("case7\n\n"); + // Convert from hex to float + redVal = buf[1]; + greenVal = buf[2]; + blueVal = buf[3]; + + // Put in range from 0-1 + redVal=redVal/255; + greenVal=greenVal/255; + blueVal=blueVal/255; + + // Store for holding purposes + redHold = redVal; + greenHold = greenVal; + blueHold = blueVal; + } + else{ + pc.printf("CASE CONFUSED\n\n"); + } + } // End readable + + else { + //if we can detect BT or no BT + //if(//conditions for aux mode) + //else if (conditions for mic mode) + //else IR mode + + } // End !readable + + if(redVal < 0){ + writeColors(0,0,0,strobeVal); + } + else{ + writeColors(redVal, greenVal, blueVal, strobeVal); + } + + wait(0.1); + }// End while(1) loop +}// End main + \ No newline at end of file
diff -r 000000000000 -r 85385a11b2da mbed-dsp.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-dsp.lib Sat Dec 12 01:22:30 2015 +0000 @@ -0,0 +1,1 @@ +https://mbed.org/teams/mbed-official/code/mbed-dsp/#7a284390b0ce
diff -r 000000000000 -r 85385a11b2da mbed-rtos.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-rtos.lib Sat Dec 12 01:22:30 2015 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed-rtos/#d7bd06319118
diff -r 000000000000 -r 85385a11b2da mbed.bld --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Sat Dec 12 01:22:30 2015 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/165afa46840b \ No newline at end of file