39、构建 TouchScreen 库:从代码实现到应用示例

构建 TouchScreen 库:从代码实现到应用示例

1. 库头文件的创建

在创建 TouchScreen 库时,首先要处理的是头文件 TouchScreen.h 。在这个头文件里,我们需要定义类和相关的方法与变量。

1.1 类的基本结构

#ifndef TouchScreen_h
#define TouchScreen_h

#include "WProgram.h"

class TouchScreen
{
  public:
    TouchScreen(byte pinX1, byte pinX2, byte pinY1, byte pinY2);
    void read(int *coordinates);
  private:
    byte _pinX1;  // Analog pin connected to screen line X1
    byte _pinX2;  // Analog pin connected to screen line X2
    byte _pinY1;  // Analog pin connected to screen line Y1
    byte _pinY2;  // Analog pin connected to screen line Y2
    int _xVal;    // Current X coordinate
    int _yVal;    // Current Y coordinate
};

#endif

这里,我们把构造函数 TouchScreen 放在了 public 部分,因为构造函数需要被外部程序调用。而 read 方法同样是 public 的,这样使用该库的程序就能调用它来获取触摸屏的坐标。 private 变量前面带有下划线,这是一种常见的约定,用于提示这些变量是对象内部的私有变量。

1.2 方法和变量的作用

  • 构造函数 :接收四个参数,分别对应触摸屏的四个引脚,用于初始化对象。
  • read 方法 :用于读取触摸屏当前被触摸位置的 X 和 Y 坐标。
  • 私有变量 :存储引脚信息和当前的坐标值。

2. 库类文件的编写

接下来,我们要创建 TouchScreen.cpp 文件,用于实现头文件中声明的公共方法。

2.1 包含头文件

#include "TouchScreen.h"
#define DIGITAL_OFFSET 14

通过 #include "TouchScreen.h" 包含头文件, #define DIGITAL_OFFSET 14 用于处理引脚的数字编号。

2.2 实现构造函数

TouchScreen::TouchScreen(int pinX1, int pinX2, int pinY1, int pinY2)
{
  _pinX1 = pinX1;
  _pinX2 = pinX2;
  _pinY1 = pinY1;
  _pinY2 = pinY2;
}

构造函数的作用是将传入的引脚值存储到对应的私有变量中,这样使用该库的程序就能自定义触摸屏的引脚连接。

2.3 实现 read 方法

void TouchScreen::read(int *coordinates)
{
  pinMode( _pinX2 + DIGITAL_OFFSET, INPUT );
  pinMode( _pinX1 + DIGITAL_OFFSET, INPUT );
  pinMode( _pinY1 + DIGITAL_OFFSET, OUTPUT );
  digitalWrite( _pinY1 + DIGITAL_OFFSET, LOW );
  pinMode( _pinY2 + DIGITAL_OFFSET, OUTPUT );
  digitalWrite( _pinY2 + DIGITAL_OFFSET, HIGH );
  _xVal = analogRead( _pinX2 );

  pinMode( _pinY1 + DIGITAL_OFFSET, INPUT );
  pinMode( _pinY2 + DIGITAL_OFFSET, INPUT );
  pinMode( _pinX2 + DIGITAL_OFFSET, OUTPUT );
  digitalWrite( _pinX2 + DIGITAL_OFFSET, LOW );
  pinMode( _pinX1 + DIGITAL_OFFSET, OUTPUT );
  digitalWrite( _pinX1 + DIGITAL_OFFSET, HIGH );
  _yVal = analogRead( _pinY1 );

  coordinates[0] = _xVal;
  coordinates[1] = _yVal;
}

read 方法的主要功能是读取触摸屏的 X 和 Y 坐标,并将结果存储在传入的数组中。由于 C++ 方法不能直接返回数组,所以我们通过传入数组指针的方式来传递结果。

3. 示例草图的创建

为了验证 TouchScreen 库的功能,我们创建一个简单的 Arduino 草图 ReadTouchscreen

3.1 草图代码

#include <TouchScreen.h>

TouchScreen ts(3, 1, 0, 2);

void setup()
{
  Serial.begin(38400);
}

void loop()
{
  int coords[2];
  ts.read(coords);
  Serial.print(coords[0]);
  Serial.print(",");
  Serial.println(coords[1]);
  delay (1000);
}

3.2 代码解释

  • #include <TouchScreen.h> :引入 TouchScreen 库。
  • TouchScreen ts(3, 1, 0, 2) :创建 TouchScreen 类的对象 ts ,并传入触摸屏的引脚信息。
  • setup() 函数:初始化串口通信。
  • loop() 函数:循环读取触摸屏的坐标,并通过串口输出。

下面是创建 TouchScreen 库的流程 mermaid 图:

graph TD;
    A[创建 TouchScreen.h 头文件] --> B[定义类和方法变量];
    B --> C[创建 TouchScreen.cpp 文件];
    C --> D[包含头文件];
    D --> E[实现构造函数];
    E --> F[实现 read 方法];
    F --> G[创建示例草图 ReadTouchscreen];
    G --> H[包含库文件并创建对象];
    H --> I[初始化串口并循环读取坐标];

4. 支持文件的添加

为了让库更加完善,我们还需要添加一些支持文件。

4.1 README 文件

创建一个 README 文件,在其中包含库的相关信息、版权声明和许可信息,这有助于其他开发者更好地理解和使用该库。

4.2 关键字文件

创建 keywords.txt 文件,用于指定语法高亮。示例内容如下:

TouchScreen    KEYWORD1
Read           KEYWORD2

这样,Arduino IDE 就能正确地对类和方法进行语法高亮显示。

4.3 平台特定的变化

由于不同的 Arduino 型号在引脚编号系统上可能存在差异,为了让 TouchScreen 库能在不同型号上通用,我们需要进行一些调整。

4.3.1 问题分析

在大多数 Arduino 型号中,模拟引脚 0 - 5 可以作为数字引脚 14 - 19 使用,我们通过 DIGITAL_OFFSET 来处理这种转换。但 Arduino Mega 的引脚编号系统不同,模拟引脚从 54 开始。

4.3.2 解决方案
#if defined(__AVR_ATmega1280__)
  #define DIGITAL_OFFSET 54
#else
  #define DIGITAL_OFFSET 14
#endif

通过这种方式,库就能在普通 Arduino 型号和 Mega 型号上都能正常工作。

以下是不同 Arduino 型号引脚编号处理的表格:
| Arduino 型号 | 模拟引脚起始编号 | 数字引脚对应关系 | DIGITAL_OFFSET 值 |
| ---- | ---- | ---- | ---- |
| 普通型号 | 0 | 模拟引脚 + 14 = 数字引脚 | 14 |
| Mega 型号 | 54 | 模拟引脚 = 数字引脚 | 54 |

综上所述,通过以上步骤,我们成功创建了 TouchScreen 库,并通过示例草图验证了其功能。同时,添加支持文件和处理平台特定变化,让库更加完善和通用。

5. 库的使用与注意事项

5.1 库的使用步骤

使用 TouchScreen 库时,可按照以下步骤操作:
1. 包含库文件 :在 Arduino 草图中,使用 #include <TouchScreen.h> 来引入库。
2. 创建对象 :使用 TouchScreen 类创建对象,并传入触摸屏的引脚信息,如 TouchScreen ts(3, 1, 0, 2);
3. 初始化串口(可选) :如果需要将读取的坐标信息输出,可在 setup() 函数中初始化串口,如 Serial.begin(38400);
4. 读取坐标 :在 loop() 函数中,声明一个数组用于存储坐标,调用对象的 read() 方法读取坐标,并将结果存储在数组中,如 int coords[2]; ts.read(coords);
5. 处理结果 :对读取到的坐标进行处理,如通过串口输出, Serial.print(coords[0]); Serial.print(","); Serial.println(coords[1]);

5.2 注意事项

  • 引脚连接 :在创建 TouchScreen 对象时,要确保传入的引脚信息与实际的触摸屏连接一致。
  • 数组传递 :由于 read() 方法通过数组指针传递结果,调用时要确保传入的数组有足够的空间来存储坐标。
  • 平台差异 :不同的 Arduino 型号可能有不同的引脚编号系统,要根据实际情况调整 DIGITAL_OFFSET 的值。

下面是使用 TouchScreen 库的操作步骤流程图:

graph TD;
    A[包含 TouchScreen.h 库文件] --> B[创建 TouchScreen 对象并传入引脚信息];
    B --> C{是否需要输出坐标};
    C -- 是 --> D[初始化串口通信];
    C -- 否 --> E[继续下一步];
    D --> E;
    E --> F[在 loop 函数中声明坐标数组];
    F --> G[调用 read 方法读取坐标];
    G --> H[处理读取到的坐标];

6. 代码示例扩展

6.1 增加错误处理

在实际应用中,可能会遇到读取坐标失败的情况。我们可以在 read() 方法中增加错误处理逻辑。

void TouchScreen::read(int *coordinates)
{
  // 尝试读取 X 坐标
  pinMode( _pinX2 + DIGITAL_OFFSET, INPUT );
  pinMode( _pinX1 + DIGITAL_OFFSET, INPUT );
  pinMode( _pinY1 + DIGITAL_OFFSET, OUTPUT );
  digitalWrite( _pinY1 + DIGITAL_OFFSET, LOW );
  pinMode( _pinY2 + DIGITAL_OFFSET, OUTPUT );
  digitalWrite( _pinY2 + DIGITAL_OFFSET, HIGH );
  _xVal = analogRead( _pinX2 );

  // 检查 X 坐标是否有效
  if (_xVal < 0 || _xVal > 1023) {
    // 处理错误,可设置默认值或返回错误码
    _xVal = 0;
  }

  // 尝试读取 Y 坐标
  pinMode( _pinY1 + DIGITAL_OFFSET, INPUT );
  pinMode( _pinY2 + DIGITAL_OFFSET, INPUT );
  pinMode( _pinX2 + DIGITAL_OFFSET, OUTPUT );
  digitalWrite( _pinX2 + DIGITAL_OFFSET, LOW );
  pinMode( _pinX1 + DIGITAL_OFFSET, OUTPUT );
  digitalWrite( _pinX1 + DIGITAL_OFFSET, HIGH );
  _yVal = analogRead( _pinY1 );

  // 检查 Y 坐标是否有效
  if (_yVal < 0 || _yVal > 1023) {
    // 处理错误,可设置默认值或返回错误码
    _yVal = 0;
  }

  coordinates[0] = _xVal;
  coordinates[1] = _yVal;
}

6.2 优化读取频率

在示例草图中,使用 delay(1000); 来控制读取频率。如果需要更高的读取频率,可以调整延迟时间或采用其他方式。

void loop()
{
  int coords[2];
  ts.read(coords);
  Serial.print(coords[0]);
  Serial.print(",");
  Serial.println(coords[1]);
  // 调整延迟时间
  delay (100); 
}

6.3 与其他功能结合

可以将 TouchScreen 库与其他功能结合,如控制 LED 灯的亮灭。

#include <TouchScreen.h>

TouchScreen ts(3, 1, 0, 2);
const int ledPin = 13;

void setup()
{
  Serial.begin(38400);
  pinMode(ledPin, OUTPUT);
}

void loop()
{
  int coords[2];
  ts.read(coords);
  Serial.print(coords[0]);
  Serial.print(",");
  Serial.println(coords[1]);

  // 根据坐标控制 LED 灯
  if (coords[0] > 500) {
    digitalWrite(ledPin, HIGH);
  } else {
    digitalWrite(ledPin, LOW);
  }

  delay (1000);
}

7. 总结

通过本文的介绍,我们详细了解了 TouchScreen 库的创建过程,包括头文件的定义、类文件的实现、示例草图的编写以及支持文件的添加。同时,我们还探讨了库的使用方法、注意事项以及代码示例的扩展。

在实际应用中,可根据具体需求对库进行进一步的优化和扩展,如增加更多的功能方法、优化错误处理逻辑等。通过合理使用 TouchScreen 库,可以方便地实现触摸屏的坐标读取功能,为 Arduino 项目增添更多的交互性。

以下是创建和使用 TouchScreen 库的关键步骤总结表格:
| 步骤 | 操作内容 | 代码示例 |
| ---- | ---- | ---- |
| 创建头文件 | 定义类和方法变量 | class TouchScreen { ... } |
| 创建类文件 | 实现构造函数和 read 方法 | TouchScreen::TouchScreen(...) { ... } |
| 创建示例草图 | 包含库文件,创建对象,读取坐标 | #include <TouchScreen.h> TouchScreen ts(3, 1, 0, 2); ... |
| 添加支持文件 | 创建 README keywords.txt 文件 | TouchScreen KEYWORD1 |
| 处理平台差异 | 根据不同 Arduino 型号调整 DIGITAL_OFFSET | #if defined(__AVR_ATmega1280__) #define DIGITAL_OFFSET 54 ... |
| 使用库 | 按照步骤包含库、创建对象、读取坐标 | #include <TouchScreen.h> TouchScreen ts(3, 1, 0, 2); ts.read(coords); |

希望本文能帮助你更好地理解和使用 TouchScreen 库,在 Arduino 项目中实现触摸屏的坐标读取功能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值