【雕爷学编程】Arduino动手做(93)--- 0.96寸OLED液晶屏模块8

news2024/10/6 3:51:05

37款传感器与执行器的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块,依照实践出真知(一定要动手做)的理念,以学习和交流为目的,这里准备逐一动手尝试系列实验,不管成功(程序走通)与否,都会记录下来—小小的进步或是搞不掂的问题,希望能够抛砖引玉。

【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
实验九十三:0.96寸I2C IIC通信128*64显示器 OLED液晶屏模块

在这里插入图片描述

知识点:OLED(OrganicLight-Emitting Diode)
又称为有机电激光显示、有机发光半导体(OrganicElectroluminesence Display,OLED)。OLED属于一种电流型的有机发光器件,是通过载流子的注入和复合而致发光的现象,发光强度与注入的电流成正比。OLED在电场的作用下,阳极产生的空穴和阴极产生的电子就会发生移动,分别向空穴传输层和电子传输层注入,迁移到发光层。当二者在发光层相遇时,产生能量激子,从而激发发光分子最终产生可见光。一般而言,OLED可按发光材料分为两种:小分子OLED和高分子OLED(也可称为PLED)。OLED是一种利用多层有机薄膜结构产生电致发光的器件,它很容易制作,而且只需要低的驱动电压,这些主要的特征使得OLED在满足平面显示器的应用上显得非常突出。OLED显示屏比LCD更轻薄、亮度高、功耗低、响应快、清晰度高、柔性好、发光效率高,能满足消费者对显示技术的新需求。全球越来越多的显示器厂家纷纷投入研发,大大的推动了OLED的产业化进程。

在这里插入图片描述
OLED特点
(1)功耗低——与LCD相比,OLED不需要背光源,而背光源在LCD中是比较耗能的一部分,所以OLED是比较节能的。例如,24in的AMOLED模块功耗仅仅为440mw,而24in的多晶硅LCD模块达到了605mw。
(2)响应速度快——OLED技术与其他技术相比,其响应速度快,响应时间可以达到微秒级别。较高的响应速度更好的实现了运动的图像。根据有关的数据分析,其响应速度达到了液晶显示器响应速度的1000倍左右。
(3)较宽的视角——与其他显示相比,由于OLED是主动发光的,所以在很大视角范围内画面是不会显示失真的。其上下,左右的视角宽度超过170度。
(4)能实现高分辨率显示——大多高分辨率的OLED显示采用的是有源矩阵也就是AMOLED,它的发光层可以是吸纳26万真彩色的高分辨率,并且随着科学技术的发展,其分辨率在以后会得到更高的提升。
(5)宽温度特性——与LCD相比,OLED可以在很大的温度范围内进行工作,根据有关的技术分析,温度在-40摄氏度到80摄氏度都是可以正常运行的。这样就可以降低地域限制,在极寒地带也可以正常使用。
(6)OLED能够实现软屏——OLED可以在塑料、树脂等不同的柔性衬底材料上进行生产,将有机层蒸镀或涂布在塑料基衬上,就可以实现软屏。
(7)OLED成品的质量比较轻——与其他产品相比,OLED的质量比较小,厚度与LCD相比是比较小的,其抗震系数较高,能够适应较大的加速度,振动等比较恶劣的环境。

在这里插入图片描述

Arduino实验接线示意图

在这里插入图片描述
在这里插入图片描述

【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
实验九十三: 0.96寸I2C IIC通信128*64显示器 OLED液晶屏模块
项目二十八:Adafruit_SSD1306 综合显示测试
实验接脚: 0.96寸OLED液晶屏SDA接A4, SCL接A5

实验开源代码

/*
  【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
  实验九十七: 0.96寸I2C IIC通信128*64显示器 OLED液晶屏模块
  项目二十八:Adafruit_SSD1306 综合显示测试
  实验接脚: 0.96寸OLED液晶屏SDA接A4, SCL接A5
*/

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128 // OLED 显示宽度,以像素为单位
#define SCREEN_HEIGHT 64 // OLED 显示高度,以像素为单位

// 连接到 I2C(SDA、SCL 引脚)的 SSD1306 显示器的声明
// I2C 的引脚由 Wire 库定义。
// 在 arduino UNO 上:A4(SDA)、A5(SCL)
// 在 arduino MEGA 2560 上:20(SDA), 21(SCL)
// 在 arduino LEONARDO 上:2(SDA), 3(SCL), ...
#define OLED_RESET     4 // 重置引脚 #(如果共享 Arduino 重置引脚,则为 1)
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

#define NUMFLAKES     10 // 动画示例中的雪花数量

#define LOGO_HEIGHT   16
#define LOGO_WIDTH    16
static const unsigned char PROGMEM logo_bmp[] =
{ 0b00000000, 0b11000000,
  0b00000001, 0b11000000,
  0b00000001, 0b11000000,
  0b00000011, 0b11100000,
  0b11110011, 0b11100000,
  0b11111110, 0b11111000,
  0b01111110, 0b11111111,
  0b00110011, 0b10011111,
  0b00011111, 0b11111100,
  0b00001101, 0b01110000,
  0b00011011, 0b10100000,
  0b00111111, 0b11100000,
  0b00111111, 0b11110000,
  0b01111100, 0b11110000,
  0b01110000, 0b01110000,
  0b00000000, 0b00110000
};

void setup() {
  Serial.begin(9600);
  // SSD1306_VCC = 从内部 3.3V 产生显示电压
  if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
    Serial.println(F("SSD1306 allocation failed"));
    for (;;); // 不要继续,永远循环
  }

  // 在屏幕上显示初始显示缓冲区内容 --
  // 库使用 Adafruit 启动画面对其进行初始化。
  display.display();
  delay(500);

  // 清除缓冲区
  display.clearDisplay();

  // 用白色绘制单个像素
  display.drawPixel(10, 10, SSD1306_WHITE);

  // 在屏幕上显示显示缓冲区。 你必须在之后调用 display()
  // 绘制命令使它们在屏幕上可见!
  display.display();
  delay(500);

  // 在每个绘图命令之后都不需要 display.display(),
  // 除非那是你想要的......相反,你可以批量处理
  // 绘制操作,然后通过调用一次更新屏幕
  // display.display(). 这些示例演示了这两种方法......
  testdrawline();      // Draw many lines

  testdrawrect();      // Draw rectangles (outlines)

  testfillrect();      // Draw rectangles (filled)

  testdrawcircle();    // Draw circles (outlines)

  testfillcircle();    // Draw circles (filled)

  testdrawroundrect(); // Draw rounded rectangles (outlines)

  testfillroundrect(); // Draw rounded rectangles (filled)

  testdrawtriangle();  // Draw triangles (outlines)

  testfilltriangle();  // Draw triangles (filled)

  testdrawchar();      // Draw characters of the default font

  testdrawstyles();    // Draw 'stylized' characters

  testscrolltext();    // Draw scrolling text

  testdrawbitmap();    // Draw a small bitmap image

  // 反转和恢复显示,中间暂停
  display.invertDisplay(true);
  delay(500);
  display.invertDisplay(false);
  delay(500);

  testanimate(logo_bmp, LOGO_WIDTH, LOGO_HEIGHT); // 动画位图
}

void loop() {
}

void testdrawline() {
  int16_t i;

  display.clearDisplay(); // 清除显示缓冲区

  for (i = 0; i < display.width(); i += 4) {
    display.drawLine(0, 0, i, display.height() - 1, SSD1306_WHITE);
    display.display(); // 用每条新画的线更新屏幕
    delay(1);
  }
  for (i = 0; i < display.height(); i += 4) {
    display.drawLine(0, 0, display.width() - 1, i, SSD1306_WHITE);
    display.display();
    delay(1);
  }
  delay(250);

  display.clearDisplay();

  for (i = 0; i < display.width(); i += 4) {
    display.drawLine(0, display.height() - 1, i, 0, SSD1306_WHITE);
    display.display();
    delay(1);
  }
  for (i = display.height() - 1; i >= 0; i -= 4) {
    display.drawLine(0, display.height() - 1, display.width() - 1, i, SSD1306_WHITE);
    display.display();
    delay(1);
  }
  delay(250);

  display.clearDisplay();

  for (i = display.width() - 1; i >= 0; i -= 4) {
    display.drawLine(display.width() - 1, display.height() - 1, i, 0, SSD1306_WHITE);
    display.display();
    delay(1);
  }
  for (i = display.height() - 1; i >= 0; i -= 4) {
    display.drawLine(display.width() - 1, display.height() - 1, 0, i, SSD1306_WHITE);
    display.display();
    delay(1);
  }
  delay(250);

  display.clearDisplay();

  for (i = 0; i < display.height(); i += 4) {
    display.drawLine(display.width() - 1, 0, 0, i, SSD1306_WHITE);
    display.display();
    delay(1);
  }
  for (i = 0; i < display.width(); i += 4) {
    display.drawLine(display.width() - 1, 0, i, display.height() - 1, SSD1306_WHITE);
    display.display();
    delay(1);
  }

  delay(1000);
}

void testdrawrect(void) {
  display.clearDisplay();

  for (int16_t i = 0; i < display.height() / 2; i += 2) {
    display.drawRect(i, i, display.width() - 2 * i, display.height() - 2 * i, SSD1306_WHITE);
    display.display(); // 使用每个新绘制的矩形更新屏幕
    delay(1);
  }

  delay(1000);
}

void testfillrect(void) {
  display.clearDisplay();

  for (int16_t i = 0; i < display.height() / 2; i += 3) {
    // 使用 INVERSE 颜色,因此矩形交替白色/黑色
    display.fillRect(i, i, display.width() - i * 2, display.height() - i * 2, SSD1306_INVERSE);
    display.display(); // 使用每个新绘制的矩形更新屏幕
    delay(1);
  }

  delay(1000);
}

void testdrawcircle(void) {
  display.clearDisplay();

  for (int16_t i = 0; i < max(display.width(), display.height()) / 2; i += 2) {
    display.drawCircle(display.width() / 2, display.height() / 2, i, SSD1306_WHITE);
    display.display();
    delay(1);
  }

  delay(1000);
}

void testfillcircle(void) {
  display.clearDisplay();

  for (int16_t i = max(display.width(), display.height()) / 2; i > 0; i -= 3) {
    // The INVERSE color is used so circles alternate white/black
    display.fillCircle(display.width() / 2, display.height() / 2, i, SSD1306_INVERSE);
    display.display(); // 使用每个新绘制的圆圈更新屏幕
    delay(1);
  }

  delay(1000);
}

void testdrawroundrect(void) {
  display.clearDisplay();

  for (int16_t i = 0; i < display.height() / 2 - 2; i += 2) {
    display.drawRoundRect(i, i, display.width() - 2 * i, display.height() - 2 * i,
                          display.height() / 4, SSD1306_WHITE);
    display.display();
    delay(1);
  }

  delay(1000);
}

void testfillroundrect(void) {
  display.clearDisplay();

  for (int16_t i = 0; i < display.height() / 2 - 2; i += 2) {
    // 使用 INVERSE 颜色,因此圆形矩形交替白色/黑色
    display.fillRoundRect(i, i, display.width() - 2 * i, display.height() - 2 * i,
                          display.height() / 4, SSD1306_INVERSE);
    display.display();
    delay(1);
  }

  delay(1000);
}

void testdrawtriangle(void) {
  display.clearDisplay();

  for (int16_t i = 0; i < max(display.width(), display.height()) / 2; i += 5) {
    display.drawTriangle(
      display.width() / 2  , display.height() / 2 - i,
      display.width() / 2 - i, display.height() / 2 + i,
      display.width() / 2 + i, display.height() / 2 + i, SSD1306_WHITE);
    display.display();
    delay(1);
  }

  delay(1000);
}

void testfilltriangle(void) {
  display.clearDisplay();

  for (int16_t i = max(display.width(), display.height()) / 2; i > 0; i -= 5) {
    // 使用 INVERSE 颜色,因此三角形交替白色/黑色
    display.fillTriangle(
      display.width() / 2  , display.height() / 2 - i,
      display.width() / 2 - i, display.height() / 2 + i,
      display.width() / 2 + i, display.height() / 2 + i, SSD1306_INVERSE);
    display.display();
    delay(1);
  }

  delay(1000);
}

void testdrawchar(void) {
  display.clearDisplay();

  display.setTextSize(1);      // Normal 1:1 pixel scale
  display.setTextColor(SSD1306_WHITE); // Draw white text
  display.setCursor(0, 0);     // Start at top-left corner
  display.cp437(true);         // Use full 256 char 'Code Page 437' font

  // 并非所有字符都适合显示。 这是正常的。
  // 库将绘制它可以绘制的内容,其余部分将被剪切。
  for (int16_t i = 0; i < 256; i++) {
    if (i == '\n') display.write(' ');
    else          display.write(i);
  }

  display.display();
  delay(1000);
}

void testdrawstyles(void) {
  display.clearDisplay();

  display.setTextSize(1);             // Normal 1:1 pixel scale
  display.setTextColor(SSD1306_WHITE);        // Draw white text
  display.setCursor(0, 0);            // Start at top-left corner
  display.println(F("Hello, world!"));

  display.setTextColor(SSD1306_BLACK, SSD1306_WHITE); // Draw 'inverse' text
  display.println(3.141592);

  display.setTextSize(2);             // Draw 2X-scale text
  display.setTextColor(SSD1306_WHITE);
  display.print(F("0x")); display.println(0xDEADBEEF, HEX);

  display.display();
  delay(1000);
}

void testscrolltext(void) {
  display.clearDisplay();

  display.setTextSize(2); // Draw 2X-scale text
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(10, 0);
  display.println(F("scroll"));
  display.display();      // Show initial text
  delay(100);

  // 向各个方向滚动,中间暂停:
  display.startscrollright(0x00, 0x0F);
  delay(2000);
  display.stopscroll();
  delay(1000);
  display.startscrollleft(0x00, 0x0F);
  delay(1000);
  display.stopscroll();
  delay(1000);
  display.startscrolldiagright(0x00, 0x07);
  delay(1000);
  display.startscrolldiagleft(0x00, 0x07);
  delay(1000);
  display.stopscroll();
  delay(1000);
}

void testdrawbitmap(void) {
  display.clearDisplay();

  display.drawBitmap(
    (display.width()  - LOGO_WIDTH ) / 2,
    (display.height() - LOGO_HEIGHT) / 2,
    logo_bmp, LOGO_WIDTH, LOGO_HEIGHT, 1);
  display.display();
  delay(1000);
}

#define XPOS   0 //在下面的函数中索引到“图标”数组
#define YPOS   1
#define DELTAY 2

void testanimate(const uint8_t *bitmap, uint8_t w, uint8_t h) {
  int8_t f, icons[NUMFLAKES][3];

  // 初始化“雪花”位置
  for (f = 0; f < NUMFLAKES; f++) {
    icons[f][XPOS]   = random(1 - LOGO_WIDTH, display.width());
    icons[f][YPOS]   = -LOGO_HEIGHT;
    icons[f][DELTAY] = random(1, 6);
    Serial.print(F("x: "));
    Serial.print(icons[f][XPOS], DEC);
    Serial.print(F(" y: "));
    Serial.print(icons[f][YPOS], DEC);
    Serial.print(F(" dy: "));
    Serial.println(icons[f][DELTAY], DEC);
  }

  for (;;) { // Loop forever...
    display.clearDisplay(); // Clear the display buffer

    // Draw each snowflake:
    for (f = 0; f < NUMFLAKES; f++) {
      display.drawBitmap(icons[f][XPOS], icons[f][YPOS], bitmap, w, h, SSD1306_WHITE);
    }

    display.display(); // Show the display buffer on the screen
    delay(200);        // Pause for 1/10 second

    // 然后更新每个薄片的坐标...
    for (f = 0; f < NUMFLAKES; f++) {
      icons[f][YPOS] += icons[f][DELTAY];
      // If snowflake is off the bottom of the screen...
      if (icons[f][YPOS] >= display.height()) {
        // Reinitialize to a random position, just off the top
        icons[f][XPOS]   = random(1 - LOGO_WIDTH, display.width());
        icons[f][YPOS]   = -LOGO_HEIGHT;
        icons[f][DELTAY] = random(1, 6);
      }
    }
  }
}

【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
实验九十七: 0.96寸I2C IIC通信128*64显示器 OLED液晶屏模块
项目二十八:Adafruit_SSD1306 综合显示测试
实验接脚: 0.96寸OLED液晶屏SDA接A4, SCL接A5
Arduino实验场景图

在这里插入图片描述
在这里插入图片描述

【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
实验九十三: 0.96寸I2C IIC通信128*64显示器 OLED液晶屏模块
项目二十九:SSD1306 显示测试
实验接脚: 0.96寸OLED液晶屏SDA接A4, SCL接A5

实验开源代码

/*
  【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
  实验九十七: 0.96寸I2C IIC通信128*64显示器 OLED液晶屏模块
  项目二十九:SSD1306 显示测试
  实验接脚: 0.96寸OLED液晶屏SDA接A4, SCL接A5
*/

#include "ssd1306.h"
#include "nano_gfx.h"
#include "sova.h"

//下面的心脏图像是直接在闪存中定义的。这减少了 SRAM 消耗。
// 图像定义为从下到上(位),从左到正确(字节)。
const PROGMEM uint8_t heartImage[8] = {
  0B00001110,
  0B00011111,
  0B00111111,
  0B01111110,
  0B01111110,
  0B00111101,
  0B00011001,
  0B00001110
};

//定义精灵宽度。 宽度可以是任意大小。
//但精灵高度总是假定为 8 像素(单字节中的位数)。
const int spriteWidth = sizeof(heartImage);

SAppMenu menu;

const char *menuItems[] ={
  "draw bitmap",
  "sprites",
  "fonts",
  "canvas gfx",
  "draw lines",
};

static void bitmapDemo(){
  ssd1306_drawBitmap(0, 0, 128, 64, Sova);
  delay(1000);
  ssd1306_invertMode();
  delay(2000);
  ssd1306_normalMode();
}

static void spriteDemo(){
  ssd1306_clearScreen();
  /* Declare variable that represents our sprite */
  SPRITE sprite;
  /* Create sprite at 0,0 position. The function initializes sprite structure. */
  sprite = ssd1306_createSprite( 0, 0, spriteWidth, heartImage );
  for (int i = 0; i < 250; i++)
  {
    delay(15);
    sprite.x++;
    if (sprite.x >= ssd1306_displayWidth())
    {
      sprite.x = 0;
    }
    sprite.y++;
    if (sprite.y >= ssd1306_displayHeight())
    {
      sprite.y = 0;
    }
    /* Erase sprite on old place. The library knows old position of the sprite. */
    sprite.eraseTrace();
    /* Draw sprite on new place */
    sprite.draw();
  }
}

static void textDemo(){
  ssd1306_setFixedFont(ssd1306xled_font6x8);
  ssd1306_clearScreen();
  ssd1306_printFixed(0,  8, "Normal text", STYLE_NORMAL);
  ssd1306_printFixed(0, 16, "Bold text", STYLE_BOLD);
  ssd1306_printFixed(0, 24, "Italic text", STYLE_ITALIC);
  ssd1306_negativeMode();
  ssd1306_printFixed(0, 32, "Inverted bold", STYLE_BOLD);
  ssd1306_positiveMode();
  delay(3000);
}

static void canvasDemo(){
  uint8_t buffer[64 * 16 / 8];
  NanoCanvas canvas(64, 16, buffer);
  ssd1306_setFixedFont(ssd1306xled_font6x8);
  ssd1306_clearScreen();
  canvas.clear();
  canvas.fillRect(10, 3, 80, 5, 0xFF);
  canvas.blt((ssd1306_displayWidth() - 64) / 2, 1);
  delay(500);
  canvas.fillRect(50, 1, 60, 15, 0xFF);
  canvas.blt((ssd1306_displayWidth() - 64) / 2, 1);
  delay(1500);
  canvas.printFixed(20, 1, " DEMO ", STYLE_BOLD );
  canvas.blt((ssd1306_displayWidth() - 64) / 2, 1);
  delay(3000);
}

static void drawLinesDemo(){
  ssd1306_clearScreen();
  for (uint8_t y = 0; y < ssd1306_displayHeight(); y += 8)
  {
    ssd1306_drawLine(0, 0, ssd1306_displayWidth() - 1, y);
  }
  for (uint8_t x = ssd1306_displayWidth() - 1; x > 7; x -= 8)
  {
    ssd1306_drawLine(0, 0, x, ssd1306_displayHeight() - 1);
  }
  delay(3000);
}

void setup(){
  /* Select the font to use with menu and all font functions */
  ssd1306_setFixedFont(ssd1306xled_font6x8);

  ssd1306_128x64_i2c_init();
  //    ssd1306_128x64_spi_init(-1, 0, 1);  // Use this line for nano pi (RST not used, 0=CE, gpio1=D/C)
  //    ssd1306_128x64_spi_init(3,4,5);     // Use this line for Atmega328p (3=RST, 4=CE, 5=D/C)
  //    ssd1306_128x64_spi_init(24, 0, 23); // Use this line for Raspberry  (gpio24=RST, 0=CE, gpio23=D/C)
  //    ssd1306_128x64_spi_init(22, 5, 21); // Use this line for ESP32 (VSPI)  (gpio22=RST, gpio5=CE for VSPI, gpio21=D/C)
  //    composite_video_128x64_mono_init(); // Use this line for ESP32 with Composite video support

  ssd1306_clearScreen();
  ssd1306_createMenu( &menu, menuItems, sizeof(menuItems) / sizeof(char *) );
  ssd1306_showMenu( &menu );
}

void loop(){
  delay(1000);
  switch (ssd1306_menuSelection(&menu))
  {
    case 0:
      bitmapDemo();
      break;

    case 1:
      spriteDemo();
      break;

    case 2:
      textDemo();
      break;

    case 3:
      canvasDemo();
      break;

    case 4:
      drawLinesDemo();
      break;

    default:
      break;
  }
  ssd1306_clearScreen( );
  ssd1306_showMenu(&menu);
  delay(500);
  ssd1306_menuDown(&menu);
  ssd1306_updateMenu(&menu);
}

【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
实验九十七: 0.96寸I2C IIC通信128*64显示器 OLED液晶屏模块
项目二十九:SSD1306 显示测试
实验接脚: 0.96寸OLED液晶屏SDA接A4, SCL接A5

在这里插入图片描述
在这里插入图片描述

【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
实验九十三: 0.96寸I2C IIC通信128*64显示器 OLED液晶屏模块
项目三十: OLED 显示串口信息
实验接脚: 0.96寸OLED液晶屏SDA接A4, SCL接A5

实验开源代码

/*
  【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
  实验九十七: 0.96寸I2C IIC通信128*64显示器 OLED液晶屏模块
  项目三十: OLED 显示串口信息
  实验接脚: 0.96寸OLED液晶屏SDA接A4, SCL接A5
*/

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);

#define LOGO16_GLCD_HEIGHT 16
#define LOGO16_GLCD_WIDTH  16

void setup()
{
  Serial.begin(9600);
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.clearDisplay();
  Serial.println("OLED准备就绪");
  delay(1000);
}

void loop(){
  String inString = "";
  while (Serial.available() > 0) {
    char inChar = Serial.read();      //
    inString += (char)inChar;
    delay(10);
  }

  if (inString != ""){
    display.setTextSize(2);   //设置字体大小
    display.setTextColor(WHITE);  //设置字体颜色白色
    display.setCursor(0, 0); //设置字体的起始位置
    display.println(inString);  //显示输入数据
    display.display();  //显示信息
    Serial.print("串口输入=");
    Serial.println(inString);
    delay (1000);
    display.clearDisplay();
  }
}

【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
实验九十三: 0.96寸I2C IIC通信128*64显示器 OLED液晶屏模块
项目三十: OLED 显示串口信息
实验接脚: 0.96寸OLED液晶屏SDA接A4, SCL接A5

OLED 实时读取串口信息,可应用于诸多适用场合,方便人们在第一时间识别和处理一些信息(需要串口助手)

实验串口绘图器返回情况

在这里插入图片描述

【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
实验九十三: 0.96寸I2C IIC通信128*64显示器 OLED液晶屏模块
项目三十: OLED 显示串口信息
实验接脚: 0.96寸OLED液晶屏SDA接A4, SCL接A5

实验场景图

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/800579.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++ inline 内联函数

1.什么是内联函数 在函数声明或定义中&#xff0c;在函数的返回类型前加上C关键字inline&#xff0c;即将函数指定为内联函数。这样可以**解决一些频繁调用的简单函数大量消耗栈空间&#xff08;栈内存&#xff09;**的问题。关键字inline必须与函数定义放在一起才能使函数成为…

C++模拟实现queue

1.前言 queue 遵循的原则是先进先出&#xff0c;那到底是用list 还是 vector呢&#xff1f;其实都可以&#xff0c;但是严格来讲vector是不可以的&#xff0c;因为他头删的效率太低了。所以vs官方是不允许用vector的&#xff1a; 因为底层的pop用的是pop_front(), vector是没有…

【C刷题】矩阵相等判断与序列中删除指定的数字

目录 BC105-矩阵相等判断 方法1:两矩阵输入完毕后&#xff0c;进行比较 方法2:在接收过程中直接比较 BC98 - 序列中删除指定的数字 方法1:把要删除的元素改为0 方法2:打印不用删除的元素 方法3:定义两个下标 i 和 j(动图演示) 此篇文章是关于牛客网刷题的做题思路和代码…

Java版知识付费平台免费搭建 前后端分离实现知识付费平台

提供职业教育、企业培训、知识付费系统搭建服务。系统功能包含&#xff1a;录播课、直播课、题库、营销、公司组织架构、员工入职培训等。 提供私有化部署&#xff0c;免费售后&#xff0c;专业技术指导&#xff0c;支持PC、APP、H5、小程序多终端同步&#xff0c;支持二次开发…

大模型开发(十一):Chat Completions模型的Function calling功能详解

全文共5000余字&#xff0c;预计阅读时间约15~25分钟 | 满满干货(附代码案例)&#xff0c;建议收藏&#xff01; 本文目标&#xff1a;介绍Chat Completions模型的Function calling参数和使用方法&#xff0c;并完整的实现一个Chat模型的Function calling功能案例。 代码下载地…

字节跳动 EB 级 Iceberg 数据湖的机器学习应用与优化

深度学习的模型规模越来越庞大&#xff0c;其训练数据量级也成倍增长&#xff0c;这对海量训练数据的存储方案也提出了更高的要求&#xff1a;怎样更高性能地读取训练样本、不使数据读取成为模型训练的瓶颈&#xff0c;怎样更高效地支持特征工程、更便捷地增删和回填特征。本文…

Java IO,BIO、NIO、AIO

操作系统中的 I/O 以上是 Java 对操作系统的各种 IO 模型的封装&#xff0c;【文件的输入、输出】在文件处理时&#xff0c;其实依赖操作系统层面的 IO 操作实现的。【把磁盘的数据读到内存种】操作系统中的 IO 有 5 种&#xff1a; 阻塞、 非阻塞、【轮询】 异步、 IO复…

STM32的SDIO功能框图及SDIO结构体

目录 STM32的SDIO功能框图及SDIO结构体 STM32的SDIO功能框图 SDIO适配器 命令路径 CPSM状态机 数据路径 DPSM状态机 数据FIFO 适配器寄存器 SDIO相关结构体 SDIO初始化结构体 SDIO命令初始化结构体 SDIO数据初始化结构体 STM32的SDIO功能框图及SDIO结构体 STM32的…

3d软件动物生活习性仿真互动教学有哪些优势

软体动物是一类广泛存在于海洋和淡水环境中的生物&#xff0c;其独特的形态和生活习性给学生带来了新奇和有趣的学习主题&#xff0c;为了方便相关专业学科日常授课教学&#xff0c;web3d开发公司深圳华锐视点基于真实的软体动物&#xff0c;制作软体动物3D虚拟展示系统&#x…

发点实用的快捷键(mac

切换输入法&#xff1a;ctrlspace /ctrloptionspace&#xff08;更快捷 切换网页&#xff1a; shifttab 切换应用界面&#xff1a;alttab 关闭页面&#xff1a;altw 搜索&#xff1a;altspace 展示mac隐藏文件&#xff1a; Commangshift . (点) 以下是一些浏览器快捷键&am…

【初阶C语言】认识和使用函数

1. 函数是什么 2. 库函数 3. 自定义函数 4. 函数参数 5. 函数调用 6. 函数的嵌套调用和链式访问 7. 函数的声明和定义 8. 函数递归 一、什么是函数 在数学中有函数&#xff0c;在C语言中也有函数&#xff0c;我们直接先给出一个定义&#xff1a; 在基维百科中函数被定义为子程…

MyBatisPlus入门到精通-1

MyBatisPlus(简称MP) 这篇博客主要讲解用MyBatisPlus进行三层架构中Dao层的开发 以这个为目的来进行我们的学习 我们会先通过一个概述和入门案例进行快速上手 之后我们再通过对我们原先的案列的问题进行分析 来进一步了解MP操作数据库的知识 快速入门 MP简介 MP是国人开发的…

HEVC并行处理技术介绍

h265 相比 h264 的复杂度 复杂度体现 ○ h265 帧内预测模式增多&#xff0c;h265 包含角度预测、DC 预测、平面模式等 35 种预测模式&#xff0c;远超 h264 的 17 种模式&#xff0c;帧内模式选择的复杂度大大增加&#xff1b; ○ h265 的区域划分方式更加多样化&#xff0c;提…

聊聊STM32串口通讯的话题

STM32 微控制器系列提供了多个串口模块&#xff0c;用于实现串口通讯。其中&#xff0c;STM32HAL 库中的 UART 驱动模块提供了一套方便易用的函数接口&#xff0c;可以用来配置和操作串口。 串口通讯是一种常见的数据传输方式&#xff0c;可以实现微控制器与外部设备或其他微控…

Jetbrains 2023.2教程

IDEA 2023.2 激活演示 Pycharm 2023.2 激活演示 WebStorm 2023.2 激活演示 Clion 2023.2 激活演示 DataGrip 2023.2 PhpStorm 2023.1.4 激活演示&#xff08;2023.2尚未发布&#xff09; RubyMine 2023.2 激活演示 获取方式 仔细看每一个工具演示的图片 本文由 mdnice …

深度探索 Elasticsearch 8.X:function_score 参数解读与实战案例分析

在 Elasticsearch 中&#xff0c;function_score 可以让我们在查询的同时对搜索结果进行自定义评分。 function_score 提供了一系列的参数和函数让我们可以根据需求灵活地进行设置。 近期有同学反馈&#xff0c;function_score 的相关参数不好理解&#xff0c;本文将深入探讨 f…

2023软件设计师中级备考经验分享(文中有资料链接分享)

先摊结论吧&#xff0c;软考中级设计师备考只是备考半个月&#xff08;期间还摆烂了几天&#xff09;&#xff0c;然而成绩如下&#xff1a; 我自己都没想到会这么好的成绩。。。 上午题&#xff1a;推荐把软考通APP里的历年真题刷3-4遍&#xff0c;直接刷真题&#xff0c;然后…

TimescaleDB多节点功能概述

如果您有更大的pb级工作负载&#xff0c;则可能需要多个TimescaleDB实例。TimescaleDB多节点允许您运行和管理数据库集群&#xff0c;这可以为您提供更快的数据摄取&#xff0c;以及对大型工作负载响应更快、更高效的查询。 多节点架构 多节点TimescaleDB允许您将多个数据库连…

【学习笔记】视频检测方法调研

目录 1 引言2 方法2.1 视频目标跟踪2.1.1 生成式模型方法2.1.2 判别式模型方法2.1.2.1 基于相关滤波跟踪2.1.2.2 基于深度学习跟踪 2.2 视频异常检测2.2.1 基于重构方法2.2.2 基于预测方法2.2.3 基于分类方法2.2.4 基于回归方法 2.3 深度伪造人脸视频检测2.3.1 基于RNN时空融合…

UG NX二次开发(C++)-利用UFun函数获取曲面上等参数的点

文章目录 1、前言2、叶片的三维模型3、利用UFun函数获取曲面的三种方法3.1 利用UF_Modl来实现3.2 利用UF_Point来实现3.2 利用UF_So来实现4、结果展示1、前言 在多轴加工过程中(尤其是薄壁零件),由于需要根据工件表面的几何信息以获取切触点,然后生成刀位轨迹,本文以叶片…