Class: Denko::Display::SSD1306
- Inherits:
-
Object
- Object
- Denko::Display::SSD1306
- Includes:
- I2C::Peripheral
- Defined in:
- lib/denko/display/ssd1306.rb
Constant Summary collapse
- PIXELS_FROM_RAM =
Single byte (no need to OR with anything)
0xA4
- PIXELS_ALL_ON =
0xA5
- INVERT_OFF =
0xA6
- INVERT_ON =
0xA7
- DISPLAY_OFF =
0xAE
- DISPLAY_ON =
0xAF
- CONTRAST =
Double byte (following byte sets value)
0x81
- COLUMN_START_LOWER =
Single byte. OR with value. These are for page addressing mode only.
0x00
- COLUMN_START_UPPER =
lower 4 bytes of column
0x10
- PAGE_START =
upper 4 bytes of column
0xB0
- ADDRESSING_MODE =
Double byte. Following byte sets value.
0x20
- COLUMN_ADDRESS_RANGE =
Triple byte. Following 2 bytes sets value. For H/V addressing modes only.
0x21
- PAGE_ADDRESS_RANGE =
0x22
- START_LINE =
Single byte. OR with value.
0x40
- SEGMENT_REMAP =
Value: lowest 6 bits set RAM start line (default 0b000000)
0xA0
- COM_DIRECTION =
Value: 0x00 = default, 0x01 = column draw order reversed (horizontal reflection)
0xC0
- CHARGE_PUMP =
Double-byte commands. Following byte sets value.
0x8D
- MULTIPLEX_RATIO =
Value: 0x10 = disable/external, 0x14 = enable/internal
0xA8
- DISPLAY_OFFSET =
Value: rows of display - 1
0xD3
- COM_PIN_CONFIG =
Value: lowest 5 bits. Vertically shifts COM by that amount.
0xDA
- CLOCK =
Double-byte commands. Following byte sets value.
0xD5
- PRECHARGE_PERIOD =
Lowest 4 bits = divider. Upper 4 bits = oscillator frequency.
0xD9
- VCOM_DESELECT_LEVEL =
Lowest 4 bits = phase 1. Upper 4 bits = phase 2. 0xF1 for internal charge pump. 0x22 for external.
0xDB
- WIDTHS =
Valid widths and heights for displays
[64,96,128]
- HEIGHTS =
[16,32,48,64]
Instance Attribute Summary collapse
-
#canvas ⇒ Object
Returns the value of attribute canvas.
Attributes included from I2C::Peripheral
#i2c_frequency, #i2c_repeated_start
Attributes included from Behaviors::Callbacks
Attributes included from Behaviors::BusPeripheral
Attributes included from Behaviors::Component
Instance Method Summary collapse
- #after_initialize(options = {}) ⇒ Object
- #before_initialize(options = {}) ⇒ Object
-
#command(bytes) ⇒ Object
Commands are I2C messages prefixed with 0x00.
- #contrast=(value) ⇒ Object
-
#data(bytes) ⇒ Object
Data are I2C messages prefixed with 0x40.
- #draw(x_min = 0, x_max = (@columns-1), y_min = 0, y_max = (@rows-1)) ⇒ Object
- #draw_partial(buffer, x_min, x_max, p_min, p_max) ⇒ Object
- #off ⇒ Object
- #on ⇒ Object
Methods included from I2C::Peripheral
Methods included from Behaviors::Reader
#_read, #read, #read_using, #wait_for_read
Methods included from Behaviors::Callbacks
#add_callback, #callbacks, #initialize, #pre_callback_filter, #remove_callback, #update
Methods included from Behaviors::State
Methods included from Behaviors::BusPeripheral
Methods included from Behaviors::Component
Instance Attribute Details
#canvas ⇒ Object
Returns the value of attribute canvas.
116 117 118 |
# File 'lib/denko/display/ssd1306.rb', line 116 def canvas @canvas end |
Instance Method Details
#after_initialize(options = {}) ⇒ Object
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/denko/display/ssd1306.rb', line 70 def after_initialize(={}) super() # Default to a 128x64 display. @columns = [:columns] || [:width] || 128 @rows = [:rows] || [:height] || 64 # Validate known sizes. raise ArgumentError, "error in SSD1306 width: #{@columns}. Must be in: #{WIDTHS.inspect}" unless WIDTHS.include?(@columns) raise ArgumentError, "error in SSD1306 height: #{@rows}. Must be in: #{HEIGHTS.inspect}" unless HEIGHTS.include?(@rows) # Everything except 96x16 size uses clock 0x80. clock = 0x80 clock = 0x60 if (@columns == 96 && @rows == 16) # 128x32 and 96x16 sizes use com pin config 0x02 com_pin_config = 0x12 com_pin_config = 0x02 if (@columns == 96 && @rows == 16) || (@columns == 128 && @rows == 32) # Reflecting horizontally and vertically to effectively rotate 180 degrees. seg_remap = [:rotate] ? 0x01 : 0x00 com_direction = [:rotate] ? 0x08 : 0x00 # Startup sequence command [ MULTIPLEX_RATIO, @rows - 1, DISPLAY_OFFSET, 0x00, START_LINE | 0x00, SEGMENT_REMAP | seg_remap, COM_DIRECTION | com_direction, COM_PIN_CONFIG, com_pin_config, PIXELS_FROM_RAM, INVERT_OFF, CLOCK, clock, VCOM_DESELECT_LEVEL, 0x20, PRECHARGE_PERIOD, 0xF1, # Charge period for internal charge pump CHARGE_PUMP, 0x14, # Internal charge pump ADDRESSING_MODE, 0x00, # Horizontal addressing mode so pages auto increment DISPLAY_ON ] # Create a new blank canvas and draw it. self.canvas = Canvas.new(@columns, @rows) draw end |
#before_initialize(options = {}) ⇒ Object
64 65 66 67 68 |
# File 'lib/denko/display/ssd1306.rb', line 64 def before_initialize(={}) @i2c_address = 0x3C @i2c_frequency = 400000 super() end |
#command(bytes) ⇒ Object
Commands are I2C messages prefixed with 0x00.
169 170 171 |
# File 'lib/denko/display/ssd1306.rb', line 169 def command(bytes) i2c_write([0x00] + bytes) end |
#contrast=(value) ⇒ Object
126 127 128 129 |
# File 'lib/denko/display/ssd1306.rb', line 126 def contrast=(value) raise ArgumentError, "contrast must be in range 0..255" if (value < 0 || value > 255) command [CONTRAST, value] end |
#data(bytes) ⇒ Object
Data are I2C messages prefixed with 0x40.
174 175 176 |
# File 'lib/denko/display/ssd1306.rb', line 174 def data(bytes) i2c_write([0x40] + bytes) end |
#draw(x_min = 0, x_max = (@columns-1), y_min = 0, y_max = (@rows-1)) ⇒ Object
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 |
# File 'lib/denko/display/ssd1306.rb', line 131 def draw(x_min=0, x_max=(@columns-1), y_min=0, y_max=(@rows-1)) # Convert y-coords to page coords. p_min = y_min / 8 p_max = y_max / 8 # If drawing the whole frame (default), bypass temp buffer to save time. if (x_min == 0) && (x_max == @columns-1) && (p_min == 0) && (p_max == @rows/8) draw_partial(canvas.framebuffer, x_min, x_max, p_min, p_max) # Copy bytes for the given rectangle into a temp buffer. else temp_buffer = [] (p_min..p_max).each do |page| src_start = (@columns * page) + x_min src_end = (@columns * page) + x_max temp_buffer += canvas.framebuffer[src_start..src_end] end # And draw them. draw_partial(temp_buffer, x_min, x_max, p_min, p_max) end end |
#draw_partial(buffer, x_min, x_max, p_min, p_max) ⇒ Object
154 155 156 157 158 159 160 161 162 163 164 165 166 |
# File 'lib/denko/display/ssd1306.rb', line 154 def draw_partial(buffer, x_min, x_max, p_min, p_max) # Limit auto-incrementing GRAM address to the rectangle being drawn. command [ COLUMN_ADDRESS_RANGE, x_min, x_max, PAGE_ADDRESS_RANGE, p_min, p_max ] # Send all the bytes at once if within board I2C limit. if buffer.length < (bus.board.i2c_limit - 1) data(buffer) # Or split into chunks. else buffer.each_slice(bus.board.i2c_limit - 1) { |slice| data(slice) } end end |
#off ⇒ Object
118 119 120 |
# File 'lib/denko/display/ssd1306.rb', line 118 def off command(DISPLAY_OFF) end |
#on ⇒ Object
122 123 124 |
# File 'lib/denko/display/ssd1306.rb', line 122 def on command(DISPLAY_ON) end |