mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 07:03:55 +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: |- | ||||
|     it.set_component_value("gauge", 50); | ||||
|     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 | ||||
|   model: "SSD1306_128X64" | ||||
|   reset_pin: GPIO23 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user