竞价培训哪家比较好,优化快速排序,表情生成器在线制作gif,南昌seo排名方案前言#xff1a;本文为手把手教学 LinuxQT 的典型基础项目 AP3216C 的数据折线图显示#xff0c;项目使用正点原子的 IMX6ULL 阿尔法( Cortex-A7 系列)开发板。项目需要实现 AP3216C 在 Linux 系统下的驱动#xff0c;使用 QT 设计 AP3216C 的数据显示页面作为项目的应用层。…前言本文为手把手教学 LinuxQT 的典型基础项目 AP3216C 的数据折线图显示项目使用正点原子的 IMX6ULL 阿尔法( Cortex-A7 系列)开发板。项目需要实现 AP3216C 在 Linux 系统下的驱动使用 QT 设计 AP3216C 的数据显示页面作为项目的应用层。该项目属于非常简单的入门级项目核心目的是帮助大家熟悉 Linux 系统下的项目制作和工程研发过程。希望该项目可以帮助大家学会灵活使用 Linux 系统下的传感器开发文末有代码开源
硬件实物图 效果图 本项目核心是教学 LinuxQT 的工程研发流程如果专注于应用层工程学习的可以直接使用正点原子提供的 Linux 镜像文件。本教程是适配正点提供的系统镜像的可以直接使用 一、AP3216C概述
I.MX6U-ALPHA 开发板上通过 I2C1 连接了一个三合一环境传感器AP3216CAP3216C 是由敦南科技推出的一款传感器其支持环境光强度(ALS)、接近距离(PS)和红外线强度(IR)这三个环境参数检测。该芯片可以通过 IIC 接口与主控制相连并且支持中断AP3216C 的特点如下
①、I2C 接口快速模式下波特率可以到 400Kbit/S ②、多种工作模式选择ALS、PSIR、ALSPSIR、PD 等等。 ③、内建温度补偿电路。 ④、宽工作温度范围(-30°C ~ 80°C)。 ⑤、超小封装4.1mm x 2.4mm x 1.35mm ⑥、环境光传感器具有 16 位分辨率。 ⑦、接近传感器和红外传感器具有 10 位分辨率。 这个芯片设计的用途是给手机之类的使用比如返回当前环境光强以便调整屏幕亮度用户接听电话时将手机放置在耳边后自动关闭屏幕避免用户误触碰 。 二、基于Linux的AP3216C驱动
2.1 AP3216C的设备树
Linux 内核也将 I2C 驱动分为两部分
①、I2C 总线驱动I2C 总线驱动就是 SOC 的 I2C 控制器驱动也叫做 I2C 适配器驱动。 ②、I2C 设备驱动I2C 设备驱动就是针对具体的 I2C 设备而编写的驱动。 2.1.1 IO修改或添加
需要设置 UART4_TXD 和 UART4_RXD 这两个 IONXP 其实已经将他这两个 IO 设置好了打开 imx6ull-alientek-emmc.dts然后找到如下内容 pinctrl_i2c1: i2c1grp {fsl,pins MX6UL_PAD_UART4_TX_DATA__I2C1_SCL 0x4001b8b0MX6UL_PAD_UART4_RX_DATA__I2C1_SDA 0x4001b8b0 ;};
pinctrl_i2c1 就是 I2C1 的 IO 节点这里将 UART4_TXD 和 UART4_RXD 这两个 IO 分别复用为 I2C1_SCL 和 I2C1_SDA电气属性都设置为 0x4001b8b0。
2.1.2 在 i2c1 节点追加 ap3216c 子节点
AP3216C 是连接到 I2C1 上的因此需要在 i2c1 节点下添加 ap3216c 的设备子节点在 imx6ull-alientek-emmc.dts 文件中找到 i2c1 节点
i2c1 {clock-frequency 100000; /* 时钟频率 */pinctrl-names default;pinctrl-0 pinctrl_i2c1; /* pinctrl引脚电气属性 */status okay;ap3216c1e {compatible alientek,ap3216c;reg 0x1e;};
};
编译设备树传到开发板上重启。此时我们系统的I2C设备有 2.2 AP3216C 驱动编写
下面编写 AP3216 驱动
ap3216creg.h
#ifndef AP3216C_H
#define AP3216C_H
/***************************************************************
文件名 : ap3216creg.h
描述 : AP3216C寄存器地址描述头文件
***************************************************************/
#define AP3216C_ADDR 0X1E /* AP3216C器件地址 */
/* AP3316C寄存器 */
#define AP3216C_SYSTEMCONG 0x00 /* 配置寄存器 */
#define AP3216C_INTSTATUS 0X01 /* 中断状态寄存器 */
#define AP3216C_INTCLEAR 0X02 /* 中断清除寄存器 */
#define AP3216C_IRDATALOW 0x0A /* IR数据低字节 */
#define AP3216C_IRDATAHIGH 0x0B /* IR数据高字节 */
#define AP3216C_ALSDATALOW 0x0C /* ALS数据低字节 */
#define AP3216C_ALSDATAHIGH 0X0D /* ALS数据高字节 */
#define AP3216C_PSDATALOW 0X0E /* PS数据低字节 */
#define AP3216C_PSDATAHIGH 0X0F /* PS数据高字节 */
#endif
ap3216.c
#include linux/types.h
#include linux/kernel.h
#include linux/delay.h
#include linux/ide.h
#include linux/init.h
#include linux/module.h
#include linux/errno.h
#include linux/gpio.h
#include linux/cdev.h
#include linux/device.h
#include linux/of_gpio.h
#include linux/semaphore.h
#include linux/timer.h
#include linux/i2c.h
#include asm/mach/map.h
#include asm/uaccess.h
#include asm/io.h
#include ap3216creg.h#define AP3216C_CNT 1
#define AP3216C_NAME ap3216cstruct ap3216c_dev {dev_t devid; /* 设备号 */struct cdev cdev; /* cdev */struct class *class; /* 类 */struct device *device; /* 设备 */struct device_node *nd; /* 设备节点 */int major; /* 主设备号 */void *private_data; /* 私有数据 */unsigned short ir, als, ps; /* 三个光传感器数据 */
};static struct ap3216c_dev ap3216cdev;/** description : 从ap3216c读取多个寄存器数据* param - dev: ap3216c设备* param - reg: 要读取的寄存器首地址* param - val: 读取到的数据* param - len: 要读取的数据长度* return : 操作结果*/
static int ap3216c_read_regs(struct ap3216c_dev *dev, u8 reg, void *val, int len)
{int ret;struct i2c_msg msg[2];struct i2c_client *client (struct i2c_client *)dev-private_data;/* msg[0]为发送要读取的首地址 */msg[0].addr client-addr; /* ap3216c地址 */msg[0].flags 0; /* 标记为发送数据 */msg[0].buf reg; /* 读取的首地址 */msg[0].len 1; /* reg长度*//* msg[1]读取数据 */msg[1].addr client-addr; /* ap3216c地址 */msg[1].flags I2C_M_RD; /* 标记为读取数据*/msg[1].buf val; /* 读取数据缓冲区 */msg[1].len len; /* 要读取的数据长度*/ret i2c_transfer(client-adapter, msg, 2);if(ret 2) {ret 0;} else {printk(i2c rd failed%d reg%06x len%d\n,ret, reg, len);ret -EREMOTEIO;}return ret;
}/** description : 向ap3216c多个寄存器写入数据* param - dev: ap3216c设备* param - reg: 要写入的寄存器首地址* param - val: 要写入的数据缓冲区* param - len: 要写入的数据长度* return : 操作结果*/
static s32 ap3216c_write_regs(struct ap3216c_dev *dev, u8 reg, u8 *buf, u8 len)
{u8 b[256];struct i2c_msg msg;struct i2c_client *client (struct i2c_client *)dev-private_data;b[0] reg; /* 寄存器首地址 */memcpy(b[1],buf,len); /* 将要写入的数据拷贝到数组b里面 */msg.addr client-addr; /* ap3216c地址 */msg.flags 0; /* 标记为写数据 */msg.buf b; /* 要写入的数据缓冲区 */msg.len len 1; /* 要写入的数据长度 */return i2c_transfer(client-adapter, msg, 1);
}/** description : 读取ap3216c指定寄存器值读取一个寄存器* param - dev: ap3216c设备* param - reg: 要读取的寄存器* return : 读取到的寄存器值*/
static unsigned char ap3216c_read_reg(struct ap3216c_dev *dev, u8 reg)
{u8 data 0;ap3216c_read_regs(dev, reg, data, 1);return data;#if 0struct i2c_client *client (struct i2c_client *)dev-private_data;return i2c_smbus_read_byte_data(client, reg);
#endif
}/** description : 向ap3216c指定寄存器写入指定的值写一个寄存器* param - dev: ap3216c设备* param - reg: 要写的寄存器* param - data: 要写入的值* return : 无*/
static void ap3216c_write_reg(struct ap3216c_dev *dev, u8 reg, u8 data)
{u8 buf 0;buf data;ap3216c_write_regs(dev, reg, buf, 1);
}/** description : 读取AP3216C的数据读取原始数据包括ALS,PS和IR, 注意* : 如果同时打开ALS,IRPS的话两次数据读取的时间间隔要大于112.5ms* param - ir : ir数据* param - ps : ps数据* param - ps : als数据 * return : 无。*/
void ap3216c_readdata(struct ap3216c_dev *dev)
{unsigned char i 0;unsigned char buf[6];/* 循环读取所有传感器数据 */for(i 0; i 6; i) {buf[i] ap3216c_read_reg(dev, AP3216C_IRDATALOW i); }if(buf[0] 0X80) /* IR_OF位为1,则数据无效 */dev-ir 0; else /* 读取IR传感器的数据 */dev-ir ((unsigned short)buf[1] 2) | (buf[0] 0X03); dev-als ((unsigned short)buf[3] 8) | buf[2]; /* 读取ALS传感器的数据 */ if(buf[4] 0x40) /* IR_OF位为1,则数据无效 */dev-ps 0; else /* 读取PS传感器的数据 */dev-ps ((unsigned short)(buf[5] 0X3F) 4) | (buf[4] 0X0F);
}/** description : 打开设备* param - inode : 传递给驱动的inode* param - filp : 设备文件file结构体有个叫做private_data的成员变量* 一般在open的时候将private_data指向设备结构体。* return : 0 成功;其他 失败*/
static int ap3216c_open(struct inode *inode, struct file *filp)
{filp-private_data ap3216cdev;/* 初始化AP3216C */ap3216c_write_reg(ap3216cdev, AP3216C_SYSTEMCONG, 0x04); /* 复位AP3216C */mdelay(50); /* AP3216C复位最少10ms */ap3216c_write_reg(ap3216cdev, AP3216C_SYSTEMCONG, 0X03); /* 开启ALS、PSIR */return 0;
}/** description : 从设备读取数据 * param - filp : 要打开的设备文件(文件描述符)* param - buf : 返回给用户空间的数据缓冲区* param - cnt : 要读取的数据长度* param - offt : 相对于文件首地址的偏移* return : 读取的字节数如果为负值表示读取失败*/
static ssize_t ap3216c_read(struct file *filp, char __user *buf, size_t cnt, loff_t *off)
{short data[3];long err 0;struct ap3216c_dev *dev (struct ap3216c_dev *)filp-private_data;ap3216c_readdata(dev);data[0] dev-ir;data[1] dev-als;data[2] dev-ps;err copy_to_user(buf, data, sizeof(data));return 0;
}/** description : 关闭/释放设备* param - filp : 要关闭的设备文件(文件描述符)* return : 0 成功;其他 失败*/
static int ap3216c_release(struct inode *inode, struct file *filp)
{return 0;
}/* AP3216C操作函数 */
static const struct file_operations ap3216c_ops {.owner THIS_MODULE,.open ap3216c_open,.read ap3216c_read,.release ap3216c_release,
};/** description : i2c驱动的probe函数当驱动与* 设备匹配以后此函数就会执行* param - client : i2c设备* param - id : i2c设备ID* return : 0成功;其他负值,失败*/
static int ap3216c_probe(struct i2c_client *client, const struct i2c_device_id *id)
{/* 1、构建设备号 */if (ap3216cdev.major) {ap3216cdev.devid MKDEV(ap3216cdev.major, 0);register_chrdev_region(ap3216cdev.devid, AP3216C_CNT, AP3216C_NAME);} else {alloc_chrdev_region(ap3216cdev.devid, 0, AP3216C_CNT, AP3216C_NAME);ap3216cdev.major MAJOR(ap3216cdev.devid);}/* 2、注册设备 */cdev_init(ap3216cdev.cdev, ap3216c_ops);cdev_add(ap3216cdev.cdev, ap3216cdev.devid, AP3216C_CNT);/* 3、创建类 */ap3216cdev.class class_create(THIS_MODULE, AP3216C_NAME);if (IS_ERR(ap3216cdev.class)) {return PTR_ERR(ap3216cdev.class);}/* 4、创建设备 */ap3216cdev.device device_create(ap3216cdev.class, NULL, ap3216cdev.devid, NULL, AP3216C_NAME);if (IS_ERR(ap3216cdev.device)) {return PTR_ERR(ap3216cdev.device);}ap3216cdev.private_data client;return 0;
}/** description : i2c驱动的remove函数移除i2c驱动的时候此函数会执行* param - client : i2c设备* return : 0成功;其他负值,失败*/
static int ap3216c_remove(struct i2c_client *client)
{/* 删除设备 */cdev_del(ap3216cdev.cdev);unregister_chrdev_region(ap3216cdev.devid, AP3216C_CNT);/* 注销掉类和设备 */device_destroy(ap3216cdev.class, ap3216cdev.devid);class_destroy(ap3216cdev.class);return 0;
}/* 传统匹配方式ID列表 */
static const struct i2c_device_id ap3216c_id[] {{alientek,ap3216c, 0}, {}
};/* 设备树匹配列表 */
static const struct of_device_id ap3216c_of_match[] {{ .compatible alientek,ap3216c }, /* 需要和设备树下的保持一致 */{ /* Sentinel */ }
};/* i2c驱动结构体 */
static struct i2c_driver ap3216c_driver {.probe ap3216c_probe,.remove ap3216c_remove,.driver { /* 设备树的匹配方法 */.owner THIS_MODULE,.name ap3216c,.of_match_table ap3216c_of_match, },.id_table ap3216c_id, /* 传统驱动匹配方法 */
};/** description : 驱动入口函数* param : 无* return : 无*/
static int __init ap3216c_init(void)
{int ret 0;ret i2c_add_driver(ap3216c_driver);return ret;
}/** description : 驱动出口函数* param : 无* return : 无*/
static void __exit ap3216c_exit(void)
{i2c_del_driver(ap3216c_driver);
}/* module_i2c_driver(ap3216c_driver) */module_init(ap3216c_init);
module_exit(ap3216c_exit);
MODULE_LICENSE(GPL);
MODULE_AUTHOR(sneak);驱动详解可查阅注释及配合上诉的I2C驱动框架的框图及数据手册理解 我们通过 在终端输入 cat 指令可以读取到传感器的数值变量如下图 三、AP3216C的QT程序设计 IMX6ULL 的 QT-UI 的部署与实现需要依赖 QT 的很多依赖包各位读者可以根据实际情况进行移植。或者直接使用正点原子提供的系统镜像 3.1 Chart表制作
Qt Charts 很方便的绘制我们常见的曲线图、折线图、柱状图和饼状图等图表。不用自己花精力去了解第三方组件的使用了或者开发第三方组件。Qt 的帮助文档里已经有说明 Qt Charts 主要部件的使用方法。需要用到时我们可以查看 Qt 文档就可以了。
本项目中我们需要使用曲线图去展示 AP3216C 的 ALS 光强度属性。 使用一个 QSplineSeries 对象曲线一个 QChart图表一个 QChartView图表视图。首先我们创建坐 chart 图表然后创建两条坐标轴 axisX 与 axisY。将两条坐标轴添加到 chart 图表上再将 splineSeries 曲线与坐标轴连系起来。最后再将 chart 图表添加到 chartView 图表视图中。曲线上的数据由系统产生随机数使用定时器更新数据。 qtchart.pro
QT core gui chartsgreaterThan(QT_MAJOR_VERSION, 4): QT widgetsCONFIG c11# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES QT_DEPRECATED_WARNINGS# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES QT_DISABLE_DEPRECATED_BEFORE0x060000 # disables all the APIs deprecated before Qt 6.0.0SOURCES \main.cpp \mainwindow.cppHEADERS \mainwindow.hFORMS \mainwindow.ui# Default rules for deployment.
qnx: target.path /tmp/$${TARGET}/bin
else: unix:!android: target.path /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS target
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include QChartView
#include QSplineSeries
#include QScatterSeries
#include QDebug
#include QValueAxis
#include QTimer
#include QMainWindow/* 必需添加命名空间 */
QT_CHARTS_USE_NAMESPACEclass MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent nullptr);~MainWindow();private:/* 接收数据接口 */void receivedData(int);/* 数据最大个数 */int maxSize;/* x轴上的最大值 */int maxX;/* y轴上的最大值 */int maxY;/* y轴 */QValueAxis *axisY;/* x轴 */QValueAxis *axisX;/* QList int类型容器 */QListint data;/* QSplineSeries对象曲线*/QSplineSeries *splineSeries;/* QChart图表 */QChart *chart;/* 图表视图 */QChartView *chartView;/* 定时器 */QTimer *timer;private slots:void timerTimeOut();
};
#endif // MAINWINDOW_Hmainwindow.c
#include mainwindow.h
#include QDateTime
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent)
{/* 设置最显示位置与大小 */this-setGeometry(0, 0, 800, 480);/* 最大储存maxSize - 1个数据 */maxSize 51;/* x轴上的最大值 */maxX 5000;/* y轴最大值 */maxY 40;/* splineSeries曲线实例化折线用QLineSeries */splineSeries new QSplineSeries();/* 图表实例化 */chart new QChart();/* 图表视图实例化 */chartView new QChartView();/* 坐标轴 */axisY new QValueAxis();axisX new QValueAxis();/* 定时器 */timer new QTimer(this);/* legend译图例类型以绘图的颜色区分本例设置为隐藏 */chart-legend()-hide();/* chart设置标题 */chart-setTitle(实时动态曲线示例);/* 添加一条曲线splineSeries */chart-addSeries(splineSeries);/* 设置显示格式 */axisY-setLabelFormat(%i);/* y轴标题 */axisY-setTitleText(温度/℃);/* y轴标题位置设置坐标轴的方向 */chart-addAxis(axisY, Qt::AlignLeft);/* 设置y轴范围 */axisY-setRange(0, maxY);/* 将splineSeries附加于y轴上 */splineSeries-attachAxis(axisY);/* 设置显示格式 */axisX-setLabelFormat(%i);/* x轴标题 */axisX-setTitleText(时间/ms);/* x轴标题位置设置坐标轴的方向 */chart-addAxis(axisX, Qt::AlignBottom);/* 设置x轴范围 */axisX-setRange(0, maxX);/* 将splineSeries附加于x轴上 */splineSeries-attachAxis(axisX);/* 将图表的内容设置在图表视图上 */chartView-setChart(chart);/* 设置抗锯齿 */chartView-setRenderHint(QPainter::Antialiasing);/* 设置为图表视图为中心部件 */setCentralWidget(chartView);/* 定时200ms */timer-start(200);/* 信号槽连接 */connect(timer, SIGNAL(timeout()), this, SLOT(timerTimeOut()));/* 设置随机种子随机数初始化 */qsrand(time(NULL));
}MainWindow::~MainWindow()
{
}void MainWindow::timerTimeOut()
{/* 产生随机0~maxY之间的数据 */receivedData(qrand() % maxY );
}void MainWindow::receivedData(int value)
{/* 将数据添加到data中 */data.append(value);/* 当储存数据的个数大于最大值时把第一个数据删除 */while (data.size() maxSize) {/* 移除data中第一个数据 */data.removeFirst();}/* 先清空 */splineSeries-clear();/* 计算x轴上的点与点之间显示的间距 */int xSpace maxX / (maxSize - 1);/* 添加点xSpace * i 表示第i个点的x轴的位置 */for (int i 0; i data.size(); i) {splineSeries-append(xSpace * i, data.at(i));}
}
QT Chart表效果 3.2 AP3216C的数据读取
我们编写 QT 下的 AP3216C 的应用代码
ap3216c.h
#ifndef AP3216C_H
#define AP3216C_H#include QObject
#include QTimerclass Ap3216c : public QObject
{Q_OBJECTpublic:explicit Ap3216c(QObject *parent 0); //构造函数声明,explicit是一个C关键字用于修饰构造函数或函数以禁止隐式转换~Ap3216c(); //析构函数Q_INVOKABLE void setCapture(bool str); //Q_INVOKABLE是一个宏setCapture函数接受一个bool类型的参数str用于设置某个对象的捕获状态QString alsData(); //光强传感器 ALS: Ambient Light SensorQString psData(); //接近传感器 PS: Proximity SensorQString irData(); //红外 LED IR LEDprivate:QTimer *timer; //定时器timerQString alsdata; //光强数据QString psdata; //接近数据QString irdata; //红外数据QString readAlsData(); //读取Ais数据QString readPsData(); //读取Ps数据QString readIrData(); //读取IR数据Q_PROPERTY(QString alsData READ alsData NOTIFY ap3216cDataChanged)Q_PROPERTY(QString psData READ psData NOTIFY ap3216cDataChanged)Q_PROPERTY(QString irData READ irData NOTIFY ap3216cDataChanged)/*Q_PROPERTY这是一个宏用于在类中声明属性。*QStringalsData是属性的类型这里是一个QString类型的变量。*READ alsData这表示该属性可以通过alsData方法进行读取。*NOTIFY ap3216cDataChanged这表示当该属性发生变化时会发出ap3216cDataChanged信号*/public slots:void timer_timeout();signals:void ap3216cDataChanged();
};#endif // AP3216C_Hap3216c.c
#include ap3216c.h
#include stdio.h
#include string.h
#include sys/types.h
#include sys/stat.h
#include fcntl.h
#include unistd.h
#include QDebug/* AP3216C的构造函数 */
Ap3216c::Ap3216c(QObject *parent) : QObject (parent)
{timer new QTimer(); //定义一个定时器容器connect(timer, SIGNAL(timeout()),this,SLOT(timer_timeout())); //将超时信号与timer_timeout链接起来
}/* 析构函数 */
Ap3216c::~Ap3216c()
{}/* 超时函数 */
void Ap3216c::timer_timeout()
{alsdata readAlsData();psdata readPsData();irdata readIrData();emit ap3216cDataChanged(); //发送ap3216c数值变化信息
}QString Ap3216c::readIrData()
{char const *filename /sys/class/misc/ap3216c/ir;int err 0;int fd;char buf[10];fd open(filename,O_RDONLY); //只读模式打开文件if(fd 0){close(fd);return open file error!;}err read(fd,buf,sizeof(buf));if(err 0){close(fd);return read data error!;}close(fd);QString irValue buf;QStringList list irValue.split(\n); //将irValue按照换行符\n分割成一个字符串列表并将结果存储在list对象中return list[0];
}QString Ap3216c::readPsData()
{char const *filename /sys/class/misc/ap3216c/ps;int err 0;int fd;char buf[10];fd open(filename,O_RDONLY); //只读模式打开文件if(fd 0){close(fd);return open file error!;}err read(fd,buf,sizeof(buf));if(err 0){close(fd);return read data error!;}close(fd);QString irValue buf;QStringList list irValue.split(\n); //将irValue按照换行符\n分割成一个字符串列表并将结果存储在list对象中return list[0];
}QString Ap3216c::readAlsData()
{char const *filename /sys/class/misc/ap3216c/als;int err 0;int fd;char buf[10];fd open(filename,O_RDONLY); //只读模式打开文件if(fd 0){close(fd);return open file error!;}err read(fd,buf,sizeof(buf));if(err 0){close(fd);return read data error!;}close(fd);QString irValue buf;QStringList list irValue.split(\n); //将irValue按照换行符\n分割成一个字符串列表并将结果存储在list对象中return list[0];
}QString Ap3216c::alsData()
{return alsdata;
}QString Ap3216c::irData()
{return irdata;
}QString Ap3216c::psData()
{return psdata;
}void Ap3216c::setCapture(bool str)
{if(str)timer-start(500);elsetimer-stop();
} “Linux 系统之下一切皆文件”上述代码就是通过 C 语言库函数去读取系统下的属性数值信息来做到获取 AP3216C 的数据值 3.3 AP3216C与Chart联动 我们将 AP3216C 与 Chart 进行联动配合通过 Chart 实时读取显示 AP3216C 的 ALS 属性。 mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include QMainWindow
#include QVBoxLayout
#include QHBoxLayout
#include QComboBox
#include QPushButton
#include QVBoxLayout
#include QLabel
#include QScrollArea
#include QDebug
#include QChartView
#include QSplineSeries
#include QScatterSeries
#include QDebug
#include QValueAxis
#include ap3216c.h/* 必需添加命名空间 */
QT_CHARTS_USE_NAMESPACEclass MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent nullptr);~MainWindow();private:/* 主容器Widget也可以当作一种容器 */QWidget *mainWidget;/* 界面水平区域布局 */QHBoxLayout *hboxLayout[2];/* 界面右侧区域布局 */QVBoxLayout *vboxLayout[4];/* 界面右侧区域容器 */QWidget *rightWidget;/* 用一个 QLabel 对象用于显示字符串 */QLabel *labelString;/* 容器作用用于布局 */QWidget *widget[5];/* 标签文本 */QLabel *label[3];/* 数据标签 */QLabel *my_label[3];/* 数据最大个数 */int maxSize;/* x轴上的最大值 */int maxX;/* y轴上的最大值 */int maxY;/* y轴 */QValueAxis *axisY;/* x轴 */QValueAxis *axisX;/* QList int类型容器 */QListint data;/* QSplineSeries对象曲线*/QSplineSeries *splineSeries;/* QChart图表 */QChart *chart;/* 图表视图 */QChartView *chartView;/* ii2传感器类 */Ap3216c *ap3216c;/* 接收数据接口 */void receivedData(int);/* 布局初始化 */void layoutInit();private slots:/* 获取ap3216传感器数据 */void getAp3216cData();
};
#endif // MAINWINDOW_Hmainwindow.c
#include mainwindow.h
#include ui_mainwindow.h
#include QGuiApplication
#include QScreen
#include QDebugMainWindow::MainWindow(QWidget *parent): QMainWindow(parent)
{/* 布局初始化 */layoutInit();
}MainWindow::~MainWindow()
{
}/* 布局初始化 */
void MainWindow::layoutInit()
{/* 获取屏幕的分辨率Qt官方建议使用这* 种方法获取屏幕分辨率防上多屏设备导致对应不上* 注意这是获取整个桌面系统的分辨率*/QList QScreen * list_screen QGuiApplication::screens();/* 如果是ARM平台直接设置大小为屏幕的大小 */
#if __arm__/* 重设大小 */this-resize(list_screen.at(0)-geometry().width(),list_screen.at(0)-geometry().height());
#else/* 否则则设置主窗体大小为800x480 */this-resize(800,400);
#endif/* 实例化与布局常规操作 */mainWidget new QWidget();rightWidget new QWidget();for(int i 0; i 2; i) //水平布局hboxLayout[i] new QHBoxLayout();for(int i 0; i 5; i) //容器布局widget[i] new QWidget();for(int i 0; i 4; i) //垂直布局vboxLayout[i] new QVBoxLayout();for(int i 0; i 3; i) //数据变量my_label[i] new QLabel();/********************** chart表格 *****************************//* 最大储存maxSize - 1个数据 */maxSize 51;/* x轴上的最大值 */maxX 5000;/* y轴最大值 */maxY 40;/* splineSeries曲线实例化折线用QLineSeries */splineSeries new QSplineSeries();/* 图表实例化 */chart new QChart();/* 图表视图实例化 */chartView new QChartView();/* 坐标轴 */axisY new QValueAxis();axisX new QValueAxis();/* legend译图例类型以绘图的颜色区分本例设置为隐藏 */chart-legend()-hide();/* chart设置标题 */chart-setTitle(环境光强度);/* 添加一条曲线splineSeries */chart-addSeries(splineSeries);/* 设置显示格式 */axisY-setLabelFormat(%i);/* y轴标题 */axisY-setTitleText(光通亮/Lux);/* y轴标题位置设置坐标轴的方向 */chart-addAxis(axisY, Qt::AlignLeft);/* 设置y轴范围 */axisY-setRange(0, maxY);/* 将splineSeries附加于y轴上 */splineSeries-attachAxis(axisY);/* 设置显示格式 */axisX-setLabelFormat(%i);/* x轴标题 */axisX-setTitleText(时间/ms);/* x轴标题位置设置坐标轴的方向 */chart-addAxis(axisX, Qt::AlignBottom);/* 设置x轴范围 */axisX-setRange(0, maxX);/* 将splineSeries附加于x轴上 */splineSeries-attachAxis(axisX);/* 将图表的内容设置在图表视图上 */chartView-setChart(chart);/* 设置抗锯齿 */chartView-setRenderHint(QPainter::Antialiasing);
/********************** chart表格 *****************************//* 设置传感器数据标签 */QFont font;font.setPixelSize(18);QPalette pal;pal.setColor(QPalette::WindowText, Qt::black);QStringList list;list环境光强度接近距离红外强度;for (int i 0; i 3; i) {label[i] new QLabel();label[i]-setText(list[i]);label[i]-setFont(font);label[i]-setPalette(pal);label[i]-adjustSize();}/* 垂直容器布局 */vboxLayout[3]-addWidget(widget[0]);vboxLayout[3]-addWidget(widget[1]);vboxLayout[3]-addWidget(widget[2]);hboxLayout[0]-addWidget(chartView); //将chart表格添加到水平布局中widget[3]-setLayout(hboxLayout[0]);widget[4]-setLayout(vboxLayout[3]);hboxLayout[1]-addWidget(widget[3]);hboxLayout[1]-addWidget(widget[4]);mainWidget-setLayout(hboxLayout[1]);this-setCentralWidget(mainWidget);/* als布局 */vboxLayout[0]-addWidget(label[0]);vboxLayout[0]-addWidget(my_label[0]);vboxLayout[0]-setAlignment(Qt::AlignTop | Qt::AlignVCenter);widget[0]-setLayout(vboxLayout[0]);/* ps布局 */vboxLayout[1]-addWidget(label[1]);vboxLayout[1]-addWidget(my_label[1]);vboxLayout[1]-setAlignment(Qt::AlignTop | Qt::AlignVCenter);widget[1]-setLayout(vboxLayout[1]);/* ir布局 */vboxLayout[2]-addWidget(label[2]);vboxLayout[2]-addWidget(my_label[2]);vboxLayout[2]-setAlignment(Qt::AlignTop | Qt::AlignVCenter);widget[2]-setLayout(vboxLayout[2]);ap3216c new Ap3216c(this);/* 只能在开发板上开启获取数据Ubuntu上是没有ap3216c传感器的 */
#if __arm__ap3216c-setCapture(true);
#endifconnect(ap3216c,SIGNAL(ap3216cDataChanged()),this,SLOT(getAp3216cData()));
}void MainWindow::getAp3216cData()
{static QString als ap3216c-alsData();
// if (als ! ap3216c-alsData()) {
// als ap3216c-alsData();
// }als ap3216c-alsData();static QString ps ap3216c-psData();
// if (ps ! ap3216c-psData()) {
// ps ap3216c-psData();
// }ps ap3216c-psData();static QString ir ap3216c-irData();
// if (ir ! ap3216c-irData()) {
// ir ap3216c-irData();
// }ir ap3216c-irData();my_label[0]-setText(als);my_label[1]-setText(ps);my_label[2]-setText(ir);/**************** chart表数据 ******************/int num als.toInt(); //字符串转int类型数据/* 将数据添加到data中 */data.append(num);/* 当储存数据的个数大于最大值时把第一个数据删除 */while (data.size() maxSize) {/* 移除data中第一个数据 */data.removeFirst();}/* 先清空 */splineSeries-clear();/* 计算x轴上的点与点之间显示的间距 */int xSpace maxX / (maxSize - 1);/* 添加点xSpace * i 表示第i个点的x轴的位置 */for (int i 0; i data.size(); i) {splineSeries-append(xSpace * i, data.at(i));}}AP3216C 与 Chart 联动的程序主要是进行 QT 的容器布局通过 layoutInit() 函数进行布局初始化UI设计部分之后通过定时 timer 去定时读取 ap3216c 的传感器数据在读取 ap3216c 的数据之后通过 Chart 进行绘制出来 实际项目 四、项目效果 AP3216CQTChart 五、项目代码
代码地址基于IMX6ULL的AP3216C的QT动态数据曲线图显示代码资源-CSDN文库
如果积分不够的朋友点波关注评论区留下邮箱作者无偿提供源码和后续问题解答。求求啦关注一波吧