嵌入式Qt-控制硬件:滑动条控制RGB灯

前面的几篇文章,介绍qt例程,都是和硬件无关的,windows平台和嵌入式平台都能运行。
本篇,来测试一下qt界面控制嵌入式平台上的硬件,以野火i.mx6ull板子上的rgb led为例,实现qt界面控制3种颜色led的不同亮度混合显示。
1 设计qt滑条控制led界面 先来看一下最终设计的界面效果:
有一个按键作为led的总开关,控制led的点亮与熄灭。下面的3个滑条,控制3种颜色led以不同的亮度点亮。右边是一个颜色混合显示面板,模拟rgb三种颜色的led以不同亮度点亮后的混合亮度。
1.1 滑条控件 qt creator的ui设置界面中,有水平滑条和竖直滑条控件,可以直接使用:
右侧的属性窗户可以设置滑条的取值范围和初始值。
1.2 控件颜色 使用qpalette可以对界面颜色和控件的颜色进行自定义设置
qpalete::window——通常指窗口部件的背景色
qpalette::windowtext——通常指窗口不见的前景色
qpalette::base——底色
qpalette::button——指按钮窗口部件的背景色
qpalette::buttontext——指按钮窗口部件的前景色
qpalette::text——文本输入窗口的前景色
qpalette::background——背景色
qpalette::foreground——前景色(界面中文字的统一颜色)
界面的颜色 整个ui界面的颜色可以这样设置:
qpalette color = palette();//控制窗体颜色color.setcolor(qpalette::background, qcolor(255,255,255));//背景颜色//color.setcolor(qpalette::foreground, qcolor(0,0,255,255));//前景颜色setpalette(color); 这里就是把整个界面的颜色设置为纯白色
控件的颜色 例如文本标签控件(qlabel)的文字颜色可以这样设置:
qpalette pal;pal.setcolor(qpalette::windowtext,qt::red);ui->label_r->setpalette(pal); //设置滑条左侧的r字体为红色pal.setcolor(qpalette::windowtext,qt::green);ui->label_g->setpalette(pal);pal.setcolor(qpalette::windowtext,qt::blue);ui->label_b->setpalette(pal); 颜色混合面板控件(qtextbrowser)的面板颜色可以这样设置:
qcolor color;int r = ui->slider_r->value(); //读取滑条的当前值int g = ui->slider_g->value();int b = ui->slider_b->value();color.setrgb(r, g, b); //颜色混合qpalette pal;pal.setcolor(qpalette::base, color);ui->textbrowser->setpalette(pal); //显示到面板上 1.3 滑条ui界面代码编写 构造函数
ledwidget::ledwidget(qwidget *parent) : qwidget(parent), ui(new ui::ledwidget){ ui->setupui(this); ui->value_r->settext(qstring::number(ui->slider_r->value())); ui->value_g->settext(qstring::number(ui->slider_g->value())); ui->value_b->settext(qstring::number(ui->slider_b->value())); qpalette color = palette();//控制窗体颜色 color.setcolor(qpalette::background, qcolor(255,255,255));//背景颜色 setpalette(color);} 滑条滑动时的槽函数
void ledwidget::on_slider_r_valuechanged(int value){ ui->value_r->settext(qstring::number(value)); updateshowcolor();}void ledwidget::on_slider_g_valuechanged(int value){ ui->value_g->settext(qstring::number(value)); updateshowcolor();}void ledwidget::on_slider_b_valuechanged(int value){ ui->value_b->settext(qstring::number(value)); updateshowcolor();} 更新rgb三种颜色的混合显示
void ledwidget::updateshowcolor(){ qcolor color; int r = ui->slider_r->value(); int g = ui->slider_g->value(); int b = ui->slider_b->value(); color.setrgb(r, g, b); qpalette pal; pal.setcolor(qpalette::base, color); ui->textbrowser->setpalette(pal);} 2 板子上rgb led的控制 2.1 i.mx6ull系统烧录 本篇的rgb led测试,需要先烧录野火i.mx6ull自带的系统固件,因为该系统已有qt运行环境,且对应的rgb led的驱动程序也已配置好了,这样就不需要再自己写rgb led的驱动程序了,我们只写好qt的应用程序,实现对板子上led的控制即可。
烧写方法可参考:https://doc.embedfire.com/linux/imx6/quick_start/zh/latest/quick_start/install_debian/install_debian.html#
可以烧写到sd卡中
烧写到emmc中
因为在sd卡中运行系统,无法使用wifi连网,可以通过fire-config工具将sd卡的系统烧写到emmc中,刷机过程可参考:
https://doc.embedfire.com/linux/imx6/linux_base/zh/latest/linux_basis/fire-config_brief/fire-config_brief.html#id7
设置之后,选择重启,重启后的系统将自动进行从sd卡到emmc的刷机。刷机过程大约2分钟左右。刷机完成后,控制台会重新进入串口登录页面, 此时观察开发板的led灯,如果led在持续闪烁,说明刷机成功。然后调整拨码开关为相应启动方式,重新上电启动系统即可。
也可以直接通过usb-otg接口和 mfgtool2软件烧写到emmc。ssh
烧写到emmc启动,可以使用wifi连网,wifi配网步骤参考:https://doc.embedfire.com/linux/imx6/quick_start/zh/latest/quick_start/wifi/wifi.html
qt系统界面
野火i.mx6ull自带的系统固件烧录后自启动qt程序界面如下:
串口方式登录时:
普通用户(带sudo权限)
账户: debian
密码: temppwd
root用户
账户: root
密码: root
这个系统第一次运行时,会进行屏幕触摸校准,若校准的不满意,可删除掉/etc/pointercal文件后重启再进行校准。
rm /etc/pointercal
2.2 无qt的rgb led测试 野火i.mx6ull的rgb led的原理图如下,由于驱动程序不需要自己写了,实际上我们也不需要关心具体的硬件引脚是哪个,只需要使用驱动程序提供的设备描述符进行led的控制即可。
参考野火的测试代码:https://doc.embedfire.com/linux/imx6/quick_start/zh/latest/quick_start/led_subsystem/led_subsystem.html#id4
测试代码 编写自己的没有qt界面的rgb led测试代码:
#include #include #include #include #include #define rled_dev_path /sys/class/leds/red/brightness#define gled_dev_path /sys/class/leds/green/brightness#define bled_dev_path /sys/class/leds/blue/brightnessint main(int argc,int *argv[]){ int r_fd; int g_fd; int b_fd; r_fd = open(rled_dev_path,o_wronly); if(r_fd < 0) { perror(rled_dev_path); exit(1); } g_fd = open(gled_dev_path,o_wronly); if(r_fd < 0) { perror(gled_dev_path); exit(1); } b_fd = open(bled_dev_path,o_wronly); if(r_fd < 0) { perror(bled_dev_path); exit(1); } while(1) { write(r_fd,255,3); sleep(1); write(r_fd,0,3); sleep(1); write(g_fd,255,3); sleep(1); write(g_fd,0,3); sleep(1); write(b_fd,255,3); sleep(1); write(b_fd,0,3); sleep(1); } close(r_fd); close(g_fd); close(b_fd);} 将该程序在ubuntu进行交叉编译
arm-linux-gnueabihf-gcc led_noqt.c -o led_noqt
测试效果 运行效果如下,3种颜色的灯每隔1s依次点亮熄灭:
对于亮度的控制,可以先参考教程中的命令行点灯测试:https://doc.embedfire.com/linux/imx6/linux_base/zh/latest/linux_basis/led_key_command_line_testing/led_key_command_line_testing.html
实际测试,串口指令无法控制灯的亮度,只能控制亮灭,亮度为1和亮度为255的效果一样,都是同样的亮度,不知道是硬件的问题还是软件驱动的问题。
2.3 qt中移植rgb led控制代码 在滑条ui界面代码工程的基础上,添加一个自定义的类,名字可起为regled:
然后在这个类中,将无qt的rgb led测试用到的代码移植进来,并结合qt的滑动条对三种颜色的灯进行控制。
这个是构造函数,先打开3个led灯的文件描述符:
rgbled::rgbled(qobject *parent) : qobject(parent){ r_fd = open(rled_dev_path,o_wronly); if(r_fd < 0) { return; } g_fd = open(gled_dev_path,o_wronly); if(r_fd < 0) { return; } b_fd = open(bled_dev_path,o_wronly); if(r_fd 255) { val = 255; } else if (val slider_r->value(); int g = ui->slider_g->value(); int b = ui->slider_b->value(); color.setrgb(r, g, b); qpalette pal; pal.setcolor(qpalette::base, color); ui->textbrowser->setpalette(pal); //控制板子上的rgb led的亮度 m_prgbled->setrgbledvalue(t_r_led, r); m_prgbled->setrgbledvalue(t_g_led, g); m_prgbled->setrgbledvalue(t_b_led, b);} 2.4 编译时遇到的问题 程序首先在windows的qt creator上进行编译,遇到了一些问题,记录下解决方法。
找不到unistd.h
在windows中编译时,qt creater提示找不到unistd.h,这个其实是visual stidio编译器找不这个头文件。
这个头文件都是linux系统中常用的,windows中一般用不到,要消除这个编译错误,可以在vs的安装目录手动添加一个这个文件。
我的目录是:
d:\tools1\vs2015\vc\include
新建一个unistd.h:
//for qt creater, 2022/8/13#ifndef _unistd_h#define _unistd_h#include #include #endif open、write等函数的警告提示
这些也是linux中用到的函数,在window平台编译只是警告信息,没有报错,可以不用管
3 实验演示 3.1 交叉编译 和之前一样,将windows的qt creator中的源码复制到ubuntu中进行交叉编译,具体操作过程可参考之前的文章:
嵌入式qt-动手编写并运行自己的第1个arm-qt程序
这里仅记录下编译指令:
/home/xxpcb/mytest/imx6ull/otherlib/qt/qt-everywhere-src-5.12.9/arm-qt/bin/qmake
3.2 文件复制到板子中 由于这次测试使用的是野火的系统固件,不能和之前用网络位置挂载根文件系统的方式,在ubuntu中直接将文件复制到板子中(ubuntu中的网络挂载位置),因此本篇需要使用其它的方法将ubuntu中编译的文件复制到板子中。
这里使用ssh的方式进行拷贝,首先要在ubuntu中和i.mx6ull板子中配置ssh功能,配置方法如下:
配置ssh
sudo apt updatesudo apt install openssh-server -ysudo systemctl status ssh #查看状态# 如果你的防火墙开启了,使用下面语句sudo ufw allow ssh 连接方式
基本的ssh连接方法是:
ssh username@ip username表示该机器的用户名,ip表示对应的ip地址
ssh方式文件复制
从ubuntu拉取文件到板子中
# 从服务器拉取文件# scp 服务器上的某个用户@服务器ip::/服务器文件存放路径 拉取文件保存路径scp server_user_name@192.168.1.101:server_file_path local_path# 我的板子的拉取命令cd /usr/local/qt-app/mytest/scp xxpcb@192.168.5.104:~/mytest/imx6ull/qt-test/4-led/led ./ 3.3 测试效果 在测试自己的例程之前,需要先将野火的自启动qt例程kill掉,否则两个qt程序会同步运行互相遮挡。
kill掉自启动qt程序
通过ps 、top 等命令查询到ebf-qtdemo的pid,然后通过kill命令停止app运行
#879 为当前 app 的 pid 值,每次可能不一样sudo kill 879 运行自己的qt程序
野火的系统中,提供了一个运行脚本run_myapp.sh,需要调用这个脚本来运行自己的qt程序
sudo /usr/local/qt-app/run_myapp.sh /usr/local/qt-app/control_1 实际测试效果如下:
可以看出:
板子上的led的亮度其实不能调节,只能亮或灭,需要确认下是不是led驱动的问题
触摸的方式拖动板子上的滑条,不太灵活,可能是触摸和鼠标都在起作用,两者干扰了
qt界面中模拟的颜色混合面板,颜色混合显示正常
4 总结 本篇介绍了通过qt中滑条的使用,并使用滑条来控制i.mx6ull板子中rgb三个颜色led的亮灭。通过烧录野火自带的系统固件,使用系统提供的led驱动程序,再配置自己编译的qt应用程序,来实现整个功能。

金莱特“遍地开花”梦又一次搁浅
无线网桥可以用在哪一些场景
让 FreeBSD 和 Gentoo Linux 在 ZFS 存储卷上共存
洲明科技裸眼3D原创内容助力景区质变
区块链产业遇到的障碍有哪一些
嵌入式Qt-控制硬件:滑动条控制RGB灯
will.i.am创立的技术公司I.AM +与IBM携手
九张机器学习和深度学习代码速查表分享_初学者必备
用于负反馈式AGC电路
中国家电产业未来的希望和出路 就在于打破舒适区和勇闯无人区
黑科技智能魔镜——你的生活小管家
在通信领域中,什么是4G模块
麦当劳发行620万数字货币,它能超越比特币成为下一个百倍币吗?
详细盘点常用射频微波测量仪器的种类和用途!
ADI公司的人数统计算法确保高效空间利用与工作人员安全
基于一种可用于资产服务交易的去中心化P2P平台Wono介绍
关于二维/石墨烯材料及电子器件测试介绍
RFID 与 NFC 标准大揭秘
教育IWB政策引导型产业,产品发展各有特点
兴森科技:与华为在PCB业务和半导体业务领域均有合作