mirror of
https://github.com/esphome/esphome.git
synced 2024-11-27 09:18:00 +01:00
[waveshare_epaper] Add support for 4.26inch display
This commit is contained in:
parent
ba11f2ab0c
commit
56044ed0a5
5 changed files with 233 additions and 1 deletions
|
@ -27,6 +27,9 @@ WaveshareEPaperBWR = waveshare_epaper_ns.class_(
|
||||||
WaveshareEPaperTypeA = waveshare_epaper_ns.class_(
|
WaveshareEPaperTypeA = waveshare_epaper_ns.class_(
|
||||||
"WaveshareEPaperTypeA", WaveshareEPaper
|
"WaveshareEPaperTypeA", WaveshareEPaper
|
||||||
)
|
)
|
||||||
|
WaveshareEPaper4P26In = waveshare_epaper_ns.class_(
|
||||||
|
"WaveshareEPaper4P26In", WaveshareEPaper
|
||||||
|
)
|
||||||
WaveshareEPaper2P7In = waveshare_epaper_ns.class_(
|
WaveshareEPaper2P7In = waveshare_epaper_ns.class_(
|
||||||
"WaveshareEPaper2P7In", WaveshareEPaper
|
"WaveshareEPaper2P7In", WaveshareEPaper
|
||||||
)
|
)
|
||||||
|
@ -113,6 +116,7 @@ MODELS = {
|
||||||
"2.13in-ttgo-b74": ("a", WaveshareEPaperTypeAModel.TTGO_EPAPER_2_13_IN_B74),
|
"2.13in-ttgo-b74": ("a", WaveshareEPaperTypeAModel.TTGO_EPAPER_2_13_IN_B74),
|
||||||
"2.90in": ("a", WaveshareEPaperTypeAModel.WAVESHARE_EPAPER_2_9_IN),
|
"2.90in": ("a", WaveshareEPaperTypeAModel.WAVESHARE_EPAPER_2_9_IN),
|
||||||
"2.90inv2": ("a", WaveshareEPaperTypeAModel.WAVESHARE_EPAPER_2_9_IN_V2),
|
"2.90inv2": ("a", WaveshareEPaperTypeAModel.WAVESHARE_EPAPER_2_9_IN_V2),
|
||||||
|
"4.26in": ("a", WaveshareEPaper4P26In),
|
||||||
"gdew029t5": ("c", GDEW029T5),
|
"gdew029t5": ("c", GDEW029T5),
|
||||||
"2.70in": ("b", WaveshareEPaper2P7In),
|
"2.70in": ("b", WaveshareEPaper2P7In),
|
||||||
"2.70in-b": ("b", WaveshareEPaper2P7InB),
|
"2.70in-b": ("b", WaveshareEPaper2P7InB),
|
||||||
|
@ -190,7 +194,10 @@ CONFIG_SCHEMA = cv.All(
|
||||||
|
|
||||||
async def to_code(config):
|
async def to_code(config):
|
||||||
model_type, model = MODELS[config[CONF_MODEL]]
|
model_type, model = MODELS[config[CONF_MODEL]]
|
||||||
if model_type == "a":
|
if config[CONF_MODEL] == "4.26in":
|
||||||
|
rhs = model.new()
|
||||||
|
var = cg.Pvariable(config[CONF_ID], rhs, model)
|
||||||
|
elif model_type == "a":
|
||||||
rhs = WaveshareEPaperTypeA.new(model)
|
rhs = WaveshareEPaperTypeA.new(model)
|
||||||
var = cg.Pvariable(config[CONF_ID], rhs, WaveshareEPaperTypeA)
|
var = cg.Pvariable(config[CONF_ID], rhs, WaveshareEPaperTypeA)
|
||||||
elif model_type in ("b", "c"):
|
elif model_type in ("b", "c"):
|
||||||
|
|
170
esphome/components/waveshare_epaper/waveshare_4_24in.cpp
Normal file
170
esphome/components/waveshare_epaper/waveshare_4_24in.cpp
Normal file
|
@ -0,0 +1,170 @@
|
||||||
|
#include "waveshare_epaper.h"
|
||||||
|
#include "esphome/core/log.h"
|
||||||
|
#include "esphome/core/application.h"
|
||||||
|
#include <cinttypes>
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace waveshare_epaper {
|
||||||
|
|
||||||
|
static const char *const TAG = "waveshare_epaper_4.26in";
|
||||||
|
|
||||||
|
WaveshareEPaper4P26In::WaveshareEPaper4P26In() : WaveshareEPaper() { reset_duration_ = 20; }
|
||||||
|
|
||||||
|
void WaveshareEPaper4P26In::init_display_async_(bool fast_update, const std::function<void()> f) {
|
||||||
|
// Reset the display
|
||||||
|
this->reset_();
|
||||||
|
wait_until_idle_async_([this, fast_update, f] {
|
||||||
|
this->command(0x12); // SWRESET
|
||||||
|
|
||||||
|
wait_until_idle_async_([this, fast_update, f] {
|
||||||
|
// Use the internal temperature sensor
|
||||||
|
this->command(0x18);
|
||||||
|
this->data(0x80);
|
||||||
|
|
||||||
|
// Set soft start
|
||||||
|
this->command(0x0C);
|
||||||
|
this->data(0xAE);
|
||||||
|
this->data(0xC7);
|
||||||
|
this->data(0xC3);
|
||||||
|
this->data(0xC0);
|
||||||
|
this->data(0x80);
|
||||||
|
|
||||||
|
// Drive output control
|
||||||
|
this->command(0x01);
|
||||||
|
this->data((this->get_height_internal() - 1) % 256); // Y
|
||||||
|
this->data((this->get_height_internal() - 1) / 256); // Y
|
||||||
|
this->data(0x02);
|
||||||
|
|
||||||
|
// // Border settings
|
||||||
|
// this->command(0x3C);
|
||||||
|
// this->data(0x01);
|
||||||
|
|
||||||
|
// Data entry mode setting
|
||||||
|
this->command(0x11);
|
||||||
|
this->data(0x01); // x increase, y decrease : as in demo code
|
||||||
|
|
||||||
|
// Set window, this is always the full screen for now
|
||||||
|
this->command(0x44); // SET_RAM_X_ADDRESS_START_END_POSITION
|
||||||
|
this->data(0x00);
|
||||||
|
this->data(0x00);
|
||||||
|
this->data((this->get_width_internal() - 1) & 0xFF);
|
||||||
|
this->data(((this->get_width_internal() - 1) >> 8) & 0x03);
|
||||||
|
|
||||||
|
this->command(0x45); // SET_RAM_Y_ADDRESS_START_END_POSITION
|
||||||
|
this->data((this->get_height_internal() - 1) & 0xFF);
|
||||||
|
this->data(((this->get_height_internal() - 1) >> 8) & 0x03);
|
||||||
|
this->data(0x00);
|
||||||
|
this->data(0x00);
|
||||||
|
|
||||||
|
// Set cursor
|
||||||
|
this->command(0x4E); // SET_RAM_X_ADDRESS_COUNTER
|
||||||
|
this->data(0x00);
|
||||||
|
this->data(0x00);
|
||||||
|
|
||||||
|
this->command(0x4F); // SET_RAM_Y_ADDRESS_COUNTER
|
||||||
|
this->data(0x00);
|
||||||
|
this->data(0x00);
|
||||||
|
|
||||||
|
if (fast_update) {
|
||||||
|
this->wait_until_idle_async_([this, f] {
|
||||||
|
this->command(0x1A);
|
||||||
|
this->data(0x5A);
|
||||||
|
|
||||||
|
this->command(0x22);
|
||||||
|
this->data(0x91);
|
||||||
|
this->command(0x20);
|
||||||
|
|
||||||
|
this->wait_until_idle_async_(std::move(f));
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this->wait_until_idle_async_(std::move(f));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void WaveshareEPaper4P26In::initialize() {}
|
||||||
|
|
||||||
|
void WaveshareEPaper4P26In::dump_config() {
|
||||||
|
LOG_DISPLAY("", "Waveshare E-Paper", this);
|
||||||
|
ESP_LOGCONFIG(TAG, " Model: 4.26in");
|
||||||
|
ESP_LOGCONFIG(TAG, " Full Update Every: %" PRIu32, this->full_update_every_);
|
||||||
|
LOG_PIN(" Reset Pin: ", this->reset_pin_);
|
||||||
|
LOG_PIN(" DC Pin: ", this->dc_pin_);
|
||||||
|
LOG_PIN(" Busy Pin: ", this->busy_pin_);
|
||||||
|
LOG_UPDATE_INTERVAL(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HOT WaveshareEPaper4P26In::display() {
|
||||||
|
if (this->is_busy_) {
|
||||||
|
ESP_LOGE(TAG, "Skipping display, display is busy");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->is_busy_ = true;
|
||||||
|
|
||||||
|
bool full_update = this->at_update_ == 0;
|
||||||
|
bool prev_full_update = this->at_update_ == 1;
|
||||||
|
|
||||||
|
if (this->full_update_every_ >= 1) {
|
||||||
|
this->at_update_ = (this->at_update_ + 1) % this->full_update_every_;
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Wake up the display");
|
||||||
|
this->init_display_async_(!full_update, [this, full_update] {
|
||||||
|
// Border settings
|
||||||
|
this->command(0x3C);
|
||||||
|
// this->data(full_update ? 0x01 : 0x80);
|
||||||
|
this->data(0x01);
|
||||||
|
|
||||||
|
// Write RAM
|
||||||
|
this->command(0x24);
|
||||||
|
this->start_data_();
|
||||||
|
this->write_array(this->buffer_, this->get_buffer_length_());
|
||||||
|
this->end_data_();
|
||||||
|
|
||||||
|
if (full_update) {
|
||||||
|
// Write base image again on full refresh
|
||||||
|
this->command(0x26);
|
||||||
|
this->start_data_();
|
||||||
|
this->write_array(this->buffer_, this->get_buffer_length_());
|
||||||
|
this->end_data_();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Display Update Control
|
||||||
|
this->command(0x22);
|
||||||
|
this->data(full_update ? 0xF7 : 0xC7); // 0xF7 = Full update, 0xC7 = Fast update, 0xFF = Partial update
|
||||||
|
|
||||||
|
// Activate Display Update Sequence
|
||||||
|
this->command(0x20);
|
||||||
|
|
||||||
|
this->wait_until_idle_async_([this] {
|
||||||
|
ESP_LOGI(TAG, "Display updated, set it back to deep sleep");
|
||||||
|
this->deep_sleep();
|
||||||
|
this->is_busy_ = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
this->status_clear_warning();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void WaveshareEPaper4P26In::deep_sleep() {
|
||||||
|
// Set deep sleep mode
|
||||||
|
this->command(0x10);
|
||||||
|
this->data(0x01);
|
||||||
|
|
||||||
|
delay(50);
|
||||||
|
}
|
||||||
|
|
||||||
|
int WaveshareEPaper4P26In::get_width_internal() { return 800; }
|
||||||
|
|
||||||
|
int WaveshareEPaper4P26In::get_height_internal() { return 480; }
|
||||||
|
|
||||||
|
uint32_t WaveshareEPaper4P26In::idle_timeout_() { return 4000; }
|
||||||
|
|
||||||
|
void WaveshareEPaper4P26In::set_full_update_every(uint32_t full_update_every) {
|
||||||
|
this->full_update_every_ = full_update_every;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace waveshare_epaper
|
||||||
|
} // namespace esphome
|
|
@ -163,6 +163,15 @@ bool WaveshareEPaperBase::wait_until_idle_() {
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WaveshareEPaperBase::wait_until_idle_async_(const std::function<void()> f) {
|
||||||
|
if (this->busy_pin_ == nullptr || !this->busy_pin_->digital_read()) {
|
||||||
|
return f();
|
||||||
|
}
|
||||||
|
|
||||||
|
this->set_timeout(20, [this, f] { this->wait_until_idle_async_(std::move(f)); });
|
||||||
|
}
|
||||||
|
|
||||||
void WaveshareEPaperBase::update() {
|
void WaveshareEPaperBase::update() {
|
||||||
this->do_update_();
|
this->do_update_();
|
||||||
this->display();
|
this->display();
|
||||||
|
|
|
@ -36,6 +36,7 @@ class WaveshareEPaperBase : public display::DisplayBuffer,
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool wait_until_idle_();
|
bool wait_until_idle_();
|
||||||
|
void wait_until_idle_async_(const std::function<void()> f);
|
||||||
|
|
||||||
void setup_pins_();
|
void setup_pins_();
|
||||||
|
|
||||||
|
@ -154,6 +155,33 @@ class WaveshareEPaperTypeA : public WaveshareEPaper {
|
||||||
bool deep_sleep_between_updates_{false};
|
bool deep_sleep_between_updates_{false};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class WaveshareEPaper4P26In : public WaveshareEPaper {
|
||||||
|
public:
|
||||||
|
WaveshareEPaper4P26In();
|
||||||
|
|
||||||
|
void initialize() override;
|
||||||
|
void display() override;
|
||||||
|
void deep_sleep() override;
|
||||||
|
|
||||||
|
void dump_config() override;
|
||||||
|
void set_full_update_every(uint32_t full_update_every);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void init_display_async_(bool fast_update, const std::function<void()> f);
|
||||||
|
|
||||||
|
int get_width_internal() override;
|
||||||
|
int get_height_internal() override;
|
||||||
|
|
||||||
|
uint32_t idle_timeout_() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool is_busy_ = false;
|
||||||
|
uint32_t full_update_every_{30};
|
||||||
|
uint32_t at_update_{0};
|
||||||
|
|
||||||
|
bool deep_sleep_between_updates_{true};
|
||||||
|
};
|
||||||
|
|
||||||
enum WaveshareEPaperTypeBModel {
|
enum WaveshareEPaperTypeBModel {
|
||||||
WAVESHARE_EPAPER_2_7_IN = 0,
|
WAVESHARE_EPAPER_2_7_IN = 0,
|
||||||
WAVESHARE_EPAPER_2_7_IN_B,
|
WAVESHARE_EPAPER_2_7_IN_B,
|
||||||
|
|
|
@ -188,3 +188,21 @@ display:
|
||||||
full_update_every: 30
|
full_update_every: 30
|
||||||
lambda: |-
|
lambda: |-
|
||||||
it.rectangle(0, 0, it.get_width(), it.get_height());
|
it.rectangle(0, 0, it.get_width(), it.get_height());
|
||||||
|
- platform: waveshare_epaper
|
||||||
|
model: 4.26in
|
||||||
|
spi_id: spi_id_1
|
||||||
|
cs_pin:
|
||||||
|
allow_other_uses: true
|
||||||
|
number: GPIO25
|
||||||
|
dc_pin:
|
||||||
|
allow_other_uses: true
|
||||||
|
number: GPIO26
|
||||||
|
busy_pin:
|
||||||
|
allow_other_uses: true
|
||||||
|
number: GPIO27
|
||||||
|
reset_pin:
|
||||||
|
allow_other_uses: true
|
||||||
|
number: GPIO32
|
||||||
|
full_update_every: 30
|
||||||
|
lambda: |-
|
||||||
|
it.rectangle(0, 0, it.get_width(), it.get_height());
|
||||||
|
|
Loading…
Reference in a new issue