【飛凌嵌入式 OK3399-C+開發板試用體驗】使用QT工程讀取DHT11模塊的波折經歷
作者:donatello1996
上一帖中已經成功使用一個簡單的main函數成功讀取到DHT11的溫濕度數據了,雖然讀取溫濕度數據響應時間很慢,但至少算是成功讀取了,這次我就想在QT環境下進行溫濕度的讀取,結合美觀的圖形界面呈現出來,同時,還可以以文件形式讀取ADC_IN4接口 CPU0溫度以及CPU1溫度,使用到的QT類為QThread,還有Linux系統自帶的pthread。為什么說是波折經歷呢,因為DHT11這個器件對主控和系統的實時性要求實在是太高了,如果是直接用單片機主控來讀取,那就沒任何問題,但是要用到微處理器,哪怕是RK3399這種主頻那么高的CPU,讀取DHT11依然會出現實時性問題,這就很煩,由于QT的圖形化界面用到了QMainWindow類,會占用一定的CPU實時資源,在這一兩天的探索過程中,我先后用了QThread pthread QTimer三種方式讀取DHT11數據,結果表明,要想穩定讀取,只能用pthread進行,QThread這種QT內建的多線程實現類完全無法讀取,頂多只能讀取已經存在/sys中的實時CPU溫度數據和ADC接口數據,而QTimer這種定時器中斷類就更不用說了,實時性比QThread還低得多,跟pthread的效率比起來就沒法比。我不知道QThread的實現代碼是怎么寫的,按我理解來說應該也只是對pthread做一定的封裝,也沒想到實時性/效率差這么遠。
首先是讀寫兩個CPUzone的溫度,需要讀取/sys/class/thermal/thermal_zone0/temp和/sys/class/thermal/thermal_zone1/temp:
int fd_cputemp0,fd_cputemp1; unsigned char buf_cpu_temp0[5]; unsigned char buf_cpu_temp1[5]; fd_cputemp0 = open("/sys/class/thermal/thermal_zone0/temp", O_RDONLY); fd_cputemp1 = open("/sys/class/thermal/thermal_zone1/temp", O_RDONLY); read(fd_adc4 , buf_adc4 ,5); read(fd_cputemp0 , buf_cpu_temp0 ,5); read(fd_cputemp1 , buf_cpu_temp1 ,5);
而ADC_IN4則是用同樣的方法讀取/sys/bus/iio/devices/iio:device0/in_voltage4_raw:
int fd_adc4; unsigned char buf_adc4[5]; fd_adc4 = open("/sys/bus/iio/devices/iio:device0/in_voltage4_raw", O_RDONLY); read(fd_adc4 , buf_adc4 ,5);
#ifndef MY_THREAD_H #define MY_THREAD_H #include <QThread> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/time.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include "mainwindow.h" class MainWindow; class mythread : public QThread { public: mythread(QObject *parent); void closeThread(); struct timeval tv1; protected: virtual void run(); private: volatile bool isStop; MainWindow *m_pMainWindow; int fd_cputemp0,fd_cputemp1,fd_adc4; }; #endif // DHT11_THREAD_H
#include "mythread.h" #include "mainwindow.h" #include <ui_mainwindow.h> mythread::mythread(QObject *parent) { isStop = false; m_pMainWindow = qobject_cast<MainWindow*>(parent); } void mythread::closeThread() { isStop = true; } extern float dht11_temp,dht11_humi; void mythread::run() { int i=0; unsigned char buf_adc4[5]; unsigned char buf_cpu_temp0[5]; unsigned char buf_cpu_temp1[5]; while (1) { if(isStop) return; //gettimeofday(&tv1, NULL); //qDebug("tv1=%d\n",tv1.tv_usec); fd_adc4 = open("/sys/bus/iio/devices/iio:device0/in_voltage4_raw", O_RDONLY); fd_cputemp0 = open("/sys/class/thermal/thermal_zone0/temp", O_RDONLY); fd_cputemp1 = open("/sys/class/thermal/thermal_zone1/temp", O_RDONLY); read(fd_adc4 , buf_adc4 ,5); read(fd_cputemp0 , buf_cpu_temp0 ,5); read(fd_cputemp1 , buf_cpu_temp1 ,5); buf_adc4[4]=0; m_pMainWindow->ui->L1->setText(QString("%1").arg(dht11_temp)); m_pMainWindow->ui->L2->setText(QString("%1").arg(dht11_humi)); m_pMainWindow->ui->L3->setText(QString((char*)buf_adc4)); m_pMainWindow->ui->L4->setText(QString((char*)buf_cpu_temp0)); m_pMainWindow->ui->L5->setText(QString((char*)buf_cpu_temp1)); sleep(1); } }
struct dht11_data { unsigned short temp; unsigned short hum; }curdht11_data; float dht11_temp,dht11_humi; pthread_t id; int fd_dht11; void *Thread_CPU_Temp(void *arg) { int retval; while(1) { retval = read ( fd_dht11 , &curdht11_data , sizeof(curdht11_data) ); if ( retval == -1 ) { printf ( "read dht11 error" ) ; } if(curdht11_data.temp != 0xffff) { if(0 < (curdht11_data.temp>>8) && (curdht11_data.temp>>8) < 85) { dht11_temp = (curdht11_data.temp >> 8) + (curdht11_data.temp & 0xff) * 0.01; dht11_humi = (curdht11_data.hum >> 8) + (curdht11_data.hum & 0xff) * 0.01; printf("---- %f %f-----\n",dht11_temp,dht11_humi); } } //sleep(1); } }
int main(int argc, char *argv[]) { QApplication a(argc, argv); fd_dht11 = open ( "/dev/dht11" , O_RDONLY) ; if ( fd_dht11 == -1 ) { perror ( "open dht11 error\n" ) ; } printf ( "open /dev/dht11 successfully\n" ) ; pthread_create(&id , NULL , Thread_CPU_Temp , NULL); printf ( "create pthread successfully\n" ) ; MainWindow w; w.show(); return a.exec(); }
void MainWindow::on_PB1_clicked() { disconnect(ui->PB1,SIGNAL(clicked()),this,SLOT(on_PB1_clicked())); connect(ui->PB1,SIGNAL(clicked()),this,SLOT(on_PB1_clicked_2())); ui->PB1->setText("Pause"); thread1->start(); } void MainWindow::on_PB1_clicked_2() { disconnect(ui->PB1,SIGNAL(clicked()),this,SLOT(on_PB1_clicked_2())); connect(ui->PB1,SIGNAL(clicked()),this,SLOT(on_PB1_clicked())); ui->PB1->setText("Start"); thread1->closeThread(); thread1->wait(); }
相關產品 >
-
FET3399-C核心板
飛凌RK3399安卓高性能核心板采用 采用六核Rockchip RK3399芯片,雙Cortex-A72大核+四Cortex-A53小核結構,對整數、浮點、內存等作了大幅優化,在整體性能、功耗及核心面積三個方面提升。以下將對瑞芯微芯片RK3399參數,RK3399核心板方案及其性能做具體介紹。如您對飛凌RK3399系列核心板有興趣,歡迎咨詢了解。
了解詳情 -
OK3399-C開發板
飛凌嵌入式RK3399安卓開發板主芯片采用高性能六核CPU Rockchip RK3399,GPU采用Mail-T860四核 GPU,RK3399作為目RK產品線中低功耗、高性能的代表,可滿足人臉識別設備、機器人、無人機、IoT物聯網領域應用。飛凌RK3399開發板在整體性能、功耗及核心面積做了大幅度優化,更加滿足工業設計需求。飛凌RK3399開發板為進一步減少用戶二次開發難度,開放了底板原理圖,并提供了RK3399用戶手冊、芯片手冊,加上優質的技術服務,讓您的方案從構思到上市時間縮短。