From 3f9ec9de1b6df48876b9cc21b3526e938e3ce39b Mon Sep 17 00:00:00 2001 From: Shuanglei Tao Date: Wed, 26 Mar 2025 15:45:51 +0800 Subject: [PATCH] initial clock mode impl --- EPD/EPD_config.h | 4 +- EPD/EPD_driver.c | 44 ++++++ EPD/EPD_driver.h | 5 +- EPD/EPD_service.c | 25 ++-- EPD/EPD_service.h | 11 +- GUI/Calendar.c | 124 ----------------- GUI/Calendar.h | 9 -- GUI/GUI.c | 238 +++++++++++++++++++++++++++++++ GUI/GUI.h | 15 ++ GUI/Lunar.h | 4 +- GUI/fonts.c | 310 +++++++++++++++++++++++++++++------------ GUI/fonts.h | 18 +-- Keil/EPD-nRF51.uvprojx | 8 +- Keil/EPD-nRF52.uvprojx | 8 +- Makefile.nRF51 | 2 +- Makefile.nRF52 | 2 +- html/index.html | 12 +- html/js/main.js | 11 +- main.c | 5 +- 19 files changed, 578 insertions(+), 277 deletions(-) delete mode 100644 GUI/Calendar.c delete mode 100644 GUI/Calendar.h create mode 100644 GUI/GUI.c create mode 100644 GUI/GUI.h diff --git a/EPD/EPD_config.h b/EPD/EPD_config.h index 0721b5d..bf19024 100644 --- a/EPD/EPD_config.h +++ b/EPD/EPD_config.h @@ -1,5 +1,5 @@ -#ifndef EPD_CONFIG_H__ -#define EPD_CONFIG_H__ +#ifndef __EPD_CONFIG_H +#define __EPD_CONFIG_H #include #include diff --git a/EPD/EPD_driver.c b/EPD/EPD_driver.c index 4e90b74..d00cdb1 100644 --- a/EPD/EPD_driver.c +++ b/EPD/EPD_driver.c @@ -336,6 +336,50 @@ void EPD_LED_BLINK(void) } } +float EPD_ReadVoltage(void) +{ + #if defined(S112) + volatile int16_t value = 0; + NRF_SAADC->RESOLUTION = SAADC_RESOLUTION_VAL_10bit; + NRF_SAADC->ENABLE = (SAADC_ENABLE_ENABLE_Enabled << SAADC_ENABLE_ENABLE_Pos); + NRF_SAADC->CH[0].CONFIG = ((SAADC_CH_CONFIG_RESP_Bypass << SAADC_CH_CONFIG_RESP_Pos) & SAADC_CH_CONFIG_RESP_Msk) + | ((SAADC_CH_CONFIG_RESP_Bypass << SAADC_CH_CONFIG_RESN_Pos) & SAADC_CH_CONFIG_RESN_Msk) + | ((SAADC_CH_CONFIG_GAIN_Gain1_6 << SAADC_CH_CONFIG_GAIN_Pos) & SAADC_CH_CONFIG_GAIN_Msk) + | ((SAADC_CH_CONFIG_REFSEL_Internal << SAADC_CH_CONFIG_REFSEL_Pos) & SAADC_CH_CONFIG_REFSEL_Msk) + | ((SAADC_CH_CONFIG_TACQ_3us << SAADC_CH_CONFIG_TACQ_Pos) & SAADC_CH_CONFIG_TACQ_Msk) + | ((SAADC_CH_CONFIG_MODE_SE << SAADC_CH_CONFIG_MODE_Pos) & SAADC_CH_CONFIG_MODE_Msk); + NRF_SAADC->CH[0].PSELN = SAADC_CH_PSELN_PSELN_NC; + NRF_SAADC->CH[0].PSELP = SAADC_CH_PSELP_PSELP_VDD; + NRF_SAADC->RESULT.PTR = (uint32_t)&value; + NRF_SAADC->RESULT.MAXCNT = 1; + NRF_SAADC->TASKS_START = 0x01UL; + while (!NRF_SAADC->EVENTS_STARTED); + NRF_SAADC->EVENTS_STARTED = 0x00UL; + NRF_SAADC->TASKS_SAMPLE = 0x01UL; + while (!NRF_SAADC->EVENTS_END); + NRF_SAADC->EVENTS_END = 0x00UL; + NRF_SAADC->TASKS_STOP = 0x01UL; + while (!NRF_SAADC->EVENTS_STOPPED); + NRF_SAADC->EVENTS_STOPPED = 0x00UL; + if (value < 0) value = 0; + NRF_SAADC->ENABLE = (SAADC_ENABLE_ENABLE_Disabled << SAADC_ENABLE_ENABLE_Pos); +#else + NRF_ADC->ENABLE = 1; + NRF_ADC->CONFIG = (ADC_CONFIG_RES_10bit << ADC_CONFIG_RES_Pos) | + (ADC_CONFIG_INPSEL_SupplyOneThirdPrescaling << ADC_CONFIG_INPSEL_Pos) | + (ADC_CONFIG_REFSEL_VBG << ADC_CONFIG_REFSEL_Pos) | + (ADC_CONFIG_PSEL_Disabled << ADC_CONFIG_PSEL_Pos) | + (ADC_CONFIG_EXTREFSEL_None << ADC_CONFIG_EXTREFSEL_Pos); + NRF_ADC->TASKS_START = 1; + while(!NRF_ADC->EVENTS_END); + uint16_t value = NRF_ADC->RESULT; + NRF_ADC->TASKS_STOP = 1; + NRF_ADC->ENABLE = 0; +#endif + NRF_LOG_DEBUG("ADC value: %d\n", value); + return (value * 3.6) / (1 << 10); +} + // EPD models extern epd_model_t epd_uc8176_420_bw; extern epd_model_t epd_uc8176_420_bwr; diff --git a/EPD/EPD_driver.h b/EPD/EPD_driver.h index f79ed8c..3a37335 100644 --- a/EPD/EPD_driver.h +++ b/EPD/EPD_driver.h @@ -93,12 +93,15 @@ void EPD_WriteData(uint8_t *Data, uint8_t Len); void EPD_Reset(uint32_t value, uint16_t duration); void EPD_WaitBusy(uint32_t value, uint16_t timeout); -// lED +// LED void EPD_LED_ON(void); void EPD_LED_OFF(void); void EPD_LED_Toggle(void); void EPD_LED_BLINK(void); +// VDD voltage +float EPD_ReadVoltage(void); + epd_model_t *epd_get(void); epd_model_t *epd_init(epd_model_id_t id); diff --git a/EPD/EPD_service.c b/EPD/EPD_service.c index e9661de..8e6b693 100644 --- a/EPD/EPD_service.c +++ b/EPD/EPD_service.c @@ -17,14 +17,13 @@ #include "nrf_gpio.h" #include "app_scheduler.h" #include "EPD_service.h" -#include "Calendar.h" #include "nrf_log.h" #if defined(S112) //#define EPD_CFG_DEFAULT {0x14, 0x13, 0x06, 0x05, 0x04, 0x03, 0x02, 0x03, 0xFF, 0x12, 0x07} // 52811 #define EPD_CFG_DEFAULT {0x14, 0x13, 0x12, 0x11, 0x10, 0x0F, 0x0E, 0x03, 0xFF, 0x0D, 0x02} // 52810 #else -#define EPD_CFG_DEFAULT {0x05, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x01, 0x07} +//#define EPD_CFG_DEFAULT {0x05, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x01, 0x07} #endif #ifndef EPD_CFG_DEFAULT @@ -59,16 +58,14 @@ static void epd_gpio_uninit() } } -static void calendar_update(void * p_event_data, uint16_t event_size) +static void epd_gui_update(void * p_event_data, uint16_t event_size) { - epd_calendar_update_event_t *event = (epd_calendar_update_event_t *)p_event_data; + epd_gui_update_event_t *event = (epd_gui_update_event_t *)p_event_data; ble_epd_t *p_epd = event->p_epd; - p_epd->calendar_mode = true; - epd_gpio_init(); epd_model_t *epd = epd_init((epd_model_id_t)p_epd->config.model_id); - DrawCalendar(epd, event->timestamp); + DrawGUI(epd, event->timestamp, p_epd->display_mode); epd_gpio_uninit(); } @@ -138,7 +135,7 @@ static void epd_service_process(ble_epd_t * p_epd, uint8_t * p_data, uint16_t le } break; case EPD_CMD_CLEAR: - p_epd->calendar_mode = false; + p_epd->display_mode = MODE_NONE; p_epd->epd->drv->clear(); break; @@ -152,7 +149,7 @@ static void epd_service_process(ble_epd_t * p_epd, uint8_t * p_data, uint16_t le break; case EPD_CMD_DISPLAY: - p_epd->calendar_mode = false; + p_epd->display_mode = MODE_NONE; p_epd->epd->drv->refresh(); break; @@ -359,9 +356,11 @@ uint32_t ble_epd_string_send(ble_epd_t * p_epd, uint8_t * p_string, uint16_t len void ble_epd_on_timer(ble_epd_t * p_epd, uint32_t timestamp, bool force_update) { - // Update calendar on 00:00:00 - if (force_update || (p_epd->calendar_mode && timestamp % 86400 == 0)) { - epd_calendar_update_event_t event = { p_epd, timestamp }; - app_sched_event_put(&event, sizeof(epd_calendar_update_event_t), calendar_update); + // Update calendar on 00:00:00, clock on every minute + if (force_update || + (p_epd->display_mode == MODE_CALENDAR && timestamp % 86400 == 0) || + (p_epd->display_mode == MODE_CLOCK && timestamp % 60 == 0)) { + epd_gui_update_event_t event = { p_epd, timestamp }; + app_sched_event_put(&event, sizeof(epd_gui_update_event_t), epd_gui_update); } } diff --git a/EPD/EPD_service.h b/EPD/EPD_service.h index ce9af3b..fb9d0a6 100644 --- a/EPD/EPD_service.h +++ b/EPD/EPD_service.h @@ -10,8 +10,8 @@ * */ -#ifndef EPD_SERVICE_H__ -#define EPD_SERVICE_H__ +#ifndef __EPD_SERVICE_H +#define __EPD_SERVICE_H #include #include @@ -23,6 +23,7 @@ #include "sdk_config.h" #include "EPD_driver.h" #include "EPD_config.h" +#include "GUI.h" /**@brief Macro for defining a ble_hts instance. * @@ -85,16 +86,16 @@ typedef struct epd_model_t *epd; /**< current EPD model */ epd_config_t config; /**< EPD config */ epd_callback_t epd_cmd_cb; /**< EPD callback */ - bool calendar_mode; /**< Calendar mode flag */ + display_mode_t display_mode; /**< gui display mode */ } ble_epd_t; typedef struct { ble_epd_t *p_epd; uint32_t timestamp; -} epd_calendar_update_event_t; +} epd_gui_update_event_t; -#define EPD_CALENDAR_SCHD_EVENT_DATA_SIZE sizeof(epd_calendar_update_event_t) +#define EPD_GUI_SCHD_EVENT_DATA_SIZE sizeof(epd_gui_update_event_t) /**@brief Function for preparing sleep mode. * diff --git a/GUI/Calendar.c b/GUI/Calendar.c deleted file mode 100644 index c7734b3..0000000 --- a/GUI/Calendar.c +++ /dev/null @@ -1,124 +0,0 @@ -#include "Adafruit_GFX.h" -#include "fonts.h" -#include "Lunar.h" -#include "Calendar.h" -#include "nrf_log.h" - -#define PAGE_HEIGHT ((__HEAP_SIZE / 50) - 4) - -#define GFX_printf_styled(gfx, fg, bg, font, ...) \ - GFX_setTextColor(gfx, fg, bg); \ - GFX_setFont(gfx, font); \ - GFX_printf(gfx, __VA_ARGS__); - -static void DrawDateHeader(Adafruit_GFX *gfx, int16_t x, int16_t y, tm_t *tm, struct Lunar_Date *Lunar) -{ - GFX_setCursor(gfx, x, y); - GFX_printf_styled(gfx, GFX_RED, GFX_WHITE, u8g2_font_helvB18_tn, "%d", tm->tm_year + YEAR0); - GFX_printf_styled(gfx, GFX_BLACK, GFX_WHITE, u8g2_font_wqy12_t_lunar, "年"); - GFX_printf_styled(gfx, GFX_RED, GFX_WHITE, u8g2_font_helvB18_tn, "%02d", tm->tm_mon + 1); - GFX_printf_styled(gfx, GFX_BLACK, GFX_WHITE, u8g2_font_wqy12_t_lunar, "月"); - GFX_printf_styled(gfx, GFX_RED, GFX_WHITE, u8g2_font_helvB18_tn, "%02d", tm->tm_mday); - GFX_printf_styled(gfx, GFX_BLACK, GFX_WHITE, u8g2_font_wqy12_t_lunar, "日 "); - - GFX_setFont(gfx, u8g2_font_wqy9_t_lunar); - GFX_printf(gfx, "星期%s", Lunar_DayString[tm->tm_wday]); - - LUNAR_SolarToLunar(Lunar, tm->tm_year + YEAR0, tm->tm_mon + 1, tm->tm_mday); - - GFX_setCursor(gfx, x + 270, y); - GFX_printf(gfx, "%s%s%s %s%s", Lunar_MonthLeapString[Lunar->IsLeap], Lunar_MonthString[Lunar->Month], - Lunar_DateString[Lunar->Date], Lunar_StemStrig[LUNAR_GetStem(Lunar)], - Lunar_BranchStrig[LUNAR_GetBranch(Lunar)]); - GFX_setTextColor(gfx, GFX_RED, GFX_WHITE); - GFX_printf(gfx, "%s", Lunar_ZodiacString[LUNAR_GetZodiac(Lunar)]); - GFX_setTextColor(gfx, GFX_BLACK, GFX_WHITE); - GFX_printf(gfx, "年"); -} - -static void DrawWeekHeader(Adafruit_GFX *gfx, int16_t x, int16_t y) -{ - GFX_fillRect(gfx, x, y, 380, 24, GFX_RED); - GFX_fillRect(gfx, x + 50, y, 280, 24, GFX_BLACK); - GFX_setFont(gfx, u8g2_font_wqy9_t_lunar); - for (int i = 0; i < 7; i++) { - GFX_setTextColor(gfx, GFX_WHITE, (i > 0 && i < 6) ? GFX_BLACK : GFX_RED); - GFX_setCursor(gfx, x + 15 + i * 55, y + 16); - GFX_printf(gfx, "%s", Lunar_DayString[i]); - } -} - -static void DrawMonthDays(Adafruit_GFX *gfx, tm_t *tm, struct Lunar_Date *Lunar) -{ - uint8_t firstDayWeek = get_first_day_week(tm->tm_year + YEAR0, tm->tm_mon + 1); - uint8_t monthMaxDays = thisMonthMaxDays(tm->tm_year + YEAR0, tm->tm_mon + 1); - uint8_t monthDayRows = 1 + (monthMaxDays - (7 - firstDayWeek) + 6) / 7; - - for (uint8_t i = 0; i < monthMaxDays; i++) { - uint8_t day = i + 1; - - int16_t w = (firstDayWeek + i) % 7; - bool weekend = (w == 0) || (w == 6); - - int16_t x = 22 + w * 55; - int16_t y = (monthDayRows > 5 ? 69 : 72) + (firstDayWeek + i) / 7 * (monthDayRows > 5 ? 39 : 48); - - if (day == tm->tm_mday) { - GFX_fillCircle(gfx, x + 11, y + (monthDayRows > 5 ? 10 : 12), 20, GFX_RED); - GFX_setTextColor(gfx, GFX_WHITE, GFX_RED); - } else { - GFX_setTextColor(gfx, weekend ? GFX_RED : GFX_BLACK, GFX_WHITE); - } - - GFX_setFont(gfx, u8g2_font_helvB14_tn); - GFX_setCursor(gfx, x + (day < 10 ? 6 : 2), y + 10); - GFX_printf(gfx, "%d", day); - - GFX_setFont(gfx, u8g2_font_wqy9_t_lunar); - GFX_setCursor(gfx, x, y + 24); - uint8_t JQdate; - if (GetJieQi(tm->tm_year + YEAR0, tm->tm_mon + 1, day, &JQdate) && JQdate == day) { - uint8_t JQ = (tm->tm_mon + 1 - 1) * 2; - if (day >= 15) JQ++; - if (day != tm->tm_mday) GFX_setTextColor(gfx, GFX_RED, GFX_WHITE); - GFX_printf(gfx, "%s", JieQiStr[JQ]); - } else { - LUNAR_SolarToLunar(Lunar, tm->tm_year + YEAR0, tm->tm_mon + 1, day); - if (Lunar->Date == 1) - GFX_printf(gfx, "%s", Lunar_MonthString[Lunar->Month]); - else - GFX_printf(gfx, "%s", Lunar_DateString[Lunar->Date]); - } - } -} - -void DrawCalendar(epd_model_t *epd, uint32_t timestamp) -{ - tm_t tm = {0}; - struct Lunar_Date Lunar; - - transformTime(timestamp, &tm); - - Adafruit_GFX gfx; - - if (epd->bwr) - GFX_begin_3c(&gfx, epd->width, epd->height, PAGE_HEIGHT); - else - GFX_begin(&gfx, epd->width, epd->height, PAGE_HEIGHT); - - GFX_firstPage(&gfx); - do { - NRF_LOG_DEBUG("page %d\n", gfx.current_page); - GFX_fillScreen(&gfx, GFX_WHITE); - - DrawDateHeader(&gfx, 10, 28, &tm, &Lunar); - DrawWeekHeader(&gfx, 10, 32); - DrawMonthDays(&gfx, &tm, &Lunar); - } while(GFX_nextPage(&gfx, epd->drv->write_image)); - - GFX_end(&gfx); - - NRF_LOG_DEBUG("display start\n"); - epd->drv->refresh(); - NRF_LOG_DEBUG("display end\n"); -} diff --git a/GUI/Calendar.h b/GUI/Calendar.h deleted file mode 100644 index 05f987d..0000000 --- a/GUI/Calendar.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef __CALENDAR_H -#define __CALENDAR_H - -#include -#include "EPD_driver.h" - -void DrawCalendar(epd_model_t *epd, uint32_t timestamp); - -#endif diff --git a/GUI/GUI.c b/GUI/GUI.c new file mode 100644 index 0000000..7a1c051 --- /dev/null +++ b/GUI/GUI.c @@ -0,0 +1,238 @@ +#include "Adafruit_GFX.h" +#include "fonts.h" +#include "Lunar.h" +#include "GUI.h" +#include "nrf.h" +#include "nrf_log.h" +#include + +#define PAGE_HEIGHT ((__HEAP_SIZE / 50) - 4) + +#define GFX_printf_styled(gfx, fg, bg, font, ...) \ + GFX_setTextColor(gfx, fg, bg); \ + GFX_setFont(gfx, font); \ + GFX_printf(gfx, __VA_ARGS__); + +static void DrawDate(Adafruit_GFX *gfx, int16_t x, int16_t y, tm_t *tm) +{ + GFX_setCursor(gfx, x, y); + GFX_printf_styled(gfx, GFX_RED, GFX_WHITE, u8g2_font_helvB18_tn, "%d", tm->tm_year + YEAR0); + GFX_printf_styled(gfx, GFX_BLACK, GFX_WHITE, u8g2_font_wqy12_t_lunar, "年"); + GFX_printf_styled(gfx, GFX_RED, GFX_WHITE, u8g2_font_helvB18_tn, "%02d", tm->tm_mon + 1); + GFX_printf_styled(gfx, GFX_BLACK, GFX_WHITE, u8g2_font_wqy12_t_lunar, "月"); + GFX_printf_styled(gfx, GFX_RED, GFX_WHITE, u8g2_font_helvB18_tn, "%02d", tm->tm_mday); + GFX_printf_styled(gfx, GFX_BLACK, GFX_WHITE, u8g2_font_wqy12_t_lunar, "日 "); +} + +static void DrawDateHeader(Adafruit_GFX *gfx, int16_t x, int16_t y, tm_t *tm, struct Lunar_Date *Lunar) +{ + DrawDate(gfx, x, y, tm); + GFX_setFont(gfx, u8g2_font_wqy9_t_lunar); + GFX_printf(gfx, "星期%s", Lunar_DayString[tm->tm_wday]); + + GFX_setCursor(gfx, x + 270, y); + GFX_printf(gfx, "%s%s%s %s%s", Lunar_MonthLeapString[Lunar->IsLeap], Lunar_MonthString[Lunar->Month], + Lunar_DateString[Lunar->Date], Lunar_StemStrig[LUNAR_GetStem(Lunar)], + Lunar_BranchStrig[LUNAR_GetBranch(Lunar)]); + GFX_setTextColor(gfx, GFX_RED, GFX_WHITE); + GFX_printf(gfx, "%s", Lunar_ZodiacString[LUNAR_GetZodiac(Lunar)]); + GFX_setTextColor(gfx, GFX_BLACK, GFX_WHITE); + GFX_printf(gfx, "年"); +} + +static void DrawWeekHeader(Adafruit_GFX *gfx, int16_t x, int16_t y) +{ + GFX_fillRect(gfx, x, y, 380, 24, GFX_RED); + GFX_fillRect(gfx, x + 50, y, 280, 24, GFX_BLACK); + GFX_setFont(gfx, u8g2_font_wqy9_t_lunar); + for (int i = 0; i < 7; i++) { + GFX_setTextColor(gfx, GFX_WHITE, (i > 0 && i < 6) ? GFX_BLACK : GFX_RED); + GFX_setCursor(gfx, x + 15 + i * 55, y + 16); + GFX_printf(gfx, "%s", Lunar_DayString[i]); + } +} + +static void DrawMonthDays(Adafruit_GFX *gfx, tm_t *tm, struct Lunar_Date *Lunar) +{ + uint8_t firstDayWeek = get_first_day_week(tm->tm_year + YEAR0, tm->tm_mon + 1); + uint8_t monthMaxDays = thisMonthMaxDays(tm->tm_year + YEAR0, tm->tm_mon + 1); + uint8_t monthDayRows = 1 + (monthMaxDays - (7 - firstDayWeek) + 6) / 7; + + for (uint8_t i = 0; i < monthMaxDays; i++) { + uint8_t day = i + 1; + + int16_t w = (firstDayWeek + i) % 7; + bool weekend = (w == 0) || (w == 6); + + int16_t x = 22 + w * 55; + int16_t y = (monthDayRows > 5 ? 69 : 72) + (firstDayWeek + i) / 7 * (monthDayRows > 5 ? 39 : 48); + + if (day == tm->tm_mday) { + GFX_fillCircle(gfx, x + 11, y + (monthDayRows > 5 ? 10 : 12), 20, GFX_RED); + GFX_setTextColor(gfx, GFX_WHITE, GFX_RED); + } else { + GFX_setTextColor(gfx, weekend ? GFX_RED : GFX_BLACK, GFX_WHITE); + } + + GFX_setFont(gfx, u8g2_font_helvB14_tn); + GFX_setCursor(gfx, x + (day < 10 ? 6 : 2), y + 10); + GFX_printf(gfx, "%d", day); + + GFX_setFont(gfx, u8g2_font_wqy9_t_lunar); + GFX_setCursor(gfx, x, y + 24); + uint8_t JQdate; + if (GetJieQi(tm->tm_year + YEAR0, tm->tm_mon + 1, day, &JQdate) && JQdate == day) { + uint8_t JQ = (tm->tm_mon + 1 - 1) * 2; + if (day >= 15) JQ++; + if (day != tm->tm_mday) GFX_setTextColor(gfx, GFX_RED, GFX_WHITE); + GFX_printf(gfx, "%s", JieQiStr[JQ]); + } else { + LUNAR_SolarToLunar(Lunar, tm->tm_year + YEAR0, tm->tm_mon + 1, day); + if (Lunar->Date == 1) + GFX_printf(gfx, "%s", Lunar_MonthString[Lunar->Month]); + else + GFX_printf(gfx, "%s", Lunar_DateString[Lunar->Date]); + } + } +} + +static void DrawCalendar(Adafruit_GFX *gfx, tm_t *tm, struct Lunar_Date *Lunar) +{ + DrawDateHeader(gfx, 10, 28, tm, Lunar); + DrawWeekHeader(gfx, 10, 32); + DrawMonthDays(gfx, tm, Lunar); +} + +/* Routine to Draw Large 7-Segment formated number + Contributed by William Zaggle. + + int n - The number to be displayed + int xLoc = The x location of the upper left corner of the number + int yLoc = The y location of the upper left corner of the number + int cS = The size of the number. + fC is the foreground color of the number + bC is the background color of the number (prevents having to clear previous space) + nD is the number of digit spaces to occupy (must include space for minus sign for numbers < 0). + + width: nD*(11*cS+2)-2*cS + height: 20*cS+4 + + https://forum.arduino.cc/t/fast-7-segment-number-display-for-tft/296619/4 +*/ +static void Draw7Number(Adafruit_GFX *gfx, int n, unsigned int xLoc, unsigned int yLoc, char cS, unsigned int fC, unsigned int bC, char nD) { + unsigned int num=abs(n),i,t,w,col,h,a,b,j=1,d=0,S2=5*cS,S3=2*cS,S4=7*cS,x1=cS+1,x2=S3+S2+1,y1=yLoc+x1,y3=yLoc+S3+S4+1; + unsigned int seg[7][3]={{x1,yLoc,1},{x2,y1,0},{x2,y3+x1,0},{x1,(2*y3)-yLoc,1},{0,y3+x1,0},{0,y1,0},{x1,y3,1}}; + unsigned char nums[12]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00,0x40},c=(c=abs(cS))>10?10:(c<1)?1:c,cnt=(cnt=abs(nD))>10?10:(cnt<1)?1:cnt; + for (xLoc+=cnt*(d=S2+(3*S3)+2);cnt>0;cnt--){ + for (i=(num>9)?num%10:((!cnt)&&(n<0))?11:((nD<0)&&(!num))?10:num,xLoc-=d,num/=10,j=0;j<7;++j){ + col=(nums[i]&(1<tm_hour, x, y, cS, GFX_BLACK, GFX_WHITE, nD); + x += (nD*(11*cS+2)-2*cS) + 2*cS; + GFX_fillRect(gfx, x, y + 4.5*cS+1, 2*cS, 2*cS, GFX_BLACK); + GFX_fillRect(gfx, x, y + 13.5*cS+3, 2*cS, 2*cS, GFX_BLACK); + x += 4*cS; + Draw7Number(gfx, tm->tm_min, x, y, cS, GFX_BLACK, GFX_WHITE, nD); +} + +static void DrawBattery(Adafruit_GFX *gfx, int16_t x, int16_t y) +{ + float vol = EPD_ReadVoltage(); + uint8_t level = (uint8_t)(vol * 100 / 4.2); + GFX_setCursor(gfx, x - 26, y + 9); + GFX_setFont(gfx, u8g2_font_wqy9_t_lunar); + GFX_printf(gfx, "%.1fV", vol); + GFX_fillRect(gfx, x, y, 20, 10, GFX_WHITE); + GFX_drawRect(gfx, x, y, 20, 10, GFX_BLACK); + GFX_fillRect(gfx, x + 20, y + 4, 2, 2, GFX_BLACK); + GFX_fillRect(gfx, x + 2, y + 2, 16 * level / 100, 6, GFX_BLACK); +} + +static void DrawTemperature(Adafruit_GFX *gfx, int16_t x, int16_t y, int8_t temp) +{ + GFX_setCursor(gfx, x, y); + GFX_setFont(gfx, u8g2_font_wqy9_t_lunar); + GFX_printf(gfx, "%d℃", temp); +} + +static void DrawClock(Adafruit_GFX *gfx, tm_t *tm, struct Lunar_Date *Lunar, int8_t temp) +{ + DrawDate(gfx, 40, 36, tm); + GFX_setCursor(gfx, 40, 58); + GFX_setFont(gfx, u8g2_font_wqy9_t_lunar); + GFX_printf(gfx, "星期%s", Lunar_DayString[tm->tm_wday]); + GFX_setCursor(gfx, 138, 58); + GFX_printf(gfx, "%s%s%s", Lunar_MonthLeapString[Lunar->IsLeap], Lunar_MonthString[Lunar->Month], + Lunar_DateString[Lunar->Date]); + + DrawBattery(gfx, 330, 25); + DrawTemperature(gfx, 330, 58, temp); + + GFX_drawFastHLine(gfx, 30, 68, 330, GFX_BLACK); + DrawTime(gfx, tm, 70, 98, 5, 2); + GFX_drawFastHLine(gfx, 30, 232, 330, GFX_BLACK); + + GFX_setCursor(gfx, 40, 275); + GFX_setFont(gfx, u8g2_font_wqy12_t_lunar); + GFX_printf(gfx, "%s%s%s年", Lunar_StemStrig[LUNAR_GetStem(Lunar)], Lunar_BranchStrig[LUNAR_GetBranch(Lunar)], + Lunar_ZodiacString[LUNAR_GetZodiac(Lunar)]); + + uint8_t day = 0; + uint8_t JQday = GetJieQiStr(tm->tm_year + YEAR0, tm->tm_mon + 1, tm->tm_mday, &day); + if (day == 0) { + GFX_setCursor(gfx, 320, 275); + GFX_printf(gfx, "%s", JieQiStr[JQday % 24]); + } else { + GFX_setCursor(gfx, 300, 265); + GFX_printf(gfx, "离%s", JieQiStr[JQday % 24]); + GFX_setCursor(gfx, 290, 285); + GFX_printf(gfx, "还有%d天", day); + } +} + +void DrawGUI(epd_model_t *epd, uint32_t timestamp, display_mode_t mode) +{ + tm_t tm = {0}; + struct Lunar_Date Lunar; + + transformTime(timestamp, &tm); + LUNAR_SolarToLunar(&Lunar, tm.tm_year + YEAR0, tm.tm_mon + 1, tm.tm_mday); + + Adafruit_GFX gfx; + + if (epd->bwr) + GFX_begin_3c(&gfx, epd->width, epd->height, PAGE_HEIGHT); + else + GFX_begin(&gfx, epd->width, epd->height, PAGE_HEIGHT); + + GFX_firstPage(&gfx); + do { + NRF_LOG_DEBUG("page %d\n", gfx.current_page); + GFX_fillScreen(&gfx, GFX_WHITE); + + switch (mode) { + case MODE_CALENDAR: + DrawCalendar(&gfx, &tm, &Lunar); + break; + case MODE_CLOCK: + DrawClock(&gfx, &tm, &Lunar, epd->drv->read_temp()); + break; + default: + break; + } + } while(GFX_nextPage(&gfx, epd->drv->write_image)); + + GFX_end(&gfx); + + NRF_LOG_DEBUG("display start\n"); + epd->drv->refresh(); + NRF_LOG_DEBUG("display end\n"); +} diff --git a/GUI/GUI.h b/GUI/GUI.h new file mode 100644 index 0000000..4d16fca --- /dev/null +++ b/GUI/GUI.h @@ -0,0 +1,15 @@ +#ifndef __GUI_H +#define __GUI_H + +#include +#include "EPD_driver.h" + +typedef enum { + MODE_NONE = 0, + MODE_CALENDAR = 1, + MODE_CLOCK = 2, +} display_mode_t; + +void DrawGUI(epd_model_t *epd, uint32_t timestamp, display_mode_t mode); + +#endif diff --git a/GUI/Lunar.h b/GUI/Lunar.h index bf4f27f..597bebd 100644 --- a/GUI/Lunar.h +++ b/GUI/Lunar.h @@ -1,5 +1,5 @@ -#ifndef _LUNAR_H_ -#define _LUNAR_H_ +#ifndef __LUNAR_H +#define __LUNAR_H #include #include diff --git a/GUI/fonts.c b/GUI/fonts.c index 10119c3..708063c 100644 --- a/GUI/fonts.c +++ b/GUI/fonts.c @@ -3,11 +3,11 @@ /* Fontname: -wenquanyi-wenquanyi bitmap song-medium-r-normal--12-120-75-75-P-119-ISO10646-1 Copyright: (null) - Glyphs: 179/30503 + Glyphs: 186/30503 BBX Build Mode: 0 */ -const uint8_t u8g2_font_wqy9_t_lunar[3155] U8G2_FONT_SECTION("u8g2_font_wqy9_t_lunar") = - "\263\0\3\2\4\4\3\4\5\13\15\0\376\10\376\12\377\1a\2\317\4\30 \5\0L\13!\7\221F" +const uint8_t u8g2_font_wqy9_t_lunar[3333] U8G2_FONT_SECTION("u8g2_font_wqy9_t_lunar") = + "\272\0\3\2\4\4\3\4\5\13\15\0\376\10\376\12\377\1a\2\317\4\30 \5\0L\13!\7\221F" "\213S\0\42\7\64}\213\310\24#\16\226\304\233\250eX\242^\206%j\1$\17\245<\253l\251(" "\231\250%Je\213\0%\20\226<\233(\351\242%a\232DI\27-\1&\16\205D\253,\211\222\254" "\62%Q\244\4'\6\61\376\212\1(\13\263=\253$J\242nQ\26)\14\263=\213,\312\242.Q" @@ -40,97 +40,229 @@ const uint8_t u8g2_font_wqy9_t_lunar[3155] U8G2_FONT_SECTION("u8g2_font_wqy9_t_l "eD\213LKJI\26F\0w\16gD\214(\222\42\245\242t\213\262\4x\13eD\213,\251U" "jZ\0y\15\205\64\213LKJI\26fa\6z\12eD\213A\314\332\6\1{\13\243<\252$" "\252dQ[\0|\7\261\276\212\7\1}\13\243<\212,\252%QK\4~\7&\334\33\311\2\200\17" - "\225D+\251\222\15Q\66Da\24)\0\0\0\0\4\377\377N\0\12+d~(\31\16\2N\1\25" - "\252=\216\207\64\207r(\207r(\207r(\207r`\4N\3\26\272=\316\34\312\241\34\312\304!\32" - "t(\207r(l\35\4N\11\17\253<\236\341\316\313\60\344|\34\16\2N\21\27\253<\236a\220\263" - "\70\213\263l\30\324\60\15\323\60\15\243\341 N\31\32\273<\216\7\65\307\342\341\224\225\62\251K\224\244" - "Q\16D\71\20\245\13\0NY\30\272=\216w$Gr$Gr$Gr$GrDG\222\341\0" - "N]\27\272=\276\34\312\241x\30\342(\216\342(\315\322,J\302H\36N\214\14\213D\236\341\316\77" - "\16\7\1N\224\26\253<\236\341\234c\71\226\3\207\70\213\263\70\213\263h\70\10N\245\27\272=\316\34" - "\13\207C\226#Y\70Hi\24J\231Y\212V\1QT\32\273<\276\34\33\324,\35.\245,\33\6" - "\71\207\222r\322\26e\211\70\4Qk\30\253D\356\34\210r \312\201(\7\262\70K\213i\226\3I" - "\16\5Qm\24\273<\316\34\314I\303Ag\314\342\260\34\345\210\16\5Q\254\30\273<\276\34\33T-" - "\214\222\34\312\21\333\24\315\71\240\203\71\30\2R\6\30\273<\276r\226\26\323,\7\222d\30\222\60\213" - "\263\64\254F\242\6R\35\33\273<\236\34\214\206\203T+\25\243D\211\42E\213*Q[\251\30%\231" - "\2SA\27\273<\336\34\313\261\34K\207\203\232c\71\226c\71\226c)\0SH\27\272=\256\34\32" - "\206(\13\353P\70\34\322\34\312\241\34\312\241\20So\33\272=\276x\32\306LJ\62)\311\244$S" - "\224l\351\226DY\24j!\0V\333\30\251=\216\207(\211\244$\222\222HJ\42%\32f\35x\320" - "\201\0X\354\30\273<~ \207\266A\307r\254\62\34\324\34\313\261\34\213\262\341\2Y\4\32\273<\256" - "\60\15\323!I\243D\253\364\324\22\305Y\232Da&\306C\0Y\17\31\273<\216\7\65G\206\65L" - "\247\64\31\322\60\34\206,\252\205\362\64\4Y'\30\273<\336\34\313\261t\70\250\71\226CI\216\324\201" - ",-\351\200\0[P\30\273<\256a\310\241\34\312\241\34K\207\203\232c\71\226#u(\6[\305\31" - "\273<\336tx\207\224aH\322\34\70\204Qq\30\302\250\70\14\321:[\322\33\273<\336tx\213\42" - "e\30\222\60\312\206\203\30\305I\24m\212\250\203\32\0\134\17\30\273<\336\34\313\261\34\210\212Q\26e" - "\245,\24\253\71R\207b\0]\362\26\252=\216\203\16\345P\71\32\6)\207rDGt$\31\16]" - "\363\30\272=\216\203\24Gq\24G\303 \345P\16\345\210\216\350H\62\34^t\27\273<\256\34\33." - "a\65\36\6\255\234\205\303A\316\261\34\13\1^\232\33\273<\356x\70eq\62l\245l\70eQ\226" - "\14[\224\204Q\26%\252\0^\377\30\273<\276\60\15\323\60\32\16Z\230\206i\230\206i\230\16k\30" - "\1`\312\36\273<\256\60M\206A\321\201$\31\226R\226\224\6-L\243\244\226D%\245T\13\1b" - "\12\31\273<\356$G\242l\70eq\26e\245,\24KI\230\264e\223\32b\14\33\273<\356$G" - "\242l\70eq\26e\203\224U\302j&%Y\224H\242\0e\345\15\247>\216\203j\35\256\326\341\32" - "e\366\34\273<~$\32\302(\32NaT\211\242!J\242\226\250\30\25\243!\314\221\11f\16\31\273" - "<\356\341\224I\65)\32N\231T\223\242\341\224\245a-\211\324\4f\37\33\273<\256a\10\323p\30" - "\302\64\34\206\60\212\207K\230\3\207\34H\207\203\0f%\32\273<\336x\70\244\71pP\343\341 \211" - "\212\62%Y\62\244a:L\0f\221\33\273<\256a\10\323p\30\302\64\33\316I\66\34\304,\34\206" - "H\11\323a\2g\10\31\271=\256a\210\322(\215\206!J\243\64\32\206(\215\322$L\344\4g\37" - " \273<\236(\32\16I\224D-C\64$Q\313\20U\242h\70$Q\16DIT\22%\1g*" - "\27\273<\336\34\213\207s:\34\324\34\332\201\244\32\225\264LM\1kc\32\253<\216\7\65\307r " - "\312\201h\320\242\34\210r \312\201(\35\16\2l\64\30\273<\336\34\313\261\312\220(iRN\252Q" - "\61\252\265DIX\6n\5\36\273<\236\264\62\14\71\220E\311 %Y\232\14CTK\264%\312\222" - ")+e\221\2n\341 \273<\236\60\11\223a\310\242$\212\206A\11\223\60\31\206(i\231\222NJ" - "\242D-Q(r[\27\272=\336\70\212\243t\30\224\60\207\302\341\220\346P\16\345P\10r\327\35\273" - "<\216\250\232Dq\64,\215\222\262DR\322)I\244h\311\342\244\226di\4s* \273<\216," - "\252T\206$\12\223(I\206!\312RiP*\232\244\14Z\224%\245A\312\12s\64 \273<\216\244" - "\62D\305\244\62\14\321\22'\311\240\230*\265\60\31\206(\311\242\244\224D\225,u\62\26\271=\216\207" - ",\323\262\341\240eZ\66\34\264b\216\344H\10u\63\26\271=\316\34\11\207C\226\15\7-\323\262\341" - "\240\25s$\4vx\32\273<\236a\211\243\226(\11[\206$\312B\61\36\16i\222\3Y\266\12v" - "}\20\270>\276\70\35\316\362p\210\315\303!\16y\313\35\273<>)\33\323\60I\206\245\26%\332R" - "T\242,\311\222\60K\302(\253\244\1y\315\33\273<>)\33\323hx\211Z\242H)%\312\60(" - "a\32\246a\32f\0y\322\33\273<\276\332\230FIeHJ-Q\262\24\225(R\342,\15\63\65" - "Q\1z\313\30\273<\336\34L\207CN\10\323\60\216r \312\201$\307\302\341 \177\212\27\273<\256" - "\264\26\16\347\34\313\201C\16\344X:\34\324\34K\1\201J#\273<\236)\311\222(\311\222d\220\246" - "$K\206A\251#\7)\251EI\62(Q\222%\211\62(\0\201\363\27\273<\236\341\232CYZ\33" - "\316\71\226\3\207\34\310\261t\70\10\202\222\30\273<\276\332p\320\352H\16\206\303A\312\261\34\313\261\34" - "\33\6\5\206N\34\273<\336A\216\207C\22\205\321\60hQ\232D\303\220\344X\64\204QI\21\7\206" - "\307\32\273<\256\60-F\303\243\322\230\64%\203\62fqR\213\226l\212\206\0\206\360\36\273<\256\60" - "\33\222A\13\223d\210\224\254\42Ia\64\14Z\224e\303 g\311p\11\214\67\32\273<\316(\16K" - "Y\224ia\24\207\341\60(J\230da:\254a\4\217\233\27\273<\336x\270\245\251\224\3I\70\34" - "\324x\70\347X\216\245\0\217\260\34\273<\256\341\224c\311\260\345\330pJ\312I)K\42-\312JI" - "\224db\0\221I\33\273<\216\7\61\311\221\352p\252D-Q\264M\71\20\15\247\34\210\206\13\0\225" - "\360\33\273<\256h\30\242X\207\244A\22C\61\224\6I\14\305P\31\206D\7\6\226M\36\273<\216" - "!\12\243hX\42)Q\245$\222\246\254\224\14\203\322\226$\303 gq\6\226\350\30\273<\216\7\65" - "\307\342\341\224\225\222N\221\247J\247\254\224E\12\0\226\352\31\273<\236\341\234\16\217\241\242$J\216\16" - "w,\33\6\35\213\206\13\0\227\34\35\273<\236\341\234\16OI\251\66$\203\22e\331\220I%%\31" - "\222NY\66$\0\227\62\36\273<\236\341\234\16OIi\220\206$J\244d\310\304HZ\16I-J" - "\206hH\0\232l\30\273<\236a\320\261\64L\263\64L\207;\226c\303)\307rD\1\236!\35\273" - "<~ \33\222AL\262$J\232\222nQ\61\32\226r\22\15\212\16\345\210\2\237 \36\272=\216!" - "\31\222\34H\206dHr \31\356\240\244DIE\262$J\313\240L\1\237\231\32\273<\316(\7\262" - "\70\36\16b\222#\245\60J\322H\315*\231I\32\2\0"; + "\225D+\251\222\15Q\66Da\24)\0\0\0\0\4\377\377!\3\27\252D\36m\211\222,\221r$" + "\207r(\207r,\207\262x\1N\0\12+d~(\31\16\2N\1\25\252=\216\207\64\207r(\207" + "r(\207r(\207r`\4N\3\26\272=\316\34\312\241\34\312\304!\32t(\207r(l\35\4N" + "\11\17\253<\236\341\316\313\60\344|\34\16\2N\21\27\253<\236a\220\263\70\213\263l\30\324\60\15\323" + "\60\15\243\341 N\31\32\273<\216\7\65\307\342\341\224\225\62\251K\224\244Q\16D\71\20\245\13\0N" + "Y\30\272=\216w$Gr$Gr$Gr$GrDG\222\341\0N]\27\272=\276\34\312\241" + "x\30\342(\216\342(\315\322,J\302H\36N\214\14\213D\236\341\316\77\16\7\1N\224\26\253<\236" + "\341\234c\71\226\3\207\70\213\263\70\213\263h\70\10N\245\27\272=\316\34\13\207C\226#Y\70Hi" + "\24J\231Y\212V\1QT\32\273<\276\34\33\324,\35.\245,\33\6\71\207\222r\322\26e\211\70" + "\4Qk\30\253D\356\34\210r \312\201(\7\262\70K\213i\226\3I\16\5Qm\24\273<\316\34" + "\314I\303Ag\314\342\260\34\345\210\16\5Q\234\33\273<\336x\70$Y\250ia\224\3QMJ\262" + "$+%Q*jq\0Q\254\30\273<\276\34\33T-\214\222\34\312\21\333\24\315\71\240\203\71\30\2" + "R\6\30\273<\276r\226\26\323,\7\222d\30\222\60\213\263\64\254F\242\6R\35\33\273<\236\34\214" + "\206\203T+\25\243D\211\42E\213*Q[\251\30%\231\2SA\27\273<\336\34\313\261\34K\207\203" + "\232c\71\226c\71\226c)\0SH\27\272=\256\34\32\206(\13\353P\70\34\322\34\312\241\34\312\241" + "\20So\33\272=\276x\32\306LJ\62)\311\244$S\224l\351\226DY\24j!\0S\206\32\273" + "<\256\341\224c\345,N\206!\312JY\251\230da\22\245R\250\0V\333\30\251=\216\207(\211\244" + "$\222\222HJ\42%\32f\35x\320\201\0X\354\30\273<~ \207\266A\307r\254\62\34\324\34\313" + "\261\34\213\262\341\2Y\4\32\273<\256\60\15\323!I\243D\253\364\324\22\305Y\232Da&\306C\0" + "Y\17\31\273<\216\7\65G\206\65L\247\64\31\322\60\34\206,\252\205\362\64\4Y'\30\273<\336\34" + "\313\261t\70\250\71\226CI\216\324\201,-\351\200\0Y)\30\273<\236\341\234c\71\226\16\7\65\207" + "\222\34\251\3YZ\322\1\1[P\30\273<\256a\310\241\34\312\241\34K\207\203\232c\71\226#u(" + "\6[\305\31\273<\336tx\207\224aH\322\34\70\204Qq\30\302\250\70\14\321:[\322\33\273<\336" + "tx\213\42e\30\222\60\312\206\203\30\305I\24m\212\250\203\32\0\134\17\30\273<\336\34\313\261\34\210" + "\212Q\26e\245,\24\253\71R\207b\0]\362\26\252=\216\203\16\345P\71\32\6)\207rDGt" + "$\31\16]\363\30\272=\216\203\24Gq\24G\303 \345P\16\345\210\216\350H\62\34^t\27\273<" + "\256\34\33.a\65\36\6\255\234\205\303A\316\261\34\13\1^\232\33\273<\356x\70eq\62l\245l" + "\70eQ\226\14[\224\204Q\26%\252\0^\377\30\273<\276\60\15\323\60\32\16Z\230\206i\230\206i" + "\230\16k\30\1`\312\36\273<\256\60M\206A\321\201$\31\226R\226\224\6-L\243\244\226D%\245" + "T\13\1b\12\31\273<\356$G\242l\70eq\26e\245,\24KI\230\264e\223\32b\14\33\273" + "<\356$G\242l\70eq\26e\203\224U\302j&%Y\224H\242\0e\345\15\247>\216\203j\35" + "\256\326\341\32e\366\34\273<~$\32\302(\32NaT\211\242!J\242\226\250\30\25\243!\314\221\11" + "f\16\31\273<\356\341\224I\65)\32N\231T\223\242\341\224\245a-\211\324\4f\37\33\273<\256a" + "\10\323p\30\302\64\34\206\60\212\207K\230\3\207\34H\207\203\0f%\32\273<\336x\70\244\71pP" + "\343\341 \211\212\62%Y\62\244a:L\0f\221\33\273<\256a\10\323p\30\302\64\33\316I\66\34" + "\304,\34\206H\11\323a\2g\10\31\271=\256a\210\322(\215\206!J\243\64\32\206(\215\322$L" + "\344\4g\11\30\273<\316x\70h\71\66\214b\226\14S\61\35\326\60\15\323L\2g\37 \273<\236" + "(\32\16I\224D-C\64$Q\313\20U\242h\70$Q\16DIT\22%\1g*\27\273<\336" + "\34\213\207s:\34\324\34\332\201\244\32\225\264LM\1kc\32\253<\216\7\65\307r \312\201h\320" + "\242\34\210r \312\201(\35\16\2l\64\30\273<\336\34\313\261\312\220(iRN\252Q\61\252\265D" + "IX\6n\5\36\273<\236\264\62\14\71\220E\311 %Y\232\14CTK\264%\312\222)+e\221" + "\2n\341 \273<\236\60\11\223a\310\242$\212\206A\11\223\60\31\206(i\231\222NJ\242D-Q" + "(r[\27\272=\336\70\212\243t\30\224\60\207\302\341\220\346P\16\345P\10r\327\35\273<\216\250\232" + "Dq\64,\215\222\262DR\322)I\244h\311\342\244\226di\4s* \273<\216,\252T\206$" + "\12\223(I\206!\312RiP*\232\244\14Z\224%\245A\312\12s\64 \273<\216\244\62D\305\244" + "\62\14\321\22'\311\240\230*\265\60\31\206(\311\242\244\224D\225,u\62\26\271=\216\207,\323\262\341" + "\240eZ\66\34\264b\216\344H\10u\63\26\271=\316\34\11\207C\226\15\7-\323\262\341\240\25s$" + "\4vx\32\273<\236a\211\243\226(\11[\206$\312B\61\36\16i\222\3Y\266\12v}\20\270>" + "\276\70\35\316\362p\210\315\303!\16y\273\33\273<\336t\70HIcTL\32\207!\7\342\341\324\22" + "%\203\22\305\12\0y\313\35\273<>)\33\323\60I\206\245\26%\332RT\242,\311\222\60K\302(" + "\253\244\1y\315\33\273<>)\33\323hx\211Z\242H)%\312\60(a\32\246a\32f\0y\322" + "\33\273<\276\332\230FIeHJ-Q\262\24\225(R\342,\15\63\65Q\1z\313\30\273<\336\34" + "L\207CN\10\323\60\216r \312\201$\307\302\341 \177\212\27\273<\256\264\26\16\347\34\313\201C\16" + "\344X:\34\324\34K\1\201J#\273<\236)\311\222(\311\222d\220\246$K\206A\251#\7)\251" + "EI\62(Q\222%\211\62(\0\201\363\27\273<\236\341\232CYZ\33\316\71\226\3\207\34\310\261t" + "\70\10\202\222\30\273<\276\332p\320\352H\16\206\303A\312\261\34\313\261\34\33\6\5\206N\34\273<\336" + "A\216\207C\22\205\321\60hQ\232D\303\220\344X\64\204QI\21\7\206\307\32\273<\256\60-F\303" + "\243\322\230\64%\203\62fqR\213\226l\212\206\0\206\360\36\273<\256\60\33\222A\13\223d\210\224\254" + "\42Ia\64\14Z\224e\303 g\311p\11\214\67\32\273<\316(\16KY\224ia\24\207\341\60(" + "J\230da:\254a\4\217\233\27\273<\336x\270\245\251\224\3I\70\34\324x\70\347X\216\245\0\217" + "\260\34\273<\256\341\224c\311\260\345\330pJ\312I)K\42-\312JI\224db\0\217\330\33\273<" + "\236h\30\242\64\254c\331\246dQ\22U\242\306\64\254\344@\66\14\1\221I\33\273<\216\7\61\311\221" + "\352p\252D-Q\264M\71\20\15\247\34\210\206\13\0\225\360\33\273<\256h\30\242X\207\244A\22C" + "\61\224\6I\14\305P\31\206D\7\6\226M\36\273<\216!\12\243hX\42)Q\245$\222\246\254\224" + "\14\203\322\226$\303 gq\6\226\350\30\273<\216\7\65\307\342\341\224\225\222N\221\247J\247\254\224E" + "\12\0\226\352\31\273<\236\341\234\16\217\241\242$J\216\16w,\33\6\35\213\206\13\0\227\34\35\273<" + "\236\341\234\16OI\251\66$\203\22e\331\220I%%\31\222NY\66$\0\227\62\36\273<\236\341\234" + "\16OIi\220\206$J\244d\310\304HZ\16I-J\206hH\0\232l\30\273<\236a\320\261\64" + "L\263\64L\207;\226c\303)\307rD\1\236!\35\273<~ \33\222AL\262$J\232\222nQ" + "\61\32\226r\22\15\212\16\345\210\2\237 \36\272=\216!\31\222\34H\206dHr \31\356\240\244D" + "IE\262$J\313\240L\1\237\231\32\273<\316(\7\262\70\36\16b\222#\245\60J\322H\315*\231" + "I\32\2\0"; /* - Fontname: -wenquanyi-wenquanyi bitmap song-medium-r-normal--16-160-75-75-P-80-iso10646-1 + Fontname: -wenquanyi-wenquanyi bitmap song-bold-r-normal--16-160-75-75-P-80-iso10646-1 Copyright: (null) - Glyphs: 21/41295 + Glyphs: 186/29889 BBX Build Mode: 0 */ -const uint8_t u8g2_font_wqy12_t_lunar[484] U8G2_FONT_SECTION("u8g2_font_wqy12_t_lunar") = - "\25\0\4\2\4\5\3\4\6\17\20\0\376\13\375\14\374\0\0\0\0\0\243\60\16\267\212\250l*R~" - "\225\310d&\0\61\12\265\216\250DF\375\311@\62\16\267\212\250l*R\261T\237\15\6\1\63\22\267" - "\212h\14\42\241\134,\225\331\225\211\42\203\10\0\64\23\270\212i\305T\211P$\323I(\62\30\250r" - "%\0\65\20\267\212(\34\310\312\6\272\262\230(\62\210\0\66\23\267\212\250\14\42\251X\305D\223HY" - "%\62\231\11\0\67\16\267\212(\34\304R\261\252XU\254\6\70\23\267\212\250l*R\252D&\263\251" - "H\251\22\231\314\4\71\22\267\212\250l*RV\211\214d\21\253\212\14\42\0\0\0\0\4\377\377N\0" - "\10\37\350\60\374\0N\11\21\317\210p\14\36\344\271\31\34\350y\62\370\0N\214\15\257\230\260\14\16\364" - "\374\311\340\3N\224\34\357xp\14\36\344\342M\7\7\301T\60\25L\5S\271X.\226\213e\6\37" - "Qm\34\377x\260\345\1y@<\17\33|O\225\211\206\202\261\134U\60\24\215d\23\0V\333\35\335" - "z\60|\240\251\321\324hj\64\65\232\32I(#I\15\24\311\251v\360m\0^t\35\17i\360\304" - "\343\203\3M*\230\312\305\222\203\203T(\31J\206b\203\17\343\235\1e\345\21\371n\60<\310y\67" - "\70\320\371np\240\13f\37\36\355z\260\14\216r\241\301Q.\64\70\254\11\16\16\42\241X*\70\70" - "\14\307\6\17\2g\10#\14m\360\14nr\231\134&\227\311e\6\67\271L.\223\313\14nr\231\134" - "$\30\11&r\11e\2g\37:\16i\260d\222\231\310@\61\30$\62\221L$\23\311D\62\221\201" - "d \311D\62\221L$\23\31H\62\221Ld \311D\62\203\213L*\22\212d\22\241D*\223P" - "U\0\0"; - +const uint8_t u8g2_font_wqy12_t_lunar[4560] U8G2_FONT_SECTION("u8g2_font_wqy12_t_lunar") = + "\272\0\4\3\5\5\3\5\6\21\22\377\374\13\375\14\374\1\367\3\367\5\231 \6\0\60\246\0!\11\302" + "\375\245\360\300\210\0\42\11\305\270\246 \301\27\2#\36\211\21\246#!$!$!r\20\42!$!" + "$!$!r\20\42!$!$!\3$\25\250\361\245#Ec\241\202B\210\212\221\4\205\12\33*" + "\31\0%$\214\25\272\61$\42!#\42!\42#\241HB\325\204\250\304\224\204\32\21\11\31\21\11\21" + "\31\11\21\241\11\0&\33\213\25\266\63'!&!&!F\67\70#B#!\42\61!R\42\63T" + "A'\7\302\270\226pP(\16\5\226\235#\242FDF\77\222\21R)\17\5\226\235 \244FHF" + "\77\221\21Q\3*\21(Q\246#&#\241\302\206\306B\33\61\31\0+\15l\25\272%\252\253\203*" + "Q]\1,\10\203\330\245`A\1-\6%p\232P.\6C\370\245`/\22\7\226\245\245HJ\221" + "\224\42)ER\212\244\244\0\60\16g\25\246\62#\241\206\337H\250\31\1\61\13f\25\246\42\63B\244" + "\237\30\62\15g\25\246Q!C#\245H\257\16\63\22h\21\246Q\42#'&%C\247\214F\244\4" + "\0\64\25h\21\246%\65D#!\242BFBF\342 JL\5\0\65\22h\21\246p!\246\314d" + "DNL\214F\244\4\0\66\25h\21\246B#\42!&f\62\42!\304HBD\206\4\0\67\22h" + "\21\246p\20&%&%&%\246JL\10\0\70\23h\21\246B#\242\67\64\42\22B\214$Dd" + "H\0\71\24h\21\246B#\42!\304HBd\304L\205\210\14\11\0:\7\342\30\226 *;\7\2" + "\371\225 J<\15J\371\265(\66\265\335\344\244\344\2=\12\213T\266p@\17w@>\13K\365\265" + " \272\313\261\35\2\77\17f\25\246A!\42\244F\221z\10\21\0@\31i\25\262b\42#\42q!" + "B!B!B!B!\42!A\42h\1A\30k\21\262\64\70'!&!%#$#$#s" + " \42%!G'B\22h\31\262p!\304\215\204\211\214\204\20\243\3\11\0C\20i\25\256c\42#" + "!&\247C\65\62\25\0D\22i\31\266p\42$!$!\305G\22B\22'\0E\16h\31\256p" + "\60\246\331\205\230f\7\1F\15g\31\252p \245\325\201\224\256\0G\23i\25\262c\42#!&\247" + "\215\225\204\220\210\214\214\1H\14h\31\262 \304\243\203\42\36\11I\10b\31\226\360A\0J\13\206\365" + "\245\244\377F\202\4\0K\27i\31\262 E$!#\242FB\210\252HDF\211\220\204\224\0L\11" + "g\31\252 \245\177uM\26k\31\276\60eus\20c\241\202B\5\311\10\311\10\35;\1N\22h" + "\31\262\60ScbrA!Aq\342\246f\0O\24j\25\266C%\42#$!\306\63\11!\31\21" + ")\32\0P\20h\31\256`\42#!\304\215\204\211\230f\0Q\23\252\325\265C%\42#$!\306\63" + "\11m$\246*\25R\22h\31\256p!\304\321\201\204\210n$d$\204\4S\22h\25\252B#\42" + "!&'G\247\214F\244\4\0T\13j\25\262p\60$\250\177\4U\15h\31\262 \304\77\222\20\221" + "!\1V\31k\21\262 G'!%\42%\243HFHFJBLBnp\10\0W\36n\25\302" + " $D$D\244B\204D\11\211\22\22\31\22\42\22\42\22*!\61!\31\0X\26K\21\262 '" + "!%\243JBnpNBJF\225\204\234\0Y\21j\21\262 F&!$#\42E'\250G\0" + "Z\21i\25\256p &'\246NL\235\230\330\201\0[\12\4\226\231`\242\377'\4\134\22\7\226\245" + " %&\245LJ\231\224\62)eR\2]\12\4\222\231@\242\377'\6^\11f\370\256\42C!\42" + "_\7+\224\265p@`\7C\34\247 \42a\16\347\24\246Q!#%q\20C#ab\17g\25" + "\246 \245\225\305\10\15\67\7\21\0c\15\347\24\246Q!C\245\215D\5\0d\15g\25\246\245\213\203" + "\220\32N&\14e\16\347\20\242Q!Cs@%#Q\1f\15f\25\232B!\244\246DHo\0" + "g\21h\261\245\65R\242OJ\344\16\204\210$,\0h\15g\25\246 \245\225\305\10\15o\4i\10" + "b\25\226 vpj\13\305\255\225#\17\243\277\261\0k\21g\25\246 \245\23\11%\64\64\22\42*" + "d\4l\10b\25\226\360A\0m\24\353\24\272`\261d\202F\204F\204F\204F\204FD\0n\13" + "\347\24\246`\61B\303\33\1o\14\347\24\246Q!\303\33\211\12\0p\17G\265\245`\61B\303\315A" + "\204\224*\0q\15G\265\245q\20R\303\311\204\225\6r\13\345\24\232p\20\42\243\33\0s\13\346\20" + "\236q$E%t\1t\14%\25\236!#R!\243\243\1u\12\347\24\246 \303'\23\6v\17\350" + "\20\242 D$!\242\15\21\225\14\0w\25\352\20\262 \42B\242\342 \344 \344 FDHD\4" + "\0x\20\350\20\242 $!\42C%E#\42!$y\21H\261\241 $!\242\15\21\225\230*\241" + ")\0z\11\347\20\242p\244W\7{\16\7\226\245C\42\245G\63bSzF|\10\2\232\225\360\3" + "\2}\20\7\226\245\60&\245gb#CR\272\31\2~\11H\64\257\301d\2\0\200\24\210\21\246C" + "#\42!&e#e#\246ND\206\2\0\0\0\0\4\377\377!\3\27\256\65\306\61*!b\241\311" + "\12!)a\275\226\22\223\21,\1N\0\11\60\320\306\360@\0N\1\16\356\325\305\360LX\377SZ" + "\71\0N\3\25\357\361\305&\255'UF\7\321\272\22\223\22\223\222;\10N\11\20\220\21\306qp\217" + "\273\203z\274;\70\20N\21#\320\361\305r@)#)#)#)#)#u@($($(" + "$($($($sp N\31'\360\321\305\360@N\134\341\301\211\220\22!%\62\64\42\62\22" + "\42\332H\210H\10I\210\210\212\210\212\10\222H\212\0NY\23\316\365\305pP\253\77\226\225\224\220\224" + "\220\24\71(N]\42\20\322\305%\256\351\1\245\214\244\214\244\214\240\220\240\220\240\220\234\224\210\214\224\210" + "\62\21\11\301s\0N\214\15P\61\306rP\217\77=\70\20N\224\36\320\361\305qp'\256\351\1\241" + "\220\240\220\240\220\240\220\234\224\234\224\234\224\314\301\201\0N\245\42\16\326\305%-\17up%\253HJ" + "H\352 DNDlDjFh\210pDjJ\202P\0QT(\20\322\305$.~\20'%&" + "%v`B\243HF\221\214\242\203\42\21\22\71\11B\21\11\61\31\11%BBe\7Qk#\357\325" + "\305()\42)\42)\42)\42)\42)#'$'$'\245LJNFPFRBV\0Qm" + "!\360\361\305&\17 \17 .\17wp \217NDTFPJNLJNHRDT\2\0Q" + "\234$\20\322\305'\256\360\340DFJBH\35\61\215\230\210\204\330\10\31\215\230\204\220\22)\71\42\261" + "E\242\0Q\254!\20\322\305%.} \246\212HJD-\351\310\330\222\321)z\200y\0Az\200" + "y\0)\0R\6(\20\322\305)*\42*#($'&%(#*!q \42%#)#)" + "#($($'%&C&%\6R\35*\17\322\305\42.\17rp\20\242HFDFHDF" + "HD\244DE\215\10\5\211\32\22\65\372\211\220\214\204\10\21\221\10\0SA\20\20\322\305'\256w\7" + "\7r\342\372;\0SH\30\20\322\305$\256\372\200JDRFPH\134\335\301\201\234\270\336\1So" + "\60\16\326\305\63Hs \42!C\42!C\42!C\42!C\42!C\42!C\42!C\61!s" + "\20a%\241JDPDNFLH\12\0S\206)\360\321\305rp\42.$($($x`#" + "$\243HF#\31E\62\42R\62\42R\42\312D$\204H$\304d\0V\333\37\256\365\305\360@D" + "\11\211\22\22%$JH\224P\310\210P\10\35\10V\222\36\34\220\12X\354\23\360\361\305+kt\256" + "\273\203\3\71q\275<(\1Y\4,\20\322\305#$($($X!(!\61&\42A%\42\241" + "\206B\211\204\4\211\42\22I\31I\31A\22\71\221A\251\203q\0Y\17!\20\322\305qp'{\60" + "\246\354`L\331\301\230\262\203\71\351\203)\42)\21\265\224$\64\204\4Y'\34\20\322\305'\256\273\203" + "\3\71qibZ\21Q\21I!\71\61)A\221\321\1Y)\35\360\321\305rP)\256\335\301\201\234" + "\64\61\255\210\250\210\244\220\234\230\224\240\310\350\0[P\24\360\321\305q`\255\361\264\334\301\201\234\270\36" + "S\13\2[\305'\20\322\305&\17 xp\20!KqP(z\60&\242LD\331\301\230\210\62\21" + "e\7\203\42\222Brb\62\0[\322+\20\322\305&\17 xp\20!\242\206\342\240LD\356\240N" + "D\352\340@H\235\304\210\224\220\210\310\230\310\324<\300<\200\24\0\134\17\36\20\322\305'\256S\21e" + "\42\62R\42B\62\212dTI\10IQ\251\23\27\246\26\4]\362\26\315\371\305p@\253\211\234\210\234" + "\310\1\211\254\226,%\16\12]\363\33\315\371\305p@\42'\42'\42'\42'\42'r@\42\253%" + "K\211\203\2^t\37\20\322\305#.~P#$($'%y@%#)#)#vp (" + "\256\63\0^\232'\20\322\305'\17 xp\42.$xP\244DH\211\320\301\211\220\210\220\22\241\203" + "\32!\62\31\21!\221\241\205\3^\377(\20\322\305$%'%'%'%'%sp $%'" + "%'%'%'%'%'%'%w '%\3`\312.\20\322\305#$(%'q\60#" + ">{pB\42$B\42$\241\344 HJND\202JDB\221\204\210\32\32\21\31\31:!)\0" + "b\12+\20\322\305(!+\42*xp\42$($($\243JDFJBHJBHlJL" + "D\25\205*\21\12\231\241\222\71\1b\14*\20\322\305I,!+wp\42%'%'%\42#%" + "\42c!\42#F$F$'!\42\66\241L\202BJ\246J\1e\345\20\352\335\305pP\306\263\203" + "\63>;\70\23e\366&\17\326\305+-b%\242JD\344\300DJD\225\210\225\210\12\21]\210h" + "!\242J\304JD\225,\261\14\0f\16,\356\325\305w`!C\42!C\42!C\42q`!C" + "\42!C\42!C\42q`!C\42!#&$&$%C$%\1f\37\37\316\365\305r\60$" + "&t\60$&t\60\250D\360\200DFLH\360`PX\354\340\0f%%\20\322\305'.xp" + "(yP(xp \244NL\352\240dBHbH\341A\240\220\240\220\340A\20\0f\221&\20\322" + "\305s\60\246\354`L\331\301\244\354\301\244\210\320\301\201\330\354\201\24\225\314\304\201\234\224\334\201\234\224\14" + "\0g\10&\15\332\305s\60#&#&#&#&s\60#&#&#&s\60#&#&\42" + "'\42'!f(\1g\11&\20\322\305&.xp %.} '%\66%u@$!%#" + "\42%w '%'%'C'$\4g\37.\17\322\305\242RD\302\342`D\13\21-DD," + "LT\210h!\42b!\242\205\211\12\221\3\23)\11\31\21\21\32\11!\21#\25\0g*\36\20\322" + "\305'\256\362\240R\134\335\301\201\30\255\245\204:\21U\62J\206\204\346\304\345\0kc\36\320\361\305q" + "p(\256\251\210\250\310\225\210\250\210\250\210\250\210\250\210\250\210\334\301\201\0l\64!\20\322\305'\256\215" + "\244\214\314\201\204\340\241\4\245\4\241\210\204\234\210*\31\215\204\252\204\251\5\1n\5+\20\322\305)'" + "%xP\244J\350 FL\311\1\215\270\304A\220\210\220\10\311A\220\210\220\222\203 \21!%\42\204" + "\62\62\0n\341\61\20\322\305'#$\243\352\300FDFD\36@\344\200BJBLFB\354\300D" + "B\13\13\235H\34\220HL\210\214H\310\211HHQ\211I\0r[\33\20\322\305'*\42*\42*" + "\42z@$#($\256\356\340@N\134\357\0r\327,\17\322\305(&\42!G!)r\20b%" + "!\61F\42Q!$\241\315\204&\24zQA\42\241\221\234\220\234\4\25\215\234\10\0s*\60\20\322" + "\305)%\42#\42Bq #%!CD#q`#$(#\70rC\61#\42a#%r%" + "\42#%\42#Bs#$#\2s\64\61\20\322\305\247D\342\206DFHDH\206\342\240\242B\260" + "BPB\302f\202B\210BF\205\304\301\214\204\214\230\204\10\225\204\10\23\11\21\65D\2u\62\34\354" + "\331\305\360F\206F\206F\346\340@F\206F\206F\346\340@F\225\250\256\0u\63\37\14\332\305%\252" + "\352\340F\206F\206F\346\340@F\206F\206F\346\340@F\225\250*\0vx%\20\322\305(!t" + "@*!\242\13!\242\61U\202\42\23\7\21s\342\202\7\207\322\245\62rSB\203\42\0v}\24\14" + "\332\305%\251\356\340\220\303\203\3A\36\36\34\10\12y\273)\20\322\305&\17 wp \17DB&" + "A!FBv\60*xp\42#%\242\27\7\21\42j$D\4I$E\0y\313/\20\322\305$" + "#H\42U$($(B\42q@\42$B!\64!AE#fAeA$!#!&\242L" + "DFJBJ\210N\0y\315,\17\322\305\244\214F\246JLJL\344\340`B\215\210\204\222\21\11" + "%\24Z\34\134\34DHPH\211I\211I\211I\211I\311\0y\322.\20\322\305\244\216F\250JN" + "\306J\206B\342\202DFDBDdDB\314DB\304FB\304\206DBNJL\225\234\314\240\304" + "\34\0z\313\37\360\361\305&\17 .\17yp\17-\246NHPHRDTDTB\36\356\340@" + "\0\177\212\32\20\322\305\244RFRD\354\340P\134\345A\245\270\272\203\3\71q\355\0\201J\67\20\322" + "\305(\42S\242FBD\215\304A\205\22\65%j$\16*\324JH\34\204T\10\211H(\22\221\220" + "\70\10\221P$\42\241HDB\342 BbBH\2\0\201\363\32\320\361\305qp'\255HNL\352" + "\240\134R\134\362\240R\134\335\301\201\0\202\222\33\360\361\305\244PH\350\340@H\241\220\250<\200\334\301" + "\201\220\270\236\37P\0\206N%\17\322\305'}(x`\42#$\42Su\20\42\243#\33i\21+" + "\21U\42\212Dd$\64\222\240\20#\206\307'\360\361\305#%'\246\321\301A\304A\224\304\225\210\205" + "\234\205\210\214\205\42\32:\231A\12!\231#\23\42\11\261\3\206\360,\17\322\305\243PF\352\300JF" + "BjbB\244F\202F\344 \202BhD\202H\346`JD\225\210\252\203I\31\221\203\23I\1\214" + "\67!\20\322\305\244PJLDFHFHD\206VDRHl\311\350\314\301\230\376\354`L\15\0" + "\217\233\33\20\322\305&\17 yP\17'$)\42up '\256\360\340P\134w\0\217\260&\360\321" + "\305r`#.~P$.~`#\241PB\211\220\204\10\225\204\214\224\210\220\22\32\21\231\251)I" + "\0\217\330#\320\361\305\42r $%'%-.US&B!%\241D\210D\221B!A!\71" + "Z\221\3\2\221I%\360\321\305\360@JDTD\354\340D\377BFD\204\252dRDT\344\340D" + "TDT\344\340DT\2\0\225\360#\16\326\305!-q \42HJzp@$D$Dq\20A" + "$D$D$tp@Jh)\1\226M.\17\326\305'f!&\42q\241\215\210\204\205\14\321\220" + "\204\304\22\11\22\211\22\31!\221\203\11\21\31\241\23!\212\203:!\71!\71!\0\226\350(\360\321\305" + "\360@N\134\341\301\211\220\22!%\22\22$J(\224\10)\221\220 QB\241DH\211\220\10\211\244" + "\10\0\226\352 \20\322\305rP)xp\20!$EqP(z\60\17vP\256\352\200\134\321A\271" + "\10\0\227\34+\20\322\305rP)xp\20!$EqP(z\60\17(\362@Fh\344\246BF" + "D\342\200BD\215\224\310\225\210\214\4\0\227\62(\20\322\305rP)xp\20!$EqP(z" + "\60,fa#b!c\63&BAaJ\343BD\204\310\4\0\232l\32\357\321\305q@\255LJ" + "LJLJ\354\240Z\365\301\205\264Rb\21\0\236!*\20\322\305*-}q!#&A!&!" + "#\42!\42AC\242JFR\346 \204PDBNB\344\300X\226Z\4\0\237 (\16\332\305#" + "IS\42(\322DPDP\344\240\36\202\205\210\4\23\31%\24\24\42\22\24\7\61\62\7\21$&C" + "\2\237\231-\20\322\305%#)$($(yp %!+!\42'!\42'\241N\204PdP" + "FHFdHD\204HBD\344@\34\0\0"; /* Fontname: -Adobe-Helvetica-Bold-R-Normal--20-140-100-100-P-105-ISO10646-1 diff --git a/GUI/fonts.h b/GUI/fonts.h index 0bba292..fc4991b 100644 --- a/GUI/fonts.h +++ b/GUI/fonts.h @@ -1,5 +1,5 @@ -#ifndef _FONTS_H -#define _FONTS_H +#ifndef __FONTS_H +#define __FONTS_H #include "u8g2_font.h" @@ -8,27 +8,19 @@ 所有 ASCII 字符 (32-128) 正月二月三月四月五月六月七月八月九月十月 冬月腊月 -闰 +农历闰 初一初二初三初四初五初六初七初八初九初十 十一十二十三十四十五十六十七十八十九二十 廿一廿二廿三廿四廿五廿六廿七廿八廿九三十 -日 -一二三四五六 +星期一二三四五六日 猴鸡狗猪鼠牛虎兔龙蛇马羊 庚辛壬癸甲乙丙丁戊已 申酉戌亥子丑寅卯辰巳午未 小寒大寒立春雨水惊蛰春分清明谷雨立夏小满芒种夏至小暑大暑立秋处暑白露秋分寒露霜降立冬小雪大雪冬至 年月日时分秒 -星期 +离还有天 */ extern const uint8_t u8g2_font_wqy9_t_lunar[] U8G2_FONT_SECTION("u8g2_font_wqy9_t_lunar"); - -/** - * 文字列表: -年月日 -星期 -一二三四五六 - */ extern const uint8_t u8g2_font_wqy12_t_lunar[] U8G2_FONT_SECTION("u8g2_font_wqy12_t_lunar"); // 以下字库来自 u8g2,用于显示数字 diff --git a/Keil/EPD-nRF51.uvprojx b/Keil/EPD-nRF51.uvprojx index 1ecaf79..0bc73f9 100644 --- a/Keil/EPD-nRF51.uvprojx +++ b/Keil/EPD-nRF51.uvprojx @@ -430,9 +430,9 @@ GUI - Calendar.c + GUI.c 1 - ..\GUI\Calendar.c + ..\GUI\GUI.c Lunar.c @@ -1037,9 +1037,9 @@ GUI - Calendar.c + GUI.c 1 - ..\GUI\Calendar.c + ..\GUI\GUI.c Lunar.c diff --git a/Keil/EPD-nRF52.uvprojx b/Keil/EPD-nRF52.uvprojx index fdc9353..2ada03b 100644 --- a/Keil/EPD-nRF52.uvprojx +++ b/Keil/EPD-nRF52.uvprojx @@ -430,9 +430,9 @@ GUI - Calendar.c + GUI.c 1 - ..\GUI\Calendar.c + ..\GUI\GUI.c Lunar.c @@ -1162,9 +1162,9 @@ GUI - Calendar.c + GUI.c 1 - ..\GUI\Calendar.c + ..\GUI\GUI.c Lunar.c diff --git a/Makefile.nRF51 b/Makefile.nRF51 index 0b21bfa..63a3b3f 100644 --- a/Makefile.nRF51 +++ b/Makefile.nRF51 @@ -41,7 +41,7 @@ SRC_FILES += \ $(PROJ_DIR)/EPD/EPD_service.c \ $(PROJ_DIR)/EPD/UC8176.c \ $(PROJ_DIR)/EPD/SSD1619.c \ - $(PROJ_DIR)/GUI/Calendar.c \ + $(PROJ_DIR)/GUI/GUI.c \ $(PROJ_DIR)/GUI/Lunar.c \ $(PROJ_DIR)/GUI/fonts.c \ $(PROJ_DIR)/GUI/Adafruit_GFX.c \ diff --git a/Makefile.nRF52 b/Makefile.nRF52 index a3f55d1..87cc2e9 100644 --- a/Makefile.nRF52 +++ b/Makefile.nRF52 @@ -66,7 +66,7 @@ SRC_FILES += \ $(PROJ_DIR)/EPD/EPD_service.c \ $(PROJ_DIR)/EPD/UC8176.c \ $(PROJ_DIR)/EPD/SSD1619.c \ - $(PROJ_DIR)/GUI/Calendar.c \ + $(PROJ_DIR)/GUI/GUI.c \ $(PROJ_DIR)/GUI/Lunar.c \ $(PROJ_DIR)/GUI/fonts.c \ $(PROJ_DIR)/GUI/Adafruit_GFX.c \ diff --git a/html/index.html b/html/index.html index 931de53..74aba6b 100644 --- a/html/index.html +++ b/html/index.html @@ -68,7 +68,8 @@
- + +
@@ -113,7 +114,14 @@ 提示

驱动板上 LED 灯(如果有的话)闪烁的时候表示墨水屏处于忙碌状态,此时上位机发送的指令可能不会被执行

    -
  • 日历模式: 点击“日历模式”按钮将自动从浏览器同步时间到墨水屏,并切换到日历显示
  • +
  • 日历模式: 点击“日历模式”按钮将自动从浏览器同步时间到墨水屏,并切换到日历显示,每天凌晨更新日历
  • +
  • + 时钟模式: 点击“时钟模式”按钮将自动从浏览器同步时间到墨水屏,并切换到时钟显示,每分钟刷新一次时间 +
      +
    • 此功能为预览版,不建议日常使用,目前使用全刷实现(以后可能会支持局刷)
    • +
    • 三色屏请不要开启时钟模式(刷新太慢,如误点开启可以传图或者清屏退出)
    • +
    +
  • 引脚配置:格式为十六进制,顺序:MOSI/SCLK/CS/DC/RST/BUSY/BS/EN,前面 7 个引脚配置为必须,EN 为可选(没有用到的引脚可配置为 FF
  • 确认间隔: 这个间隔指的是数据包数量间隔,即发送此数量的不确认响应的数据包后才发送一次需确认响应的数据包。加大此值可优化传图速度,但是丢包风险也更大(你可能会发现图片有部分位置显示不正常,此时需调小这个值)
  • 指令列表: 支持的指令可在项目 README 查询(此功能一般只会在开发测试时用到) diff --git a/html/js/main.js b/html/js/main.js index 1dfac9a..2fe19ba 100644 --- a/html/js/main.js +++ b/html/js/main.js @@ -105,18 +105,18 @@ async function setDriver() { await write(EpdCmd.INIT, document.getElementById("epddriver").value); } -async function syncTime() { +async function syncTime(mode) { const timestamp = new Date().getTime() / 1000; const data = new Uint8Array([ (timestamp >> 24) & 0xFF, (timestamp >> 16) & 0xFF, (timestamp >> 8) & 0xFF, timestamp & 0xFF, - -(new Date().getTimezoneOffset() / 60) + -(new Date().getTimezoneOffset() / 60), + mode ]); if(await write(EpdCmd.SET_TIME, data)) { - addLog("日历模式:时间已同步!"); - addLog("需要一定时间刷新,请耐心等待。"); + addLog("时间已同步!"); } } @@ -194,7 +194,8 @@ function updateButtonStatus() { const status = connected ? null : 'disabled'; document.getElementById("reconnectbutton").disabled = (gattServer == null || gattServer.connected) ? 'disabled' : null; document.getElementById("sendcmdbutton").disabled = status; - document.getElementById("synctimebutton").disabled = status; + document.getElementById("calendarmodebutton").disabled = status; + document.getElementById("clockmodebutton").disabled = status; document.getElementById("clearscreenbutton").disabled = status; document.getElementById("sendimgbutton").disabled = status; document.getElementById("setDriverbutton").disabled = status; diff --git a/main.c b/main.c index 272a993..36ec2ea 100644 --- a/main.c +++ b/main.c @@ -73,7 +73,7 @@ #define NEXT_CONN_PARAMS_UPDATE_DELAY TIMER_TICKS(30000) /**< Time between each call to sd_ble_gap_conn_param_update after the first call (30 seconds). */ #define MAX_CONN_PARAMS_UPDATE_COUNT 3 /**< Number of attempts before giving up the connection parameter negotiation. */ -#define SCHED_MAX_EVENT_DATA_SIZE EPD_CALENDAR_SCHD_EVENT_DATA_SIZE /**< Maximum size of scheduler events. */ +#define SCHED_MAX_EVENT_DATA_SIZE EPD_GUI_SCHD_EVENT_DATA_SIZE /**< Maximum size of scheduler events. */ #define SCHED_QUEUE_SIZE 10 /**< Maximum number of events in the scheduler queue. */ #define CLOCK_TIMER_INTERVAL TIMER_TICKS(1000) /**< Clock timer interval (ticks). */ @@ -179,6 +179,7 @@ bool epd_cmd_callback(uint8_t cmd, uint8_t *data, uint16_t len) m_timestamp = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]; m_timestamp += (len > 4 ? (int8_t)data[4] : 8) * 60 * 60; // timezone app_timer_start(m_clock_timer_id, CLOCK_TIMER_INTERVAL, NULL); + m_epd.display_mode = len > 5 ? (display_mode_t)data[5] : MODE_CALENDAR; ble_epd_on_timer(&m_epd, m_timestamp, true); return true; @@ -342,7 +343,7 @@ static void on_adv_evt(ble_adv_evt_t ble_adv_evt) case BLE_ADV_EVT_IDLE: NRF_LOG_INFO("advertising timeout\n"); if (m_epd.config.wakeup_pin != 0xFF) { - if (m_epd.calendar_mode) + if (m_epd.display_mode != MODE_NONE) setup_wakeup_pin(m_epd.config.wakeup_pin); else sleep_mode_enter();