Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ssd1306oled: Add display of scrolling DoES logo #1

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
271 changes: 248 additions & 23 deletions LoraOledESP32/ssd1306oled.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"execution_count": 83,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[34mConnecting to Serial /dev/ttyUSB2 baud=115200 \u001b[0m\n",
"\u001b[34mConnecting to --port=/dev/ttyUSB0 --baud=115200 \u001b[0m\n",
"\u001b[34mReady.\n",
"\u001b[0m"
]
Expand All @@ -21,27 +21,191 @@
},
{
"cell_type": "code",
"execution_count": 2,
"execution_count": 10,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Sent 168 lines (5477 bytes) to ssd1306.py.\n"
"Sent 147 lines (4584 bytes) to ssd1306.py.\n"
]
}
],
"source": [
"%sendtofile --source ssd1306.py\n"
"%sendtofile ssd1306.py\n",
"\n",
"# MicroPython SSD1306 OLED driver, I2C and SPI interfaces\n",
"\n",
"from micropython import const\n",
"import framebuf\n",
"\n",
"\n",
"# register definitions\n",
"SET_CONTRAST = const(0x81)\n",
"SET_ENTIRE_ON = const(0xa4)\n",
"SET_NORM_INV = const(0xa6)\n",
"SET_DISP = const(0xae)\n",
"SET_MEM_ADDR = const(0x20)\n",
"SET_COL_ADDR = const(0x21)\n",
"SET_PAGE_ADDR = const(0x22)\n",
"SET_DISP_START_LINE = const(0x40)\n",
"SET_SEG_REMAP = const(0xa0)\n",
"SET_MUX_RATIO = const(0xa8)\n",
"SET_COM_OUT_DIR = const(0xc0)\n",
"SET_DISP_OFFSET = const(0xd3)\n",
"SET_COM_PIN_CFG = const(0xda)\n",
"SET_DISP_CLK_DIV = const(0xd5)\n",
"SET_PRECHARGE = const(0xd9)\n",
"SET_VCOM_DESEL = const(0xdb)\n",
"SET_CHARGE_PUMP = const(0x8d)\n",
"\n",
"# Subclassing FrameBuffer provides support for graphics primitives\n",
"# http://docs.micropython.org/en/latest/pyboard/library/framebuf.html\n",
"class SSD1306(framebuf.FrameBuffer):\n",
" def __init__(self, width, height, external_vcc):\n",
" self.width = width\n",
" self.height = height\n",
" self.external_vcc = external_vcc\n",
" self.pages = self.height // 8\n",
" self.buffer = bytearray(self.pages * self.width)\n",
" super().__init__(self.buffer, self.width, self.height, framebuf.MONO_VLSB)\n",
" self.init_display()\n",
"\n",
" def init_display(self):\n",
" for cmd in (\n",
" SET_DISP | 0x00, # off\n",
" # address setting\n",
" SET_MEM_ADDR, 0x00, # horizontal\n",
" # resolution and layout\n",
" SET_DISP_START_LINE | 0x00,\n",
" SET_SEG_REMAP | 0x01, # column addr 127 mapped to SEG0\n",
" SET_MUX_RATIO, self.height - 1,\n",
" SET_COM_OUT_DIR | 0x08, # scan from COM[N] to COM0\n",
" SET_DISP_OFFSET, 0x00,\n",
" SET_COM_PIN_CFG, 0x02 if self.height == 32 else 0x12,\n",
" # timing and driving scheme\n",
" SET_DISP_CLK_DIV, 0x80,\n",
" SET_PRECHARGE, 0x22 if self.external_vcc else 0xf1,\n",
" SET_VCOM_DESEL, 0x30, # 0.83*Vcc\n",
" # display\n",
" SET_CONTRAST, 0xff, # maximum\n",
" SET_ENTIRE_ON, # output follows RAM contents\n",
" SET_NORM_INV, # not inverted\n",
" # charge pump\n",
" SET_CHARGE_PUMP, 0x10 if self.external_vcc else 0x14,\n",
" SET_DISP | 0x01): # on\n",
" self.write_cmd(cmd)\n",
" self.fill(0)\n",
" self.show()\n",
"\n",
" def poweroff(self):\n",
" self.write_cmd(SET_DISP | 0x00)\n",
"\n",
" def poweron(self):\n",
" self.write_cmd(SET_DISP | 0x01)\n",
"\n",
" def contrast(self, contrast):\n",
" self.write_cmd(SET_CONTRAST)\n",
" self.write_cmd(contrast)\n",
"\n",
" def invert(self, invert):\n",
" self.write_cmd(SET_NORM_INV | (invert & 1))\n",
"\n",
" def show(self):\n",
" x0 = 0\n",
" x1 = self.width - 1\n",
" if self.width == 64:\n",
" # displays with width of 64 pixels are shifted by 32\n",
" x0 += 32\n",
" x1 += 32\n",
" self.write_cmd(SET_COL_ADDR)\n",
" self.write_cmd(x0)\n",
" self.write_cmd(x1)\n",
" self.write_cmd(SET_PAGE_ADDR)\n",
" self.write_cmd(0)\n",
" self.write_cmd(self.pages - 1)\n",
" self.write_data(self.buffer)\n",
"\n",
"\n",
"class SSD1306_I2C(SSD1306):\n",
" def __init__(self, width, height, i2c, addr=0x3c, external_vcc=False):\n",
" self.i2c = i2c\n",
" self.addr = addr\n",
" self.temp = bytearray(2)\n",
" super().__init__(width, height, external_vcc)\n",
"\n",
" def write_cmd(self, cmd):\n",
" self.temp[0] = 0x80 # Co=1, D/C#=0\n",
" self.temp[1] = cmd\n",
" self.i2c.writeto(self.addr, self.temp)\n",
"\n",
" def write_data(self, buf):\n",
" self.temp[0] = self.addr << 1\n",
" self.temp[1] = 0x40 # Co=0, D/C#=1\n",
" self.i2c.start()\n",
" self.i2c.write(self.temp)\n",
" self.i2c.write(buf)\n",
" self.i2c.stop()\n",
"\n",
"\n",
"class SSD1306_SPI(SSD1306):\n",
" def __init__(self, width, height, spi, dc, res, cs, external_vcc=False):\n",
" self.rate = 10 * 1024 * 1024\n",
" dc.init(dc.OUT, value=0)\n",
" res.init(res.OUT, value=0)\n",
" cs.init(cs.OUT, value=1)\n",
" self.spi = spi\n",
" self.dc = dc\n",
" self.res = res\n",
" self.cs = cs\n",
" import time\n",
" self.res(1)\n",
" time.sleep_ms(1)\n",
" self.res(0)\n",
" time.sleep_ms(10)\n",
" self.res(1)\n",
" super().__init__(width, height, external_vcc)\n",
"\n",
" def write_cmd(self, cmd):\n",
" self.spi.init(baudrate=self.rate, polarity=0, phase=0)\n",
" self.cs(1)\n",
" self.dc(0)\n",
" self.cs(0)\n",
" self.spi.write(bytearray([cmd]))\n",
" self.cs(1)\n",
"\n",
" def write_data(self, buf):\n",
" self.spi.init(baudrate=self.rate, polarity=0, phase=0)\n",
" self.cs(1)\n",
" self.dc(1)\n",
" self.cs(0)\n",
" self.spi.write(buf)\n",
" self.cs(1)"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": true
},
"execution_count": 11,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"['boot.py', 'hmac.py', 'hotpie.py', 'ssd1306.py']\r\n"
]
}
],
"source": [
"import os\n",
"print(os.listdir())"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [],
"source": [
"#https://forum.micropython.org/viewtopic.php?f=18&p=23080\n",
Expand All @@ -53,6 +217,7 @@
"scl = Pin(15, Pin.OUT, Pin.PULL_UP)\n",
"sda = Pin(4, Pin.OUT, Pin.PULL_UP)\n",
"i2c = I2C(scl=scl, sda=sda, freq=450000)\n",
"\n",
"o = ssd1306.SSD1306_I2C(128, 64, i2c, addr=0x3c)\n",
"\n",
"o.fill(0)\n",
Expand All @@ -63,14 +228,16 @@
},
{
"cell_type": "code",
"execution_count": 4,
"execution_count": 80,
"metadata": {},
"outputs": [
{
"name": "stdout",
"name": "stderr",
"output_type": "stream",
"text": [
"[60]\r\n"
"Traceback (most recent call last):\n",
" File \"<stdin>\", line 1, in <module>\n",
"NameError: name 'i2c' is not defined\n"
]
}
],
Expand All @@ -80,12 +247,22 @@
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {
"collapsed": true
},
"outputs": [],
"execution_count": 81,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"Traceback (most recent call last):\n",
" File \"<stdin>\", line 3, in <module>\n",
"NameError: name 'o' is not defined\n"
]
}
],
"source": [
"import framebuf\n",
"\n",
"o.fill(0)\n",
"for i in range(128):\n",
" o.framebuf.fill_rect(1, 3, i, 34, 1)\n",
Expand Down Expand Up @@ -114,12 +291,60 @@
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
"execution_count": 84,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
".......\u001b[34m\n",
"\n",
"*** Sending Ctrl-C\n",
"\n",
"\u001b[0m"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"Traceback (most recent call last):\n",
" File \"<stdin>\", line 28, in <module>\n",
"KeyboardInterrupt: \n"
]
}
],
"source": [
"# Show the DoES logo. Scrolls across the screen\n",
"\n",
"import ssd1306\n",
"import framebuf\n",
"from machine import I2C, Pin\n",
"rst = Pin(16, Pin.OUT)\n",
"rst.value(1)\n",
"scl = Pin(15, Pin.OUT, Pin.PULL_UP)\n",
"sda = Pin(4, Pin.OUT, Pin.PULL_UP)\n",
"i2c = I2C(scl=scl, sda=sda, freq=450000)\n",
"display = ssd1306.SSD1306_I2C(128, 64, i2c, addr=0x3c)\n",
"#o = ssd1306.SSD1306_I2C(128, 64, i2c, addr=0x3c)\n",
"\n",
"buffer = bytearray(\n",
" b'\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x3f\\xff\\xff\\xff\\xff\\xff\\xe0\\x3f\\xff\\xff\\xff\\xff\\xff\\xe0\\x3f\\xff\\xff\\xff\\xff\\xff\\xe0\\x3f\\xff\\xff\\xff\\xff\\xff\\xe0\\x3f\\xff\\xff\\xff\\xff\\xff\\xe0\\x3f\\xff\\xff\\xff\\xff\\xff\\xe0\\x3f\\xff\\xff\\xff\\xff\\xff\\xe0\\x3f\\xff\\xff\\xff\\xff\\xff\\xe0\\x3f\\xff\\xff\\xff\\xff\\xff\\xe0\\x3f\\xff\\xff\\xff\\xff\\xff\\xe0\\x3f\\xff\\xff\\xff\\xff\\xff\\xe0\\x3f\\xff\\xff\\xff\\xff\\xff\\xe0\\x3f\\xff\\xff\\xff\\xff\\xff\\xe0\\x3f\\xff\\xff\\xff\\xff\\xff\\xe0\\x3f\\xff\\xff\\xff\\xff\\xff\\xe0\\x3f\\xff\\xff\\xff\\xff\\xff\\xe0\\x3f\\xff\\xff\\xff\\xff\\xff\\xe0\\x3f\\xff\\xff\\xff\\xff\\xff\\xe0\\x3f\\xff\\xff\\xff\\xff\\xff\\xe0\\x3f\\xff\\xff\\xff\\xff\\xff\\xe0\\x3f\\xff\\xff\\xff\\xff\\xff\\xe0\\x3f\\xff\\xff\\xff\\xff\\xff\\xe0\\x3f\\xff\\xff\\xff\\xff\\xff\\xe0\\x3f\\xff\\xff\\xff\\xff\\xff\\xe0\\x3f\\xff\\xff\\xff\\xff\\xff\\xe0\\x3f\\xff\\xff\\xff\\xff\\xff\\xe0\\x3f\\xff\\xff\\xff\\xff\\xff\\xe0\\x3f\\xff\\xff\\xff\\xff\\xff\\xe0\\x3f\\xff\\xff\\xff\\xff\\xff\\xe0\\x3f\\xff\\xff\\xff\\xff\\xff\\xe0\\x3f\\xff\\xff\\xff\\xff\\xff\\xe0\\x3f\\xff\\xff\\xff\\xff\\xff\\xe0\\x3f\\xff\\xff\\xff\\xff\\xff\\xe0\\x3f\\xff\\xff\\xff\\xff\\xff\\xe0\\x3f\\xff\\xff\\xff\\xff\\xe7\\xe0\\x30\\x0f\\xff\\xf0\\x07\\x00\\xe0\\x30\\x03\\xff\\xf0\\x06\\x18\\xe0\\x31\\xe3\\xe1\\xf3\\xfe\\x3c\\xe0\\x31\\xf1\\xc0\\x73\\xfe\\x3f\\xe0\\x31\\xf1\\x8c\\x73\\xff\\x07\\xe0\\x31\\xf1\\x9e\\x30\\x07\\x80\\xe0\\x31\\xf1\\x1e\\x30\\x0f\\xf0\\x60\\x31\\xf1\\x1e\\x33\\xff\\xfc\\x60\\x31\\xf3\\x9e\\x33\\xfe\\x7e\\x60\\x31\\xc3\\x8e\\x73\\xfe\\x3c\\x60\\x30\\x07\\xc0\\x70\\x07\\x00\\xe0\\x30\\x1f\\xe1\\xf0\\x07\\x81\\xe0\\x3f\\xff\\xff\\xff\\xff\\xff\\xe0\\x3f\\xff\\xff\\xff\\xff\\xff\\xe0\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x40\\x00\\x00\\x00\\x00\\x60\\x30\\x00\\x00\\x00\\x00\\x00\\x60\\x30\\x48\\x8c\\x15\\x86\\x0c\\x60\\x30\\x49\\xb6\\xe6\\xcd\\x9b\\x60\\x30\\x49\\xb2\\xc4\\x58\\xb3\\x60\\x30\\x4d\\x3e\\xc4\\x58\\xb3\\x60\\x30\\x47\\x30\\xc4\\x49\\xb3\\x60\\x3f\\x46\\x1e\\xc7\\xcf\\x1e\\x60\\x00\\x00\\x00\\x04\\x00\\x00\\x00\\x00\\x00\\x00\\x04\\x00\\x00\\x00\\x00\\x00\\x00\\x04\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00'\n",
")\n",
"# FRAMEBUF_MHLSB = 3\n",
"fb = framebuf.FrameBuffer(buffer, 56, 64,3)\n",
"\n",
"while True:\n",
" for x in range(0,128-56):\n",
" display.fill(0)\n",
" display.blit(fb, x, 0)\n",
" display.show()\n",
" for x in range(0,128-56):\n",
" display.fill(0)\n",
" display.blit(fb, (128-56-x), 0)\n",
" display.show()\n"
]
}
],
"metadata": {
Expand Down