aquarium light controller wannabe
Dependencies: DS3231 FastPWM Menu QEI TextLCD _24LCXXX mbed
Revision 0:0b9548db2291, committed 2015-03-05
- Comitter:
- rakware
- Date:
- Thu Mar 05 17:40:21 2015 +0000
- Child:
- 1:b0e2b4fdeb12
- Commit message:
- initial commit
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DS3231.lib Thu Mar 05 17:40:21 2015 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/cromda/code/DS3231/#6718c4fabf95
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/FastPWM.lib Thu Mar 05 17:40:21 2015 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/Sissors/code/FastPWM/#ba7a5bf634b3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Menu.lib Thu Mar 05 17:40:21 2015 +0000 @@ -0,0 +1,1 @@ +http://developer.mbed.org/users/rakware/code/Menu/#742c6553f5f7
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/QEI.lib Thu Mar 05 17:40:21 2015 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/aberk/code/QEI/#5c2ad81551aa
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TextLCD.lib Thu Mar 05 17:40:21 2015 +0000 @@ -0,0 +1,1 @@ +http://developer.mbed.org/users/rakware/code/TextLCD/#7509320b22a5
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/_24LCXXX.lib Thu Mar 05 17:40:21 2015 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/bant62/code/_24LCXXX/#859387a87312
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Thu Mar 05 17:40:21 2015 +0000 @@ -0,0 +1,630 @@ +#include "mbed.h" +#include "TextLCD.h" +#include "QEI.h" +#include "Menu.h" +#include "FastPWM.h" +#include "DS3231.h" +#include "_24LCXXX.h" + + +Serial pc(USBTX, USBRX); //DEBUG +DigitalOut myled(LED1); //DEBUG + +// I2C Bus +I2C i2c(PB_4, PA_8); // SDA, SCL + +TextLCD_I2C lcd(&i2c, PCF8574_SA7); +_24LCXXX eeprom(&i2c, 0x57); +DS3231 rtc(PB_4, PA_8); +//End I2C BUS + +QEI qei(PH_0, PH_1, NC, 80, QEI::X4_ENCODING); //Index is NC(see QEI class), we use PC_13 as digital input +DigitalIn qei_idx(PC_13); + +bool qei_pb() //check and debounces qei_idx +{ + int check = qei_idx; + wait_us(5); + if((!check) && !qei_idx) { + return true; + } else return false; +} + +//PA_11 = ESP SERIAL!!! +FastPWM Pwm_Array[] = {PA_7,PA_5,PA_6,PB_6,PA_9,PB_3,PB_5,PB_7,PA_10,PB_10,PC_8,PB_8,PA_11,PC_9,PB_9}; + +//Ticker Pwm_Ticker[sizeof(Pwm_Array)/sizeof(FastPWM)]; +Ticker Sunrise_Ticker; +Ticker Sunset_Ticker; + +//uint8_t Pwm_Min_Max_Array[sizeof(Pwm_Array)/sizeof(FastPWM)][1][2] = { +// { {0, 100} }, +// { {20, 80} }, +// { {0, 100} }, +// { {0, 100} }, +// { {0, 100} }, +// { {0, 100} }, +// { {0, 100} }, +// { {0, 100} }, +// { {0, 100} }, +// { {0, 100} }, +// { {0, 100} }, +// { {0, 100} }, +// { {0, 100} }, +// { {0, 100} }, +// { {0, 100} } +//}; + +uint8_t Pwm_Min_Max_Array[sizeof(Pwm_Array)/sizeof(FastPWM)][2] = { + {0, 100}, + {20, 80}, + {0, 100}, + {0, 100}, + {0, 100}, + {0, 100}, + {0, 100}, + {0, 100}, + {0, 100}, + {0, 100}, + {0, 100}, + {0, 100}, + {0, 100}, + {0, 100}, + {0, 100} +}; + +int pwm_idx = 0; + +uint8_t SunRiseSet[2][2] = {{0,1},{21,9}}; + +uint8_t ramptime = 1; //in minutes + +bool refresh_display = true; + +enum { IDLE, + MAIN, + SETTINGS, + PWM_MIN, + PWM_MAX, + SUNRISE, + SUNSET, + RAMPTIME, + SUNRISE_HOUR, + SUNRISE_MINUTE, + SUNSET_HOUR, + SUNSET_MINUTE, + SET_DATE_TIME, + SET_DATE_DAY, + SET_DATE_MONTH, + SET_DATE_YEAR, + SET_TIME_HOUR, + SET_TIME_MINUTE, + SET_TIME_SECOND + } menu_state = MAIN ; // Initial state = MAIN ; + +int cursorPos = 0; +Menu *activeMenu; + +//struct tm *t; //read time +struct tm t; //mktime + +Ticker qei_t; //ticker for qei_cb() + +void qei_cb() +{ + if(qei.getCurrentState() == 3 && qei.getPulses() < 0) { //one tab left + refresh_display = true; + switch (menu_state) { + case SETTINGS: + cursorPos--; + if (cursorPos < 0) + cursorPos = activeMenu->selections.size()-1; + break; + case PWM_MIN: + if (Pwm_Min_Max_Array[cursorPos][0] > 0) + Pwm_Min_Max_Array[cursorPos][0]--; + break; + case PWM_MAX: + if (Pwm_Min_Max_Array[cursorPos][1] > 0) + Pwm_Min_Max_Array[cursorPos][1]--; + break; + case RAMPTIME: + ramptime--; + break; + case SUNRISE_HOUR: + SunRiseSet[0][0]--; + break; + case SUNRISE_MINUTE: + SunRiseSet[0][1]--; + break; + case SUNSET_HOUR: + SunRiseSet[1][0]--; + break; + case SUNSET_MINUTE: + SunRiseSet[1][1]--; + break; + } + qei.reset(); + } else if(qei.getCurrentState() == 3 && qei.getPulses() > 0) { //one tab right + refresh_display = true; + switch (menu_state) { + case SETTINGS: + cursorPos++; + if (cursorPos >= activeMenu->selections.size()) + cursorPos = 0; + break; + case PWM_MIN: + if (Pwm_Min_Max_Array[cursorPos][0] < 100) + Pwm_Min_Max_Array[cursorPos][0]++; + break; + case PWM_MAX: + if (Pwm_Min_Max_Array[cursorPos][1] < 100) + Pwm_Min_Max_Array[cursorPos][1]++; + break; + case RAMPTIME: + ramptime++; + break; + case SUNRISE_HOUR: + SunRiseSet[0][0]++; + break; + case SUNRISE_MINUTE: + SunRiseSet[0][1]++; + break; + case SUNSET_HOUR: + SunRiseSet[1][0]++; + break; + case SUNSET_MINUTE: + SunRiseSet[1][1]++; + break; + } + qei.reset(); + } + + if(qei_pb()) { //button press + Timer qei_pb_t; + if (qei_pb_t.read() == 0) { + qei_pb_t.start(); + } + while(qei_pb()) { //check long press + if(qei_pb_t.read() > 1) { + qei_pb_t.stop(); + pc.printf("long press");//do stuff on long press + refresh_display = true; + lcd.cls(); + lcd.locate(0,0); + lcd.printf("%s", activeMenu->menuID); + lcd.locate(0,1); + lcd.printf("%s", activeMenu->selections[cursorPos].selText); + + menu_state = SETTINGS; + wait(0.5); + } + } + if(qei_pb_t.read() < 1) { + qei_pb_t.stop(); + //do stuff on short press + pc.printf("short press"); + refresh_display = true; + switch (menu_state) { + case MAIN: + break; + case SETTINGS: + pc.printf("apasat SETTINGS\n"); + if(activeMenu->selections[cursorPos].fun != NULL) { + (activeMenu->selections[cursorPos].fun)(); + } + if(activeMenu->selections[cursorPos].childMenu != NULL) { + activeMenu = activeMenu->selections[cursorPos].childMenu; + cursorPos = 0; + } + // print_menu(); + wait(0.2); + break; + case PWM_MIN: + menu_state = SETTINGS; + wait(0.2); + break; + case PWM_MAX: + menu_state = SETTINGS; + wait(0.2); + break; + case SUNRISE: + wait(0.2); + menu_state = SUNRISE_HOUR; + break; + case SUNRISE_HOUR: + wait(0.2); + menu_state = SUNRISE_MINUTE; + break; + case SUNSET: + wait(0.2); + menu_state = SUNSET_HOUR; + break; + case SUNSET_HOUR: + wait(0.2); + menu_state = SUNSET_MINUTE; + break; + default: + menu_state = SETTINGS; + wait(0.2); + break; + } + wait(0.2); + } + } +} + +void exit_settings() +{ +// menu_state = SAVE_SETTINGS; +// lcd.locate(0,1); +// lcd.printf("<N SAVE Y>"); + menu_state = MAIN; +} + +void pwm_min() +{ + menu_state = PWM_MIN; +} + +void pwm_max() +{ + menu_state = PWM_MAX; +} + +void sun_rise() +{ + menu_state = SUNRISE; +} + +void sun_set() +{ + menu_state = SUNSET; +} + +void ramp_time() +{ + menu_state = RAMPTIME; +} + +void set_date_time() +{ + menu_state = SET_DATE_TIME; +} + +// void inc() { +// _pin = _pin + 0.01/8.0; // 0.01 = 1% => 0.125% increments, if you modify this you need to modify 'ramp/8' too +// } +// void dec() { +// _pin = _pin - 0.01/8.0; +// } + +//void bl(uint8_t pwmnameArray[10][3], PwmOut &pwmname, Ticker &pwmname_t, Ramp &pwmname_r) //pwmnameArray, pwmname, pwmname_t, pwmname_r +//void bl() +//{ +// struct tm *t; +// time_t seconds = time(NULL); +// t = localtime(&seconds); +// +// int timerica = (t->tm_hour*3600) + (t->tm_min*60) + t->tm_sec; +// +// for (uint8_t index = 0; index < 10; index++) { //cycle array (sizeof(pwmArray)/sizeof(pwmArray[0])) = 0? +// +//// if (pwmnameArray[index][2] != 255 && pwmnameArray[index+1][2] != 255) { +//// +//// if ( timerica == (pwmnameArray[index][0]*3600) + (pwmnameArray[index][1]*60) ) { +//// +//// pwmname_t.detach(); +//// +//// pwmname = pwmnameArray[index][2]/100.0; +//// +//// float ramp = float( (((pwmnameArray[index+1][0]*3600) + (pwmnameArray[index+1][1]*60))-((pwmnameArray[index][0]*3600) + (pwmnameArray[index][1]*60))) ) / float( (pwmnameArray[index+1][2]-pwmnameArray[index][2]) ) ; +//// +//// pc.printf("ramp ?%f\n", ramp); +//// +//// if (ramp > 0) { +//// pwmname_t.attach(&pwmname_r, &Ramp::inc, ramp/8); +//// } +//// if (ramp < 0) { +//// pwmname_t.attach(&pwmname_r, &Ramp::dec, ramp/8); +//// } +//// +//// pc.printf("PWMSTART\n"); +//// pc.printf("index %d\n",index); +//// } +//// } +// +//// if (pwmnameArray[index][2] != 255 && pwmnameArray[index+1][2] == 255) { //pwm_end = 255 +//// if ( timerica == (pwmnameArray[index][0]*3600) + (pwmnameArray[index][1]*60) ) { +//// +//// pwmname_t.detach(); +//// +//// pwmname = pwmnameArray[index][2]/100.0; +//// +//// pc.printf("PWMZERO\n"); +//// pc.printf("index %d\n",index); +//// } +//// } +// } +//} + +void incs() +{ + for(uint8_t index = 0; index < sizeof(Pwm_Array)/sizeof(FastPWM); index++) { //index < sizeof(Pwm_Array)/sizeof(FastPWM) + + double ramp = double( (Pwm_Min_Max_Array[index][1]-Pwm_Min_Max_Array[index][0]) ) / double( (( ((SunRiseSet[0][0]*3600) + (SunRiseSet[0][1]*60))+(ramptime*60) )-( (SunRiseSet[0][0]*3600) + (SunRiseSet[0][1]*60) )) ) ; + + if (Pwm_Array[index].read() < Pwm_Min_Max_Array[index][1]/100.0) { + Pwm_Array[index] = Pwm_Array[index].read() + double(ramp/100.0); + pc.printf("sunrise:[%i]%f ", index, Pwm_Array[index].read()); + } + if (Pwm_Array[index].read() > Pwm_Min_Max_Array[index][1]/100.0) { + Pwm_Array[index] = Pwm_Min_Max_Array[index][1]/100.0; + Sunrise_Ticker.detach(); + pc.printf("\n sunrise end:[%i]%f \n", index, Pwm_Array[index].read()); + } + } +} + +void decs() +{ + for(uint8_t index = 0; index < sizeof(Pwm_Array)/sizeof(FastPWM); index++) { //index < sizeof(Pwm_Array)/sizeof(FastPWM) + + double ramp = double( (Pwm_Min_Max_Array[index][1]-Pwm_Min_Max_Array[index][0]) ) / double( (( ((SunRiseSet[0][0]*3600) + (SunRiseSet[0][1]*60))+(ramptime*60) )-( (SunRiseSet[0][0]*3600) + (SunRiseSet[0][1]*60) )) ) ; + + if (Pwm_Array[index].read() < Pwm_Min_Max_Array[index][1]/100.0) { + Pwm_Array[index] = Pwm_Array[index].read() + double(ramp/100.0); + pc.printf("sunset:[%i]%f ", index, Pwm_Array[index].read()); + } + if (Pwm_Array[index].read() > Pwm_Min_Max_Array[index][1]/100.0) { + Pwm_Array[index] = Pwm_Min_Max_Array[index][1]/100.0; + Sunset_Ticker.detach(); + pc.printf("\n sunset end:[%i]%f \n", index, Pwm_Array[index].read()); + } + } +} + +//TODO +//init RTC + +void set_time_from_rtc() +{ + int rtc_hour; + int rtc_min; + int rtc_sec; + int rtc_dow; //day of week + int rtc_mday; + int rtc_mon; + int rtc_year; + + rtc.readDateTime(&rtc_dow,&rtc_mday,&rtc_mon,&rtc_year,&rtc_hour,&rtc_min,&rtc_sec); +//TODO +//asuming that day of week is allways != 0, return an error if dow == 0. + lcd.cls(); + lcd.printf("rtc: %i / %02i-%02i-%02i %02i:%02i:%02i",rtc_dow,rtc_mday,rtc_mon,rtc_year,rtc_hour,rtc_min,rtc_sec); + + + t.tm_sec = rtc_sec; // 0-59 + t.tm_min = rtc_min; // 0-59 + t.tm_hour = rtc_hour; // 0-23 + t.tm_mday = rtc_mday; // 1-31 + t.tm_mon = rtc_mon; // 0-11 + t.tm_year = rtc_year-1900; // year since 1900 + + // convert to timestamp and set (1256729737) + time_t epoch = mktime(&t); + set_time(epoch); + wait(1); //not necessary + lcd.cls(); + epoch = time(NULL); + lcd.printf("stm: %i / %02i-%02i-%02i %02i:%02i:%02i",rtc_dow,localtime(&epoch)->tm_mday,localtime(&epoch)->tm_mon,localtime(&epoch)->tm_year+1900,localtime(&epoch)->tm_hour,localtime(&epoch)->tm_min,localtime(&epoch)->tm_sec); + wait(1); //not necessary +} + +void read_eeprom() //int nbyte_read( int mem_addr, void *data, int size ); //TODO +{ + char data2[4096]; //32Kbit eeprom +// pc.printf("memory int data read!\n"); + eeprom.nbyte_read( 0, &data2, 4096 ); //MAXADR_24LCXXX <=4096 + //lcd.printf("int:%d sizeofint:%d",data2, sizeof(uint8_t)); +// pc.printf("\nend\n"); + lcd.printf("sizeof: %d", sizeof(data2)); +} + +int main() +{ + //lcd init + lcd.setBacklight(TextLCD::LightOn); + lcd.setMode(TextLCD::DispOn); + + //TODO + //rtc init (set 32KHz output to enable, erase OSF, etc? + + set_time_from_rtc(); //read time from DS3231, set time to STM32 + //read external EEPROM and restore saved values (what values?) + //lcd.cls(); + //read_eeprom(); + //wait(4); + + //TODO set initial pwm_channel state (ie: if it's betweeen sunrise_end and sunset_start set it to sunrise_max, if it's ramping calculate the initial value + + qei_idx.mode(PullUp); + qei_t.attach(&qei_cb, 0.05); //calls qei_cb every 50ms + + Menu settingsMenu("SettingsID"); + + Menu pwm_minMenu("PWM MinID"); + pwm_minMenu.add(Selection(&pwm_min, 0, NULL, "< CH00 >")); + pwm_minMenu.add(Selection(&pwm_min, 1, NULL, "< CH01 >")); + pwm_minMenu.add(Selection(&pwm_min, 2, NULL, "< CH02 >")); + pwm_minMenu.add(Selection(&pwm_min, 3, NULL, "< CH03 >")); + pwm_minMenu.add(Selection(&pwm_min, 4, NULL, "< CH04 >")); + pwm_minMenu.add(Selection(&pwm_min, 5, NULL, "< CH05 >")); + pwm_minMenu.add(Selection(&pwm_min, 6, NULL, "< CH06 >")); + pwm_minMenu.add(Selection(&pwm_min, 7, NULL, "< CH07 >")); + pwm_minMenu.add(Selection(&pwm_min, 8, NULL, "< CH08 >")); + pwm_minMenu.add(Selection(&pwm_min, 9, NULL, "< CH09 >")); + pwm_minMenu.add(Selection(NULL, 10, &settingsMenu, "< Return >")); + + Menu pwm_maxMenu("PWM MaxID"); + pwm_maxMenu.add(Selection(&pwm_max, 0, NULL, "< CH00 >")); + pwm_maxMenu.add(Selection(&pwm_max, 1, NULL, "< CH01 >")); + pwm_maxMenu.add(Selection(&pwm_max, 2, NULL, "< CH02 >")); + pwm_maxMenu.add(Selection(&pwm_max, 3, NULL, "< CH03 >")); + pwm_maxMenu.add(Selection(&pwm_max, 4, NULL, "< CH04 >")); + pwm_maxMenu.add(Selection(&pwm_max, 5, NULL, "< CH05 >")); + pwm_maxMenu.add(Selection(&pwm_max, 6, NULL, "< CH06 >")); + pwm_maxMenu.add(Selection(&pwm_max, 7, NULL, "< CH07 >")); + pwm_maxMenu.add(Selection(&pwm_max, 8, NULL, "< CH08 >")); + pwm_maxMenu.add(Selection(&pwm_max, 9, NULL, "< CH09 >")); + pwm_maxMenu.add(Selection(NULL, 10, &settingsMenu, "< Return >")); + +// Menu sunriseMenu("PWM MaxID"); +// +// Menu sunsetMenu("PWM MaxID"); + +// Menu ramptimeMenu("RampTimeID"); + + settingsMenu.add(Selection(NULL, 0, &pwm_maxMenu, "<PWM Day>")); + settingsMenu.add(Selection(NULL, 1, &pwm_minMenu, "<PWM Night>")); + settingsMenu.add(Selection(&sun_rise, 2, NULL, "<Sunrise>")); + settingsMenu.add(Selection(&sun_set, 3, NULL, "<Sunset>")); + settingsMenu.add(Selection(&ramp_time, 4, NULL, "<Ramp Time>")); + settingsMenu.add(Selection(&set_date_time, 5, NULL, "<Set Date/Time>")); + + settingsMenu.add(Selection(&exit_settings, 6, NULL, "<Exit Setup>")); + + activeMenu = &settingsMenu; + + + char buffer[32]; + struct tm *twhile; + + while(1) { + + time_t seconds = time(NULL); + strftime(buffer, 32, "%H:%M:%S", localtime(&seconds)); + + + twhile = localtime(&seconds); + + int timerica = (twhile->tm_hour*3600) + (twhile->tm_min*60) + twhile->tm_sec; + + + pc.printf("%s %d %d\n", buffer, timerica, (SunRiseSet[0][0]*3600) + (SunRiseSet[0][1]*60) ); + + if (timerica == (SunRiseSet[0][0]*3600) + (SunRiseSet[0][1]*60)) { //TODO attach once at start out of while() + Sunrise_Ticker.attach(&incs,1); //TODO check if allready attached + } + + if (timerica == (SunRiseSet[1][0]*3600) + (SunRiseSet[1][1]*60)) { + Sunset_Ticker.attach(&decs,1); //TODO check if allready attached + } + +// for(uint8_t index = 0; index < 3; index++) { //index < sizeof(Pwm_Array)/sizeof(FastPWM) +// pc.printf("pwm:[%i]%f ", index, Pwm_Array[index].read()); +// } + + + if (refresh_display == true) { + switch(menu_state) { + case MAIN: + lcd.cls(); + lcd.printf("MAIN"); + refresh_display = false; + break; + case SETTINGS: + lcd.cls(); + lcd.locate(0,0); + lcd.printf("%s", activeMenu->menuID); + lcd.locate(0,1); + lcd.printf("%s", activeMenu->selections[cursorPos].selText); + refresh_display = false; + break; + case PWM_MIN: + lcd.cls(); + lcd.printf("%s %2i", activeMenu->menuID, cursorPos); + lcd.locate(0,1); + lcd.printf("<- %3i%% +>", Pwm_Min_Max_Array[cursorPos][0]); + refresh_display = false; + break; + case PWM_MAX: + lcd.cls(); + lcd.printf("%s %2i", activeMenu->menuID, cursorPos); + lcd.locate(0,1); + lcd.printf("<- %3i%% +>", Pwm_Min_Max_Array[cursorPos][1]); + refresh_display = false; + break; + case SUNRISE: + lcd.cls(); + lcd.printf("%s %2i", activeMenu->menuID, cursorPos); + lcd.locate(0,1); + lcd.printf("%02d:%02d", SunRiseSet[0][0],SunRiseSet[0][1]); + refresh_display = false; + break; + case SUNRISE_HOUR: + while(menu_state == SUNRISE_HOUR) { + lcd.locate(0,1); + lcd.printf(" "); + wait(0.1); + lcd.locate(0,1); + lcd.printf("%02d",SunRiseSet[0][0]); + wait(0.2); + } + break; + case SUNRISE_MINUTE: + while(menu_state == SUNRISE_MINUTE) { + lcd.locate(3,1); + lcd.printf(" "); + wait(0.1); + lcd.locate(3,1); + lcd.printf("%02d",SunRiseSet[0][1]); + wait(0.2); + } + break; + case SUNSET: + lcd.cls(); + lcd.printf("%s %2i", activeMenu->menuID, cursorPos); + lcd.locate(0,1); + lcd.printf("%02d:%02d", SunRiseSet[1][0],SunRiseSet[1][1]); + refresh_display = false; + break; + case SUNSET_HOUR: + while(menu_state == SUNSET_HOUR) { + lcd.locate(0,1); + lcd.printf(" "); + wait(0.1); + lcd.locate(0,1); + lcd.printf("%02d",SunRiseSet[1][0]); + wait(0.2); + } + break; + case SUNSET_MINUTE: + while(menu_state == SUNSET_MINUTE) { + lcd.locate(3,1); + lcd.printf(" "); + wait(0.1); + lcd.locate(3,1); + lcd.printf("%02d",SunRiseSet[1][1]); + wait(0.2); + } + break; + case RAMPTIME: + lcd.cls(); + lcd.printf("%s %2i", activeMenu->menuID, cursorPos); + lcd.locate(0,1); + lcd.printf("<- %3i +>", ramptime); + refresh_display = false; + break; + case SET_DATE_TIME: + lcd.cls(); + lcd.printf("%02d/%02d/%04d",twhile->tm_mday, twhile->tm_mon, twhile->tm_year + 1900); + lcd.locate(0,1); + lcd.printf("%02d:%02d:%02d",twhile->tm_hour, twhile->tm_min, twhile->tm_sec); + refresh_display = false; + break; + } + } + wait(0.5); + } +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Thu Mar 05 17:40:21 2015 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/e188a91d3eaa \ No newline at end of file