diff --git a/.DS_Store b/.DS_Store index d1579ac..046bdd8 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/README.md b/README.md index da85a07..1ff2b08 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,7 @@ ## 展示 ![workday](https://raw.githubusercontent.com/217heidai/eInkCalendar/main/doc/workday.jpeg) ![holiday](https://raw.githubusercontent.com/217heidai/eInkCalendar/main/doc/holiday.jpeg) +![battery](https://raw.githubusercontent.com/217heidai/eInkCalendar/main/doc/battery.jpeg) ## 功能 1. 日历信息展示,包括日期、星期、农历、节假日; @@ -14,8 +15,7 @@ 6. 每 8 小时(具体见代码中 `REFRESH_FREQUENCY` 定义)联网刷新一次日期、天气信息。如日期发生变化,则强制刷新。 ## 计划 -1. 采集、展示电量; -2. 翻页展示更多功能... +1. 翻页展示更多功能... ## 电路图 1. 电路图`doc/SCH_三色墨水屏日历_2021-07-23.json`,请使用 立创EDA 打开 @@ -32,11 +32,14 @@ 3. `eInkCalendar.ino`中修改位置信息,支持到城市级别,设置 `url_FutureWeather`、`url_LifeIndex`。 ## 更新日志 +### 0.0.3【2021/12/15】 +1. 增加电量显示,绘制电池图标 + ### 0.0.2【2021/12/08】 1. 参考`甘草酸不酸`大佬的源码,修复了 `U8g2_for_Adafruit_GFX` 库崩溃问题,源码详见 lib 目录; 2. 为了省电,调整为每 8 小时(具体见代码中 `REFRESH_FREQUENCY` 定义)联网刷新一次日期、天气信息。当然如日期发生变化,则会强制刷新; 3. 拆机发现板子上没有温湿度模块,只能问候下 JS 了。 ### 0.0.1【2021/08/19】 -1. 初始版本 +1. 初始版本。 diff --git a/doc/.DS_Store b/doc/.DS_Store new file mode 100644 index 0000000..5008ddf Binary files /dev/null and b/doc/.DS_Store differ diff --git a/doc/battery.jpeg b/doc/battery.jpeg new file mode 100644 index 0000000..28ddb5c Binary files /dev/null and b/doc/battery.jpeg differ diff --git a/doc/workday.jpeg b/doc/workday.jpeg index c2936df..f81e892 100644 Binary files a/doc/workday.jpeg and b/doc/workday.jpeg differ diff --git a/src/bitmap.cpp b/src/bitmap.cpp index 26af18c..b47706e 100755 --- a/src/bitmap.cpp +++ b/src/bitmap.cpp @@ -119,7 +119,7 @@ const unsigned char Bitmap_gengxing[] PROGMEM = { 0x9f, 0xf8, 0xc3, 0x98, 0xc3, const unsigned char Bitmap_riqi[] PROGMEM = { 0xff, 0xfc, 0x3f, 0xff, 0x0f, 0xff, 0xc0, 0xff, 0xf8, 0x3f, 0xff, 0x07, 0xff, 0xc0, 0xff, 0xf0, 0x1f, 0xfe, 0x03, 0xff, 0xc0, 0xff, 0xf0, 0x1f, 0xfe, 0x03, 0xff, 0xc0, 0xff, 0xf0, 0x1f, 0xfe, 0x03, 0xff, 0xc0, 0xff, 0xf0, 0x1f, 0xfe, 0x03, 0xff, 0xc0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x0f, 0xf8, 0x1f, 0xfe, 0x07, 0xfc, 0x00, 0x0f, 0xf8, 0x3f, 0xff, 0x07, 0xfc, 0x00, 0x1f, 0xfc, 0x7f, 0xff, 0x8f, 0xfe, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x1f, 0x80, 0xfc, 0x0f, 0xc0, 0x7e, 0x00, 0x1f, 0x80, 0xfc, 0x0f, 0xc0, 0x7e, 0x00, 0x1f, 0x80, 0xfc, 0x0f, 0xc0, 0x7e, 0x00, 0x1f, 0xc1, 0xfc, 0x0f, 0xe0, 0xfe, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x1f, 0x80, 0xfc, 0x0f, 0xc0, 0x7e, 0x00, 0x1f, 0x80, 0xfc, 0x0f, 0xc0, 0x7e, 0x00, 0x1f, 0x80, 0xfc, 0x0f, 0xc0, 0x7e, 0x00, 0x1f, 0x80, 0xfc, 0x0f, 0xc0, 0x7e, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc0 }; //电量低中图标 width: 24, height: 35 -const unsigned char Bitmap_batlow[] PROGMEM = { 0xfe, 0x00, 0xff, 0xfe, 0x00, 0xff, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x01 }; +const unsigned char Bitmap_BAT_LOW[] PROGMEM = { 0xfe, 0x00, 0xff, 0xfe, 0x00, 0xff, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x01 }; //湿度小图标 width: 13, height: 13 const unsigned char Bitmap_humidity[] PROGMEM = { 0xfc, 0xf8, 0xf8, 0xf8, 0xf2, 0x78, 0xe7, 0x38, 0xcf, 0x98, 0xcf, 0x98, 0x9f, 0xc8, 0x9f, 0xc8, 0x9e, 0x48, 0x9c, 0xc8, 0xcd, 0x98, 0xe3, 0x18, 0xf0, 0x78 }; diff --git a/src/bitmap.h b/src/bitmap.h index dd0f870..c098dcb 100644 --- a/src/bitmap.h +++ b/src/bitmap.h @@ -39,7 +39,7 @@ extern const unsigned char Bitmap_weizhi[]; extern const unsigned char Bitmap_zhuangtai[]; extern const unsigned char Bitmap_gengxing[]; extern const unsigned char Bitmap_riqi[]; -extern const unsigned char Bitmap_batlow[]; +extern const unsigned char Bitmap_BAT_LOW[]; extern const unsigned char Bitmap_humidity[]; extern const unsigned char Bitmap_fx[]; extern const unsigned char Bitmap_rdfb[]; diff --git a/src/display.ino b/src/display.ino index c1d418f..c3bddff 100644 --- a/src/display.ino +++ b/src/display.ino @@ -12,6 +12,8 @@ extern void display_setup(void) //display_test_number(); //display_test_weather(); //display_test_str(); + //display_test_battery(); + //esp_sleep(SLEEP_TIME); } static void GetWeekday(char *pszWeekday, uint8_t nWeekday) @@ -296,6 +298,39 @@ static bool RefreshHitokoto(void) return true; } +static void RefreshBattery(void) +{ + //电量百分比 + uint8_t percentage = bat_get_percentage(); + + //电量图标 + int16_t x_start = 3; + int16_t y_start = SCREEN_HEIGTH - FONT_SIZE_CHINESE_SPACING; + int16_t head_width = 3; + int16_t head_height = 6; + int16_t body_width = 24; + int16_t body_height = 14; + int16_t full_width = (body_width - 2 - 2) * percentage / 100; //填充宽度 + int16_t full_height = body_height - 2 - 2; //填充高度,留1像素间隙 + uint16_t color = COLOR_BLACK; //颜色 + if(percentage <= 10) color = COLOR_RED; //低于10%使用红色 + //head + int16_t x_head = x_start; + int16_t y_head = y_start + (FONT_SIZE_CHINESE_SPACING - body_height)/2 + (body_height - head_height)/2; + display.fillRect(x_head, y_head, head_width, head_height, color); + //body + int16_t x_body = x_head + head_width; + int16_t y_body = y_start + (FONT_SIZE_CHINESE_SPACING - body_height)/2; + display.drawRect(x_body, y_body, body_width, body_height, color); + //full + if(percentage >= 5) + { + int16_t x_full = x_body + 2 + (body_width - 2 - 2) - full_width; + int16_t y_full = y_start + (FONT_SIZE_CHINESE_SPACING - full_height)/2; + display.fillRect(x_full, y_full, full_width, full_height, color); + } +} + extern void display_MainPage(void) { display.setPartialWindow(0, 0, SCREEN_WIDTH, SCREEN_HEIGTH); //设置全局刷新 @@ -306,6 +341,7 @@ extern void display_MainPage(void) RefreshWeather();//刷新天气 RefreshLifeIndex();//刷新天气指数 RefreshHitokoto();//刷新一言 + RefreshBattery();//刷新电量 } while (display.nextPage()); } diff --git a/src/eInkCalendar.ino b/src/eInkCalendar.ino index 5835b34..c12989b 100644 --- a/src/eInkCalendar.ino +++ b/src/eInkCalendar.ino @@ -13,7 +13,13 @@ #include "bitmap.h" //按键定义 -#define KEY_UP 5 +#define KEY_UP 5 //上方按键 +#define KEY_DOWN EN //下方按键 +//电量读取PIN +#define BAT_PIN_SWITCH 12 //电池电压读取开关 +#define BAT_PIN_VCC A0 //读取电池电压引脚 +#define BAT_FULL 4.2 //满电压 +#define BAT_LOW 3.2 //低电压 //U8g2显示 U8G2_FOR_ADAFRUIT_GFX u8g2Fonts; diff --git a/src/test.ino b/src/test.ino index 9700e3b..950f2eb 100644 --- a/src/test.ino +++ b/src/test.ino @@ -98,5 +98,56 @@ extern void display_test_weather() //图标测试 display.drawInvertedBitmap(0, 200, Bitmap_zx_ws, 45, 45, COLOR_BLACK); display.drawInvertedBitmap(50, 200, Bitmap_weizhi, 13, 13, COLOR_BLACK); + display.display(1); +} + +static void test_battery(uint8_t percentage, int16_t x_start) +{ + //电量百分比 + //uint8_t percentage = bat_get_percentage(); + + //电量图标 + //int16_t x_start = 3; + int16_t y_start = SCREEN_HEIGTH - FONT_SIZE_CHINESE_SPACING; + int16_t head_width = 3; + int16_t head_height = 6; + int16_t body_width = 24; + int16_t body_height = 14; + int16_t full_width = (body_width - 2 - 2) * percentage / 100; //填充宽度 + int16_t full_height = body_height - 2 - 2; //填充高度,留1像素间隙 + uint16_t color = COLOR_BLACK; //颜色 + if(percentage <= 10) color = COLOR_RED; //低于10%使用红色 + //head + int16_t x_head = x_start; + int16_t y_head = y_start + (FONT_SIZE_CHINESE_SPACING - body_height)/2 + (body_height - head_height)/2; + display.fillRect(x_head, y_head, head_width, head_height, color); + //body + int16_t x_body = x_head + head_width; + int16_t y_body = y_start + (FONT_SIZE_CHINESE_SPACING - body_height)/2; + display.drawRect(x_body, y_body, body_width, body_height, color); + //full + if(percentage >= 5) + { + int16_t x_full = x_body + 2 + (body_width - 2 - 2) - full_width; + int16_t y_full = y_start + (FONT_SIZE_CHINESE_SPACING - full_height)/2; + display.fillRect(x_full, y_full, full_width, full_height, color); + } +} + +extern void display_test_battery(void) +{ + display.fillScreen(COLOR_WHITE); // 填充屏幕 + display.display(1); // 显示缓冲内容到屏幕,用于全屏缓冲 + + test_battery(100, 3); + test_battery( 90, 33); + test_battery( 70, 63); + test_battery( 50, 93); + test_battery( 30, 123); + test_battery( 10, 153); + test_battery( 5, 183); + test_battery( 3, 213); + test_battery( 0, 243); + display.display(1); } \ No newline at end of file diff --git a/src/util.ino b/src/util.ino index 95c2917..815d8b9 100644 --- a/src/util.ino +++ b/src/util.ino @@ -31,7 +31,6 @@ extern void SetForegroundColorBLACK(void) u8g2Fonts.setBackgroundColor(COLOR_WHITE); // 设置背景色 } - //系统休眠 extern void esp_sleep(uint32_t minutes) { @@ -56,4 +55,39 @@ extern void led_controller(bool controller) pinMode(LED_BUILTIN, INPUT); } +} + +//获取电压 +static float bat_get_vcc(void) //即时的电压 +{ + pinMode(BAT_PIN_SWITCH, OUTPUT); + digitalWrite(BAT_PIN_SWITCH, 1); + delay(1); + float vcc_cache = 0.0; + for (uint8_t i = 0; i < 20; i++) + { + //delay(1); + vcc_cache += analogRead(BAT_PIN_VCC) * 0.0009765625 * 5.537; + } + digitalWrite(BAT_PIN_SWITCH, 0); //关闭电池测量 + pinMode(BAT_PIN_SWITCH, INPUT); //改为输入状态避免漏电 + return (vcc_cache / 20); +} + +//获取电量百分比 +extern float bat_get_percentage(void) +{ + float vcc = 0.0; + float percentage = 0.0; + + vcc = bat_get_vcc(); + + //低电量 + if(vcc > BAT_LOW) + { + percentage = ((vcc - BAT_LOW) / (BAT_FULL - BAT_LOW)) * 100 + 0.5; //计算百分比 + if (percentage > 100) percentage = 100.0; + } + + return percentage; } \ No newline at end of file diff --git a/src/wifi.ino b/src/wifi.ino index d60f714..1f6312d 100644 --- a/src/wifi.ino +++ b/src/wifi.ino @@ -39,6 +39,7 @@ extern String callHttps(const char *url) client->setBufferSizes(512, 512); HTTPClient https; + https.setReuse(false); //是否keep-alive Serial.printf("[HTTPS] begin... url: %s\n", url); if (https.begin(*client, String(url))) { // HTTPS