前面的幾篇文章,介紹Qt例程,都是和硬件無(wú)關(guān)的,Windows平臺(tái)和嵌入式平臺(tái)都能運(yùn)行。
本篇,來(lái)測(cè)試一下Qt界面控制嵌入式平臺(tái)上的硬件,以野火i.MX6ULL板子上的RGB LED為例,實(shí)現(xiàn)Qt界面控制3種顏色LED的不同亮度混合顯示。
1 設(shè)計(jì)Qt滑條控制LED界面
先來(lái)看一下最終設(shè)計(jì)的界面效果:
有一個(gè)按鍵作為L(zhǎng)ED的總開關(guān),控制LED的點(diǎn)亮與熄滅。下面的3個(gè)滑條,控制3種顏色LED以不同的亮度點(diǎn)亮。右邊是一個(gè)顏色混合顯示面板,模擬RGB三種顏色的LED以不同亮度點(diǎn)亮后的混合亮度。
1.1 滑條控件
Qt Creator的UI設(shè)置界面中,有水平滑條和豎直滑條控件,可以直接使用:
右側(cè)的屬性窗戶可以設(shè)置滑條的取值范圍和初始值。
1.2 控件顏色
使用QPalette可以對(duì)界面顏色和控件的顏色進(jìn)行自定義設(shè)置
QPalete::Window——通常指窗口部件的背景色
QPalette::WindowText——通常指窗口不見的前景色
QPalette::Base——底色
QPalette::Button——指按鈕窗口部件的背景色
QPalette::ButtonText——指按鈕窗口部件的前景色
QPalette::Text——文本輸入窗口的前景色
QPalette::Background——背景色
QPalette::Foreground——前景色(界面中文字的統(tǒng)一顏色)
界面的顏色
整個(gè)UI界面的顏色可以這樣設(shè)置:
QPalette color = palette();//控制窗體顏色
color.setColor(QPalette::Background, QColor(255,255,255));//背景顏色
//color.setColor(QPalette::Foreground, QColor(0,0,255,255));//前景顏色
setPalette(color);
這里就是把整個(gè)界面的顏色設(shè)置為純白色
控件的顏色
例如文本標(biāo)簽控件(QLabel)的文字顏色可以這樣設(shè)置:
QPalette pal;
pal.setColor(QPalette::WindowText,Qt::red);
ui->label_R->setPalette(pal); //設(shè)置滑條左側(cè)的R字體為紅色
pal.setColor(QPalette::WindowText,Qt::green);
ui->label_G->setPalette(pal);
pal.setColor(QPalette::WindowText,Qt::blue);
ui->label_B->setPalette(pal);
顏色混合面板控件(QTextBrowser)的面板顏色可以這樣設(shè)置:
QColor color;
int R = ui->Slider_R->value(); //讀取滑條的當(dāng)前值
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界面代碼編寫
構(gòu)造函數(shù)
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);
}
滑條滑動(dòng)時(shí)的槽函數(shù)
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系統(tǒng)燒錄
本篇的RGB LED測(cè)試,需要先燒錄野火i.MX6ULL自帶的系統(tǒng)固件,因?yàn)樵撓到y(tǒng)已有Qt運(yùn)行環(huán)境,且對(duì)應(yīng)的RGB LED的驅(qū)動(dòng)程序也已配置好了,這樣就不需要再自己寫RGB LED的驅(qū)動(dòng)程序了,我們只寫好Qt的應(yīng)用程序,實(shí)現(xiàn)對(duì)板子上LED的控制即可。
燒寫方法可參考:https://doc.embedfire.com/linux/imx6/quick_start/zh/latest/quick_start/install_debian/install_debian.html#
可以燒寫到SD卡中
燒寫到eMMC中
因?yàn)樵赟D卡中運(yùn)行系統(tǒng),無(wú)法使用WIFI連網(wǎng),可以通過(guò)fire-config工具將SD卡的系統(tǒng)燒寫到eMMC中,刷機(jī)過(guò)程可參考:
https://doc.embedfire.com/linux/imx6/linux_base/zh/latest/linux_basis/fire-config_brief/fire-config_brief.html#id7
設(shè)置之后,選擇重啟,重啟后的系統(tǒng)將自動(dòng)進(jìn)行從SD卡到EMMC的刷機(jī)。刷機(jī)過(guò)程大約2分鐘左右。刷機(jī)完成后,控制臺(tái)會(huì)重新進(jìn)入串口登錄頁(yè)面, 此時(shí)觀察開發(fā)板的LED燈,如果LED在持續(xù)閃爍,說(shuō)明刷機(jī)成功。然后調(diào)整撥碼開關(guān)為相應(yīng)啟動(dòng)方式,重新上電啟動(dòng)系統(tǒng)即可。
也可以直接通過(guò)USB-OTG接口和 MFGTool2軟件燒寫到eMMC。ssh
燒寫到eMMC啟動(dòng),可以使用WIFI連網(wǎng),WIFI配網(wǎng)步驟參考:https://doc.embedfire.com/linux/imx6/quick_start/zh/latest/quick_start/wifi/wifi.html
Qt系統(tǒng)界面
野火i.MX6ULL自帶的系統(tǒng)固件燒錄后自啟動(dòng)Qt程序界面如下:
串口方式登錄時(shí):
普通用戶(帶sudo權(quán)限)
賬戶: debian
密碼: temppwd
ROOT用戶
賬戶: root
密碼: root
這個(gè)系統(tǒng)第一次運(yùn)行時(shí),會(huì)進(jìn)行屏幕觸摸校準(zhǔn),若校準(zhǔn)的不滿意,可刪除掉/etc/pointercal文件后重啟再進(jìn)行校準(zhǔn)。
rm /etc/pointercal
2.2 無(wú)Qt的RGB LED測(cè)試
野火i.MX6ULL的RGB LED的原理圖如下,由于驅(qū)動(dòng)程序不需要自己寫了,實(shí)際上我們也不需要關(guān)心具體的硬件引腳是哪個(gè),只需要使用驅(qū)動(dòng)程序提供的設(shè)備描述符進(jìn)行LED的控制即可。
參考野火的測(cè)試代碼:https://doc.embedfire.com/linux/imx6/quick_start/zh/latest/quick_start/led_subsystem/led_subsystem.html#id4
測(cè)試代碼
編寫自己的沒(méi)有Qt界面的RGB LED測(cè)試代碼:
#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/brightness"
int 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進(jìn)行交叉編譯
arm-linux-gnueabihf-gcc led_noqt.c -o led_noqt
測(cè)試效果
運(yùn)行效果如下,3種顏色的燈每隔1s依次點(diǎn)亮熄滅:
對(duì)于亮度的控制,可以先參考教程中的命令行點(diǎn)燈測(cè)試:https://doc.embedfire.com/linux/imx6/linux_base/zh/latest/linux_basis/led_key_command_line_testing/led_key_command_line_testing.html
實(shí)際測(cè)試,串口指令無(wú)法控制燈的亮度,只能控制亮滅,亮度為1和亮度為255的效果一樣,都是同樣的亮度,不知道是硬件的問(wèn)題還是軟件驅(qū)動(dòng)的問(wèn)題。
2.3 Qt中移植RGB LED控制代碼
在滑條UI界面代碼工程的基礎(chǔ)上,添加一個(gè)自定義的類,名字可起為regled:
然后在這個(gè)類中,將無(wú)Qt的RGB LED測(cè)試用到的代碼移植進(jìn)來(lái),并結(jié)合Qt的滑動(dòng)條對(duì)三種顏色的燈進(jìn)行控制。
這個(gè)是構(gòu)造函數(shù),先打開3個(gè)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 < 0)
{
return;
}
}
編寫一個(gè)RGB燈的顏色和亮度的控制函數(shù),供外部調(diào)用:
void rgbled::SetRGBLedValue(LED_TYPE type, int val)
{
if (val > 255)
{
val = 255;
}
else if (val < 0)
{
val = 0;
}
std::string value = std::to_string(val);
switch (type)
{
case T_R_LED:
write(r_fd, value.c_str(), 3);
break;
case T_G_LED:
write(g_fd, value.c_str(), 3);
break;
case T_B_LED:
write(b_fd, value.c_str(), 3);
break;
default:break;
}
}
在UI界面類中,可以對(duì)RGB LED進(jìn)行控制:
//LedWidget類中定義一個(gè)rgbled成員變量
rgbled *m_pRGBLed;
//LedWidget構(gòu)造函數(shù)中實(shí)例化一個(gè)rgbled對(duì)象
m_pRGBLed = new rgbled(this);
在更新UI界面上的模擬顏色面板的同時(shí),也將板子上的RGB LED的亮度進(jìn)行同步控制:
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);
//控制板子上的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 編譯時(shí)遇到的問(wèn)題
程序首先在Windows的Qt Creator上進(jìn)行編譯,遇到了一些問(wèn)題,記錄下解決方法。
找不到unistd.h
在Windows中編譯時(shí),Qt Creater提示找不到unistd.h,這個(gè)其實(shí)是Visual Stidio編譯器找不這個(gè)頭文件。
這個(gè)頭文件都是Linux系統(tǒng)中常用的,Windows中一般用不到,要消除這個(gè)編譯錯(cuò)誤,可以在VS的安裝目錄手動(dòng)添加一個(gè)這個(gè)文件。
我的目錄是:
D:\Tools1\vs2015\VC\include
新建一個(gè)unistd.h:
//for qt creater, 2022/8/13
#ifndef _UNISTD_H
#define _UNISTD_H
#include
#include
#endif
open、write等函數(shù)的警告提示
這些也是Linux中用到的函數(shù),在Window平臺(tái)編譯只是警告信息,沒(méi)有報(bào)錯(cuò),可以不用管
3 實(shí)驗(yàn)演示
3.1 交叉編譯
和之前一樣,將Windows的Qt Creator中的源碼復(fù)制到Ubuntu中進(jìn)行交叉編譯,具體操作過(guò)程可參考之前的文章:
嵌入式Qt-動(dòng)手編寫并運(yùn)行自己的第1個(gè)ARM-Qt程序
這里僅記錄下編譯指令:
/home/xxpcb/myTest/imx6ull/otherlib/qt/qt-everywhere-src-5.12.9/arm-qt/bin/qmake
3.2 文件復(fù)制到板子中
由于這次測(cè)試使用的是野火的系統(tǒng)固件,不能和之前用網(wǎng)絡(luò)位置掛載根文件系統(tǒng)的方式,在Ubuntu中直接將文件復(fù)制到板子中(Ubuntu中的網(wǎng)絡(luò)掛載位置),因此本篇需要使用其它的方法將Ubuntu中編譯的文件復(fù)制到板子中。
這里使用SSH的方式進(jìn)行拷貝,首先要在Ubuntu中和i.MX6ULL板子中配置SSH功能,配置方法如下:
配置ssh
sudo apt update
sudo apt install openssh-server -y
sudo systemctl status ssh #查看狀態(tài)
# 如果你的防火墻開啟了,使用下面語(yǔ)句
sudo ufw allow ssh
連接方式
基本的ssh連接方法是:
ssh username@ip
username表示該機(jī)器的用戶名,ip表示對(duì)應(yīng)的ip地址
ssh方式文件復(fù)制
從Ubuntu拉取文件到板子中
# 從服務(wù)器拉取文件
# scp 服務(wù)器上的某個(gè)用戶@服務(wù)器IP::/服務(wù)器文件存放路徑 拉取文件保存路徑
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 測(cè)試效果
在測(cè)試自己的例程之前,需要先將野火的自啟動(dòng)Qt例程kill掉,否則兩個(gè)Qt程序會(huì)同步運(yùn)行互相遮擋。
kill掉自啟動(dòng)Qt程序
通過(guò)ps 、top 等命令查詢到ebf-qtdemo的pid,然后通過(guò)kill命令停止App運(yùn)行
#879 為當(dāng)前 App 的 PID 值,每次可能不一樣
sudo kill 879
運(yùn)行自己的Qt程序
野火的系統(tǒng)中,提供了一個(gè)運(yùn)行腳本run_myapp.sh,需要調(diào)用這個(gè)腳本來(lái)運(yùn)行自己的Qt程序
sudo /usr/local/qt-app/run_myapp.sh /usr/local/qt-app/Control_1
實(shí)際測(cè)試效果如下:
可以看出:
板子上的LED的亮度其實(shí)不能調(diào)節(jié),只能亮或滅,需要確認(rèn)下是不是LED驅(qū)動(dòng)的問(wèn)題
觸摸的方式拖動(dòng)板子上的滑條,不太靈活,可能是觸摸和鼠標(biāo)都在起作用,兩者干擾了
Qt界面中模擬的顏色混合面板,顏色混合顯示正常
4 總結(jié)
本篇介紹了通過(guò)Qt中滑條的使用,并使用滑條來(lái)控制i.MX6ULL板子中RGB三個(gè)顏色LED的亮滅。通過(guò)燒錄野火自帶的系統(tǒng)固件,使用系統(tǒng)提供的LED驅(qū)動(dòng)程序,再配置自己編譯的Qt應(yīng)用程序,來(lái)實(shí)現(xiàn)整個(gè)功能。
-
嵌入式
+關(guān)注
關(guān)注
5087文章
19153瀏覽量
306416 -
Qt
+關(guān)注
關(guān)注
1文章
308瀏覽量
37988
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論