* 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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #include "EthernetInterface.h"
00003 
00004 #include "HTTPClient.h"     // HTTP Client library
00005 #include "NTPClient.h"      // NTP Client library (Network Time Protocol)
00006 
00007 #include "DigitDisplay.h"   // Seeed Grove: 4-digit Display
00008 #include "SeeedGrayOLED.h"  // Seeed Grove: OLED Display 0.96" 96x96
00009 
00010 Serial pc(USBTX, USBRX);
00011 
00012 PwmOut Buzzer(D6);
00013 DigitDisplay display(D0, D1); // 4-Digit Display connected to UART Grove connector
00014 SeeedGrayOLED SeeedGrayOled(D14, D15);
00015 DigitalOut myled(LED1);
00016 
00017 Ticker tick;
00018 
00019 ////////////////////////////////////////////////////////////////
00020 // Defines
00021 ////////////////////////////////////////////////////////////////
00022 
00023 /* User adjustable defines */
00024 ////////////////////////////////////////////////////////////////
00025 /* Debug Message Enable */
00026 #define _DEBUG_BUS_ARRIVAL_ALARM_       0
00027 
00028 /* Number of Displayed Bus Info */
00029 #define MAX_BUS_INFO                    3       // The maximum bus information request can be up to Three (3)
00030 
00031 /* Display mode */
00032 #define DISPLAY_MODE_CHANGE_CNT_SEC     10      // The OLED display holding time(sec) for each bus information displayed
00033 #define BUS_NUM_BLINK_ENABLE            1       // blink the 4-digit display when displayed bus numbers
00034 
00035 /* Alarm Sound Enabled and Time */
00036 #define ALARM_SOUND_ENABLE              1
00037 #define SOUND_START_HOUR                6
00038 #define SOUND_START_MIN                 15
00039 #define SOUND_END_HOUR                  07
00040 #define SOUND_END_MIN                   00
00041 
00042 /* HTTP client */
00043 //#define MAX_HTTPC_RETRY_CNT             2       // not used
00044 ////////////////////////////////////////////////////////////////
00045 
00046 /* Buzzer */
00047 #define VOLUME                          0.2     // 0.02
00048 #define BPM                             100.0
00049 
00050 /* Display mode define */
00051 #define DISPLAY_TIME_MODE               0   // do not change!
00052 
00053 /* Bus and Station (Busstop) info for GBIS openAPI */
00054 #define DEFAULT_STATION_NUM             38270 //(Gwangju -> Seoul)
00055 #define DEFAULT_STATION_ID              234000302       
00056 // for test
00057 //#define DEFAULT_STATION_NUM           38269 //(Seoul -> Gwangju)
00058 //#define DEFAULT_STATION_ID            234000294       
00059 
00060 typedef struct
00061 {    
00062     uint8_t * busNum;       // Bus number, This value should be input at initialize stage
00063     uint16_t stationNum;    // Station number, notused, This value should be input at initialize stage
00064     uint32_t routeId;       // Bus route id for openAPI querying (openapi.gbis.go.kr)   // This value should be input at initialize stage
00065     uint32_t stationId;     // Bus station id for openAPI querying (openapi.gbis.go.kr) // This value should be input at initialize stage
00066     uint8_t resultCode;     // 0; success, 4; bus info none
00067     uint8_t predictTime1;   // 1st bus arrival predict time ('1' means the bus gone)
00068     uint8_t predictTime2;   // 2st bus arrival predict time ('1' means the none of next bus info)
00069     uint8_t remainSeatCnt1; // 1st bus remain seat count
00070     uint8_t remainSeatCnt2; // 2st bus remain seat count    
00071 }BUSINFO;
00072 
00073 ////////////////////////////////////////////////////////////////
00074 // Function declaration
00075 ////////////////////////////////////////////////////////////////
00076 void BuzzerSound(void);                     // Buzzer
00077 void Display_BusNumber(uint8_t * busnum);   // 4-digit display
00078 uint8_t get_businfo(BUSINFO * bus);         // Get Bus information (HTTP client) 
00079 
00080 // OLED display
00081 void Draw_OLED_init(void);
00082 void Draw_OLED_default(void);
00083 void Draw_OLED_busInfo(uint8_t * busnum, uint8_t seats);
00084 void Draw_OLED_arrivalMin(uint8_t min);
00085 void Draw_OLED_nextMin(uint8_t nextmin);
00086 void Draw_OLED_busList(void);
00087 
00088 // for ticker
00089 void beat();
00090 
00091 ////////////////////////////////////////////////////////////////
00092 // Global variable declaration
00093 ////////////////////////////////////////////////////////////////
00094 BUSINFO businfo[MAX_BUS_INFO];
00095 uint8_t flag_display_mode[MAX_BUS_INFO+1] = {0, };
00096 uint8_t display_mode = 0;
00097 uint8_t buzzer_sound_enable = 0;
00098 
00099 time_t beat_cTime;
00100 struct tm *beat_localtime;
00101 
00102 uint8_t mac[6] = {0x00,0x08,0xDC,0x01,0x02,0x03};   // MAC address, It must be modified as users MAC address
00103 
00104 int main()
00105 {   
00106     pc.baud(115200);   
00107     EthernetInterface ethernet;   
00108     
00109     uint8_t i;
00110         
00111     ////////////////////////////////////////////////////////////////
00112     // Realtime Bus Information: Initialization
00113     ////////////////////////////////////////////////////////////////     
00114     
00115     /* Bus number and route ID */
00116     uint8_t busnum_1117[4] = {1, 1, 1, 7};
00117     uint32_t busnum_1117_routeId = 234000069;
00118     
00119     uint8_t busnum_1113[4] = {1, 1, 1, 3};
00120     uint32_t busnum_1113_routeId = 234000042;
00121     
00122     uint8_t busnum_1005[4] = {1, 0, 0, 5};
00123     uint32_t busnum_1005_routeId = 234000065;
00124     
00125     // Bus info structure initialize    
00126     businfo[0].busNum = busnum_1117;
00127     businfo[0].stationNum = DEFAULT_STATION_NUM;
00128     businfo[0].routeId = busnum_1117_routeId;
00129     businfo[0].stationId = DEFAULT_STATION_ID;    
00130     
00131     businfo[1].busNum = busnum_1113;    
00132     businfo[1].stationNum = DEFAULT_STATION_NUM;
00133     businfo[1].routeId = busnum_1113_routeId;    
00134     businfo[1].stationId = DEFAULT_STATION_ID;
00135     
00136     businfo[2].busNum = busnum_1005;    
00137     businfo[2].stationNum = DEFAULT_STATION_NUM;
00138     businfo[2].routeId = busnum_1005_routeId;    
00139     businfo[2].stationId = DEFAULT_STATION_ID;
00140     
00141     // OLED display initialize
00142     SeeedGrayOled.init();             // Initialize SEEED OLED display
00143     SeeedGrayOled.clearDisplay();     // Clear Display
00144     SeeedGrayOled.setNormalDisplay(); // Set Normal Display Mode
00145     
00146     // OLED display initial draw     
00147     Draw_OLED_default();    //Draw_OLED_init();
00148     
00149     printf("\r\n==========================================\r\n");
00150     printf(" Real-time Bus Arrival Alarm\r\n");
00151     printf("==========================================\r\n");
00152     printf(" Buzzer Sound START Time: %d:%.2d\r\n", SOUND_START_HOUR, SOUND_START_MIN);
00153     printf(" Buzzer Sound END Time  : %d:%.2d\r\n", SOUND_END_HOUR, SOUND_END_MIN);
00154     printf("==========================================\r\n");
00155     
00156     // Ethernet initialize
00157     int ret = ethernet.init(mac);    
00158     printf("\r\nWIZwiki-W7500 Networking Started\r\n");
00159     wait(1); // 1 second for stable state
00160 
00161     if (!ret) {
00162         printf("Initialized, MAC: %s\r\n", ethernet.getMACAddress());
00163         ret = ethernet.connect();
00164         if (!ret) {
00165             printf("IP: %s, MASK: %s, GW: %s\r\n",
00166                       ethernet.getIPAddress(), ethernet.getNetworkMask(), ethernet.getGateway());
00167         } else {
00168             printf("Error ethernet.connect() - ret = %d\r\n", ret);
00169             exit(0);
00170         }
00171     } else {
00172         printf("Error ethernet.init() - ret = %d\r\n", ret);
00173         exit(0);
00174     }
00175     
00176     // NTP initialize
00177     NTPClient ntp;    
00178     printf("\r\nTrying to update time...\r\n");    
00179     if (ntp.setTime("211.233.40.78") == 0) 
00180     {
00181         printf("Set time successfully\r\n");
00182         time_t ctTime;
00183         ctTime = time(NULL);
00184         ctTime += 32400; // GMT+9/Seoul
00185         printf("Time is set to (GMT+9): %s\r\n", ctime(&ctTime));
00186     }
00187     else
00188     {
00189         printf("Error\r\n");
00190     }
00191     
00192     // 4-Digit display initialize
00193     display.write(0, 0);
00194     display.write(1, 0);
00195     display.write(2, 0);
00196     display.write(3, 0);
00197     display.setColon(true);
00198     tick.attach(&beat, 0.5);
00199     
00200     // Initial flag setting for get the bus info
00201     flag_display_mode[DISPLAY_TIME_MODE] = 1;
00202     
00203     printf(">> Initialize Done\r\n");    
00204     
00205     // Main routine
00206     while(1) {
00207         
00208         if(display_mode == DISPLAY_TIME_MODE) // Display: Time mode
00209         {
00210             if(flag_display_mode[display_mode])
00211             {   
00212                 Draw_OLED_default();   
00213                 flag_display_mode[display_mode] = 0;
00214                 
00215                 // Get the buses info: Bus arrival time preparation (beforehand)
00216                 for(i = 0; i < MAX_BUS_INFO; i++)
00217                 {
00218                     get_businfo(&businfo[i]);                                    
00219                     
00220 #if (_DEBUG_BUS_ARRIVAL_ALARM_) //Debug message
00221                     printf("Businfo #%d\r\n", i);
00222                     printf("bus.resultCode = %c\r\n", businfo[i].resultCode);
00223                     printf("1st Bus arrive after %d min\r\n", businfo[i].predictTime1);    
00224                     printf("1st Bus remain seats %d\r\n", businfo[i].remainSeatCnt1);
00225                     printf("2nd Bus arrive after %d min\r\n", businfo[i].predictTime2);
00226                     printf("2nd Bus remain seats %d\r\n\r\n", businfo[i].remainSeatCnt2);
00227 #endif
00228                 }
00229             }
00230         }
00231         else // Display: Bus info mode
00232         {
00233             i = display_mode - 1;
00234             if(flag_display_mode[display_mode])
00235             {                   
00236                 Draw_OLED_busInfo(businfo[i].busNum, businfo[i].remainSeatCnt1);
00237                 Draw_OLED_arrivalMin(businfo[i].predictTime1);
00238                 if(businfo[i].predictTime2 == 1)
00239                 {
00240                     Draw_OLED_nextMin(0);
00241                 }
00242                 else
00243                 {
00244                     Draw_OLED_nextMin(businfo[i].predictTime2);   
00245                 }
00246                 
00247                 // Buzzer sound!
00248                 // Each case means the displayed time(Remaining time until the bus arrival, minute) to ringing the buzzer
00249                 switch(businfo[i].predictTime1)
00250                 {
00251                     case 5:
00252                     case 6:
00253                     case 7:                                                
00254                     case 8:
00255                     case 9:                        
00256                     case 10:                                         
00257                         BuzzerSound();                       
00258                         break;
00259                     default:
00260                         break;
00261                 }
00262                 
00263                 flag_display_mode[display_mode] = 0;                
00264             }
00265         }       
00266     }
00267 }
00268 
00269 ////////////////////////////////////////////////////////////////
00270 // Member function of Ticker interface (attaching to a ticker)
00271 ////////////////////////////////////////////////////////////////
00272 void beat()
00273 {
00274     static uint8_t colon = 0;
00275     static uint8_t myled_blink = 1;
00276     static uint8_t display_mode_change_cnt = 0; // initial count value; 5 sec reduced    
00277         
00278     // Get current local time info
00279     beat_cTime = time(NULL);
00280     beat_cTime += 32400; // GMT+9/Seoul    
00281     beat_localtime = localtime(&beat_cTime);    
00282     
00283     // Display Mode change handler (Time / Bus mode)
00284     display_mode_change_cnt++; // ++ every 0.5sec
00285     if((display_mode_change_cnt/2) >= DISPLAY_MODE_CHANGE_CNT_SEC)
00286     {
00287         display_mode++;        
00288         
00289         if(display_mode > MAX_BUS_INFO)
00290         {
00291             display_mode = DISPLAY_TIME_MODE; // 0
00292         }
00293          
00294         // Skip: (resultCode == 4) means 'Bus arrival info does not appear'
00295         while((display_mode != DISPLAY_TIME_MODE) && (businfo[display_mode-1].resultCode == 4))
00296         {
00297             display_mode++;
00298             
00299             if(display_mode > MAX_BUS_INFO)
00300             {
00301                 display_mode = DISPLAY_TIME_MODE; // 0
00302             }
00303         }        
00304         
00305         flag_display_mode[display_mode] = 1;
00306         display_mode_change_cnt = 0;
00307     }
00308     
00309     // 4-Digit Display handler
00310     if(display_mode == DISPLAY_TIME_MODE) // Time mode
00311     {
00312         display.on();
00313         display.setColon(colon);    
00314         if (colon) {                             
00315             display.write(0, beat_localtime->tm_hour / 10);
00316             display.write(1, beat_localtime->tm_hour % 10);        
00317             display.write(2, beat_localtime->tm_min / 10);
00318             display.write(3, beat_localtime->tm_min % 10);            
00319         }            
00320         //colon = 1 - colon;  // moved below     
00321     }
00322     else // Bus info mode                
00323     {       
00324 #if (BUS_NUM_BLINK_ENABLE)
00325         if(colon)
00326         {        
00327             Display_BusNumber(businfo[display_mode-1].busNum);
00328         }
00329         else
00330         {
00331             Display_BusNumber(NULL);
00332         }
00333 #else
00334         Display_BusNumber(businfo[display_mode-1].busNum);
00335 #endif
00336            
00337     }
00338     
00339     // Buzzer sound enable handler 
00340     buzzer_sound_enable = 0;
00341 #if (ALARM_SOUND_ENABLE)
00342     if(((beat_localtime->tm_hour == SOUND_START_HOUR) && (beat_localtime->tm_min >= SOUND_START_MIN)) || (beat_localtime->tm_hour > SOUND_START_HOUR))
00343     {
00344         if((beat_localtime->tm_hour < SOUND_END_HOUR) || ((beat_localtime->tm_hour == SOUND_END_HOUR) && (beat_localtime->tm_min < SOUND_END_MIN)))
00345         {
00346             buzzer_sound_enable = 1;
00347         }
00348     }
00349 #endif
00350     
00351     // LED blink; Device working indicator
00352     myled_blink ^= 1;
00353     myled = myled_blink ;
00354     
00355     // Invert every 0.5sec
00356     colon = 1 - colon;
00357 }
00358 
00359 ////////////////////////////////////////////////////////////////
00360 // Get Bus Information (HTTP client) Functions
00361 ////////////////////////////////////////////////////////////////
00362 uint8_t get_businfo(BUSINFO * bus)
00363 {
00364     uint8_t ret = 0;
00365     char str[2048] = {0, };
00366     char get_req[512] =  {0, };    
00367     char predictTime1[3], predictTime2[3];
00368     char remainSeatCnt1[3], remainSeatCnt2[3];    
00369     char *CurrentAddr = 0;
00370     
00371     //uint8_t retry_cnt = 0;            // Unimplemented, MAX_HTTPC_RETRY_CNT
00372     
00373     HTTPClient httpc;
00374     
00375     sprintf(get_req, "http://openapi.gbis.go.kr/ws/rest/busarrivalservice?serviceKey=test&routeId=%ld&stationId=%ld", bus->routeId, bus->stationId);    
00376     httpc.get(get_req, str, sizeof(str), 1000);
00377     
00378     CurrentAddr = strstr(str,"<resultCode>");
00379     bus->resultCode = *(CurrentAddr+12);  
00380         
00381     if(bus->resultCode == '0')
00382     {    
00383         CurrentAddr = strstr(str,"<predictTime1>");
00384         if((*(CurrentAddr+15)) == '<')
00385         {
00386             predictTime1[0] = *(CurrentAddr+14);
00387             predictTime1[1] = 0;
00388             predictTime1[2] = 0;
00389         }
00390         else
00391         {
00392             predictTime1[0] = *(CurrentAddr+14);
00393             predictTime1[1] = *(CurrentAddr+15);
00394             predictTime1[2] = 0;
00395         }
00396         bus->predictTime1 = (uint8_t)atoi(predictTime1);
00397             
00398         CurrentAddr = strstr(str,"<predictTime2>");
00399         if((*(CurrentAddr+15)) == '<')
00400         {
00401             predictTime2[0] = *(CurrentAddr+14);
00402             predictTime2[1] = 0;
00403             predictTime2[2] = 0;
00404         }
00405         else
00406         {
00407             predictTime2[0] = *(CurrentAddr+14);
00408             predictTime2[1] = *(CurrentAddr+15);
00409             predictTime2[2] = 0;
00410         }
00411         bus->predictTime2 = (uint8_t)atoi(predictTime2);
00412         
00413         CurrentAddr = strstr(str,"<remainSeatCnt1>");
00414         if((*(CurrentAddr+17)) == '<')
00415         {
00416             remainSeatCnt1[0] = *(CurrentAddr+16);
00417             remainSeatCnt1[1] = 0;
00418             remainSeatCnt1[2] = 0;
00419         }
00420         else
00421         {
00422             remainSeatCnt1[0] = *(CurrentAddr+16);
00423             remainSeatCnt1[1] = *(CurrentAddr+17);
00424             remainSeatCnt1[2] = 0;
00425         }
00426         bus->remainSeatCnt1 = (uint8_t)atoi(remainSeatCnt1);
00427         
00428         if(bus->predictTime2 > 1)   // (predictTime2 == 1) => The next bus information is not confirmed.
00429         {        
00430             CurrentAddr = strstr(str,"<remainSeatCnt2>");
00431             if((*(CurrentAddr+17)) == '<')
00432             {
00433                 remainSeatCnt2[0] = *(CurrentAddr+16);
00434                 remainSeatCnt2[1] = 0;
00435                 remainSeatCnt2[2] = 0;
00436             }
00437             else
00438             {
00439                 remainSeatCnt2[0] = *(CurrentAddr+16);
00440                 remainSeatCnt2[1] = *(CurrentAddr+17);
00441                 remainSeatCnt2[2] = 0;
00442             }
00443             bus->remainSeatCnt2 = (uint8_t)atoi(remainSeatCnt2);
00444         }
00445         
00446         ret = 1;
00447     }
00448     
00449     return ret;
00450 }
00451 
00452 ////////////////////////////////////////////////////////////////
00453 // Piezo Buzzer Functions
00454 ////////////////////////////////////////////////////////////////
00455 
00456 void playNote(float frequency, float duration, float volume) 
00457 {
00458     Buzzer.period(1.0/(double)frequency);
00459     Buzzer = ((double)volume/2.0);
00460     wait(duration);
00461     Buzzer = 0.0;
00462 }
00463 
00464 void BuzzerSound(void)
00465 {
00466     // Calculate duration of a quarter note from bpm
00467     float beat_duration = 60.0 / BPM;    
00468 
00469     if(buzzer_sound_enable)
00470     {
00471         //playNote(329.628, (0.75 * (double)beat_duration), VOLUME);
00472         //playNote(261.626, (0.75 * (double)beat_duration), VOLUME);
00473         playNote(529.628, (0.50 * (double)beat_duration), VOLUME);
00474         playNote(301.626, (0.50 * (double)beat_duration), VOLUME);
00475     }
00476 }
00477 
00478 ////////////////////////////////////////////////////////////////
00479 // 4-Digit Display Functions
00480 ////////////////////////////////////////////////////////////////
00481 
00482 void Display_BusNumber(uint8_t * busnum)
00483 {       
00484     display.setColon(false);
00485     
00486     if(busnum != NULL)
00487     {
00488         display.on();
00489         display.write(0, busnum[0]);
00490         display.write(1, busnum[1]);
00491         display.write(2, busnum[2]);
00492         display.write(3, busnum[3]);
00493     }
00494     else
00495     {
00496         display.off();    
00497     }
00498 }
00499 
00500 ////////////////////////////////////////////////////////////////
00501 // OLED Display Functions
00502 ////////////////////////////////////////////////////////////////
00503 
00504 void Draw_OLED_init(void)
00505 {
00506     uint8_t empty_busnum[4] = {0, 0, 0, 0};
00507     
00508     Draw_OLED_busInfo(empty_busnum, 0);
00509     Draw_OLED_nextMin(0);    
00510 }
00511 
00512 void Draw_OLED_default(void)
00513 {
00514     SeeedGrayOled.setTextXY(0, 1);
00515     SeeedGrayOled.putString("Bus NearBy ");
00516     SeeedGrayOled.setTextXY(1, 1);    
00517     SeeedGrayOled.putString("========== ");
00518     
00519     Draw_OLED_arrivalMin('b');
00520     
00521     SeeedGrayOled.setTextXY(11, 0);
00522     SeeedGrayOled.putString("WIZnet::Eric");    
00523 }
00524 
00525 void Draw_OLED_busList(void)
00526 {
00527     uint8_t i;
00528     char buf[15] = {0, };
00529     
00530     SeeedGrayOled.setTextXY(0, 1);
00531     SeeedGrayOled.putString("           ");
00532     SeeedGrayOled.setTextXY(1, 1);    
00533     SeeedGrayOled.putString("Bus List:");
00534     
00535     Draw_OLED_arrivalMin('t');   
00536     
00537     for(i = 0; i < MAX_BUS_INFO; i++)
00538     {        
00539         SeeedGrayOled.setTextXY(3+i, 2);
00540         sprintf(buf, "- %.1d%.1d%.1d%.1d", businfo[i].busNum[0], businfo[i].busNum[1], businfo[i].busNum[2], businfo[i].busNum[3]);
00541         SeeedGrayOled.putString(buf);
00542     }
00543     
00544     SeeedGrayOled.setTextXY(11, 1);
00545     SeeedGrayOled.putString("           ");
00546 }
00547 
00548 void Draw_OLED_busInfo(uint8_t * busnum, uint8_t seats)
00549 {
00550     char buf[15] = {0, };
00551     sprintf(buf, "Bus  %.1d%.1d%.1d%.1d ", busnum[0], busnum[1], busnum[2], busnum[3]);    
00552     SeeedGrayOled.setTextXY(0, 1);
00553     SeeedGrayOled.putString(buf);
00554     sprintf(buf, "Seats  %.2d ", seats);    
00555     SeeedGrayOled.setTextXY(1, 1);
00556     SeeedGrayOled.putString(buf);    
00557 }
00558 
00559 void Draw_OLED_nextMin(uint8_t nextmin)
00560 {
00561     char buf[15] = {0, };
00562     if(nextmin == 0)
00563     {
00564         sprintf(buf, "Next: -- min");
00565     }
00566     else
00567     {
00568         sprintf(buf, "Next: %.2d min", nextmin);
00569     }
00570     
00571     SeeedGrayOled.setTextXY(11, 0);
00572     SeeedGrayOled.putString(buf);
00573 }
00574 
00575 void Draw_OLED_arrivalMin(uint8_t min)
00576 {
00577     switch(min)
00578     {
00579          case 't':
00580             SeeedGrayOled.setTextXY(3, 0);
00581             SeeedGrayOled.putString("           ");
00582             SeeedGrayOled.setTextXY(4, 0);
00583             SeeedGrayOled.putString("           ");
00584             SeeedGrayOled.setTextXY(5, 0);
00585             SeeedGrayOled.putString("           ");
00586             SeeedGrayOled.setTextXY(6, 0);
00587             SeeedGrayOled.putString("           ");
00588             SeeedGrayOled.setTextXY(7, 0);
00589             SeeedGrayOled.putString("           ");
00590             SeeedGrayOled.setTextXY(8, 0);
00591             SeeedGrayOled.putString("           ");
00592             SeeedGrayOled.setTextXY(9, 0);
00593             SeeedGrayOled.putString("            ");
00594             break;
00595         case 'b':
00596             SeeedGrayOled.setTextXY(3, 0);
00597             SeeedGrayOled.putString("   ~~~~~   ");
00598             SeeedGrayOled.setTextXY(4, 0);
00599             SeeedGrayOled.putString("  ~     ~  ");
00600             SeeedGrayOled.setTextXY(5, 0);
00601             SeeedGrayOled.putString("  ~     ~  ");
00602             SeeedGrayOled.setTextXY(6, 0);
00603             SeeedGrayOled.putString("  ~~~~~~~  ");
00604             SeeedGrayOled.setTextXY(7, 0);
00605             SeeedGrayOled.putString("  ~ ~~~ ~  ");
00606             SeeedGrayOled.setTextXY(8, 0);
00607             SeeedGrayOled.putString("  ~~~~~~~  ");
00608             SeeedGrayOled.setTextXY(9, 0);
00609             SeeedGrayOled.putString("   ~~ ~~    ");
00610             break;
00611         case 0:
00612             SeeedGrayOled.setTextXY(3, 0);
00613             SeeedGrayOled.putString(" ~~~~ ~~~~ ");
00614             SeeedGrayOled.setTextXY(4, 0);
00615             SeeedGrayOled.putString(" ~  ~ ~  ~ ");
00616             SeeedGrayOled.setTextXY(5, 0);
00617             SeeedGrayOled.putString(" ~  ~ ~  ~ ");
00618             SeeedGrayOled.setTextXY(6, 0);
00619             SeeedGrayOled.putString(" ~  ~ ~  ~ ");
00620             SeeedGrayOled.setTextXY(7, 0);
00621             SeeedGrayOled.putString(" ~  ~ ~  ~ ");
00622             SeeedGrayOled.setTextXY(8, 0);
00623             SeeedGrayOled.putString(" ~  ~ ~  ~ ");
00624             SeeedGrayOled.setTextXY(9, 0);
00625             SeeedGrayOled.putString(" ~~~~ ~~~~  ");
00626             break;
00627         case 1:
00628             SeeedGrayOled.setTextXY(3, 0);
00629             SeeedGrayOled.putString("           ");
00630             SeeedGrayOled.setTextXY(4, 0);
00631             SeeedGrayOled.putString("    ~      ");
00632             SeeedGrayOled.setTextXY(5, 0);
00633             SeeedGrayOled.putString("   ~~      ");
00634             SeeedGrayOled.setTextXY(6, 0);
00635             SeeedGrayOled.putString("  ~~~~~~~  ");
00636             SeeedGrayOled.setTextXY(7, 0);
00637             SeeedGrayOled.putString("   ~~      ");
00638             SeeedGrayOled.setTextXY(8, 0);
00639             SeeedGrayOled.putString("    ~      ");
00640             SeeedGrayOled.setTextXY(9, 0);
00641             SeeedGrayOled.putString("      Gone! ");
00642             break;
00643         case 2:
00644             SeeedGrayOled.setTextXY(3, 0);
00645             SeeedGrayOled.putString("      ~~~~ ");
00646             SeeedGrayOled.setTextXY(4, 0);
00647             SeeedGrayOled.putString("         ~ ");
00648             SeeedGrayOled.setTextXY(5, 0);
00649             SeeedGrayOled.putString("         ~ ");
00650             SeeedGrayOled.setTextXY(6, 0);
00651             SeeedGrayOled.putString("      ~~~~ ");
00652             SeeedGrayOled.setTextXY(7, 0);
00653             SeeedGrayOled.putString("      ~    ");
00654             SeeedGrayOled.setTextXY(8, 0);
00655             SeeedGrayOled.putString("      ~    ");
00656             SeeedGrayOled.setTextXY(9, 0);
00657             SeeedGrayOled.putString("      ~~~~  ");
00658             break;
00659         case 3:
00660             SeeedGrayOled.setTextXY(3, 0);
00661             SeeedGrayOled.putString("      ~~~~ ");
00662             SeeedGrayOled.setTextXY(4, 0);
00663             SeeedGrayOled.putString("         ~ ");
00664             SeeedGrayOled.setTextXY(5, 0);
00665             SeeedGrayOled.putString("         ~ ");
00666             SeeedGrayOled.setTextXY(6, 0);
00667             SeeedGrayOled.putString("      ~~~~ ");
00668             SeeedGrayOled.setTextXY(7, 0);
00669             SeeedGrayOled.putString("         ~ ");
00670             SeeedGrayOled.setTextXY(8, 0);
00671             SeeedGrayOled.putString("         ~ ");
00672             SeeedGrayOled.setTextXY(9, 0);
00673             SeeedGrayOled.putString("      ~~~~  ");
00674             break;
00675          case 4:
00676             SeeedGrayOled.setTextXY(3, 0);
00677             SeeedGrayOled.putString("      ~ ~  ");
00678             SeeedGrayOled.setTextXY(4, 0);
00679             SeeedGrayOled.putString("      ~ ~  ");
00680             SeeedGrayOled.setTextXY(5, 0);
00681             SeeedGrayOled.putString("      ~ ~  ");
00682             SeeedGrayOled.setTextXY(6, 0);
00683             SeeedGrayOled.putString("      ~~~~ ");
00684             SeeedGrayOled.setTextXY(7, 0);
00685             SeeedGrayOled.putString("        ~  ");
00686             SeeedGrayOled.setTextXY(8, 0);
00687             SeeedGrayOled.putString("        ~  ");
00688             SeeedGrayOled.setTextXY(9, 0);
00689             SeeedGrayOled.putString("        ~   ");
00690             break;
00691         case 5:
00692             SeeedGrayOled.setTextXY(3, 0);
00693             SeeedGrayOled.putString("      ~~~~ ");
00694             SeeedGrayOled.setTextXY(4, 0);
00695             SeeedGrayOled.putString("      ~    ");
00696             SeeedGrayOled.setTextXY(5, 0);
00697             SeeedGrayOled.putString("      ~    ");
00698             SeeedGrayOled.setTextXY(6, 0);
00699             SeeedGrayOled.putString("      ~~~~ ");
00700             SeeedGrayOled.setTextXY(7, 0);
00701             SeeedGrayOled.putString("         ~ ");
00702             SeeedGrayOled.setTextXY(8, 0);
00703             SeeedGrayOled.putString("         ~ ");
00704             SeeedGrayOled.setTextXY(9, 0);
00705             SeeedGrayOled.putString("      ~~~~  ");
00706             break;
00707         case 6:
00708             SeeedGrayOled.setTextXY(3, 0);
00709             SeeedGrayOled.putString("      ~~~~ ");
00710             SeeedGrayOled.setTextXY(4, 0);
00711             SeeedGrayOled.putString("      ~    ");
00712             SeeedGrayOled.setTextXY(5, 0);
00713             SeeedGrayOled.putString("      ~    ");
00714             SeeedGrayOled.setTextXY(6, 0);
00715             SeeedGrayOled.putString("      ~~~~ ");
00716             SeeedGrayOled.setTextXY(7, 0);
00717             SeeedGrayOled.putString("      ~  ~ ");
00718             SeeedGrayOled.setTextXY(8, 0);
00719             SeeedGrayOled.putString("      ~  ~ ");
00720             SeeedGrayOled.setTextXY(9, 0);
00721             SeeedGrayOled.putString("      ~~~~  ");
00722             break;
00723         case 7:
00724             SeeedGrayOled.setTextXY(3, 0);
00725             SeeedGrayOled.putString("      ~~~~ ");
00726             SeeedGrayOled.setTextXY(4, 0);
00727             SeeedGrayOled.putString("      ~  ~ ");
00728             SeeedGrayOled.setTextXY(5, 0);
00729             SeeedGrayOled.putString("      ~  ~ ");
00730             SeeedGrayOled.setTextXY(6, 0);
00731             SeeedGrayOled.putString("      ~  ~ ");
00732             SeeedGrayOled.setTextXY(7, 0);
00733             SeeedGrayOled.putString("         ~ ");
00734             SeeedGrayOled.setTextXY(8, 0);
00735             SeeedGrayOled.putString("         ~ ");
00736             SeeedGrayOled.setTextXY(9, 0);
00737             SeeedGrayOled.putString("         ~  ");
00738             break;
00739         case 8:
00740             SeeedGrayOled.setTextXY(3, 0);
00741             SeeedGrayOled.putString("      ~~~~ ");
00742             SeeedGrayOled.setTextXY(4, 0);
00743             SeeedGrayOled.putString("      ~  ~ ");
00744             SeeedGrayOled.setTextXY(5, 0);
00745             SeeedGrayOled.putString("      ~  ~ ");
00746             SeeedGrayOled.setTextXY(6, 0);
00747             SeeedGrayOled.putString("      ~~~~ ");
00748             SeeedGrayOled.setTextXY(7, 0);
00749             SeeedGrayOled.putString("      ~  ~ ");
00750             SeeedGrayOled.setTextXY(8, 0);
00751             SeeedGrayOled.putString("      ~  ~ ");
00752             SeeedGrayOled.setTextXY(9, 0);
00753             SeeedGrayOled.putString("      ~~~~  ");
00754             break;
00755         case 9:
00756             SeeedGrayOled.setTextXY(3, 0);
00757             SeeedGrayOled.putString("      ~~~~ ");
00758             SeeedGrayOled.setTextXY(4, 0);
00759             SeeedGrayOled.putString("      ~  ~ ");
00760             SeeedGrayOled.setTextXY(5, 0);
00761             SeeedGrayOled.putString("      ~  ~ ");
00762             SeeedGrayOled.setTextXY(6, 0);
00763             SeeedGrayOled.putString("      ~~~~ ");
00764             SeeedGrayOled.setTextXY(7, 0);
00765             SeeedGrayOled.putString("         ~ ");
00766             SeeedGrayOled.setTextXY(8, 0);
00767             SeeedGrayOled.putString("         ~ ");
00768             SeeedGrayOled.setTextXY(9, 0);
00769             SeeedGrayOled.putString("      ~~~~  ");
00770             break;        
00771         case 10:
00772         case 11: // 10
00773             SeeedGrayOled.setTextXY(3, 0);
00774             SeeedGrayOled.putString("  ~~  ~~~~ ");
00775             SeeedGrayOled.setTextXY(4, 0);
00776             SeeedGrayOled.putString("   ~  ~  ~ ");
00777             SeeedGrayOled.setTextXY(5, 0);
00778             SeeedGrayOled.putString("   ~  ~  ~ ");
00779             SeeedGrayOled.setTextXY(6, 0);
00780             SeeedGrayOled.putString("   ~  ~  ~ ");
00781             SeeedGrayOled.setTextXY(7, 0);
00782             SeeedGrayOled.putString("   ~  ~  ~ ");
00783             SeeedGrayOled.setTextXY(8, 0);
00784             SeeedGrayOled.putString("   ~  ~  ~ ");
00785             SeeedGrayOled.setTextXY(9, 0);
00786             SeeedGrayOled.putString("   ~  ~~~~  ");
00787             break;
00788         case 12:
00789         case 13:
00790         case 14: // 12
00791             SeeedGrayOled.setTextXY(3, 0);
00792             SeeedGrayOled.putString("  ~~  ~~~~ ");
00793             SeeedGrayOled.setTextXY(4, 0);
00794             SeeedGrayOled.putString("   ~     ~ ");
00795             SeeedGrayOled.setTextXY(5, 0);
00796             SeeedGrayOled.putString("   ~     ~ ");
00797             SeeedGrayOled.setTextXY(6, 0);
00798             SeeedGrayOled.putString("   ~  ~~~~ ");
00799             SeeedGrayOled.setTextXY(7, 0);
00800             SeeedGrayOled.putString("   ~  ~    ");
00801             SeeedGrayOled.setTextXY(8, 0);
00802             SeeedGrayOled.putString("   ~  ~    ");
00803             SeeedGrayOled.setTextXY(9, 0);
00804             SeeedGrayOled.putString("   ~  ~~~~  ");
00805             break;
00806         case 15:
00807         case 16: // 15        
00808             SeeedGrayOled.setTextXY(3, 0);
00809             SeeedGrayOled.putString("  ~~  ~~~~ ");
00810             SeeedGrayOled.setTextXY(4, 0);
00811             SeeedGrayOled.putString("   ~  ~    ");
00812             SeeedGrayOled.setTextXY(5, 0);
00813             SeeedGrayOled.putString("   ~  ~    ");
00814             SeeedGrayOled.setTextXY(6, 0);
00815             SeeedGrayOled.putString("   ~  ~~~~ ");
00816             SeeedGrayOled.setTextXY(7, 0);
00817             SeeedGrayOled.putString("   ~     ~ ");
00818             SeeedGrayOled.setTextXY(8, 0);
00819             SeeedGrayOled.putString("   ~     ~ ");
00820             SeeedGrayOled.setTextXY(9, 0);
00821             SeeedGrayOled.putString("   ~  ~~~~  ");
00822             break;
00823         case 17:
00824         case 18: // 17
00825         case 19: // 17
00826             SeeedGrayOled.setTextXY(3, 0);
00827             SeeedGrayOled.putString("  ~~  ~~~~ ");
00828             SeeedGrayOled.setTextXY(4, 0);
00829             SeeedGrayOled.putString("   ~  ~  ~ ");
00830             SeeedGrayOled.setTextXY(5, 0);
00831             SeeedGrayOled.putString("   ~  ~  ~ ");
00832             SeeedGrayOled.setTextXY(6, 0);
00833             SeeedGrayOled.putString("   ~  ~  ~ ");
00834             SeeedGrayOled.setTextXY(7, 0);
00835             SeeedGrayOled.putString("   ~     ~ ");
00836             SeeedGrayOled.setTextXY(8, 0);
00837             SeeedGrayOled.putString("   ~     ~ ");
00838             SeeedGrayOled.setTextXY(9, 0);
00839             SeeedGrayOled.putString("   ~     ~  ");
00840             break;
00841         case 20: // 20
00842             SeeedGrayOled.setTextXY(3, 0);
00843             SeeedGrayOled.putString(" ~~~~ ~~~~ ");
00844             SeeedGrayOled.setTextXY(4, 0);
00845             SeeedGrayOled.putString("    ~ ~  ~ ");
00846             SeeedGrayOled.setTextXY(5, 0);
00847             SeeedGrayOled.putString("    ~ ~  ~ ");
00848             SeeedGrayOled.setTextXY(6, 0);
00849             SeeedGrayOled.putString(" ~~~~ ~  ~ ");
00850             SeeedGrayOled.setTextXY(7, 0);
00851             SeeedGrayOled.putString(" ~    ~  ~ ");
00852             SeeedGrayOled.setTextXY(8, 0);
00853             SeeedGrayOled.putString(" ~    ~  ~ ");
00854             SeeedGrayOled.setTextXY(9, 0);
00855             SeeedGrayOled.putString(" ~~~~ ~~~~  ");
00856             break;
00857         default: // 20
00858             SeeedGrayOled.setTextXY(3, 0);
00859             SeeedGrayOled.putString(" ~~~~ ~~~~ ");
00860             SeeedGrayOled.setTextXY(4, 0);
00861             SeeedGrayOled.putString("    ~ ~  ~ ");
00862             SeeedGrayOled.setTextXY(5, 0);
00863             SeeedGrayOled.putString("    ~ ~  ~ ");
00864             SeeedGrayOled.setTextXY(6, 0);
00865             SeeedGrayOled.putString(" ~~~~ ~  ~ ");
00866             SeeedGrayOled.setTextXY(7, 0);
00867             SeeedGrayOled.putString(" ~    ~  ~ ");
00868             SeeedGrayOled.setTextXY(8, 0);
00869             SeeedGrayOled.putString(" ~    ~  ~ ");
00870             SeeedGrayOled.setTextXY(9, 0);
00871             SeeedGrayOled.putString(" ~~~~ ~~~~ ~");
00872             break;
00873     }
00874 }