树莓派+QT+多线程实现RGB七彩灯

项目介绍

在树莓派上安装QT,使用wiringPi.h库文件开启树莓派的GPIO,通过多线程实现对RGB的控制,用线程中的msleep()来实现PWM的控制。

查询GPIO引脚

首先是确定要使用的GPIO引脚,在控制命令界面上,输入gpio readall。

在这里插入图片描述选取了23、24、25作为使用的GPIO用于后续的RGB控制。

界面设计

预期目标:

  1. 通过控制滑块来调节RGB的数值0—255。
  2. 在文本框内显示RGB当前对应的数值。
  3. 通过点击按钮来亮红、绿或蓝灯。
  4. 通过点击按钮可以实现开启和关闭任务

在这里插入图片描述
根据目标,设计了如上界面。

功能设计

开启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的数值设置问题

有更好方案的朋友,欢迎留言交流~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

辰阳星宇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值