项目介绍
在树莓派上安装QT,使用wiringPi.h库文件开启树莓派的GPIO,通过多线程实现对RGB的控制,用线程中的msleep()来实现PWM的控制。
查询GPIO引脚
首先是确定要使用的GPIO引脚,在控制命令界面上,输入gpio readall。
选取了23、24、25作为使用的GPIO用于后续的RGB控制。
界面设计
预期目标:
- 通过控制滑块来调节RGB的数值0—255。
- 在文本框内显示RGB当前对应的数值。
- 通过点击按钮来亮红、绿或蓝灯。
- 通过点击按钮可以实现开启和关闭任务
根据目标,设计了如上界面。
功能设计
开启GPIO
.pro 文件里添加
LIBS += -lwiringPi
mainwindow.cpp里
wiringPiSetup();
pinMode(23,OUTPUT);
pinMode(24,OUTPUT);
pinMode(25,OUTPUT);
点击按钮可亮灯
void MainWindow::on_R_clicked()
{
digitalWrite(23,1);
digitalWrite(24,0);
digitalWrite(25,0);
}
void MainWindow::on_G_clicked()
{
digitalWrite(23,0);
digitalWrite(24,1);
digitalWrite(25,0);
}
void MainWindow::on_B_clicked()
{
digitalWrite(23,0);
digitalWrite(24,0);
digitalWrite(25,1);
}
设置滑块
// QSlider
ui->horizontalSlider->setMinimum(0);
ui->horizontalSlider->setMaximum(255);
ui->horizontalSlider->setSingleStep(1);
ui->horizontalSlider_2->setMinimum(0);
ui->horizontalSlider_2->setMaximum(255);
ui->horizontalSlider_2->setSingleStep(1);
ui->horizontalSlider_3->setMinimum(0);
ui->horizontalSlider_3->setMaximum(255);
ui->horizontalSlider_3->setSingleStep(1);
最小值为0,最大值为255,步长为1。
设置多线程
mainwindow.cpp
Thread *thread_1;
thread_1->R = ui->horizontalSlider;
thread.h
#ifndef THREAD_H
#define THREAD_H
#include <QThread>
#include <QSlider>
#include <wiringPi.h>
class Thread : public QThread
{
Q_OBJECT
public:
Thread();
QSlider *R;
protected:
void run();
};
#endif // THREAD_H
thread.cpp
#include "thread.h"
Thread::Thread()
{
R = new QSlider();
}
void Thread::run()
{
while(true)
{
if(R->value()!=0){
digitalWrite(23,1);
msleep(30*((R->value())/255));
digitalWrite(23,0);
msleep(30*((255-R->value())/255));
}else{
digitalWrite(23,0);
}
}
}
获取控制R的滑块当前的数值,msleep()为毫秒级的延时函数可以使线程暂时休眠,从而实现PWM的控制,因为msleep()中设置的数值控制并不完美,就需要if-else来实现当数值为0时,灯不会亮。如果有更好的延时数值变化设计方案的朋友,请多多留言~~~
设置按钮开启和关闭任务
start按钮
void MainWindow::on_pushButton_clicked()
{
pinMode(23,OUTPUT);
pinMode(24,OUTPUT);
pinMode(25,OUTPUT);
timer_1 = new QTimer(this);
connect(timer_1,SIGNAL(timeout()),this,SLOT(timer_1_click()));
timer_1->start(10);
thread_1->R = ui->horizontalSlider;
thread_2->G = ui->horizontalSlider_2;
thread_3->B = ui->horizontalSlider_3;
thread_1->start();
thread_2->start();
thread_3->start();
}
timer_1_click()函数(作用:更新文本框内数据)
void MainWindow::timer_1_click()
{
// qDebug() << "1:" << ui->horizontalSlider->value();
// qDebug() << "2:" << ui->horizontalSlider_2->value();
// qDebug() << "3:" << ui->horizontalSlider_3->value();
QString s1,s2,s3;
s1.sprintf("R:%d\n",ui->horizontalSlider->value());
s2.sprintf("G:%d\n",ui->horizontalSlider_2->value());
s3.sprintf("B:%d",ui->horizontalSlider_3->value());
ui->textEdit->setText(s1+s2+s3);
}
stop按钮
void MainWindow::on_pushButton_2_clicked()
{
ui->horizontalSlider->setValue(0);
ui->horizontalSlider_2->setValue(0);
ui->horizontalSlider_3->setValue(0);
thread_1->quit();
thread_2->quit();
thread_3->quit();
}
实现效果
当界面中滚动的数值为如下所示的时候━━∑( ̄□ ̄*|||━━
现实情况是这样子的········
又调了调数值·······
完整代码
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <thread.h>
#include <thread_2.h>
#include <thread_3.h>
#include <QTimer>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
Thread *thread_1;
Thread_2 *thread_2;
Thread_3 *thread_3;
QTimer *timer_1;
QString s1,s2,s3;
private slots:
void on_pushButton_clicked();
void on_R_clicked();
void on_G_clicked();
void on_B_clicked();
void on_pushButton_2_clicked();
void timer_1_click();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <wiringPi.h>
#include <qdebug.h>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
wiringPiSetup();
thread_1 = new Thread();
thread_2 = new Thread_2();
thread_3 = new Thread_3();
ui->horizontalSlider->setMinimum(0);
ui->horizontalSlider->setMaximum(255);
ui->horizontalSlider->setSingleStep(1);
ui->horizontalSlider_2->setMinimum(0);
ui->horizontalSlider_2->setMaximum(255);
ui->horizontalSlider_2->setSingleStep(1);
ui->horizontalSlider_3->setMinimum(0);
ui->horizontalSlider_3->setMaximum(255);
ui->horizontalSlider_3->setSingleStep(1);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
pinMode(23,OUTPUT);
pinMode(24,OUTPUT);
pinMode(25,OUTPUT);
timer_1 = new QTimer(this);
connect(timer_1,SIGNAL(timeout()),this,SLOT(timer_1_click()));
timer_1->start(10);
thread_1->R = ui->horizontalSlider;
thread_2->G = ui->horizontalSlider_2;
thread_3->B = ui->horizontalSlider_3;
thread_1->start();
thread_2->start();
thread_3->start();
}
void MainWindow::timer_1_click()
{
// qDebug() << "1:" << ui->horizontalSlider->value();
// qDebug() << "2:" << ui->horizontalSlider_2->value();
// qDebug() << "3:" << ui->horizontalSlider_3->value();
s1.sprintf("R:%d\n",ui->horizontalSlider->value());
s2.sprintf("G:%d\n",ui->horizontalSlider_2->value());
s3.sprintf("B:%d",ui->horizontalSlider_3->value());
ui->textEdit->setText(s1+s2+s3);
}
void MainWindow::on_R_clicked()
{
ui->horizontalSlider->setValue(255);
ui->horizontalSlider_2->setValue(0);
ui->horizontalSlider_3->setValue(0);
}
void MainWindow::on_G_clicked()
{
ui->horizontalSlider->setValue(0);
ui->horizontalSlider_2->setValue(255);
ui->horizontalSlider_3->setValue(0);
}
void MainWindow::on_B_clicked()
{
ui->horizontalSlider->setValue(0);
ui->horizontalSlider_2->setValue(0);
ui->horizontalSlider_3->setValue(255);
}
void MainWindow::on_pushButton_2_clicked()
{
ui->horizontalSlider->setValue(0);
ui->horizontalSlider_2->setValue(0);
ui->horizontalSlider_3->setValue(0);
thread_1->quit();
thread_2->quit();
thread_3->quit();
}
thread.h
#ifndef THREAD_H
#define THREAD_H
#include <QThread>
#include <QSlider>
#include <wiringPi.h>
class Thread : public QThread
{
Q_OBJECT
public:
Thread();
QSlider *R;
protected:
void run();
};
#endif // THREAD_H
thread.cpp
#include "thread.h"
Thread::Thread()
{
R = new QSlider();
}
void Thread::run()
{
while(true)
{
if(R->value()!=0){
digitalWrite(23,1);
msleep(30*((R->value())/255));
digitalWrite(23,0);
msleep(30*((255-R->value())/255));
}else{
digitalWrite(23,0);
}
}
}
控制G和B的线程与控制R的线程代码逻辑相同,就不再展示了。
PWM的数值设置问题
有更好方案的朋友,欢迎留言交流~