* Project Real-time Bus Arrival Alarm * Parts - WIZwiki-W7500 Platform - Seeed Grove OLED display - Seeed Grove 4-digit display - Seeed Grove Buzzer * Detailed description Real Time Bus Information will show you when your bus is due to arrive at your bus stop. * Target Bus Information System - GyeongGi Bus Information, Korea (www.gbis.go.kr)

Dependencies:   WIZnetInterface mbed DigitDisplay HTTPClient NTPClient SeeedGrayOLED

Files at this revision

API Documentation at this revision

Comitter:
hkjung
Date:
Wed Aug 26 05:12:36 2015 +0000
Commit message:
Real-time Bus Arrival Alarm based on ARM mbed WIZwiki-W7500 Platform

Changed in this revision

Libraries/DigitDisplay.lib Show annotated file Show diff for this revision Revisions of this file
Libraries/HTTPClient.lib Show annotated file Show diff for this revision Revisions of this file
Libraries/NTPClient.lib Show annotated file Show diff for this revision Revisions of this file
Libraries/SeeedGrayOLED.lib Show annotated file Show diff for this revision Revisions of this file
WIZnetInterface.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r 879add9a219d Libraries/DigitDisplay.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Libraries/DigitDisplay.lib	Wed Aug 26 05:12:36 2015 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/seeed/code/DigitDisplay/#d3173c8bfd48
diff -r 000000000000 -r 879add9a219d Libraries/HTTPClient.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Libraries/HTTPClient.lib	Wed Aug 26 05:12:36 2015 +0000
@@ -0,0 +1,1 @@
+https://developer.mbed.org/users/hkjung/code/HTTPClient/#db3ba053226c
diff -r 000000000000 -r 879add9a219d Libraries/NTPClient.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Libraries/NTPClient.lib	Wed Aug 26 05:12:36 2015 +0000
@@ -0,0 +1,1 @@
+https://developer.mbed.org/users/donatien/code/NTPClient/#881559865a93
diff -r 000000000000 -r 879add9a219d Libraries/SeeedGrayOLED.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Libraries/SeeedGrayOLED.lib	Wed Aug 26 05:12:36 2015 +0000
@@ -0,0 +1,1 @@
+https://developer.mbed.org/users/hkjung/code/SeeedGrayOLED/#d9f6f04e3d54
diff -r 000000000000 -r 879add9a219d WIZnetInterface.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/WIZnetInterface.lib	Wed Aug 26 05:12:36 2015 +0000
@@ -0,0 +1,1 @@
+http://developer.mbed.org/teams/WIZnet/code/WIZnetInterface/#3b64df29662f
diff -r 000000000000 -r 879add9a219d main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Wed Aug 26 05:12:36 2015 +0000
@@ -0,0 +1,874 @@
+#include "mbed.h"
+#include "EthernetInterface.h"
+
+#include "HTTPClient.h"     // HTTP Client library
+#include "NTPClient.h"      // NTP Client library (Network Time Protocol)
+
+#include "DigitDisplay.h"   // Seeed Grove: 4-digit Display
+#include "SeeedGrayOLED.h"  // Seeed Grove: OLED Display 0.96" 96x96
+
+Serial pc(USBTX, USBRX);
+
+PwmOut Buzzer(D6);
+DigitDisplay display(D0, D1); // 4-Digit Display connected to UART Grove connector
+SeeedGrayOLED SeeedGrayOled(D14, D15);
+DigitalOut myled(LED1);
+
+Ticker tick;
+
+////////////////////////////////////////////////////////////////
+// Defines
+////////////////////////////////////////////////////////////////
+
+/* User adjustable defines */
+////////////////////////////////////////////////////////////////
+/* Debug Message Enable */
+#define _DEBUG_BUS_ARRIVAL_ALARM_       0
+
+/* Number of Displayed Bus Info */
+#define MAX_BUS_INFO                    3       // The maximum bus information request can be up to Three (3)
+
+/* Display mode */
+#define DISPLAY_MODE_CHANGE_CNT_SEC     10      // The OLED display holding time(sec) for each bus information displayed
+#define BUS_NUM_BLINK_ENABLE            1       // blink the 4-digit display when displayed bus numbers
+
+/* Alarm Sound Enabled and Time */
+#define ALARM_SOUND_ENABLE              1
+#define SOUND_START_HOUR                6
+#define SOUND_START_MIN                 15
+#define SOUND_END_HOUR                  07
+#define SOUND_END_MIN                   00
+
+/* HTTP client */
+//#define MAX_HTTPC_RETRY_CNT             2       // not used
+////////////////////////////////////////////////////////////////
+
+/* Buzzer */
+#define VOLUME                          0.2     // 0.02
+#define BPM                             100.0
+
+/* Display mode define */
+#define DISPLAY_TIME_MODE               0   // do not change!
+
+/* Bus and Station (Busstop) info for GBIS openAPI */
+#define DEFAULT_STATION_NUM             38270 //(Gwangju -> Seoul)
+#define DEFAULT_STATION_ID              234000302       
+// for test
+//#define DEFAULT_STATION_NUM           38269 //(Seoul -> Gwangju)
+//#define DEFAULT_STATION_ID            234000294       
+
+typedef struct
+{    
+    uint8_t * busNum;       // Bus number, This value should be input at initialize stage
+    uint16_t stationNum;    // Station number, notused, This value should be input at initialize stage
+    uint32_t routeId;       // Bus route id for openAPI querying (openapi.gbis.go.kr)   // This value should be input at initialize stage
+    uint32_t stationId;     // Bus station id for openAPI querying (openapi.gbis.go.kr) // This value should be input at initialize stage
+    uint8_t resultCode;     // 0; success, 4; bus info none
+    uint8_t predictTime1;   // 1st bus arrival predict time ('1' means the bus gone)
+    uint8_t predictTime2;   // 2st bus arrival predict time ('1' means the none of next bus info)
+    uint8_t remainSeatCnt1; // 1st bus remain seat count
+    uint8_t remainSeatCnt2; // 2st bus remain seat count    
+}BUSINFO;
+
+////////////////////////////////////////////////////////////////
+// Function declaration
+////////////////////////////////////////////////////////////////
+void BuzzerSound(void);                     // Buzzer
+void Display_BusNumber(uint8_t * busnum);   // 4-digit display
+uint8_t get_businfo(BUSINFO * bus);         // Get Bus information (HTTP client) 
+
+// OLED display
+void Draw_OLED_init(void);
+void Draw_OLED_default(void);
+void Draw_OLED_busInfo(uint8_t * busnum, uint8_t seats);
+void Draw_OLED_arrivalMin(uint8_t min);
+void Draw_OLED_nextMin(uint8_t nextmin);
+void Draw_OLED_busList(void);
+
+// for ticker
+void beat();
+
+////////////////////////////////////////////////////////////////
+// Global variable declaration
+////////////////////////////////////////////////////////////////
+BUSINFO businfo[MAX_BUS_INFO];
+uint8_t flag_display_mode[MAX_BUS_INFO+1] = {0, };
+uint8_t display_mode = 0;
+uint8_t buzzer_sound_enable = 0;
+
+time_t beat_cTime;
+struct tm *beat_localtime;
+
+uint8_t mac[6] = {0x00,0x08,0xDC,0x01,0x02,0x03};   // MAC address, It must be modified as users MAC address
+
+int main()
+{   
+    pc.baud(115200);   
+    EthernetInterface ethernet;   
+    
+    uint8_t i;
+        
+    ////////////////////////////////////////////////////////////////
+    // Realtime Bus Information: Initialization
+    ////////////////////////////////////////////////////////////////     
+    
+    /* Bus number and route ID */
+    uint8_t busnum_1117[4] = {1, 1, 1, 7};
+    uint32_t busnum_1117_routeId = 234000069;
+    
+    uint8_t busnum_1113[4] = {1, 1, 1, 3};
+    uint32_t busnum_1113_routeId = 234000042;
+    
+    uint8_t busnum_1005[4] = {1, 0, 0, 5};
+    uint32_t busnum_1005_routeId = 234000065;
+    
+    // Bus info structure initialize    
+    businfo[0].busNum = busnum_1117;
+    businfo[0].stationNum = DEFAULT_STATION_NUM;
+    businfo[0].routeId = busnum_1117_routeId;
+    businfo[0].stationId = DEFAULT_STATION_ID;    
+    
+    businfo[1].busNum = busnum_1113;    
+    businfo[1].stationNum = DEFAULT_STATION_NUM;
+    businfo[1].routeId = busnum_1113_routeId;    
+    businfo[1].stationId = DEFAULT_STATION_ID;
+    
+    businfo[2].busNum = busnum_1005;    
+    businfo[2].stationNum = DEFAULT_STATION_NUM;
+    businfo[2].routeId = busnum_1005_routeId;    
+    businfo[2].stationId = DEFAULT_STATION_ID;
+    
+    // OLED display initialize
+    SeeedGrayOled.init();             // Initialize SEEED OLED display
+    SeeedGrayOled.clearDisplay();     // Clear Display
+    SeeedGrayOled.setNormalDisplay(); // Set Normal Display Mode
+    
+    // OLED display initial draw     
+    Draw_OLED_default();    //Draw_OLED_init();
+    
+    printf("\r\n==========================================\r\n");
+    printf(" Real-time Bus Arrival Alarm\r\n");
+    printf("==========================================\r\n");
+    printf(" Buzzer Sound START Time: %d:%.2d\r\n", SOUND_START_HOUR, SOUND_START_MIN);
+    printf(" Buzzer Sound END Time  : %d:%.2d\r\n", SOUND_END_HOUR, SOUND_END_MIN);
+    printf("==========================================\r\n");
+    
+    // Ethernet initialize
+    int ret = ethernet.init(mac);    
+    printf("\r\nWIZwiki-W7500 Networking Started\r\n");
+    wait(1); // 1 second for stable state
+
+    if (!ret) {
+        printf("Initialized, MAC: %s\r\n", ethernet.getMACAddress());
+        ret = ethernet.connect();
+        if (!ret) {
+            printf("IP: %s, MASK: %s, GW: %s\r\n",
+                      ethernet.getIPAddress(), ethernet.getNetworkMask(), ethernet.getGateway());
+        } else {
+            printf("Error ethernet.connect() - ret = %d\r\n", ret);
+            exit(0);
+        }
+    } else {
+        printf("Error ethernet.init() - ret = %d\r\n", ret);
+        exit(0);
+    }
+    
+    // NTP initialize
+    NTPClient ntp;    
+    printf("\r\nTrying to update time...\r\n");    
+    if (ntp.setTime("211.233.40.78") == 0) 
+    {
+        printf("Set time successfully\r\n");
+        time_t ctTime;
+        ctTime = time(NULL);
+        ctTime += 32400; // GMT+9/Seoul
+        printf("Time is set to (GMT+9): %s\r\n", ctime(&ctTime));
+    }
+    else
+    {
+        printf("Error\r\n");
+    }
+    
+    // 4-Digit display initialize
+    display.write(0, 0);
+    display.write(1, 0);
+    display.write(2, 0);
+    display.write(3, 0);
+    display.setColon(true);
+    tick.attach(&beat, 0.5);
+    
+    // Initial flag setting for get the bus info
+    flag_display_mode[DISPLAY_TIME_MODE] = 1;
+    
+    printf(">> Initialize Done\r\n");    
+    
+    // Main routine
+    while(1) {
+        
+        if(display_mode == DISPLAY_TIME_MODE) // Display: Time mode
+        {
+            if(flag_display_mode[display_mode])
+            {   
+                Draw_OLED_default();   
+                flag_display_mode[display_mode] = 0;
+                
+                // Get the buses info: Bus arrival time preparation (beforehand)
+                for(i = 0; i < MAX_BUS_INFO; i++)
+                {
+                    get_businfo(&businfo[i]);                                    
+                    
+#if (_DEBUG_BUS_ARRIVAL_ALARM_) //Debug message
+                    printf("Businfo #%d\r\n", i);
+                    printf("bus.resultCode = %c\r\n", businfo[i].resultCode);
+                    printf("1st Bus arrive after %d min\r\n", businfo[i].predictTime1);    
+                    printf("1st Bus remain seats %d\r\n", businfo[i].remainSeatCnt1);
+                    printf("2nd Bus arrive after %d min\r\n", businfo[i].predictTime2);
+                    printf("2nd Bus remain seats %d\r\n\r\n", businfo[i].remainSeatCnt2);
+#endif
+                }
+            }
+        }
+        else // Display: Bus info mode
+        {
+            i = display_mode - 1;
+            if(flag_display_mode[display_mode])
+            {                   
+                Draw_OLED_busInfo(businfo[i].busNum, businfo[i].remainSeatCnt1);
+                Draw_OLED_arrivalMin(businfo[i].predictTime1);
+                if(businfo[i].predictTime2 == 1)
+                {
+                    Draw_OLED_nextMin(0);
+                }
+                else
+                {
+                    Draw_OLED_nextMin(businfo[i].predictTime2);   
+                }
+                
+                // Buzzer sound!
+                // Each case means the displayed time(Remaining time until the bus arrival, minute) to ringing the buzzer
+                switch(businfo[i].predictTime1)
+                {
+                    case 5:
+                    case 6:
+                    case 7:                                                
+                    case 8:
+                    case 9:                        
+                    case 10:                                         
+                        BuzzerSound();                       
+                        break;
+                    default:
+                        break;
+                }
+                
+                flag_display_mode[display_mode] = 0;                
+            }
+        }       
+    }
+}
+
+////////////////////////////////////////////////////////////////
+// Member function of Ticker interface (attaching to a ticker)
+////////////////////////////////////////////////////////////////
+void beat()
+{
+    static uint8_t colon = 0;
+    static uint8_t myled_blink = 1;
+    static uint8_t display_mode_change_cnt = 0; // initial count value; 5 sec reduced    
+        
+    // Get current local time info
+    beat_cTime = time(NULL);
+    beat_cTime += 32400; // GMT+9/Seoul    
+    beat_localtime = localtime(&beat_cTime);    
+    
+    // Display Mode change handler (Time / Bus mode)
+    display_mode_change_cnt++; // ++ every 0.5sec
+    if((display_mode_change_cnt/2) >= DISPLAY_MODE_CHANGE_CNT_SEC)
+    {
+        display_mode++;        
+        
+        if(display_mode > MAX_BUS_INFO)
+        {
+            display_mode = DISPLAY_TIME_MODE; // 0
+        }
+         
+        // Skip: (resultCode == 4) means 'Bus arrival info does not appear'
+        while((display_mode != DISPLAY_TIME_MODE) && (businfo[display_mode-1].resultCode == 4))
+        {
+            display_mode++;
+            
+            if(display_mode > MAX_BUS_INFO)
+            {
+                display_mode = DISPLAY_TIME_MODE; // 0
+            }
+        }        
+        
+        flag_display_mode[display_mode] = 1;
+        display_mode_change_cnt = 0;
+    }
+    
+    // 4-Digit Display handler
+    if(display_mode == DISPLAY_TIME_MODE) // Time mode
+    {
+        display.on();
+        display.setColon(colon);    
+        if (colon) {                             
+            display.write(0, beat_localtime->tm_hour / 10);
+            display.write(1, beat_localtime->tm_hour % 10);        
+            display.write(2, beat_localtime->tm_min / 10);
+            display.write(3, beat_localtime->tm_min % 10);            
+        }            
+        //colon = 1 - colon;  // moved below     
+    }
+    else // Bus info mode                
+    {       
+#if (BUS_NUM_BLINK_ENABLE)
+        if(colon)
+        {        
+            Display_BusNumber(businfo[display_mode-1].busNum);
+        }
+        else
+        {
+            Display_BusNumber(NULL);
+        }
+#else
+        Display_BusNumber(businfo[display_mode-1].busNum);
+#endif
+           
+    }
+    
+    // Buzzer sound enable handler 
+    buzzer_sound_enable = 0;
+#if (ALARM_SOUND_ENABLE)
+    if(((beat_localtime->tm_hour == SOUND_START_HOUR) && (beat_localtime->tm_min >= SOUND_START_MIN)) || (beat_localtime->tm_hour > SOUND_START_HOUR))
+    {
+        if((beat_localtime->tm_hour < SOUND_END_HOUR) || ((beat_localtime->tm_hour == SOUND_END_HOUR) && (beat_localtime->tm_min < SOUND_END_MIN)))
+        {
+            buzzer_sound_enable = 1;
+        }
+    }
+#endif
+    
+    // LED blink; Device working indicator
+    myled_blink ^= 1;
+    myled = myled_blink ;
+    
+    // Invert every 0.5sec
+    colon = 1 - colon;
+}
+
+////////////////////////////////////////////////////////////////
+// Get Bus Information (HTTP client) Functions
+////////////////////////////////////////////////////////////////
+uint8_t get_businfo(BUSINFO * bus)
+{
+    uint8_t ret = 0;
+    char str[2048] = {0, };
+    char get_req[512] =  {0, };    
+    char predictTime1[3], predictTime2[3];
+    char remainSeatCnt1[3], remainSeatCnt2[3];    
+    char *CurrentAddr = 0;
+    
+    //uint8_t retry_cnt = 0;            // Unimplemented, MAX_HTTPC_RETRY_CNT
+    
+    HTTPClient httpc;
+    
+    sprintf(get_req, "http://openapi.gbis.go.kr/ws/rest/busarrivalservice?serviceKey=test&routeId=%ld&stationId=%ld", bus->routeId, bus->stationId);    
+    httpc.get(get_req, str, sizeof(str), 1000);
+    
+    CurrentAddr = strstr(str,"<resultCode>");
+    bus->resultCode = *(CurrentAddr+12);  
+        
+    if(bus->resultCode == '0')
+    {    
+        CurrentAddr = strstr(str,"<predictTime1>");
+        if((*(CurrentAddr+15)) == '<')
+        {
+            predictTime1[0] = *(CurrentAddr+14);
+            predictTime1[1] = 0;
+            predictTime1[2] = 0;
+        }
+        else
+        {
+            predictTime1[0] = *(CurrentAddr+14);
+            predictTime1[1] = *(CurrentAddr+15);
+            predictTime1[2] = 0;
+        }
+        bus->predictTime1 = (uint8_t)atoi(predictTime1);
+            
+        CurrentAddr = strstr(str,"<predictTime2>");
+        if((*(CurrentAddr+15)) == '<')
+        {
+            predictTime2[0] = *(CurrentAddr+14);
+            predictTime2[1] = 0;
+            predictTime2[2] = 0;
+        }
+        else
+        {
+            predictTime2[0] = *(CurrentAddr+14);
+            predictTime2[1] = *(CurrentAddr+15);
+            predictTime2[2] = 0;
+        }
+        bus->predictTime2 = (uint8_t)atoi(predictTime2);
+        
+        CurrentAddr = strstr(str,"<remainSeatCnt1>");
+        if((*(CurrentAddr+17)) == '<')
+        {
+            remainSeatCnt1[0] = *(CurrentAddr+16);
+            remainSeatCnt1[1] = 0;
+            remainSeatCnt1[2] = 0;
+        }
+        else
+        {
+            remainSeatCnt1[0] = *(CurrentAddr+16);
+            remainSeatCnt1[1] = *(CurrentAddr+17);
+            remainSeatCnt1[2] = 0;
+        }
+        bus->remainSeatCnt1 = (uint8_t)atoi(remainSeatCnt1);
+        
+        if(bus->predictTime2 > 1)   // (predictTime2 == 1) => The next bus information is not confirmed.
+        {        
+            CurrentAddr = strstr(str,"<remainSeatCnt2>");
+            if((*(CurrentAddr+17)) == '<')
+            {
+                remainSeatCnt2[0] = *(CurrentAddr+16);
+                remainSeatCnt2[1] = 0;
+                remainSeatCnt2[2] = 0;
+            }
+            else
+            {
+                remainSeatCnt2[0] = *(CurrentAddr+16);
+                remainSeatCnt2[1] = *(CurrentAddr+17);
+                remainSeatCnt2[2] = 0;
+            }
+            bus->remainSeatCnt2 = (uint8_t)atoi(remainSeatCnt2);
+        }
+        
+        ret = 1;
+    }
+    
+    return ret;
+}
+
+////////////////////////////////////////////////////////////////
+// Piezo Buzzer Functions
+////////////////////////////////////////////////////////////////
+
+void playNote(float frequency, float duration, float volume) 
+{
+    Buzzer.period(1.0/(double)frequency);
+    Buzzer = ((double)volume/2.0);
+    wait(duration);
+    Buzzer = 0.0;
+}
+
+void BuzzerSound(void)
+{
+    // Calculate duration of a quarter note from bpm
+    float beat_duration = 60.0 / BPM;    
+
+    if(buzzer_sound_enable)
+    {
+        //playNote(329.628, (0.75 * (double)beat_duration), VOLUME);
+        //playNote(261.626, (0.75 * (double)beat_duration), VOLUME);
+        playNote(529.628, (0.50 * (double)beat_duration), VOLUME);
+        playNote(301.626, (0.50 * (double)beat_duration), VOLUME);
+    }
+}
+
+////////////////////////////////////////////////////////////////
+// 4-Digit Display Functions
+////////////////////////////////////////////////////////////////
+
+void Display_BusNumber(uint8_t * busnum)
+{       
+    display.setColon(false);
+    
+    if(busnum != NULL)
+    {
+        display.on();
+        display.write(0, busnum[0]);
+        display.write(1, busnum[1]);
+        display.write(2, busnum[2]);
+        display.write(3, busnum[3]);
+    }
+    else
+    {
+        display.off();    
+    }
+}
+
+////////////////////////////////////////////////////////////////
+// OLED Display Functions
+////////////////////////////////////////////////////////////////
+
+void Draw_OLED_init(void)
+{
+    uint8_t empty_busnum[4] = {0, 0, 0, 0};
+    
+    Draw_OLED_busInfo(empty_busnum, 0);
+    Draw_OLED_nextMin(0);    
+}
+
+void Draw_OLED_default(void)
+{
+    SeeedGrayOled.setTextXY(0, 1);
+    SeeedGrayOled.putString("Bus NearBy ");
+    SeeedGrayOled.setTextXY(1, 1);    
+    SeeedGrayOled.putString("========== ");
+    
+    Draw_OLED_arrivalMin('b');
+    
+    SeeedGrayOled.setTextXY(11, 0);
+    SeeedGrayOled.putString("WIZnet::Eric");    
+}
+
+void Draw_OLED_busList(void)
+{
+    uint8_t i;
+    char buf[15] = {0, };
+    
+    SeeedGrayOled.setTextXY(0, 1);
+    SeeedGrayOled.putString("           ");
+    SeeedGrayOled.setTextXY(1, 1);    
+    SeeedGrayOled.putString("Bus List:");
+    
+    Draw_OLED_arrivalMin('t');   
+    
+    for(i = 0; i < MAX_BUS_INFO; i++)
+    {        
+        SeeedGrayOled.setTextXY(3+i, 2);
+        sprintf(buf, "- %.1d%.1d%.1d%.1d", businfo[i].busNum[0], businfo[i].busNum[1], businfo[i].busNum[2], businfo[i].busNum[3]);
+        SeeedGrayOled.putString(buf);
+    }
+    
+    SeeedGrayOled.setTextXY(11, 1);
+    SeeedGrayOled.putString("           ");
+}
+
+void Draw_OLED_busInfo(uint8_t * busnum, uint8_t seats)
+{
+    char buf[15] = {0, };
+    sprintf(buf, "Bus  %.1d%.1d%.1d%.1d ", busnum[0], busnum[1], busnum[2], busnum[3]);    
+    SeeedGrayOled.setTextXY(0, 1);
+    SeeedGrayOled.putString(buf);
+    sprintf(buf, "Seats  %.2d ", seats);    
+    SeeedGrayOled.setTextXY(1, 1);
+    SeeedGrayOled.putString(buf);    
+}
+
+void Draw_OLED_nextMin(uint8_t nextmin)
+{
+    char buf[15] = {0, };
+    if(nextmin == 0)
+    {
+        sprintf(buf, "Next: -- min");
+    }
+    else
+    {
+        sprintf(buf, "Next: %.2d min", nextmin);
+    }
+    
+    SeeedGrayOled.setTextXY(11, 0);
+    SeeedGrayOled.putString(buf);
+}
+
+void Draw_OLED_arrivalMin(uint8_t min)
+{
+    switch(min)
+    {
+         case 't':
+            SeeedGrayOled.setTextXY(3, 0);
+            SeeedGrayOled.putString("           ");
+            SeeedGrayOled.setTextXY(4, 0);
+            SeeedGrayOled.putString("           ");
+            SeeedGrayOled.setTextXY(5, 0);
+            SeeedGrayOled.putString("           ");
+            SeeedGrayOled.setTextXY(6, 0);
+            SeeedGrayOled.putString("           ");
+            SeeedGrayOled.setTextXY(7, 0);
+            SeeedGrayOled.putString("           ");
+            SeeedGrayOled.setTextXY(8, 0);
+            SeeedGrayOled.putString("           ");
+            SeeedGrayOled.setTextXY(9, 0);
+            SeeedGrayOled.putString("            ");
+            break;
+        case 'b':
+            SeeedGrayOled.setTextXY(3, 0);
+            SeeedGrayOled.putString("   ~~~~~   ");
+            SeeedGrayOled.setTextXY(4, 0);
+            SeeedGrayOled.putString("  ~     ~  ");
+            SeeedGrayOled.setTextXY(5, 0);
+            SeeedGrayOled.putString("  ~     ~  ");
+            SeeedGrayOled.setTextXY(6, 0);
+            SeeedGrayOled.putString("  ~~~~~~~  ");
+            SeeedGrayOled.setTextXY(7, 0);
+            SeeedGrayOled.putString("  ~ ~~~ ~  ");
+            SeeedGrayOled.setTextXY(8, 0);
+            SeeedGrayOled.putString("  ~~~~~~~  ");
+            SeeedGrayOled.setTextXY(9, 0);
+            SeeedGrayOled.putString("   ~~ ~~    ");
+            break;
+        case 0:
+            SeeedGrayOled.setTextXY(3, 0);
+            SeeedGrayOled.putString(" ~~~~ ~~~~ ");
+            SeeedGrayOled.setTextXY(4, 0);
+            SeeedGrayOled.putString(" ~  ~ ~  ~ ");
+            SeeedGrayOled.setTextXY(5, 0);
+            SeeedGrayOled.putString(" ~  ~ ~  ~ ");
+            SeeedGrayOled.setTextXY(6, 0);
+            SeeedGrayOled.putString(" ~  ~ ~  ~ ");
+            SeeedGrayOled.setTextXY(7, 0);
+            SeeedGrayOled.putString(" ~  ~ ~  ~ ");
+            SeeedGrayOled.setTextXY(8, 0);
+            SeeedGrayOled.putString(" ~  ~ ~  ~ ");
+            SeeedGrayOled.setTextXY(9, 0);
+            SeeedGrayOled.putString(" ~~~~ ~~~~  ");
+            break;
+        case 1:
+            SeeedGrayOled.setTextXY(3, 0);
+            SeeedGrayOled.putString("           ");
+            SeeedGrayOled.setTextXY(4, 0);
+            SeeedGrayOled.putString("    ~      ");
+            SeeedGrayOled.setTextXY(5, 0);
+            SeeedGrayOled.putString("   ~~      ");
+            SeeedGrayOled.setTextXY(6, 0);
+            SeeedGrayOled.putString("  ~~~~~~~  ");
+            SeeedGrayOled.setTextXY(7, 0);
+            SeeedGrayOled.putString("   ~~      ");
+            SeeedGrayOled.setTextXY(8, 0);
+            SeeedGrayOled.putString("    ~      ");
+            SeeedGrayOled.setTextXY(9, 0);
+            SeeedGrayOled.putString("      Gone! ");
+            break;
+        case 2:
+            SeeedGrayOled.setTextXY(3, 0);
+            SeeedGrayOled.putString("      ~~~~ ");
+            SeeedGrayOled.setTextXY(4, 0);
+            SeeedGrayOled.putString("         ~ ");
+            SeeedGrayOled.setTextXY(5, 0);
+            SeeedGrayOled.putString("         ~ ");
+            SeeedGrayOled.setTextXY(6, 0);
+            SeeedGrayOled.putString("      ~~~~ ");
+            SeeedGrayOled.setTextXY(7, 0);
+            SeeedGrayOled.putString("      ~    ");
+            SeeedGrayOled.setTextXY(8, 0);
+            SeeedGrayOled.putString("      ~    ");
+            SeeedGrayOled.setTextXY(9, 0);
+            SeeedGrayOled.putString("      ~~~~  ");
+            break;
+        case 3:
+            SeeedGrayOled.setTextXY(3, 0);
+            SeeedGrayOled.putString("      ~~~~ ");
+            SeeedGrayOled.setTextXY(4, 0);
+            SeeedGrayOled.putString("         ~ ");
+            SeeedGrayOled.setTextXY(5, 0);
+            SeeedGrayOled.putString("         ~ ");
+            SeeedGrayOled.setTextXY(6, 0);
+            SeeedGrayOled.putString("      ~~~~ ");
+            SeeedGrayOled.setTextXY(7, 0);
+            SeeedGrayOled.putString("         ~ ");
+            SeeedGrayOled.setTextXY(8, 0);
+            SeeedGrayOled.putString("         ~ ");
+            SeeedGrayOled.setTextXY(9, 0);
+            SeeedGrayOled.putString("      ~~~~  ");
+            break;
+         case 4:
+            SeeedGrayOled.setTextXY(3, 0);
+            SeeedGrayOled.putString("      ~ ~  ");
+            SeeedGrayOled.setTextXY(4, 0);
+            SeeedGrayOled.putString("      ~ ~  ");
+            SeeedGrayOled.setTextXY(5, 0);
+            SeeedGrayOled.putString("      ~ ~  ");
+            SeeedGrayOled.setTextXY(6, 0);
+            SeeedGrayOled.putString("      ~~~~ ");
+            SeeedGrayOled.setTextXY(7, 0);
+            SeeedGrayOled.putString("        ~  ");
+            SeeedGrayOled.setTextXY(8, 0);
+            SeeedGrayOled.putString("        ~  ");
+            SeeedGrayOled.setTextXY(9, 0);
+            SeeedGrayOled.putString("        ~   ");
+            break;
+        case 5:
+            SeeedGrayOled.setTextXY(3, 0);
+            SeeedGrayOled.putString("      ~~~~ ");
+            SeeedGrayOled.setTextXY(4, 0);
+            SeeedGrayOled.putString("      ~    ");
+            SeeedGrayOled.setTextXY(5, 0);
+            SeeedGrayOled.putString("      ~    ");
+            SeeedGrayOled.setTextXY(6, 0);
+            SeeedGrayOled.putString("      ~~~~ ");
+            SeeedGrayOled.setTextXY(7, 0);
+            SeeedGrayOled.putString("         ~ ");
+            SeeedGrayOled.setTextXY(8, 0);
+            SeeedGrayOled.putString("         ~ ");
+            SeeedGrayOled.setTextXY(9, 0);
+            SeeedGrayOled.putString("      ~~~~  ");
+            break;
+        case 6:
+            SeeedGrayOled.setTextXY(3, 0);
+            SeeedGrayOled.putString("      ~~~~ ");
+            SeeedGrayOled.setTextXY(4, 0);
+            SeeedGrayOled.putString("      ~    ");
+            SeeedGrayOled.setTextXY(5, 0);
+            SeeedGrayOled.putString("      ~    ");
+            SeeedGrayOled.setTextXY(6, 0);
+            SeeedGrayOled.putString("      ~~~~ ");
+            SeeedGrayOled.setTextXY(7, 0);
+            SeeedGrayOled.putString("      ~  ~ ");
+            SeeedGrayOled.setTextXY(8, 0);
+            SeeedGrayOled.putString("      ~  ~ ");
+            SeeedGrayOled.setTextXY(9, 0);
+            SeeedGrayOled.putString("      ~~~~  ");
+            break;
+        case 7:
+            SeeedGrayOled.setTextXY(3, 0);
+            SeeedGrayOled.putString("      ~~~~ ");
+            SeeedGrayOled.setTextXY(4, 0);
+            SeeedGrayOled.putString("      ~  ~ ");
+            SeeedGrayOled.setTextXY(5, 0);
+            SeeedGrayOled.putString("      ~  ~ ");
+            SeeedGrayOled.setTextXY(6, 0);
+            SeeedGrayOled.putString("      ~  ~ ");
+            SeeedGrayOled.setTextXY(7, 0);
+            SeeedGrayOled.putString("         ~ ");
+            SeeedGrayOled.setTextXY(8, 0);
+            SeeedGrayOled.putString("         ~ ");
+            SeeedGrayOled.setTextXY(9, 0);
+            SeeedGrayOled.putString("         ~  ");
+            break;
+        case 8:
+            SeeedGrayOled.setTextXY(3, 0);
+            SeeedGrayOled.putString("      ~~~~ ");
+            SeeedGrayOled.setTextXY(4, 0);
+            SeeedGrayOled.putString("      ~  ~ ");
+            SeeedGrayOled.setTextXY(5, 0);
+            SeeedGrayOled.putString("      ~  ~ ");
+            SeeedGrayOled.setTextXY(6, 0);
+            SeeedGrayOled.putString("      ~~~~ ");
+            SeeedGrayOled.setTextXY(7, 0);
+            SeeedGrayOled.putString("      ~  ~ ");
+            SeeedGrayOled.setTextXY(8, 0);
+            SeeedGrayOled.putString("      ~  ~ ");
+            SeeedGrayOled.setTextXY(9, 0);
+            SeeedGrayOled.putString("      ~~~~  ");
+            break;
+        case 9:
+            SeeedGrayOled.setTextXY(3, 0);
+            SeeedGrayOled.putString("      ~~~~ ");
+            SeeedGrayOled.setTextXY(4, 0);
+            SeeedGrayOled.putString("      ~  ~ ");
+            SeeedGrayOled.setTextXY(5, 0);
+            SeeedGrayOled.putString("      ~  ~ ");
+            SeeedGrayOled.setTextXY(6, 0);
+            SeeedGrayOled.putString("      ~~~~ ");
+            SeeedGrayOled.setTextXY(7, 0);
+            SeeedGrayOled.putString("         ~ ");
+            SeeedGrayOled.setTextXY(8, 0);
+            SeeedGrayOled.putString("         ~ ");
+            SeeedGrayOled.setTextXY(9, 0);
+            SeeedGrayOled.putString("      ~~~~  ");
+            break;        
+        case 10:
+        case 11: // 10
+            SeeedGrayOled.setTextXY(3, 0);
+            SeeedGrayOled.putString("  ~~  ~~~~ ");
+            SeeedGrayOled.setTextXY(4, 0);
+            SeeedGrayOled.putString("   ~  ~  ~ ");
+            SeeedGrayOled.setTextXY(5, 0);
+            SeeedGrayOled.putString("   ~  ~  ~ ");
+            SeeedGrayOled.setTextXY(6, 0);
+            SeeedGrayOled.putString("   ~  ~  ~ ");
+            SeeedGrayOled.setTextXY(7, 0);
+            SeeedGrayOled.putString("   ~  ~  ~ ");
+            SeeedGrayOled.setTextXY(8, 0);
+            SeeedGrayOled.putString("   ~  ~  ~ ");
+            SeeedGrayOled.setTextXY(9, 0);
+            SeeedGrayOled.putString("   ~  ~~~~  ");
+            break;
+        case 12:
+        case 13:
+        case 14: // 12
+            SeeedGrayOled.setTextXY(3, 0);
+            SeeedGrayOled.putString("  ~~  ~~~~ ");
+            SeeedGrayOled.setTextXY(4, 0);
+            SeeedGrayOled.putString("   ~     ~ ");
+            SeeedGrayOled.setTextXY(5, 0);
+            SeeedGrayOled.putString("   ~     ~ ");
+            SeeedGrayOled.setTextXY(6, 0);
+            SeeedGrayOled.putString("   ~  ~~~~ ");
+            SeeedGrayOled.setTextXY(7, 0);
+            SeeedGrayOled.putString("   ~  ~    ");
+            SeeedGrayOled.setTextXY(8, 0);
+            SeeedGrayOled.putString("   ~  ~    ");
+            SeeedGrayOled.setTextXY(9, 0);
+            SeeedGrayOled.putString("   ~  ~~~~  ");
+            break;
+        case 15:
+        case 16: // 15        
+            SeeedGrayOled.setTextXY(3, 0);
+            SeeedGrayOled.putString("  ~~  ~~~~ ");
+            SeeedGrayOled.setTextXY(4, 0);
+            SeeedGrayOled.putString("   ~  ~    ");
+            SeeedGrayOled.setTextXY(5, 0);
+            SeeedGrayOled.putString("   ~  ~    ");
+            SeeedGrayOled.setTextXY(6, 0);
+            SeeedGrayOled.putString("   ~  ~~~~ ");
+            SeeedGrayOled.setTextXY(7, 0);
+            SeeedGrayOled.putString("   ~     ~ ");
+            SeeedGrayOled.setTextXY(8, 0);
+            SeeedGrayOled.putString("   ~     ~ ");
+            SeeedGrayOled.setTextXY(9, 0);
+            SeeedGrayOled.putString("   ~  ~~~~  ");
+            break;
+        case 17:
+        case 18: // 17
+        case 19: // 17
+            SeeedGrayOled.setTextXY(3, 0);
+            SeeedGrayOled.putString("  ~~  ~~~~ ");
+            SeeedGrayOled.setTextXY(4, 0);
+            SeeedGrayOled.putString("   ~  ~  ~ ");
+            SeeedGrayOled.setTextXY(5, 0);
+            SeeedGrayOled.putString("   ~  ~  ~ ");
+            SeeedGrayOled.setTextXY(6, 0);
+            SeeedGrayOled.putString("   ~  ~  ~ ");
+            SeeedGrayOled.setTextXY(7, 0);
+            SeeedGrayOled.putString("   ~     ~ ");
+            SeeedGrayOled.setTextXY(8, 0);
+            SeeedGrayOled.putString("   ~     ~ ");
+            SeeedGrayOled.setTextXY(9, 0);
+            SeeedGrayOled.putString("   ~     ~  ");
+            break;
+        case 20: // 20
+            SeeedGrayOled.setTextXY(3, 0);
+            SeeedGrayOled.putString(" ~~~~ ~~~~ ");
+            SeeedGrayOled.setTextXY(4, 0);
+            SeeedGrayOled.putString("    ~ ~  ~ ");
+            SeeedGrayOled.setTextXY(5, 0);
+            SeeedGrayOled.putString("    ~ ~  ~ ");
+            SeeedGrayOled.setTextXY(6, 0);
+            SeeedGrayOled.putString(" ~~~~ ~  ~ ");
+            SeeedGrayOled.setTextXY(7, 0);
+            SeeedGrayOled.putString(" ~    ~  ~ ");
+            SeeedGrayOled.setTextXY(8, 0);
+            SeeedGrayOled.putString(" ~    ~  ~ ");
+            SeeedGrayOled.setTextXY(9, 0);
+            SeeedGrayOled.putString(" ~~~~ ~~~~  ");
+            break;
+        default: // 20
+            SeeedGrayOled.setTextXY(3, 0);
+            SeeedGrayOled.putString(" ~~~~ ~~~~ ");
+            SeeedGrayOled.setTextXY(4, 0);
+            SeeedGrayOled.putString("    ~ ~  ~ ");
+            SeeedGrayOled.setTextXY(5, 0);
+            SeeedGrayOled.putString("    ~ ~  ~ ");
+            SeeedGrayOled.setTextXY(6, 0);
+            SeeedGrayOled.putString(" ~~~~ ~  ~ ");
+            SeeedGrayOled.setTextXY(7, 0);
+            SeeedGrayOled.putString(" ~    ~  ~ ");
+            SeeedGrayOled.setTextXY(8, 0);
+            SeeedGrayOled.putString(" ~    ~  ~ ");
+            SeeedGrayOled.setTextXY(9, 0);
+            SeeedGrayOled.putString(" ~~~~ ~~~~ ~");
+            break;
+    }
+}
\ No newline at end of file
diff -r 000000000000 -r 879add9a219d mbed.bld
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Wed Aug 26 05:12:36 2015 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/8ed44a420e5c
\ No newline at end of file