数码之家

 找回密码
 立即注册
搜索
查看: 4094|回复: 15

【MY808_DIY】ESP8266_OLED显示

[复制链接]
发表于 2019-3-26 23:19:22 | 显示全部楼层 |阅读模式

爱科技、爱创意、爱折腾、爱极致,我们都是技术控

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 lyy-cy 于 2019-3-27 09:06 编辑

用micropython驱动1306,列扫描,实现滚动显示。
点击图片可播放视频。
20190326_230316.jpg

20190326_230320.jpg

点击跳转到B站播放视频

2019-03-26_141050.jpg

代码,给需要的朋友参考。
  1. # MicroPython SSD1306 OLED driver, 修改过的只保留SPI的
  2. from micropython import const
  3. import framebuf
  4. from machine import Pin, SPI
  5. import time

  6. #初始化
  7. spi = SPI(-1, baudrate=100000, polarity=1, phase=0, sck=Pin(2), mosi=Pin(0), miso=Pin(15))   #这里其实给了  clk 2 和 dta 0  miso=Pin(15))没有功能
  8. oled = SSD1306_SPI(128, 64, spi,dc=Pin(5), res=Pin(4))    #dc=Pin(5), res=Pin(4),  cs给去掉了
  9. oled.contrast(0) #调整亮度。0最暗,255最亮

  10. #修改扫描方式
  11. oled.write_cmd(SET_MEM_ADDR)    # 设置1306地址模式(扫描方式方向)
  12. oled.write_cmd(0x01)            # 地址数值:0x00 水平     0x01 垂直        0x02 页

  13. def cls():
  14.   _buf = bytearray(128*64)
  15.   oled.write_cmd(SET_COL_ADDR)    #列宽度,尾 = 首+32-1
  16.   oled.write_cmd(0)
  17.   oled.write_cmd(127)
  18.   oled.write_cmd(SET_PAGE_ADDR)  #行宽度,尾 = 首+32/8 -1
  19.   oled.write_cmd(0)
  20.   oled.write_cmd(7)
  21.   oled.write_data(_buf)
  22.   del(_buf)
  23. cls()

  24. buf = [0x00]*8*128
  25. offset = 0
  26. def setBuffer(nubBytes):
  27.     global buf
  28.     global offset
  29. #    print(bytearray(buf),len(buf))
  30.     f = open('hf.FON',"rb")
  31.     f.seek(offset)
  32.     offset += nubBytes
  33.     _inNub = list(f.read(nubBytes))
  34.     f.close()
  35.     for i in _inNub :
  36.         buf.append(i)
  37.         buf.pop(0)

  38. def myShowBuf():
  39.   oled.write_cmd(SET_COL_ADDR)    #列宽度,尾 = 首+32-1
  40.   oled.write_cmd(0)
  41.   oled.write_cmd(127)
  42.   oled.write_cmd(SET_PAGE_ADDR)  #行宽度,尾 = 首+32/8 -1
  43.   oled.write_cmd(0)
  44.   oled.write_cmd(7)
  45.   oled.write_data(bytearray(buf))
  46. while True:
  47.     for i in range(640):
  48.         setBuffer(8)
  49.         myShowBuf()
  50.     offset = 0
复制代码



主要方法,步骤:

汉字按照列扫描取模,生成文件。
先设置个64*128的缓冲区(list),
每次读入n列数据,清除前面的n列。
将1306改为列扫描,显示。




打赏

参与人数 4家元 +70 收起 理由
q399050484 + 10 謝謝分享
jjbboox + 20 謝謝分享
家睦 + 20
200birds + 20

查看全部打赏

发表于 2019-8-17 17:41:43 来自手机浏览器 | 显示全部楼层
oled是不是需要负压?

点评

模块自带周边元件,直接用就OK  详情 回复 发表于 2019-8-18 00:03
回复 支持 反对

使用道具 举报

发表于 2019-8-18 00:03:12 | 显示全部楼层
兔族族长 发表于 2019-8-17 17:41
oled是不是需要负压?

模块自带周边元件,直接用就OK
回复 支持 反对

使用道具 举报

发表于 2019-8-20 12:29:08 | 显示全部楼层
micropython    micropython  我头都大了,不知道如何下手,nodemcu好像简单些吧,楼主科普一下

点评

Arduino简单点  详情 回复 发表于 2019-8-28 09:10
回复 支持 反对

使用道具 举报

发表于 2019-8-28 09:10:56 | 显示全部楼层
zxy882266 发表于 2019-8-20 12:29
micropython    micropython  我头都大了,不知道如何下手,nodemcu好像简单些吧,楼主科普一下 ...

Arduino简单点
回复 支持 反对

使用道具 举报

发表于 2019-8-28 12:41:42 | 显示全部楼层
以前买了十几个 esp8226   一直在吃灰,...

真要玩的话考虑  c, python , javascript , lua  中选一个.. 除了python 快忘了,其它几门都可以玩得转..

arduino 就不考虑了..:titter:
回复 支持 反对

使用道具 举报

发表于 2019-9-29 22:51:41 | 显示全部楼层
膜拜大神!能否私聊获取完整代码?
回复 支持 反对

使用道具 举报

发表于 2019-9-30 09:09:34 | 显示全部楼层
我的板子已经刷了micropython,只会最基本的点亮,想实现楼主的滚动效果,求指点

点评

关键是:1306 列扫描 理解这个就不难了,还有取模方式(4种) 指点谈不上,祝你成功!  详情 回复 发表于 2019-9-30 21:02
回复 支持 0 反对 0

使用道具 举报

 楼主| 发表于 2019-9-30 21:02:37 | 显示全部楼层
q399050484 发表于 2019-9-30 09:09
我的板子已经刷了micropython,只会最基本的点亮,想实现楼主的滚动效果,求指点 ...

关键是:1306  列扫描
理解这个就不难了,还有取模方式(4种)
指点谈不上,祝你成功!
回复 支持 反对

使用道具 举报

发表于 2019-10-1 21:26:35 来自手机浏览器 | 显示全部楼层
lyy-cy 发表于 2019-9-30 21:02
关键是:1306  列扫描
理解这个就不难了,还有取模方式(4种)
指点谈不上,祝你成功! ...

字面意思能理解,实现起来一脸懵逼,你的代码是spi屏的,好像对ssd1306类也做了修改,我照葫芦画瓢改出i2c的结果各种报错 看到您也有i2c的案例,能不能分享下完整代码文档啊?我家宝宝刚出生,想给老婆做个出生天数的滚动显示 已经耗了一个多周了

点评

你这明显是一个找搓衣板跪的理由啊…  详情 回复 发表于 2019-10-1 22:33
回复 支持 反对

使用道具 举报

发表于 2019-10-1 22:33:40 来自手机浏览器 | 显示全部楼层
q399050484 发表于 2019-10-1 21:26
字面意思能理解,实现起来一脸懵逼,你的代码是spi屏的,好像对ssd1306类也做了修改,我照葫芦画瓢改出i2 ...

你这明显是一个找搓衣板跪的理由啊…
回复 支持 反对

使用道具 举报

发表于 2019-10-1 23:50:58 来自手机浏览器 | 显示全部楼层
触景情伤 发表于 2019-10-1 22:33
你这明显是一个找搓衣板跪的理由啊…

小字体验不好,滚动字费时间了还没做出来,两头不是人:sad:
回复 支持 反对

使用道具 举报

发表于 2019-10-2 05:07:34 来自手机浏览器 | 显示全部楼层
看的不是很明白
回复 支持 反对

使用道具 举报

发表于 2019-10-2 11:13:20 | 显示全部楼层
已经初步实现,对我这种初学者来说非常确实吃力,把驱动源码改了一下,放进main里,不用单独import了。使用的字体名称为“han40x40_tianqi_songti.FON”,这个文件要烧录进ESP8266的,生成方法见楼主显示天气的帖子。main.py代码如下,也要烧录进ESP8266的(注意把我代码里的GPIO引脚改成你在用的)
再次感谢楼主的分享,搞定这个,后面的路就顺了。
https://www.mydigit.cn/forum.php?mod=viewthread&tid=64439

IMG_7948.gif
  1. #驱动部分
  2. from micropython import const
  3. import framebuf
  4. # register definitions
  5. SET_CONTRAST        = const(0x81)
  6. SET_ENTIRE_ON       = const(0xa4)
  7. SET_NORM_INV        = const(0xa6)
  8. SET_DISP            = const(0xae)
  9. SET_MEM_ADDR        = const(0x20)
  10. SET_COL_ADDR        = const(0x21)
  11. SET_PAGE_ADDR       = const(0x22)
  12. SET_DISP_START_LINE = const(0x40)
  13. SET_SEG_REMAP       = const(0xa0)
  14. SET_MUX_RATIO       = const(0xa8)
  15. SET_COM_OUT_DIR     = const(0xc0)
  16. SET_DISP_OFFSET     = const(0xd3)
  17. SET_COM_PIN_CFG     = const(0xda)
  18. SET_DISP_CLK_DIV    = const(0xd5)
  19. SET_PRECHARGE       = const(0xd9)
  20. SET_VCOM_DESEL      = const(0xdb)
  21. SET_CHARGE_PUMP     = const(0x8d)

  22. class SSD1306(framebuf.FrameBuffer):
  23.     def __init__(self, width, height, external_vcc):
  24.         self.width = width
  25.         self.height = height
  26.         self.external_vcc = external_vcc
  27.         self.pages = self.height // 8
  28.         self.buffer = bytearray(self.pages * self.width)
  29.         super().__init__(self.buffer, self.width, self.height, framebuf.MONO_VLSB)
  30.         self.init_display()

  31.     def init_display(self):
  32.         for cmd in (
  33.             SET_DISP | 0x00, # off
  34.             # address setting
  35.             SET_MEM_ADDR, 0x01, # horizontal
  36.             # resolution and layout
  37.             SET_DISP_START_LINE | 0x00,
  38.             SET_SEG_REMAP | 0x01, # column addr 127 mapped to SEG0
  39.             SET_MUX_RATIO, self.height - 1,
  40.             SET_COM_OUT_DIR | 0x08, # scan from COM[N] to COM0
  41.             SET_DISP_OFFSET, 0x00,
  42.             SET_COM_PIN_CFG, 0x02 if self.height == 32 else 0x12,
  43.             # timing and driving scheme
  44.             SET_DISP_CLK_DIV, 0x80,
  45.             SET_PRECHARGE, 0x22 if self.external_vcc else 0xf1,
  46.             SET_VCOM_DESEL, 0x30, # 0.83*Vcc
  47.             # display
  48.             SET_CONTRAST, 0xff, # maximum
  49.             SET_ENTIRE_ON, # output follows RAM contents
  50.             SET_NORM_INV, # not inverted
  51.             # charge pump
  52.             SET_CHARGE_PUMP, 0x10 if self.external_vcc else 0x14,
  53.             SET_DISP | 0x01): # on
  54.             self.write_cmd(cmd)
  55.         self.fill(0)
  56.         # self.show()

  57.     def contrast(self, contrast):
  58.         self.write_cmd(SET_CONTRAST)
  59.         self.write_cmd(contrast)

  60.     def show(self,x1,x2,x3,x4,x5):
  61.         self.write_cmd(SET_COL_ADDR)
  62.         self.write_cmd(x3)
  63.         self.write_cmd(x4)
  64.         self.write_cmd(SET_PAGE_ADDR)
  65.         self.write_cmd(x1)
  66.         self.write_cmd(x2)
  67.         self.write_data(x5)


  68. class SSD1306_I2C(SSD1306):
  69.     def __init__(self, width, height, i2c, addr=0x3c, external_vcc=False):
  70.         self.i2c = i2c
  71.         self.addr = addr
  72.         self.temp = bytearray(2)
  73.         self.write_list = [b'\x40', None] # Co=0, D/C#=1
  74.         super().__init__(width, height, external_vcc)

  75.     def write_cmd(self, cmd):
  76.         self.temp[0] = 0x80 # Co=1, D/C#=0
  77.         self.temp[1] = cmd
  78.         self.i2c.writeto(self.addr, self.temp)

  79.     def write_data(self, buf):
  80.         self.write_list[1] = buf
  81.         self.i2c.writevto(self.addr, self.write_list)

  82. #我的oled的地址  60     0x3c     0b111100
  83. from machine import Pin, I2C
  84. i2c = I2C(scl=Pin(12), sda=Pin(14), freq=400000)
  85. oled = SSD1306_I2C(128, 64, i2c, addr=0x3c, external_vcc=False)

  86. # #垂直水平清屏
  87. show_buffer = bytearray([0x0]*8*128)
  88. oled.show(0,7,0,127,show_buffer)

  89. # #页地址清屏
  90. # for x in range(8):
  91. #     show_buffer = bytearray([0x00]*128)
  92. #     # oled.pag_show(0,x,show_buffer)

  93. dic_han_40 = {'℃': 0, '↑': 200, '↓': 400, '★': 600, '。': 800, '一': 1000, '不': 1200, '中': 1400, '云': 1600, '今': 1800, '会': 2000, '伞': 2200, '伴': 2400, '低': 2600, '充': 2800, '光': 3000, '内': 3200, '冰': 3400, '冷': 3600, '冻': 3800, '出': 4000, '升': 4200, '卷': 4400, '国': 4600, '外': 4800, '多': 5000, '大': 5200, '天': 5400, '太': 5600, '夹': 5800, '宜': 6000, '寒': 6200, '小': 6400, '尘': 6600, '带': 6800, '度': 7000, '弱': 7200, '强': 7400, '很': 7600, '或': 7800, '扬': 8000, '旅': 8200, '明': 8400, '晴': 8600, '暴': 8800, '最': 9000, '有': 9200, '未': 9400, '气': 9600, '沙': 9800, '没': 10000, '洗': 10200, '浮': 10400, '温': 10600, '游': 10800, '炎': 11000, '热': 11200, '特': 11400, '的': 11600, '知': 11800, '示': 12000, '穿': 12200, '等': 12400, '紫': 12600, '级': 12800, '线': 13000, '者': 13200, '舒': 13400, '般': 13600, '衣': 13800, '表': 14000, '说': 14200, '足': 14400, '车': 14600, '较': 14800, '适': 15000, '部': 15200, '门': 15400, '间': 15600, '阳': 15800, '阴': 16000, '阵': 16200, '降': 16400, '雨': 16600, '雪': 16800, '雷': 17000, '雹': 17200, '雾': 17400, '霾': 17600, '风': 17800, '飓': 18000, '高': 18200, '龙': 18400, '!': 18600, ',': 18800, '?': 19000}

  94. import time

  95. #汉字 40*40点阵,每次取一列 5个字节  5*8 = 40  逐列扫描
  96. #首先开辟一块显存,对应要显示的面积 x*y*字数/8  一个字节8个点
  97. buff = [0x00]*(40*40*3//8)#40pix x  40 pix  三个字  共600个bytes

  98. han_font_file = open('han40x40_tianqi_songti.fon',"rb")
  99. # en_font_file = open('en_20x40_kaiti.FON',"rb")
  100. nubBytes = 5 #每次写入5个字节(5为步进)   5*8 = 40  一列40个点

  101. str = '明天晴天'

  102. for one_char in str:
  103.     if ord(one_char) <= 128:
  104.         # offset = (ord(one_char))*100
  105.         # en_font_file.seek(offset)
  106.         # for i in range(20):#每个英文100个bytes  
  107.         #     han_tem=en_font_file.read(nubBytes)#将一个汉字的5个字节取出
  108.         #     buff += han_tem# 将这5个bytes加到尾部
  109.         #     del buff[0:5]#删除前面的5个bytes
  110.         #     show_buffer = (bytearray(buff))#整个缓存转为字节串
  111.         #     oled.show(2,6,0,127,show_buffer)#将整个缓存写入
  112.         #     time.sleep_ms(1)
  113.         pass
  114.     else:
  115.         offset = dic_han_40[one_char]
  116.         han_font_file.seek(offset+100)
  117.         for i in range(40):#每个汉字200个bytes  每次写入5个字节(5为步进)   5*8 = 40  一列40个点
  118.             han_tem=han_font_file.read(nubBytes)#将一个汉字的5个字节取出
  119.             buff += han_tem# 将这5个bytes加到尾部
  120.             del buff[0:5]#删除前面的5个bytes
  121.             show_buffer = (bytearray(buff))#整个缓存转为字节串
  122.             oled.show(2,6,0,127,show_buffer)#将整个缓存写入
  123.             time.sleep_ms(1)
  124.     for j in range(0,2):#写入10列作为两个字之间的空白  
  125.         buff += [0x00]*5
  126.         del buff[0:5]
  127.         show_buffer = (bytearray(buff))
  128.         oled.show(2,6,0,127,show_buffer)
  129.         time.sleep_ms(1)
  130. han_font_file.close()
  131. # en_font_file.close()
复制代码





点评

,恭喜你,只要到了这一步,后面就简单了。我在新站的几个帖子都和这个有关。可以参考。  详情 回复 发表于 2019-10-2 20:47
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-10-2 20:47:17 | 显示全部楼层
本帖最后由 lyy-cy 于 2019-10-2 20:50 编辑
q399050484 发表于 2019-10-2 11:13
已经初步实现,对我这种初学者来说非常确实吃力,把驱动源码改了一下,放进main里,不用单独import了。使用 ...

:victory:,恭喜你,只要到了这一步,后面就简单了。我在新站的几个帖子都和这个有关。可以参考。宝宝出生天数这个创意很好。

回复 支持 反对

使用道具 举报

发表于 2019-10-2 20:58:56 来自手机浏览器 | 显示全部楼层
lyy-cy 发表于 2019-10-2 20:47
,恭喜你,只要到了这一步,后面就简单了。我在新站的几个帖子都和这个有关。可以参考。宝宝出生 ...

希望大神能分享更多好创意,我们也。话说今天看了esp32,本打算入个,结果某宝8MB spiRAM的要50多,瞬间打消念头了,价格都快赶上树莓派0了
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2024-3-29 02:46 , Processed in 0.093600 second(s), 12 queries , Redis On.

Powered by Discuz!

© 2006-2023 smzj.net

快速回复 返回顶部 返回列表