风筝
发表于: 2022-11-4 10:25:59 | 显示全部楼层

是否想在您的ESP8266项目中显示传感器读数,而无需通过串口输出?I2C LCD显示屏可能对您来说是一个更好的选择!它仅需要两个GPIO引脚,也可以与其他I2C设备共享。


硬件概述

常见的I2C LCD显示屏由基于HD44780的字符LCD显示和I2C LCD适配器组成。让我们一一认识他们。


字符LCD显示屏

如名所示,这些LCD是仅显示文本/字符的理想选择。例如,16×2字符LCD具有LED背光,可以显示32个ASCII字符,分别有16个字符的两行。

Character-LCD-Internal-Pixel-Grid-Structure.jpg


如果仔细观察,您会看到显示屏上每个字符的微小矩形和组成字符的像素。这些矩形中的每一个都是5×8像素的网格。


I2C LCD适配器

适配器的核心是8位I/O扩展器芯片 -  PCF8574。该芯片将I2C数据从ESP8266转换为LCD显示所需的并行数据。

适配器电路板上还配备了一个小的电位器,可以对显示器的对比度进行很好的调整。

I2C-LCD-Adapter-Hardware-Overview.jpg


此外,板上有一个跳线,可以为背光提供电源。为了控制背光的强度,您可以卸下跳线并将外部电压施加到标记为LED的插头引脚。


LCD的I2C地址

如果您在同一I2C总线上使用多个设备,则可能需要为LCD适配器设置其他I2C地址,以免与另一台I2C设备冲突。


为此,适配器有三个焊接跳线(A0、A1和A2)或焊盘。这些中的每一个都用于编码地址。如果跳线用一堆焊料短短,则设置地址。


这里的重要一点是,几家公司生产了相同的PCF8574芯片,TI德州仪器和NXP,仅举几例。 LCD的I2C地址取决于芯片制造商。


如果LCD使用的是德州仪器的PCF8574芯片:

根据德州仪器的数据手册,将三个地址选择位(A0、A1和A2)放置在7位I2C地址寄存器的末尾。

Texas-Instruments-PCF8574-I2C-Address-Register.jpg

由于有3个地址输入,可以采用2个状态,即高/低,因此我们可以创建8个不同的组合(地址)。


默认情况下,所有3个地址输入均使用板载的上拉电阻至高电平,从而使PCF8574默认I2C地址为0100111或0x27。


通过短路焊接跳线,地址输入被拉低。如果短路所有三个跳线,则地址为0x20。所有可能地点的范围从0x20到0x27。请参阅下面的图片。

I2C-LCD-Address-Selection-Jumper-Table-for-TI.jpg


如果LCD使用NXP的PCF8574芯片:

根据NXP半导体的数据手册,三个地址选择位(A0、A1和A2)也位于7位I2C地址寄存器的末尾。但是地址寄存器中的其他位是不同的。

NXP-Semiconductors-PCF8574-I2C-Address-Register.jpg

由于有3个地址输入,可以采用2个状态,即高/低,因此我们可以创建8个不同的组合(地址)。


默认情况下,所有3个地址输入均使用板载的上拉电阻至高电平,从而使PCF8574默认I2C地址为011111111或0x3f。


通过短路焊接跳线,地址输入被拉低。如果您要短路所有三个跳线,则地址为0x38。所有可能地址的范围从0x38到0x3F。请参阅下面的图片。

I2C-LCD-Address-Selection-Jumper-Table-for-NXP.jpg


I2C LCD显示引脚

I2C LCD只有4个将其连接到外界的引脚。连接如下:

I2C-LCD-Display-Pinout.jpg


●    GND是地引脚。将其连接到ESP8266的地。

●    VCC向模块和LCD提供电源。将其连接到ESP8266的VIN引脚或外部5V电源。

●    SDA是I2C数据引脚。将其连接到ESP8266的I2C数据引脚。

●    SCL是I2C时钟引脚。将其连接到ESP8266的I2C时钟引脚。


将I2C LCD显示屏接线到ESP8266

将I2C LCD连接到ESP8266非常容易,因为您只需要连接4个引脚即可。首先将VCC引脚连接到ESP8266上的VIN,然后将GND连接到地。


我们将使用ESP8266的默认I2C引脚(GPIO#4和GPIO#5)。将SDA连接到ESP8266的D2(GPIO#4)和SCL到ESP8266的D1(GPIO#5)。下图显示了如何将所有内容连接起来。

Wiring-I2C-LCD-Display-to-ESP8266.jpg


调整LCD对比度

接线后,您需要调整显示屏的对比度。在I2C模块上,您会找到一个电位器,可以用小螺丝刀旋转。


插入ESP8266的USB连接器以供电LCD。您会看到背光照亮。现在,当您在电位计上旋转旋钮时,您将开始看到第一行矩形。如果发生这种情况,恭喜!您的LCD工作正常。


完成此操作后,我们可以开始编程LCD。

跳转到指定楼层
风筝
发表于: 2022-11-4 10:44:40 | 显示全部楼层

库安装

要驱动I2C LCD显示屏,您必须首先安装一个名为LiquidCrystal_i2c的库。


要安装库导航到Sketch > Include Libraries > Manage Libraries… 等待库管理器下载库索引并更新已安装的库列表。

Manage-Libraries.jpg


输入LiquidCrystal筛选搜索结果。查找Frank de Brabander的Liquidcrystal I2C库。单击该条目,然后选择Install。

LiquidCrystal_I2C-Library-Installation.jpg


确定I2C地址

如前所述,您的LCD的I2C地址取决于制造商。如果您的LCD使用的是TI的PCF8574芯片,则其默认I2C地址为0x27。如果使用的是NXP半导体的PCF8574芯片,则其默认I2C地址为0x3F。


因此,您的LCD可能具有I2C地址0x27或0x3F。但是,建议您在使用LCD之前找出实际的I2C地址。幸运的是,有一种简单的方法可以做到这一点。以下是一个简单的I2C扫描仪草图,可扫描您的I2C总线并返回所找到的每个I2C设备的地址。

  1. #include <Wire.h>

  2. void setup() {
  3.   Serial.begin (115200);

  4.   // Leonardo: wait for serial port to connect
  5.   while (!Serial)
  6.     {
  7.     }

  8.   Serial.println ();
  9.   Serial.println ("I2C scanner. Scanning ...");
  10.   byte count = 0;
  11.   
  12.   Wire.begin();
  13.   for (byte i = 8; i < 120; i++)
  14.   {
  15.     Wire.beginTransmission (i);
  16.     if (Wire.endTransmission () == 0)
  17.       {
  18.       Serial.print ("Found address: ");
  19.       Serial.print (i, DEC);
  20.       Serial.print (" (0x");
  21.       Serial.print (i, HEX);
  22.       Serial.println (")");
  23.       count++;
  24.       delay (1);  // maybe unneeded?
  25.       } // end of good response
  26.   } // end of for loop
  27.   Serial.println ("Done.");
  28.   Serial.print ("Found ");
  29.   Serial.print (count, DEC);
  30.   Serial.println (" device(s).");
  31. }  // end of setup

  32. void loop() {}
复制代码

上传代码后,以115200的波特率打开串口显示器,然后按ESP8266上的EN按钮。 您将看到I2C LCD显示屏的I2C地址。

I2C-Address-Scanner-Output.jpg


请记录此地址。 您将在以后的示例中需要它。


基本示例代码 -  Hello World!

以下测试草图将在LCD的第一行显示Hello World!以及在第二行显示LCD Tutorial。


但是,在继续上传草图之前,您需要进行少量更改以使其适合您。 您必须将LCD的I2C地址和显示屏的尺寸传递给LiquidCrystal_i2c类的构造函数。 如果您使用的是16×2字符LCD,请输入16和2; 如果您使用的是20×4 LCD,请输入20和4。

  1. // enter the I2C address and the dimensions of your LCD here
  2. LiquidCrystal_I2C lcd(0x3F, 16, 2);
复制代码

完成后,请上传该草图。

  1. #include <LiquidCrystal_I2C.h>

  2. LiquidCrystal_I2C lcd(0x3F,16,2);  // set the LCD address to 0x3F for a 16 chars and 2 line display

  3. void setup() {
  4.   lcd.init();
  5.   lcd.clear();         
  6.   lcd.backlight();      // Make sure backlight is on
  7.   
  8.   // Print a message on both lines of the LCD.
  9.   lcd.setCursor(2,0);   //Set cursor to character 2 on line 0
  10.   lcd.print("Hello world!");
  11.   
  12.   lcd.setCursor(2,1);   //Move cursor to character 2 on line 1
  13.   lcd.print("LCD Tutorial");
  14. }

  15. void loop() {
  16. }
复制代码

如果一切顺利,您应该在显示屏上看到如下结果。

Interfacing-16x2-character-LCD-with-Arduino-Hello-world-Program-output.jpg


代码说明

草图首先包括LiquidCrystal_i2c库。

  1. #include <LiquidCrystal_I2C.h>
复制代码

创建LiquidCrystal_i2c类的对象。该对象采用三个参数LiquidCrystal_I2C(address, columns, rows)。这是您需要输入您之前发现的地址以及显示屏的尺寸。

  1. LiquidCrystal_I2C lcd(0x3F,16,2);
复制代码

声明LiquidCrystal_i2c对象后,您可以访问特定于LCD的对象函数。


在setup()函数中,我们调用三个函数。第一个函数是init()。它初始化了LCD对象。第二个函数是clear()。该函数擦除了LCD屏幕,并将光标移至左上角。第三,Backlight()函数打开LCD背光。

  1. lcd.init();
  2. lcd.clear();         
  3. lcd.backlight();
复制代码

之后,我们通过调用函数lcd.setCursor(2, 0)将光标位置设置为第一行的第三列。光标位置指定您希望在LCD上显示新文本的位置。假定左上角是col = 0,行= 0。

  1. lcd.setCursor(2,0);
复制代码

接下来,通过调用print()函数来打印字符串Hello World!。

  1. lcd.print("Hello world!");
复制代码

同样,接下来的两行代码将光标位置设置为第二行的第三列,并在LCD上打印LCD Tutorial。

  1. lcd.setCursor(2,1);
  2. lcd.print("LCD Tutorial");
复制代码

库的其他有用函数

您可以与LiquidCrystal_i2c对象一起使用一些有用的函数。其中一些在下面列出:

●    lcd.home() 函数用于将光标放置在LCD的左上角,而无需清除显示屏。

●    lcd.blink() 函数在要编写下一个字符的位置处显示了5×8像素的闪烁块。

●    lcd.cursor() 在要编写下一个字符的位置显示下划线。

●    lcd.noblink() 函数关闭闪烁的LCD光标。

●    lcd.nocursor() 隐藏了LCD光标。

●    lcd.scrolldisplayright() 函数滚动显示右侧一个空间的显示内容。如果您希望文本连续滚动,则必须在循环中使用此函数。

●    lcd.scrolldisplayleft() 函数滚动显示左侧一个空间的显示内容。类似于上述函数,将其用于循环内部进行连续滚动。

回复

使用道具 举报

风筝
发表于: 2022-11-4 11:04:45 | 显示全部楼层

创建和显示自定义字符

如果您觉得在显示屏上显示的字符比较乏味,则可以为LCD创建自己的自定义字符和符号。当您要显示不属于标准ASCII字符集的字符时,它们非常有用。


如本教程前面所述,一个字符由5×8像素矩阵组成,因此您需要在该矩阵中定义自定义字符。您可以使用CreateChar()函数来定义字符。


要使用CreateChar(),首先设置了8个字节的数组。数组中的每个字节代表5×8矩阵中的一行字符。而字节中的0和1表示该行中的哪个像素应打开,哪个应该关闭。所有这些用户定义的字符都存储在LCD的cgram中。


自定义字符生成器

创建自定义字符从未如此简单!我们创建了一个称为自定义字符生成器的小应用程序。您能看到下面的蓝网格吗?您可以单击任何5×8像素以设置/清除该特定像素。当您单击时,字符的代码将在网格旁边生成。该代码可以直接在您的ESP8266草图中使用。


ESP8266示例代码

以下草图显示了如何创建自定义字符并在LCD上打印它们。

  1. #include <LiquidCrystal_I2C.h>

  2. LiquidCrystal_I2C lcd(0x3F, 16, 2);  // set the LCD address to 0x3F for a 16 chars and 2 line display

  3. // make some custom characters:
  4. byte Heart[8] = {
  5. 0b00000,
  6. 0b01010,
  7. 0b11111,
  8. 0b11111,
  9. 0b01110,
  10. 0b00100,
  11. 0b00000,
  12. 0b00000
  13. };

  14. byte Bell[8] = {
  15. 0b00100,
  16. 0b01110,
  17. 0b01110,
  18. 0b01110,
  19. 0b11111,
  20. 0b00000,
  21. 0b00100,
  22. 0b00000
  23. };


  24. byte Alien[8] = {
  25. 0b11111,
  26. 0b10101,
  27. 0b11111,
  28. 0b11111,
  29. 0b01110,
  30. 0b01010,
  31. 0b11011,
  32. 0b00000
  33. };

  34. byte Check[8] = {
  35. 0b00000,
  36. 0b00001,
  37. 0b00011,
  38. 0b10110,
  39. 0b11100,
  40. 0b01000,
  41. 0b00000,
  42. 0b00000
  43. };

  44. byte Speaker[8] = {
  45. 0b00001,
  46. 0b00011,
  47. 0b01111,
  48. 0b01111,
  49. 0b01111,
  50. 0b00011,
  51. 0b00001,
  52. 0b00000
  53. };


  54. byte Sound[8] = {
  55. 0b00001,
  56. 0b00011,
  57. 0b00101,
  58. 0b01001,
  59. 0b01001,
  60. 0b01011,
  61. 0b11011,
  62. 0b11000
  63. };


  64. byte Skull[8] = {
  65. 0b00000,
  66. 0b01110,
  67. 0b10101,
  68. 0b11011,
  69. 0b01110,
  70. 0b01110,
  71. 0b00000,
  72. 0b00000
  73. };

  74. byte Lock[8] = {
  75. 0b01110,
  76. 0b10001,
  77. 0b10001,
  78. 0b11111,
  79. 0b11011,
  80. 0b11011,
  81. 0b11111,
  82. 0b00000
  83. };

  84. void setup()
  85. {
  86.   lcd.init();
  87.   // Make sure backlight is on      
  88.   lcd.backlight();

  89.   // create a new characters
  90.   lcd.createChar(0, Heart);
  91.   lcd.createChar(1, Bell);
  92.   lcd.createChar(2, Alien);
  93.   lcd.createChar(3, Check);
  94.   lcd.createChar(4, Speaker);
  95.   lcd.createChar(5, Sound);
  96.   lcd.createChar(6, Skull);
  97.   lcd.createChar(7, Lock);

  98.   // Clears the LCD screen
  99.   lcd.clear();

  100.   // Print a message to the lcd.
  101.   lcd.print("Custom Character");
  102. }

  103. // Print All the custom characters
  104. void loop()
  105. {
  106.   lcd.setCursor(0, 1);
  107.   lcd.write(0);

  108.   lcd.setCursor(2, 1);
  109.   lcd.write(1);

  110.   lcd.setCursor(4, 1);
  111.   lcd.write(2);

  112.   lcd.setCursor(6, 1);
  113.   lcd.write(3);

  114.   lcd.setCursor(8, 1);
  115.   lcd.write(4);

  116.   lcd.setCursor(10, 1);
  117.   lcd.write(5);

  118.   lcd.setCursor(12, 1);
  119.   lcd.write(6);

  120.   lcd.setCursor(14, 1);
  121.   lcd.write(7);
  122. }
复制代码

您将在LCD上看到以下输出:

Interfacing-16x2-LCD-with-Arduino-Custom-Character-Generation-Program-output.jpg


代码说明

包含库并创建LCD对象后,定义了自定义字符数组。数组由8个字节组成,每个字节代表一个5×8矩阵的行。在此草图中,已经创建了八个自定义字符。


让我们以Heart[8]数组为例。您可以看到如何使用位(0和1)形成心脏形状。 0关闭像素,1打开像素。

  1. byte Heart[8] = {
  2. 0b00000,
  3. 0b01010,
  4. 0b11111,
  5. 0b11111,
  6. 0b01110,
  7. 0b00100,
  8. 0b00000,
  9. 0b00000
  10. };
复制代码

在setup()函数中,使用CreateChar()函数创建自定义字符。此函数需要两个参数。第一个参数是0到7之间的数字,可以保留8个受支持的自定义字符之一。第二个是数组的名称。

  1. lcd.createChar(0, Heart);
复制代码

接下来,在loop()函数中,要显示自定义字符,我们只需使用write()函数并传递我们之前保留的字符的序号。

  1. lcd.setCursor(0, 1);
  2. lcd.write(0);
复制代码

回复

使用道具 举报

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

本版积分规则

主题 54 | 回复: 107



手机版|

GMT+8, 2024-3-28 22:08 , Processed in 0.133519 second(s), 10 queries , Gzip On, MemCache On. Powered by Discuz! X3.5

YiBoard一板网 © 2015-2022 地址:河北省石家庄市长安区高营大街 ( 冀ICP备18020117号 )

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