OLED 屏幕应用

前言

但近些年来, 有一种显示器越来越流行—-OLED
OLED应用于各种大小显示需求, 大到电视屏幕, 小到微型智能穿戴设备的显示器都是它的用武之地. 在各种照明条件下它都能熠熠生辉, 且消耗的电流很小! OLED相对于LCD等有着极大的优势
OLED是一种利用多层有机薄膜结构产生电致发光的器件,它很容易制作,而且只需要低的驱动电压,这些主要的特征使得OLED在满足平面显示器的应用上显得非常突出。OLED显示屏比LCD更轻薄、亮度高、功耗低、响应快、清晰度高、柔性好、发光效率高,能满足消费者对显示技术的新需求。全球越来越多的显示器厂家纷纷投入研发,大大的推动了OLED的产业化进程。(资料来源于百度百科)
以上介绍了OLED的优势, 相信大家都对如何使用Arduino去控制OLED显示比较好奇, 因此本篇将对Arduino如何控制OLED展开说明,以创客朋友们常用的OLED 0.96 IIC 128×64)模块进行实例应用讲解其他尺寸的OLED可参考本教程进行学习和开发

模块介绍

Arduino驱动OLED屏幕 - 图1OLED0.96屏幕样图
首先对OLED 0.96 IIC 128x64模块里的几个参数进行说明, 0.96指的是屏幕的显示尺寸0.96inch, 128×64指的是屏幕的分辨率为128×64, 而IIC指的是该模块使用IIC协议进行通讯, (关于Arduino-IIC协议可参考Arduino-Wire)
以下是OLED 0.96 12864屏幕的基本介绍

  • 高分辨率:128×64(和12864同分辨率,高PPI)
  • 超大可视角度:大于160°(显示屏中可视角度最大的一种屏幕)
  • 超低功耗:正常显示0.06w(远低于TFT显示屏)
  • 宽电压供电(3V~5V),兼容3.3V和5V电平逻辑,无需电平转换芯片
  • IIC接口只需2个IO轻松点亮
  • 工作温度范围为工业级(-20℃~70℃)
  • 军工级工艺标准,长期稳定工作
  • 提供丰富的多平台例程,提供底层驱动技术支持
  • 黄蓝、白、蓝三种颜色显示方案可选

    模块参数

    | 名称 | 颜色分类 | | | | :—- | :—- | :—- | :—- | | 显示颜色 | 白色 | 蓝色 | 黄蓝双色 | | SKU | MC096GW | MC096GB | MC096GY | | 尺寸 | 0.96(inch) | | | | 类型 | OLED | | | | OLED驱动芯片 | SSD1306 | | | | 分辨率 | 128*64 (Pixel) | | | | 模块接口 | IIC,①-GND,②-VCC,③-SCL,④-SDA | | | | 有效显示区域 | 21.744×10.864(mm) | | | | 模块尺寸 | 27.3×27.8(mm) | | | | 视角 | >160° | | | | 工作温度 | -20℃~70℃ | | | | 存储温度 | -30℃~80℃ | | | | 工作电压 | 3.3V / 5V | | | | 功耗 | 全亮约为25mA,全灭约为1.5mA。 | | | | 产品重量 | 15(g) | | |

模块尺寸

为了方便更多创客朋友们开发自己的OLED创客作品, 以下提供OLED0.96的模块尺寸图供大家参考
资料来源于[lcdwiki-OLED0.96](http://www.lcdwiki.com/zh/0.96inch_OLED_Module(IIC-4PSKU:MC096GX))
Arduino驱动OLED屏幕 - 图2

接口定义

OLED0.96 IIC模块使用IIC通信接口,只需要接4根线就可以完成OLED屏数据通信

  • VCC:电源正极(接5V电源)
  • GND:电源负极(接地)
  • SCL:IIC时钟信号线
  • SDA:IIC数据信号线

VCC接到开发板的5V电源引脚上,GND接到开发板GND引脚上,SCL和SDA需要根据不同的开发板引脚定义来接线(可参考Arduino-Wire)
该OLED模块的IIC地址0x3C

Arduino控制OLED

我们使用Adafruit_SSD1306库来更加快捷高效的实现Arduino控制OLED, 在使用这个库时,需要依赖Adafruit-GFX-Library库才能使其正常工作,因此您需要在您的ArduinoIDE同时安装这两个库, 此外您可以通过Arduino自带的库管理器来安装,在安装时,如果出现以下情况, 点击Install all即可,这是Adafruit-GFX-Library的依赖
Arduino驱动OLED屏幕 - 图3OLED0.96依赖库安装Arduino
Arduino使用硬件IIC,芯片内部已经对IIC引脚做了定义,因此软件上不需要再对IIC引脚进行定义,只是不同型号的单片机,IIC引脚定义不一样,需要在接线上根据开发板做调整。

我们将以控制OLED 0.96 I2C 屏幕为例子进行说明。无论你手里的OLED 0.96是单色的还是双色的都没关系, 这些显示器都是基于SSD1306 OLED驱动芯片,因此它们都可以使用Adafruit_SSD1306库来控制显示。
在开始之前,请大家在屏幕建立一个坐标系的概念,因为在程序里,位置都是以坐标的形式去定位的,以OLED 0.96 128X64为例,面向屏幕,以屏幕左上角为坐标原点,横向向右是X轴,竖向向下是Y轴
Arduino驱动OLED屏幕 - 图4OLED0.96坐标系建立

1 OLED显示文字

电路连接

Arduino驱动OLED屏幕 - 图5

示例程序

  1. /**********************************************************************
  2. 程序名称/Program name : words_display
  3. 团队/Team : 太极创客团队 / Taichi-Maker (www.taichi-maker.com)
  4. 作者/Author : Dapenson
  5. 日期/Date(YYYYMMDD) : 2020/07/01
  6. 程序目的/Purpose :
  7. 使用OLED0.96 IIC 12864显示文字
  8. -----------------------------------------------------------------------
  9. 修订历史/Revision History
  10. 日期/Date 作者/Author 参考号/Ref 修订说明/Revision Description
  11. 2021/03/22 金陵中学 1.0 金陵中学Arduino选修课使用
  12. -----------------------------------------------------------------------
  13. 其它说明:
  14. ***********************************************************************/
  15. // 引入IIC通讯所需的Wire库文件
  16. #include <Wire.h>
  17. // 引入驱动OLED0.96所需的库
  18. #include <Adafruit_GFX.h>
  19. #include <Adafruit_SSD1306.h>
  20. #define SCREEN_WIDTH 128 // 设置OLED宽度,单位:像素
  21. #define SCREEN_HEIGHT 64 // 设置OLED高度,单位:像素
  22. // 自定义重置引脚,虽然教程未使用,但却是Adafruit_SSD1306库文件所必需的
  23. #define OLED_RESET 4
  24. Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
  25. void setup()
  26. {
  27. // 初始化Wire库
  28. // Wire.begin();
  29. // 初始化OLED并设置其IIC地址为 0x3C
  30. display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  31. }
  32. void loop()
  33. {
  34. words_display();
  35. display.display();
  36. }
  37. void words_display()
  38. {
  39. // 清除屏幕
  40. display.clearDisplay();
  41. // 设置字体颜色,白色可见
  42. display.setTextColor(WHITE);
  43. //设置字体大小
  44. display.setTextSize(1.5);
  45. //设置光标位置
  46. display.setCursor(0, 0);
  47. display.print("JinLing High School");
  48. display.setCursor(0, 20);
  49. display.print("time: ");
  50. //打印自开发板重置以来的秒数:
  51. display.print(millis() / 1000);
  52. display.print(" s");
  53. display.setCursor(0, 40);
  54. display.print("Author: ");
  55. display.print("Your Name");
  56. }

效果演示


image.png

2 OLED显示汉字

汉字的显示需要对文字进行取模操作,紧接着使用drawBitmap()函数对取模生成的数组进行显示

汉字取模

1 打开取模软件,切换到字符模式
image.png
OLED0.96文字取模Arduino
2 在菜单栏区设置字体和尺寸选择
image.png
3 字模选项设置,设置之后点击确定按钮
Arduino驱动OLED屏幕 - 图9

4 输入字符,点击生成子模, 生成之后需要对生成的数据进行变量赋值和加工,具体格式参考示例程序
image.png

电路连接

Arduino驱动OLED屏幕 - 图11

示例程序

hans_display.ino

  1. /**********************************************************************
  2. 程序名称/Program name : hans_display
  3. 团队/Team : 太极创客团队 / Taichi-Maker (www.taichi-maker.com)
  4. 作者/Author : Dapenson
  5. 日期/Date(YYYYMMDD) : 2020/07/01
  6. 程序目的/Purpose :
  7. 使用OLED0.96 IIC 12864显示汉字
  8. -----------------------------------------------------------------------
  9. 修订历史/Revision History
  10. 日期/Date 作者/Author 参考号/Ref 修订说明/Revision Description
  11. 2021/03/22 金陵中学 1.0 金陵中学Arduino选修课使用
  12. -----------------------------------------------------------------------
  13. 其它说明:
  14. ***********************************************************************/
  15. // 引入IIC通讯所需的Wire库文件
  16. // 教程参考http://www.taichi-maker.com/homepage/reference-index/arduino-library-index/wire-library/
  17. #include <Wire.h>
  18. #include "text.h"
  19. // 引入驱动OLED0.96所需的库
  20. #include <Adafruit_GFX.h>
  21. #include <Adafruit_SSD1306.h>
  22. #define SCREEN_WIDTH 128 // 设置OLED宽度,单位:像素
  23. #define SCREEN_HEIGHT 64 // 设置OLED高度,单位:像素
  24. // 自定义重置引脚,虽然教程未使用,但却是Adafruit_SSD1306库文件所必需的
  25. #define OLED_RESET 4
  26. Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
  27. void setup()
  28. {
  29. // 初始化OLED并设置其IIC地址为 0x3C
  30. display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  31. }
  32. void loop()
  33. {
  34. hans_display_0();
  35. hans_display_1();
  36. }
  37. void hans_display_0(void)
  38. {
  39. // 显示之前清屏
  40. display.clearDisplay();
  41. // 显示文字 (左上角x坐标,左上角y坐标, 图形数组, 图形宽度像素点, 图形高度像素点, 设置颜色)
  42. display.drawBitmap(20 * 1, 16, hans_jin, 16, 16, 1);
  43. display.drawBitmap(20 * 2, 16, hans_ling, 16, 16, 1);
  44. display.drawBitmap(20 * 3, 16, hans_zhong, 16, 16, 1);
  45. display.drawBitmap(20 * 4, 16, hans_xue, 16, 16, 1);
  46. //显示图形
  47. display.display();
  48. delay(2000);
  49. }
  50. void hans_display_1(void)
  51. {
  52. // 显示之前清屏
  53. display.clearDisplay();
  54. // 显示文字 (左上角x坐标,右上角y坐标, 图形数组, 图形宽度像素点, 图形高度像素点, 设置颜色)
  55. display.drawBitmap(20 * 1, 16, hans_jin1, 16, 16, 1);
  56. display.drawBitmap(20 * 2, 16, hans_ling1, 16, 16, 1);
  57. display.drawBitmap(20 * 3, 16, hans_zhong1, 16, 16, 1);
  58. display.drawBitmap(20 * 4, 16, hans_xue1, 16, 16, 1);
  59. //显示图形
  60. display.display();
  61. delay(2000);
  62. }

text.h

  1. static const unsigned char PROGMEM hans_jin[] = {
  2. 0x01,0x00,0x01,0x00,0x02,0x80,0x04,0x40,0x08,0x20,0x10,0x10,0x2F,0xE8,0xC1,0x06,
  3. 0x01,0x00,0x3F,0xF8,0x01,0x00,0x11,0x10,0x09,0x10,0x09,0x20,0xFF,0xFE,0x00,0x00,/*"金",0*/
  4. };
  5. static const unsigned char PROGMEM hans_ling[] = {
  6. 0x00,0x20,0x78,0x20,0x49,0xFC,0x50,0x20,0x50,0x20,0x63,0xFE,0x50,0x88,0x49,0x44,
  7. 0x4A,0x42,0x48,0xF8,0x69,0x88,0x52,0x50,0x40,0x20,0x40,0x50,0x41,0x88,0x46,0x06,/*"陵",1*/
  8. /* (16 X 16 , 宋体 )*/
  9. };
  10. static const unsigned char PROGMEM hans_zhong[] = {
  11. 0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x3F,0xF8,0x21,0x08,0x21,0x08,0x21,0x08,
  12. 0x21,0x08,0x21,0x08,0x3F,0xF8,0x21,0x08,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,/*"中",2*/
  13. /* (16 X 16 , 宋体 )*/
  14. };
  15. static const unsigned char PROGMEM hans_xue[] = {
  16. 0x22,0x08,0x11,0x08,0x11,0x10,0x00,0x20,0x7F,0xFE,0x40,0x02,0x80,0x04,0x1F,0xE0,
  17. 0x00,0x40,0x01,0x80,0xFF,0xFE,0x01,0x00,0x01,0x00,0x01,0x00,0x05,0x00,0x02,0x00,/*"学",3*/
  18. /* (16 X 16 , 宋体 )*/
  19. };
  20. static const unsigned char PROGMEM hans_jin1[] = {
  21. 0x00,0x00,0x00,0x00,0x01,0x80,0x06,0x60,0x08,0x10,0x70,0x0C,0x1F,0xFA,0x01,0x00,
  22. 0x01,0x00,0x3F,0xFC,0x11,0x08,0x11,0x08,0x09,0x10,0x09,0x10,0x09,0x10,0x7F,0xFE,/*"金",0*/
  23. /* (16 X 16 , 幼圆 )*/
  24. };
  25. static const unsigned char PROGMEM hans_ling1[] = {
  26. 0x00,0x00,0x00,0x40,0x78,0x40,0x4F,0xFE,0x48,0x40,0x50,0x40,0x5F,0xFE,0x51,0x88,
  27. 0x51,0x04,0x4A,0x82,0x4D,0xFC,0x4B,0x04,0x74,0x88,0x48,0x50,0x40,0x70,0x4F,0x8C,/*"陵",1*/
  28. /* (16 X 16 , 幼圆 )*/
  29. };
  30. static const unsigned char PROGMEM hans_zhong1[] = {
  31. 0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x3F,0xFC,0x21,0x04,0x21,0x04,0x21,0x04,
  32. 0x21,0x04,0x21,0x04,0x21,0x04,0x3F,0xFC,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,/*"中",2*/
  33. /* (16 X 16 , 幼圆 )*/
  34. };
  35. static const unsigned char PROGMEM hans_xue1[] = {
  36. 0x00,0x00,0x00,0x00,0x21,0x08,0x11,0x08,0x08,0x90,0x77,0x6E,0x40,0x02,0x5F,0xF2,
  37. 0x00,0x20,0x00,0xC0,0x00,0x80,0x7F,0xFE,0x00,0x40,0x00,0x40,0x00,0x40,0x0C,0xC0,/*"学",3*/
  38. /* (16 X 16 , 幼圆 )*/
  39. };

效果演示

image.pngimage.png

3 OLED显示图片

图片的显示需要对图片进行取模操作,再使用drawBitmap()函数对取模生成的数组进行显示,下面介绍如何对图片进行取模操作

图片取模

1 打开取模软件,切换到图形模式
Arduino驱动OLED屏幕 - 图14
2 打开图片或新建图片
图形模式有三种方法可以处理图片(如下图所示)
A、点击文件->打开,打开现有的BMP单色图片
B、点击打开图片按钮打开现有的BMP单色图片
C、点击新建图片按钮,设置宽度和高度,新建一幅单色BMP图片
Arduino驱动OLED屏幕 - 图15
3 打开图片之后,点击生成子模,生成之后需要对生成的数据进行变量赋值和加工,具体格式参考示例程序
Arduino驱动OLED屏幕 - 图16

电路连接

Arduino驱动OLED屏幕 - 图17

示例程序

  1. /**********************************************************************
  2. 程序名称/Program name : words_display
  3. 团队/Team : 太极创客团队 / Taichi-Maker (www.taichi-maker.com)
  4. 作者/Author : Dapenson
  5. 日期/Date(YYYYMMDD) : 2020/07/01
  6. 程序目的/Purpose :
  7. 使用OLED0.96 IIC 12864显示图片
  8. -----------------------------------------------------------------------
  9. 修订历史/Revision History
  10. 日期/Date 作者/Author 参考号/Ref 修订说明/Revision Description
  11. -----------------------------------------------------------------------
  12. 其它说明:
  13. ***********************************************************************/
  14. // 引入IIC通讯所需的Wire库文件
  15. // 教程参考http://www.taichi-maker.com/homepage/reference-index/arduino-library-index/wire-library/
  16. #include <Wire.h>
  17. // 引入驱动OLED0.96所需的库
  18. #include <Adafruit_GFX.h>
  19. #include <Adafruit_SSD1306.h>
  20. #define SCREEN_WIDTH 128 // 设置OLED宽度,单位:像素
  21. #define SCREEN_HEIGHT 64 // 设置OLED高度,单位:像素
  22. // 自定义重置引脚,虽然教程未使用,但却是Adafruit_SSD1306库文件所必需的
  23. #define OLED_RESET 4
  24. Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
  25. static const unsigned char PROGMEM panda_bmp[] =
  26. {
  27. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  28. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  29. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  30. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  31. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  32. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  33. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  34. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  35. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  36. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  37. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  38. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  39. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  40. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  41. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  42. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  43. 0x00,0x01,0xFF,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xFF,0xFF,0xFF,0xFF,
  44. 0xC0,0x00,0x00,0x00,0x00,0x00,0x03,0xFF,0xFF,0xFF,0xFF,0xFF,0xF8,0x07,0x80,0x00,
  45. 0x00,0x00,0x0F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x1F,0xC0,0x00,0x00,0x00,0x3F,0xFF,
  46. 0xFF,0xFF,0xFF,0xC3,0xFF,0xFF,0xC0,0x00,0x00,0x00,0xFF,0xE0,0x00,0x01,0xFF,0xC0,
  47. 0x7F,0xFF,0xC0,0x00,0x00,0x01,0xFF,0x00,0x00,0x03,0xFF,0xC0,0x0F,0xFF,0xC0,0x00,
  48. 0x00,0x07,0xF8,0x00,0x00,0x03,0xFF,0xE0,0x03,0xFF,0xC0,0x00,0x00,0x0F,0xE0,0x00,
  49. 0x00,0x03,0xFF,0xE0,0x00,0xFF,0xE0,0x00,0x00,0x1F,0xC0,0x00,0x00,0x07,0xFF,0xF0,
  50. 0x00,0xFF,0xF0,0x00,0x00,0x3F,0x00,0x00,0x00,0x07,0xFF,0xF0,0x00,0xFF,0xF8,0x00,
  51. 0x00,0x7E,0x00,0x00,0x00,0x07,0xFF,0xF8,0x00,0xFF,0xFC,0x00,0x00,0xFC,0x00,0x00,
  52. 0x00,0x07,0xFF,0xFC,0x00,0xFC,0x7E,0x00,0x01,0xF8,0x00,0x00,0x00,0x0F,0xFF,0xFE,
  53. 0x00,0x60,0x3E,0x00,0x01,0xF0,0x00,0x00,0x00,0x0F,0xFF,0xFE,0x00,0x00,0x1F,0x00,
  54. 0x03,0xE0,0x00,0x00,0x00,0x0F,0xFF,0xFF,0x00,0x00,0x0F,0x00,0x03,0xC0,0x00,0x00,
  55. 0x00,0x0F,0xFF,0xFF,0x80,0x01,0xEF,0x80,0x07,0xC0,0x00,0x00,0x00,0x0F,0xFF,0xFF,
  56. 0x80,0x01,0xF7,0x80,0x07,0x80,0x00,0x00,0x00,0x0F,0xFF,0xFF,0x80,0x03,0xF7,0x80,
  57. 0x0F,0x80,0x00,0x00,0x00,0x0F,0xFF,0xFF,0xC0,0x03,0xFF,0x80,0x0F,0x00,0x10,0x00,
  58. 0x00,0x0F,0xFF,0xFF,0xC0,0x03,0xFF,0x80,0x1F,0x03,0xFF,0x80,0x00,0x1F,0xFF,0xFF,
  59. 0xC0,0x03,0xF7,0xC0,0x1E,0x07,0xFF,0xE0,0x00,0x1F,0xFF,0xFF,0xC0,0x03,0xF3,0xE0,
  60. 0x1E,0x1F,0xFF,0xF0,0x00,0x1F,0xFF,0xFF,0xC0,0x03,0xF1,0xF0,0x1E,0x3F,0xFF,0xF8,
  61. 0x00,0x1F,0xFF,0xFF,0xC0,0x01,0xE1,0xF8,0x1C,0x3F,0xFF,0xF8,0x00,0x1F,0xFF,0xFF,
  62. 0xC0,0x00,0x00,0xF8,0x3C,0x7F,0xFF,0xF8,0x00,0x1F,0xFF,0xFF,0xC0,0x00,0x00,0x7C,
  63. 0x3C,0xFF,0xFF,0xFC,0x00,0x1F,0xFF,0xFF,0xC0,0x00,0x00,0x3C,0x3C,0xFF,0xFF,0xFC,
  64. 0x00,0x0F,0xFF,0xFF,0x80,0x00,0x00,0x3C,0x3D,0xFF,0xFF,0xFC,0x00,0x0F,0xFF,0xFF,
  65. 0x80,0x00,0x00,0x3C,0x3D,0xFF,0xFF,0xF8,0x00,0x0F,0xFF,0xFF,0x80,0x60,0x00,0x7C,
  66. 0x3D,0xFF,0xFF,0xF8,0x00,0x0F,0xFF,0xFF,0xFF,0xFF,0x00,0x78,0x3D,0xFF,0xFF,0xF8,
  67. 0x00,0x0F,0xFF,0xFF,0xFF,0xFF,0xFC,0xF8,0x3F,0xFF,0xFF,0xF0,0x00,0x0F,0xFF,0xFF,
  68. 0xFF,0xFF,0xFF,0xF0,0x1F,0xFF,0xFF,0xF0,0x00,0x0F,0xFF,0xFF,0xF8,0x0F,0xFF,0xF0,
  69. 0x1F,0xFF,0xFF,0xE0,0x00,0x0F,0xFF,0xFF,0xF8,0x00,0x7F,0xE0,0x0F,0xFF,0xFF,0xC0,
  70. 0x00,0x07,0xFF,0xFF,0xF8,0x00,0x03,0x80,0x07,0xFF,0xFF,0x80,0x00,0x3F,0xFF,0xBF,
  71. 0xF8,0x00,0x00,0x00,0x03,0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xBF,0xF8,0x00,0x00,0x00,
  72. 0x01,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xBF,0xF8,0x00,0x00,0x00,0x01,0xFF,0xFB,0xFF,
  73. 0xFF,0xFF,0xFF,0xBF,0xF8,0x00,0x00,0x00,0x01,0xFF,0xE7,0xFF,0xFF,0xC3,0xFF,0xBF,
  74. 0xF8,0x00,0x00,0x00,0x01,0xFF,0xDF,0xF8,0x00,0x03,0xFF,0xBF,0xF8,0x00,0x00,0x00,
  75. 0x01,0xFF,0xFF,0xF8,0x00,0x03,0xFF,0xBF,0xF8,0x00,0x00,0x00,0x01,0xFF,0xFF,0xF8,
  76. 0x00,0x03,0xFF,0xBF,0xF8,0x00,0x00,0x00,0x01,0xFF,0xFF,0xF8,0x00,0x03,0xFF,0xBF,
  77. 0xF8,0x00,0x00,0x00,0x01,0xFF,0xFF,0xF8,0x00,0x03,0xFF,0xBF,0xF8,0x00,0x00,0x00,
  78. 0x01,0xFF,0x9F,0xF8,0x00,0x01,0xFF,0x9F,0xF8,0x00,0x00,0x00,0x01,0xFF,0x9F,0xF8,
  79. 0x00,0x01,0xFF,0x9F,0xF8,0x00,0x00,0x00,0x00,0xFF,0x9F,0xF0,0x00,0x01,0xFF,0x1F,
  80. 0xF0,0x00,0x00,0x00,0x00,0x7F,0x0F,0xF0,0x00,0x00,0xFF,0x0F,0xF0,0x00,0x00,0x00,
  81. 0x00,0x1C,0x03,0xC0,0x00,0x00,0x3C,0x01,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  82. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  83. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  84. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  85. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  86. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  87. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  88. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  89. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  90. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  91. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  92. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  93. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  94. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  95. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  96. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  97. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  98. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
  99. void setup()
  100. {
  101. // 初始化OLED并设置其IIC地址为 0x3C
  102. display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  103. }
  104. void loop()
  105. {
  106. bmp_display();
  107. }
  108. void bmp_display(void)
  109. {
  110. // 显示前清屏
  111. display.clearDisplay();
  112. // 将图片显示在中心位置
  113. display.drawBitmap(0,0,panda_bmp, 96, 96, 1);
  114. // 将内容显示到屏幕
  115. display.display();
  116. delay(1000);
  117. }

效果演示

Arduino驱动OLED屏幕 - 图18

相关资源

1 取模软件PCTOLCD2002下载地址

4 OLED贪吃蛇

image.png
image.png

  1. #include <Wire.h>
  2. #include <Adafruit_GFX.h>
  3. #include <Adafruit_SSD1306.h>
  4. //DISPLAY THINGS
  5. #define OLED_RESET 4 // Reset pin # (or -1 if sharing Arduino reset pin)
  6. #define OLED_ADDRESS 0x3C // I2C address of the display.
  7. #define SCREEN_WIDTH 128 // OLED display width, in pixels
  8. #define SCREEN_HEIGHT 64 // OLED display height, in pixels
  9. //BUTTON THINGS
  10. #define LEFT_B_IN A0
  11. #define RIGHT_B_IN A1
  12. //GAME OPTIONS
  13. #define WIN_POINTS 20
  14. #define CYCLE_INTERVAL 500
  15. #define BUTTON_INTERVAL 400
  16. unsigned long previousTime = 0;
  17. //---------DISPLAY STUFF---------
  18. // Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
  19. Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
  20. //Draws a square on the 21x10 board
  21. //(A 128x64 board reduced to 126x60, each element is 6x6)
  22. //x is between 0 and 20 inclusive
  23. //y is between 0 and 9 inclusive
  24. //thing: 0 = erase, 1 = snake, 2 = food
  25. //Could've used a switch statement here...
  26. void drawSquare(byte x, byte y, byte thing)
  27. {
  28. if (thing == 1){
  29. display.fillRect(6*x+2,6*y+3,4,4,WHITE);
  30. return;
  31. }
  32. if (thing == 2){
  33. display.drawRoundRect(6*x+2,6*y+3,4,4,1,WHITE);
  34. return;
  35. }
  36. display.fillRect(6*x+2,6*y+3,4,4,BLACK);
  37. }
  38. //---------SNAKE STUFF---------
  39. //Coordinate struct
  40. //With the size of the game board (21x10), you could technically shrink it to
  41. //1 byte, but I don't quite know how to do that yet.
  42. typedef struct
  43. {
  44. byte x;
  45. byte y;
  46. } coord;
  47. //THE SNAKE
  48. //#Apparently snake[] took up so much space that it interfered with the OLED
  49. //#Keep it a reasonable size.
  50. coord snake[100];
  51. byte snakeLength = 2;
  52. short directions[4][2] = {{1,0},{0,1},{-1,0},{0,-1}};
  53. short dirIndex = 0;
  54. coord foodCoord;
  55. //Initializes the snake with an initial length of 2
  56. //and initial direction right.
  57. void makeSnake()
  58. {
  59. snakeLength = 2;
  60. snake[0] = {1, (byte) random(0,10)};
  61. snake[1] = {0, snake[0].y};
  62. drawSquare(snake[0].x,snake[0].y,1);
  63. drawSquare(snake[1].x,snake[1].y,1);
  64. dirIndex = 0;
  65. }
  66. //Modify direction according to button press
  67. void redirect()
  68. {
  69. unsigned long tempTime = millis();
  70. bool R = false;
  71. bool L = false;
  72. //Listen for button presses
  73. while (millis()-tempTime < BUTTON_INTERVAL)
  74. {
  75. if (digitalRead(LEFT_B_IN)){L = true;}
  76. if (digitalRead(RIGHT_B_IN)){R = true;}
  77. }
  78. //Ignore double presses and non presses
  79. if (R == L){
  80. return;
  81. }
  82. //If right, increment direction index
  83. if (R){
  84. dirIndex++;
  85. if (dirIndex > 3){dirIndex = 0;}
  86. return;
  87. }
  88. //If left, decrement direction index
  89. dirIndex--;
  90. if (dirIndex < 0){dirIndex = 3;}
  91. }
  92. //Moves the snake
  93. bool moveSnake()
  94. {
  95. //Calculate the new coordinates
  96. int x = snake[0].x+directions[dirIndex][0];
  97. int y = snake[0].y+directions[dirIndex][1];
  98. //If out of bounds, exit and lose.
  99. if (x > 20 || x < 0 || y > 9 || y < 0)
  100. {
  101. return 1;
  102. }
  103. coord newHead = {byte(x),byte(y)};
  104. //Draw the new head
  105. drawSquare(newHead.x,newHead.y,1);
  106. //Did we land on food? / Does the new head line up with the food location?
  107. bool onFood = (newHead.x == foodCoord.x && newHead.y == foodCoord.y);
  108. //Shift all the snake coords back to make space for the head
  109. for (int i = snakeLength; i != 0; --i)
  110. {
  111. //If the new head contacts any snake coord, exit and lose
  112. if (!onFood && newHead.x == snake[i].x && newHead.y == snake[i].y)
  113. {
  114. return 1;
  115. }
  116. snake[i] = snake[i-1];
  117. }
  118. //If nothing wrong, set the new head of the snake.
  119. snake[0] = newHead;
  120. //If no food, erase tail
  121. if (!onFood)
  122. {
  123. drawSquare(snake[snakeLength].x,snake[snakeLength].y,0);
  124. }
  125. //Else dont erase tail, increment length of snake,
  126. //and put a new food
  127. else
  128. {
  129. snakeLength++;
  130. putFood();
  131. }
  132. return 0;
  133. }
  134. //Puts a new piece of food on the game board.
  135. void putFood()
  136. {
  137. bool foodOkay = false;
  138. //Make sure the food doesnt fall on top of the snake
  139. while (!foodOkay)
  140. {
  141. foodCoord = {byte(random(0,21)),byte(random(0,10))};
  142. foodOkay = true;
  143. for (byte i = 0; i < snakeLength; ++i)
  144. {
  145. if (foodCoord.y == snake[i].y && foodCoord.x == snake[i].x)
  146. {
  147. foodOkay = false;
  148. break;
  149. }
  150. }
  151. }
  152. drawSquare(foodCoord.x,foodCoord.y,2);
  153. }
  154. void setup()
  155. {
  156. //Serial.begin(9600);
  157. // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  158. if(!display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDRESS)) {
  159. //Serial.println(F("Oh no"));
  160. for(;;);
  161. }
  162. //Random numbers
  163. randomSeed(analogRead(7));
  164. //Set up the buttons
  165. //Left button
  166. pinMode(LEFT_B_IN, INPUT);
  167. //Right button
  168. pinMode(RIGHT_B_IN, INPUT);
  169. //Set up the title screen
  170. display.clearDisplay();
  171. display.setTextSize(3);
  172. display.setTextColor(WHITE);
  173. display.setCursor(20,5);
  174. display.println(F("SNAKE"));
  175. display.setTextSize(1);
  176. display.setCursor(26,40);
  177. display.println(F("Hit L to play"));
  178. }
  179. //Game loop
  180. void loop() {
  181. display.display();
  182. //Wait for user input
  183. while (!digitalRead(LEFT_B_IN)){}
  184. //GAME SETUP
  185. //Set up borders
  186. display.clearDisplay();
  187. display.fillRect(0,0,128,2,WHITE);
  188. display.fillRect(0,62,128,2,WHITE);
  189. display.fillRect(0,0,1,64,WHITE);
  190. display.fillRect(127,0,1,64,WHITE);
  191. //Make the snake and place the food
  192. makeSnake();
  193. putFood();
  194. display.display();
  195. bool win = false;
  196. delay(800);
  197. //Start game
  198. for(;;)
  199. {
  200. //Every cycle
  201. if (millis() - previousTime > CYCLE_INTERVAL)
  202. {
  203. previousTime = millis();
  204. //Check for direction change
  205. redirect();
  206. //Self contact/Out of bounds condition
  207. if (moveSnake())
  208. {
  209. break;
  210. }
  211. if (snakeLength == WIN_POINTS+2)
  212. {
  213. win = true;
  214. break;
  215. }
  216. display.display();
  217. }
  218. }
  219. if (win)
  220. {
  221. display.clearDisplay();
  222. display.setTextSize(2);
  223. display.setTextColor(WHITE);
  224. display.setCursor(0,5);
  225. display.println(F("YOU WON :)"));
  226. }
  227. //Show lose screen
  228. else
  229. {
  230. //Flash the screen
  231. display.invertDisplay(true);
  232. delay(400);
  233. display.invertDisplay(false);
  234. delay(400);
  235. display.invertDisplay(true);
  236. delay(400);
  237. display.invertDisplay(false);
  238. delay(400);
  239. //Loss text
  240. display.clearDisplay();
  241. display.setTextSize(2);
  242. display.setTextColor(WHITE);
  243. display.setCursor(0,5);
  244. display.println(F("YOU LOST:("));
  245. }
  246. display.setTextSize(1);
  247. display.setCursor(0,30);
  248. display.print(F("Donuts Eaten: "));
  249. display.print(snakeLength-2);
  250. display.println();
  251. display.println();
  252. display.println(F("Hit L to play again"));
  253. }