2 Commits

Author SHA1 Message Date
Jerry
1f049f4630 1.1.4 2025-10-07 10:14:02 +08:00
Jerry
cd0eb87bce 1.1.4 2025-10-07 10:09:05 +08:00
4 changed files with 42 additions and 30 deletions

View File

@@ -10,7 +10,7 @@ Bilibili连接https://www.bilibili.com/video/BV1wHDhYoE3G/<br>
1. esp32开发板(建议lolin32 lite,其他esp32开发板亦可)<br>
2. 4.2寸三色墨水屏(400*300)。
3. 通用墨水屏驱动板。
4. 锂电池,需要做ph2.0接头。(建议603048, 900mah)
4. 锂电池,需要做ph2.0接头,建议购买带保护板的电池。(推荐603048, 900mah)
5. 金属底座亚克力台卡,95*80mm。
6. 轻触开关,(12\*12\*7.3,带键帽)
7. 工具:电烙铁、电线若干。
@@ -107,12 +107,12 @@ A: 观察22针脚的LED是否点亮有闪烁说明固件已经刷入如果
3. Q: 可以支持哪种屏?<br>
A: 仅4.2寸三色屏(目前仅支持黑白红,将来支持黑白黄)。
4. Q: 我使用的屏应该烧录哪个固件?<br>
A: 从经验上预估大部分比较新一些的选z98SES的拆机屏选z21如果是非常老的屏选z15。实在不行的话三个固件都刷一遍试试。<br>
A: 从经验上预估,大部分比较新一些的选1680新一点的拆机屏选z98SES的拆机屏选z21如果是非常老的屏选z15。实在不行的话三个固件都刷一遍试试。<br>
明确的丝印对应如下:<br>
|丝印|固件|
|-----|-----|
|P420010|1680|
|E042A43-A0|z98|
|P420010|z98|
|A13600**|z21|
5. Q: 使用flash download tool刷新固件时报错连接串口失败。<br>
A: 1. 检查USB线连接是否正常。 <br>2. app的串口下拉框里是否检测到COM口。 <br>3. 把其他串口工具关闭防止占用COM口。
@@ -124,8 +124,15 @@ A: 仅刷新app固件后配置是保留的所以无需重新配置。
A: 2025年3月1日后注册的和风天气账户有API Host限制请下载1.0.25以后版本在配置时配置API Host信息。
8. Q: 如何切换日历和课程表显示?<br>
A: 在系统运行状态下(状态灯常亮),单击按键,稍等即可切换课程表的展示。
9. Q: 充一次电能使用多久?<br>
A: 这个取决于选用的电池和使用场景以及开发板的质量。正常情况下休眠的电流为120ua左右刷新一次需要1.6mah。以900mah的电池、每日刷新一次举例理论上大概可以待机半年。
10. Q: 为何我的日历待机时间很短?<br>
A: 可能是开发板或驱动板的质量问题实际发现有些板子休眠功耗能达2ma这会极大影响待机时长。另外由于电池容量的虚标待机时长与理论计算值也有较大偏差。建议增加电池测量电路及时显示电池电量情况。
## Releases
### 1.1.4
* Refine: 电池检测、功耗优化
* New: 增加1680驱动版本
### 1.1.3
* Fix: some bugs.
### 1.1.2

View File

@@ -14,20 +14,26 @@
充电截止电压 4.2
放电截止电压 3.3
*/
#include "battery.h"
#include "driver/adc.h"
#include "esp_adc_cal.h"
#include <Arduino.h>
/**
* 获取电池电压mV
*/
int readBatteryVoltage() {
esp_adc_cal_characteristics_t adc_chars;
esp_adc_cal_value_t val_type = esp_adc_cal_characterize(ADC_UNIT_1, ADC_ATTEN_11db, ADC_WIDTH_BIT_12, 1100, &adc_chars);
static const adc1_channel_t channel = ADC1_CHANNEL_4; // GPIO32
adc1_config_width(ADC_WIDTH_BIT_12);
adc1_config_channel_atten(channel, ADC_ATTEN_11db);
adc_power_acquire();
delay(10);
int adc_val = adc1_get_raw(channel);
adc_power_release();
esp_adc_cal_characteristics_t adc_chars;
esp_adc_cal_value_t val_type = esp_adc_cal_characterize(ADC_UNIT_1, ADC_ATTEN_11db, ADC_WIDTH_BIT_12, 1100, &adc_chars);
int voltage = esp_adc_cal_raw_to_voltage(adc_val, &adc_chars);
voltage *= 2;

View File

@@ -92,13 +92,6 @@ void setup() {
Serial.println("\r\n\r\n");
delay(10);
button.setClickMs(300);
button.setPressMs(3000); // 设置长按的时长
button.attachClick(buttonClick, &button);
button.attachDoubleClick(buttonDoubleClick, &button);
// button.attachMultiClick()
button.attachLongPressStop(buttonLongPressStop, &button);
attachInterrupt(digitalPinToInterrupt(KEY_M), checkTicks, CHANGE);
Serial.printf("***********************\r\n");
Serial.printf(" J-Calendar\r\n");
@@ -111,8 +104,8 @@ void setup() {
delay(1000);
int voltage = readBatteryVoltage();
Serial.printf("Battery: %d mV\r\n", voltage);
if(voltage < 1000) {
Serial.println("[WARN]无电池");
if(voltage < 2500) {
Serial.println("[INFO]电池损坏或无ADC电路");
} else if(voltage < 3000) {
Serial.println("[WARN]电量低于3v系统休眠。");
go_sleep();
@@ -121,8 +114,18 @@ void setup() {
Serial.println("[WARN]电量低于3.3v,警告并系统休眠。");
si_warning("电量不足,请充电!");
go_sleep();
} else if (voltage > 4400) {
Serial.println("[INFO]未接电池。");
}
button.setClickMs(300);
button.setPressMs(3000); // 设置长按的时长
button.attachClick(buttonClick, &button);
button.attachDoubleClick(buttonDoubleClick, &button);
// button.attachMultiClick()
button.attachLongPressStop(buttonLongPressStop, &button);
attachInterrupt(digitalPinToInterrupt(KEY_M), checkTicks, CHANGE);
Serial.println("Wm begin...");
led_fast();
wm.setHostname("J-Calendar");
@@ -343,24 +346,19 @@ void go_sleep() {
if (_qweather_key.length() == 0 || weather_type() == 0) { // 没有配置天气或者使用按日天气,则第二天刷新。
// Sleep to next day
int secondsToNextDay = (24 - local.tm_hour) * 3600 - local.tm_min * 60 - local.tm_sec;
if (secondsToNextDay <= 0) {
secondsToNextDay += 24 * 3600;
}
Serial.printf("Seconds to next day: %d seconds.\n", secondsToNextDay);
p = (uint64_t)(secondsToNextDay);
p = p < 0 ? 3600 * 24 : (p + 30); // 额外增加30秒避免过早唤醒
} else {
// Sleep to next even hour.
int secondsToNextHour = (60 - local.tm_min) * 60 - local.tm_sec;
if (secondsToNextHour <= 0) {
secondsToNextHour += 3600;
}
if ((local.tm_hour % 2) == 0) { // 如果是奇数点则多睡1小时
secondsToNextHour += 3600;
}
Serial.printf("Seconds to next even hour: %d seconds.\n", secondsToNextHour);
p = (uint64_t)(secondsToNextHour);
p = p < 0 ? 3600 : (p + 10); // 额外增加10秒避免过早唤醒
}
p += 10; // 额外增加10秒避免过早唤醒
esp_sleep_enable_timer_wakeup(p * (uint64_t)uS_TO_S_FACTOR);
esp_sleep_enable_ext0_wakeup(KEY_M, LOW);
@@ -370,21 +368,22 @@ void go_sleep() {
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_SLOW_MEM, ESP_PD_OPTION_OFF); //
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_FAST_MEM, ESP_PD_OPTION_OFF);
esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL, ESP_PD_OPTION_OFF);
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC8M, ESP_PD_OPTION_OFF);
gpio_deep_sleep_hold_dis(); // 解除所有引脚的保持状态
// 省电考虑重置gpio平均每针脚能省8ua。
gpio_reset_pin(PIN_LED_R); // 减小deep-sleep电流
// gpio_reset_pin(PIN_LED_R); // 减小deep-sleep电流
gpio_reset_pin(SPI_CS); // 减小deep-sleep电流
gpio_reset_pin(SPI_DC); // 减小deep-sleep电流
gpio_reset_pin(SPI_RST); // 减小deep-sleep电流
gpio_reset_pin(SPI_BUSY); // 减小deep-sleep电流
gpio_reset_pin(SPI_BUSY); // 减小deep-sleep电流`
gpio_reset_pin(SPI_MOSI); // 减小deep-sleep电流
gpio_reset_pin(SPI_MISO); // 减小deep-sleep电流
gpio_reset_pin(SPI_SCK); // 减小deep-sleep电流
gpio_reset_pin(PIN_ADC); // 减小deep-sleep电流
gpio_reset_pin(I2C_SDA); // 减小deep-sleep电流
gpio_reset_pin(I2C_SCL); // 减小deep-sleep电流
// gpio_reset_pin(PIN_ADC); // 减小deep-sleep电流
// gpio_reset_pin(I2C_SDA); // 减小deep-sleep电流
// gpio_reset_pin(I2C_SCL); // 减小deep-sleep电流
delay(10);
Serial.println("Deep sleep...");

View File

@@ -1087,7 +1087,7 @@ void task_screen(void* param) {
pref.putInt(PREF_SI_CAL_DATE, _calendar_date);
pref.end();
display.powerOff(); // !!!important!!!, 关闭屏幕否则会多0.5ma的空载电流(全屏刷新的话会自动关闭,局部刷新必须手动关闭)
display.powerOff();
display.hibernate();
Serial.println("[Task] screen update end...");
@@ -1150,7 +1150,7 @@ void si_warning(const char* str) {
u8g2Fonts.print("\u0118");
u8g2Fonts.setForegroundColor(GxEPD_BLACK);
u8g2Fonts.setCursor(u8g2Fonts.getCursorX() + space, u8g2Fonts.getCursorY() - 5);
u8g2Fonts.setCursor(u8g2Fonts.getCursorX() + space, u8g2Fonts.getCursorY() - 8);
u8g2Fonts.setFont(FONT_TEXT);
u8g2Fonts.print(str);
} while (display.nextPage());