单片机类库封装
轻语言单片机的类库与 Arduino Library 结构基本一致,封装前需要您掌握基础的 C/C++ 编程知识。
内置类库参考
安装包里面已经内置了常用传感器的扩展库,路径位于:
VcnStudio安装目录/sdk/mcu/components/esp32
上方路径指向的文件夹中,每个子文件夹表示一个独立类库。
每个类库的文件夹结构都是相同的,具体含义请参考下方结构说明。
类库结构
轻语言单片机类库采用 文件夹/文件
结构,非独立类库文件,因为方便修改类库源代码、测试,轻语言类库文件结构为:
类库名称文件夹/
├── static/
│ ├── libs/
│ └── └── C|C++|Arduino类库(只能为英文、拼音名称文件夹)
└── libtree.xml
-
static
-
静态资源文件夹、在该文件夹中含有一个 libs 文件夹, libs 文件夹中存放封装好的 C 或 Arduino 标准库。
-
该文件夹中目前不能储存其它数据,只能在libs中存放原始C/C++库。
-
-
libtree.xml
- 类库配置文件,该文件用于配置类库的名称、描述、以及类库组件的函数。
配置文件 libtree.xml 详解
轻语言单片机类库封装的本质是将原生 Arduino 库或 C++ 写的库翻译成中文。
因此如果您已经有了一个 Arduino 的库,那么只需要在配置文件中添加其中文函数即可,如果没有 Arduino 库需要先将需要的功能或者传感器代码封装成 Arduino 库。
以安装包内置的 DHT22
温湿度传感器库为例,该库中的配置文档内容为:
<?xml version="1.0" encoding="utf-8"?>
<package>
<library
name="DHT22"
author="官方"
package=""
description="DHT22温度传感器是一种结合了温度和湿度测量功能的数字传感器,广泛用于各种环境监测和控制系统中。 它通过数字信号输出测量结果,具有高精度、快速响应和稳定性,适用于物联网应用。"
type="component">
<component
name="DHT22"
en="DHT22"
include="DHT22.h"
comment="本库封装自开源库 https://github.com/dvarrel/DHT22 可用于在单片机中读取基于DHT22系列的温湿度传感器相关数据。">
<construct name="DHT22" args="(数据引脚 为 整数型)" comment="使用指定的接收数据的引脚构造一个DHT22对象。" />
<method name="取原始数据值" en="getRawData" args="()" return="整数型" comment="获取传感器原始数据(40位)。返回类型:uint64_t 类型的变量,包含40位的原始数据。" />
<method name="取原始文本数据值" en="getRawStrData" args="()" return="文本型" comment="获取传感器原始数据(40位)并转换为字符串;包含40位的原始数据,并在左侧补零。" />
<method name="取湿度百分比" en="getHumidity" args="()" return="单精度小数" comment="获取湿度百分比(%rH)、单位为百分比(%rH)。" />
<method name="取温度" en="getTemperature" args="()" return="单精度小数" comment="获取温度值、单位为摄氏度(°C)。" />
<method name="取错误代码" en="getLastError" args="()" return="整数型" comment="获取上次读取传感器时的错误代码。" />
<method name="取调试信息" en="debug" args="()" return="文本型" comment="获取调试信息,包括定时信息、40位数据和计算值。" />
</component>
</library>
</package>
上方文档中,library 节点中的属性含义分别为:
-
name 表示类库名称
-
author 表示类库作者
-
package 单片机暂时不需要设置包名,但需要保留设置为空
-
description 描述类库的功能
-
type 类库类型,默认为:component 不可视组件、后期可能会支持可视组件。
library 节点中存放当前类库中的组件,可以含有多个组件:
组件节点(不可视)必须使用 component 标签名,component 节点中的属性含义为:
-
name 组件名称、一般对应组件的中文名称,如果没有合适的中文名称使用类名作为组件名称也是可以的,这个名称主要是在使用时,定义组件类型变量时使用。
-
en 组件对应的原生英文名称
-
include 使用这个组件时需要导入的头文件
-
comment 组件注释、描述
component 节点即表示一个组件,其子节点表示组件的方法和构造函数,componen 节点中支持的标签有:
-
construct 表示构造函数
-
name 构造函数名称,必须为原生类构造函数
-
args 表示构造函数参数、如果没有参数则设置值为空字符串
-
comment 构造函数注释
-
-
method 表示函数方法
-
name 翻译后的中文函数名称
-
en 函数对应英文名称
-
args 函数参数、如果没有参数则设置值为空字符串
-
return 函数返回值
-
comment 函数注释说明
-
核心封装逻辑
将英文版本的库翻译成中文,核心逻辑是通过在配置文件中配置 component、 method 等节点实现将原库中使用 public 修饰的英文函数翻译成中文。
#ifndef _DHT22_H
#define _DHT22_H
#include "Arduino.h"
class DHT22{
public:
enum error{
OK,
ERR_TIMING_80,
ERR_TIMING_50,
ERR_TIMING_BITS,
ERR_CRC
};
private:
uint8_t _pinData;
uint32_t _timer;
uint64_t _rawData;
uint16_t _h16bits;
uint16_t _t16bits;
uint8_t _crc8bits;
uint8_t _timing80L = 80;
uint8_t _timing80H = 80;
uint8_t _timing50 = 50;
uint8_t _timingBit0 = 27; //specs for AM2303
uint8_t _timingBit1 = 70; //specs for AM2303
bool _firstStart=true;
error _lastError;
const uint8_t T = 30;
const uint16_t cSamplingTime = 2100; // ms : dht22 sampling rate ~0.5Hz
public:
DHT22(uint8_t pinData){
_pinData = pinData;
};
/** @return 40bits of data sensor : h16 + t16 + crc8**/
uint64_t getRawData();
/** @return 40bits in a String ("0" left include)**/
String getRawStrData();
/** @return humidity %rH **/
float getHumidity();
/** @return temperature in °C **/
float getTemperature();
/** @return code from last readSensor() request **/
uint8_t getLastError();
/** @return String with timings, 40bits, and calculate values**/
String debug();
private:
/** @brief measure timings of sensor*/
void measureTimings();
/**
*@brief read the 40bits sensor data
*@return 0 if no error, num of error instead
*/
uint8_t readSensor();
/** @brief compute checksum of h & t data
* @return true if checksum==crc**/
bool computeCRC();
};
#endif
上方代码中 public 修饰的函数即为我们要封装翻译成中文的函数。
例如构造函数:
DHT22(uint8_t pinData){
_pinData = pinData;
};
对应的配置节点为:
<construct name="DHT22" args="(数据引脚 为 整数型)" comment="使用指定的接收数据的引脚构造一个DHT22对象。" />
其它函数:
/** @return 40bits of data sensor : h16 + t16 + crc8**/
uint64_t getRawData();
对应配置节点为:
<method name="取原始数据值" en="getRawData" args="()" return="整数型" comment="获取传感器原始数据(40位)。返回类型:uint64_t 类型的变量,包含40位的原始数据。" />
构造函数节点中,name 属性值为 英文类名。
函数节点中,name 属性值为中文函数名,en 为对应的英文函数名称。
封装方式
由于单片机的封装方式较为简单,因此在IDE中目前暂无单片机类库封装插件,因此只需要在安装包内置类库文件夹中,先复制一份类库,然后修改其名称为您要封装的类库名称。
然后删除其中原 C++ 库文件,以及相关文件。
然后根据规则修改配置文件即可。
使用组件
当组件封装好,打开IDE、如果类库配置文件无错误,在IDE的支持库窗口中就能看到封装的组件。
例如上方的温度组件,使用示例:
' 定义操作传感器的对象、构造函数中的参数为数据引脚、这里为 10
变量 dht22 为 DHT22(10)
事件 程序被启动()
初始化串口通信(115200)
调试输出("程序被启动")
结束 事件
函数 无限循环()
' 在循环中每隔 2 秒读取一次数据
变量 温度值 为 单精度小数
变量 湿度百分比 为 单精度小数
温度值 = dht22.取温度()
湿度百分比 = dht22.取湿度百分比()
调试打印("温度值:")
调试输出(温度值)
调试打印("湿度百分比:")
调试输出(湿度百分比)
如果(dht22.取错误代码() != dht22.OK)
调试打印("错误代码:")
调试输出(dht22.取错误代码())
结束 如果
延时(2000)
结束 函数
注意:单片机中使用组件时,不能使用
创建
关键字创建组件对象,只需要声明定义,如果组件存在构造函数,在定义声明变量对象的时候直接在类型后面通过括号设置参数值即可。
注意事项
-
大多数情况下,文件名与库中的类名应该是一致的,例如文件名称为:DHT22.cpp、DHT22.h,那么对应代码中的组件类名应该为:DHT22
-
如果代码中的类名与文件名称不一致,component 节点中的
en
属性的值应该设置为英文类名。同时 component 中的 construct 节点的构造函数 name 属性也必须设置为英文类名。 -
函数没有参数值时,args 的属性值留空即可,不可设置成:
无
或空
。 -
函数返回值针对不同格式的整数类型、配置文档中应该全部为
整数型
,如果函数返回String
类型,请优先将其封装成 Arduino 中的 String 类型再返回,String 类型的值在配置文档中为文本型