* 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
Diff: main.cpp
- Revision:
- 0:879add9a219d
--- /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
Eric Jung