mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 15:12:06 +00:00 
			
		
		
		
	Support for pcd8544 (nokia 5110 and 3310) screen (#973)
* First version of working compontent for pc8544 screen * Fixed lint errors * Fixed lint errors #2
This commit is contained in:
		
				
					committed by
					
						 GitHub
						GitHub
					
				
			
			
				
	
			
			
			
						parent
						
							25cdbacecc
						
					
				
				
					commit
					4620ad6124
				
			
							
								
								
									
										0
									
								
								esphome/components/pcd8544/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								esphome/components/pcd8544/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										39
									
								
								esphome/components/pcd8544/display.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								esphome/components/pcd8544/display.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | |||||||
|  | import esphome.codegen as cg | ||||||
|  | import esphome.config_validation as cv | ||||||
|  | from esphome import pins | ||||||
|  | from esphome.components import display, spi | ||||||
|  | from esphome.const import ( | ||||||
|  |     CONF_DC_PIN, CONF_ID, CONF_LAMBDA, CONF_PAGES, CONF_RESET_PIN, CONF_CS_PIN, | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | DEPENDENCIES = ['spi'] | ||||||
|  |  | ||||||
|  | pcd8544_ns = cg.esphome_ns.namespace('pcd8544') | ||||||
|  | PCD8544 = pcd8544_ns.class_('PCD8544', cg.PollingComponent, display.DisplayBuffer, spi.SPIDevice) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | CONFIG_SCHEMA = cv.All(display.FULL_DISPLAY_SCHEMA.extend({ | ||||||
|  |     cv.GenerateID(): cv.declare_id(PCD8544), | ||||||
|  |     cv.Required(CONF_DC_PIN): pins.gpio_output_pin_schema, | ||||||
|  |     cv.Required(CONF_RESET_PIN): pins.gpio_output_pin_schema, | ||||||
|  |     cv.Required(CONF_CS_PIN): pins.gpio_output_pin_schema,  # CE | ||||||
|  | }).extend(cv.polling_component_schema('1s')).extend(spi.SPI_DEVICE_SCHEMA), | ||||||
|  |                        cv.has_at_most_one_key(CONF_PAGES, CONF_LAMBDA)) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def to_code(config): | ||||||
|  |     var = cg.new_Pvariable(config[CONF_ID]) | ||||||
|  |  | ||||||
|  |     yield cg.register_component(var, config) | ||||||
|  |     yield display.register_display(var, config) | ||||||
|  |     yield spi.register_spi_device(var, config) | ||||||
|  |  | ||||||
|  |     dc = yield cg.gpio_pin_expression(config[CONF_DC_PIN]) | ||||||
|  |     cg.add(var.set_dc_pin(dc)) | ||||||
|  |     reset = yield cg.gpio_pin_expression(config[CONF_RESET_PIN]) | ||||||
|  |     cg.add(var.set_reset_pin(reset)) | ||||||
|  |  | ||||||
|  |     if CONF_LAMBDA in config: | ||||||
|  |         lambda_ = yield cg.process_lambda(config[CONF_LAMBDA], [(display.DisplayBufferRef, 'it')], | ||||||
|  |                                           return_type=cg.void) | ||||||
|  |         cg.add(var.set_writer(lambda_)) | ||||||
							
								
								
									
										127
									
								
								esphome/components/pcd8544/pcd_8544.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										127
									
								
								esphome/components/pcd8544/pcd_8544.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,127 @@ | |||||||
|  | #include "pcd_8544.h" | ||||||
|  | #include "esphome/core/log.h" | ||||||
|  | #include "esphome/core/application.h" | ||||||
|  | #include "esphome/core/helpers.h" | ||||||
|  |  | ||||||
|  | namespace esphome { | ||||||
|  | namespace pcd8544 { | ||||||
|  |  | ||||||
|  | static const char *TAG = "pcd_8544"; | ||||||
|  |  | ||||||
|  | void PCD8544::setup_pins_() { | ||||||
|  |   this->spi_setup(); | ||||||
|  |   this->init_reset_(); | ||||||
|  |   this->dc_pin_->setup(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void PCD8544::init_reset_() { | ||||||
|  |   if (this->reset_pin_ != nullptr) { | ||||||
|  |     this->reset_pin_->setup(); | ||||||
|  |     this->reset_pin_->digital_write(true); | ||||||
|  |     delay(1); | ||||||
|  |     // Trigger Reset | ||||||
|  |     this->reset_pin_->digital_write(false); | ||||||
|  |     delay(10); | ||||||
|  |     // Wake up | ||||||
|  |     this->reset_pin_->digital_write(true); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void PCD8544::initialize() { | ||||||
|  |   this->init_internal_(this->get_buffer_length_()); | ||||||
|  |  | ||||||
|  |   this->command(this->PCD8544_FUNCTIONSET | this->PCD8544_EXTENDEDINSTRUCTION); | ||||||
|  |   // LCD bias select (4 is optimal?) | ||||||
|  |   this->command(this->PCD8544_SETBIAS | 0x04); | ||||||
|  |  | ||||||
|  |   // contrast | ||||||
|  |   // TODO: in future version we may add a user a control over contrast | ||||||
|  |   this->command(this->PCD8544_SETVOP | 0x7f);  // Experimentally determined | ||||||
|  |  | ||||||
|  |   // normal mode | ||||||
|  |   this->command(this->PCD8544_FUNCTIONSET); | ||||||
|  |  | ||||||
|  |   // Set display to Normal | ||||||
|  |   this->command(this->PCD8544_DISPLAYCONTROL | this->PCD8544_DISPLAYNORMAL); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void PCD8544::start_command_() { | ||||||
|  |   this->dc_pin_->digital_write(false); | ||||||
|  |   this->enable(); | ||||||
|  | } | ||||||
|  | void PCD8544::end_command_() { this->disable(); } | ||||||
|  | void PCD8544::start_data_() { | ||||||
|  |   this->dc_pin_->digital_write(true); | ||||||
|  |   this->enable(); | ||||||
|  | } | ||||||
|  | void PCD8544::end_data_() { this->disable(); } | ||||||
|  |  | ||||||
|  | int PCD8544::get_width_internal() { return 84; } | ||||||
|  | int PCD8544::get_height_internal() { return 48; } | ||||||
|  |  | ||||||
|  | size_t PCD8544::get_buffer_length_() { | ||||||
|  |   return size_t(this->get_width_internal()) * size_t(this->get_height_internal()) / 8u; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void HOT PCD8544::display() { | ||||||
|  |   uint8_t col, maxcol, p; | ||||||
|  |  | ||||||
|  |   for (p = 0; p < 6; p++) { | ||||||
|  |     this->command(this->PCD8544_SETYADDR | p); | ||||||
|  |  | ||||||
|  |     // start at the beginning of the row | ||||||
|  |     col = 0; | ||||||
|  |     maxcol = this->get_width_internal() - 1; | ||||||
|  |  | ||||||
|  |     this->command(this->PCD8544_SETXADDR | col); | ||||||
|  |  | ||||||
|  |     this->start_data_(); | ||||||
|  |     for (; col <= maxcol; col++) { | ||||||
|  |       this->write_byte(this->buffer_[(this->get_width_internal() * p) + col]); | ||||||
|  |     } | ||||||
|  |     this->end_data_(); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   this->command(this->PCD8544_SETYADDR); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void HOT PCD8544::draw_absolute_pixel_internal(int x, int y, int color) { | ||||||
|  |   if (x >= this->get_width_internal() || y >= this->get_height_internal() || x < 0 || y < 0) { | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   uint16_t pos = x + (y / 8) * this->get_width_internal(); | ||||||
|  |   uint8_t subpos = y % 8; | ||||||
|  |   if (color) { | ||||||
|  |     this->buffer_[pos] |= (1 << subpos); | ||||||
|  |   } else { | ||||||
|  |     this->buffer_[pos] &= ~(1 << subpos); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void PCD8544::dump_config() { | ||||||
|  |   LOG_DISPLAY("", "PCD8544", this); | ||||||
|  |   LOG_PIN("  DC Pin: ", this->dc_pin_); | ||||||
|  |   LOG_PIN("  Reset Pin: ", this->reset_pin_); | ||||||
|  |   LOG_UPDATE_INTERVAL(this); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void PCD8544::command(uint8_t value) { | ||||||
|  |   this->start_command_(); | ||||||
|  |   this->write_byte(value); | ||||||
|  |   this->end_command_(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void PCD8544::update() { | ||||||
|  |   this->do_update_(); | ||||||
|  |   this->display(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void PCD8544::fill(int color) { | ||||||
|  |   uint8_t fill = color ? 0xFF : 0x00; | ||||||
|  |   for (uint32_t i = 0; i < this->get_buffer_length_(); i++) | ||||||
|  |     this->buffer_[i] = fill; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | }  // namespace pcd8544 | ||||||
|  | }  // namespace esphome | ||||||
							
								
								
									
										75
									
								
								esphome/components/pcd8544/pcd_8544.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								esphome/components/pcd8544/pcd_8544.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,75 @@ | |||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #include "esphome/core/component.h" | ||||||
|  | #include "esphome/components/spi/spi.h" | ||||||
|  | #include "esphome/components/display/display_buffer.h" | ||||||
|  |  | ||||||
|  | namespace esphome { | ||||||
|  | namespace pcd8544 { | ||||||
|  |  | ||||||
|  | class PCD8544 : public PollingComponent, | ||||||
|  |                 public display::DisplayBuffer, | ||||||
|  |                 public spi::SPIDevice<spi::BIT_ORDER_MSB_FIRST, spi::CLOCK_POLARITY_HIGH, spi::CLOCK_PHASE_TRAILING, | ||||||
|  |                                       spi::DATA_RATE_8MHZ> { | ||||||
|  |  public: | ||||||
|  |   const uint8_t PCD8544_POWERDOWN = 0x04; | ||||||
|  |   const uint8_t PCD8544_ENTRYMODE = 0x02; | ||||||
|  |   const uint8_t PCD8544_EXTENDEDINSTRUCTION = 0x01; | ||||||
|  |  | ||||||
|  |   const uint8_t PCD8544_DISPLAYBLANK = 0x0; | ||||||
|  |   const uint8_t PCD8544_DISPLAYNORMAL = 0x4; | ||||||
|  |   const uint8_t PCD8544_DISPLAYALLON = 0x1; | ||||||
|  |   const uint8_t PCD8544_DISPLAYINVERTED = 0x5; | ||||||
|  |  | ||||||
|  |   const uint8_t PCD8544_FUNCTIONSET = 0x20; | ||||||
|  |   const uint8_t PCD8544_DISPLAYCONTROL = 0x08; | ||||||
|  |   const uint8_t PCD8544_SETYADDR = 0x40; | ||||||
|  |   const uint8_t PCD8544_SETXADDR = 0x80; | ||||||
|  |  | ||||||
|  |   const uint8_t PCD8544_SETTEMP = 0x04; | ||||||
|  |   const uint8_t PCD8544_SETBIAS = 0x10; | ||||||
|  |   const uint8_t PCD8544_SETVOP = 0x80; | ||||||
|  |  | ||||||
|  |   void set_dc_pin(GPIOPin *dc_pin) { this->dc_pin_ = dc_pin; } | ||||||
|  |   void set_reset_pin(GPIOPin *reset) { this->reset_pin_ = reset; } | ||||||
|  |   float get_setup_priority() const override { return setup_priority::PROCESSOR; } | ||||||
|  |  | ||||||
|  |   void command(uint8_t value); | ||||||
|  |   void data(uint8_t value); | ||||||
|  |  | ||||||
|  |   void initialize(); | ||||||
|  |   void dump_config() override; | ||||||
|  |   void HOT display(); | ||||||
|  |  | ||||||
|  |   void update() override; | ||||||
|  |  | ||||||
|  |   void fill(int color) override; | ||||||
|  |  | ||||||
|  |   void setup() override { | ||||||
|  |     this->setup_pins_(); | ||||||
|  |     this->initialize(); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |  protected: | ||||||
|  |   void draw_absolute_pixel_internal(int x, int y, int color) override; | ||||||
|  |  | ||||||
|  |   void setup_pins_(); | ||||||
|  |  | ||||||
|  |   void init_reset_(); | ||||||
|  |  | ||||||
|  |   size_t get_buffer_length_(); | ||||||
|  |  | ||||||
|  |   void start_command_(); | ||||||
|  |   void end_command_(); | ||||||
|  |   void start_data_(); | ||||||
|  |   void end_data_(); | ||||||
|  |  | ||||||
|  |   int get_width_internal() override; | ||||||
|  |   int get_height_internal() override; | ||||||
|  |  | ||||||
|  |   GPIOPin *reset_pin_; | ||||||
|  |   GPIOPin *dc_pin_; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | }  // namespace pcd8544 | ||||||
|  | }  // namespace esphome | ||||||
| @@ -1444,6 +1444,12 @@ display: | |||||||
|   lambda: |- |   lambda: |- | ||||||
|     it.set_component_value("gauge", 50); |     it.set_component_value("gauge", 50); | ||||||
|     it.set_component_text("textview", "Hello World!"); |     it.set_component_text("textview", "Hello World!"); | ||||||
|  | - platform: pcd8544 | ||||||
|  |   cs_pin: GPIO23 | ||||||
|  |   dc_pin: GPIO23 | ||||||
|  |   reset_pin: GPIO23 | ||||||
|  |   lambda: |- | ||||||
|  |     it.rectangle(0, 0, it.get_width(), it.get_height()); | ||||||
| - platform: ssd1306_i2c | - platform: ssd1306_i2c | ||||||
|   model: "SSD1306_128X64" |   model: "SSD1306_128X64" | ||||||
|   reset_pin: GPIO23 |   reset_pin: GPIO23 | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user