Mais um vídeo sobre DISPLAY,
um assunto que eu gosto demais e, por quê? Com ele é possível melhorar muito a
interface com o usuário. Isso porque o usuário da automação precisa ter uma boa
indicação visual. Eu trago, então, um exemplo com um display de 7 polegadas com
touch capacitivo e um Raspberry Pi com QT Creator, que se trata de uma
biblioteca gráfica.
No vídeo de hoje, portanto, apresentamos
uma automação com QT Creator utilizando novos componentes e um exemplo de
acionamento de servo motores utilizando a saída PWM do Raspberry Pi.
Utilizaremos também um módulo de 4 relés na nossa automação.
Recursos usados
·
Raspberry Pi 3 model B+
·
2x Servos Towerpro MG996R
·
Módulo de 4 relés
·
2x lâmpadas
·
Extensão de tomadas
·
Fonte 5V
·
Adaptador de pinos de alimentação arduino
·
Jumpers
·
Protoboard
·
Display 7inch HDMI LCD 7’’ (Touch Screen)
·
Ventilador
Pinout Raspberry Pi 3 Model B
Montagem
Pinos PWM Raspberry Pi 3 Model B
Os pinos PWM no Raspberry Pi 3
são mostrados na figura abaixo. Usamos o canal 0 para um servo motor e o canal
1 para o outro. Devemos nos atentar quanto a GPIO utilizada pelo Wiring Pi
(figura à direita), portanto utilizaremos o GPIO1 e GPIO24 é NÃO os pinos de
BCM (Broadcom SOC channel) GPIO18 e GPIO19.
Interface do projeto QT
OBS: O componente push button
não suporta giffs, portanto utilizamos uma label (lblFan) para a reprodução do
giff. Utilizamos também um push button invisível chamado imgFan que fica acima
da label e assim podemos trabalhar com o evento de clique. Existe outra forma
de fazermos criando uma classe clickable label, mas optamos por não criar essa
classe e deixar o código mais simples.
Código
mainwindow.cpp
Declarações e Variáveis
// Bibliotecas padrões #include "mainwindow.h" #include "ui_mainwindow.h" #include <QtWidgets> // Biblioteca PWM #include <softPwm.h> // Biblioteca Wiring Pi para utilização das funções de GPIO #include <wiringPi.h> // Objeto que controlará a exibição do giff (ventilador funcionando) QMovie *fanGiff; // Fator de divisão usado para setarmos o clock dos servo motores const int freq_div = 375; // Pinos do relé - lampadas, extensão de tomadas (ventilador) e servo motores const int LAMP1 = 29, LAMP2 = 25, POWER_PLUG = 28, SERVO1 = 1, SERVO2 = 24; // Assinatura das funções para evitar erro de compilação void setPins(Ui::MainWindow *); void updateStatus(Ui::MainWindow *);
Construtor e Destrutor
// Construtor da janela/formulário
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
{
// Inicialização da user interface (o Qt gera o construtor já com este comando)
ui->setupUi(this);
// Setamos o tamanho fixo 1024x600, desabilitando o botão de maximizar
setFixedSize(1024, 600);
// Setamos os pinos (pinMode) e configuramos os PWM dos motores
setPins(ui);
// Instanciamos o objeto QMovie com o giff do ventilador
fanGiff = new QMovie("/home/pi/Desktop/Automacao/Automacao/images/ventilator2.gif");
// Setamos o tamanho do giff sendo mesmo o tamanho da label que o receberá
fanGiff->setScaledSize(ui->lblFan->size());
// Setamos o giff para a label lblFan
ui->lblFan->setMovie(fanGiff);
// Iniciamos o giff (se o ventilador estiver desligado o giff será pausado pela função updateStatus)
fanGiff->start();
// Sincronizamos os componentes da tela com as GPIOs dos relés
updateStatus(ui);
}
// Destrutor
MainWindow::~MainWindow()
{ delete ui; }
setPins
// Função que inicializa os pinos de saída e configura os PWM dos servo motores
void setPins(Ui::MainWindow *ui)
{
// Iniciamos a biblioteca wiring, se acontecer algum erro abortamos o programa
if (wiringPiSetup () == -1)
exit(1);
// Setamos os pios de saída
pinMode(LAMP1, OUTPUT);
pinMode(LAMP2, OUTPUT);
pinMode(POWER_PLUG, OUTPUT);
// Setamos os pinos PWM como PWM_OUTPUT
pinMode(SERVO1, PWM_OUTPUT); //canal 0
pinMode(SERVO2, PWM_OUTPUT); //canal 1
// Configuramos o clock e modo dos servo motores
pwmSetClock(freq_div);
pwmSetMode(PWM_MODE_MS);
}
updateStatus
// Função que atualiza os componentes da tela com o estado atual dos pinos dos relés
void updateStatus(Ui::MainWindow *ui)
{
// Atualiza o componente referente ao ventilador
if(digitalRead(POWER_PLUG))
fanGiff->stop();
else
fanGiff->start();
// Atualiza o componente referente a lampada 1
if(digitalRead(LAMP1))
changeImageButton(ui->imgLamp1, "lamp_off.png");
else
changeImageButton(ui->imgLamp1, "lamp_on.png");
// Atualiza o componente referente a lampada 2
if(digitalRead(LAMP2))
changeImageButton(ui->imgLamp2, "lamp_off.png");
else
changeImageButton(ui->imgLamp2, "lamp_on.png");
}
Eventos dos sliders
// Evento de mudança do slide do servo 1
void MainWindow::on_slider1_valueChanged(int value)
{
// Setamos a label de graus com o novo valor
ui->lblSignalS1->setText(QString::number(value));
// Obtemos o valor PWM correspondente
long ciclo = map(value,0,180,34,120);
// Setamos o PWM no pino do servo 1
pwmWrite(SERVO1, ciclo);
}
void MainWindow::on_slider2_valueChanged(int value)
{
// Setamos a label de graus com o novo valor
ui->lblSignalS2->setText(QString::number(value));
// Obtemos o valor PWM correspondente
long ciclo = map(value,0,180,25,102);
// Setamos o PWM no pino do servo 2
pwmWrite(SERVO2, ciclo);
}
Eventos dos botões das lâmpadas
// Evento de clique da lâmpada 1
void MainWindow::on_imgLamp1_clicked()
{
// Mudamos a imagem da lâmpada para acesa ou apagada, de acordo com o estado atual do pino
// Os relés possuem lógica inversa
// LOW = Ligada
// HIGH = Desligada
// Se o estado atual estiver ligado, mudamos para OFF e vice versa
if(digitalRead(LAMP1) == LOW)
changeImageButton(ui->imgLamp1, "lamp_off.png");
else
changeImageButton(ui->imgLamp1, "lamp_on.png");
// Mudamos o estado do pino, ligando ou desligando a lâmpada
digitalWrite(LAMP1, !digitalRead(LAMP1));
}
// Evento de clique da lâmpada 2, possuí a mesma lógica da função de evento da lâmpada 1
void MainWindow::on_imgLamp2_clicked()
{
if(digitalRead(LAMP2) == LOW)
changeImageButton(ui->imgLamp2, "lamp_off.png");
else
changeImageButton(ui->imgLamp2, "lamp_on.png");
digitalWrite(LAMP2, !digitalRead(LAMP2));
}
changeImageButton
// Função que altera a imagem do push button
// Parametros: Objeto QPushButton, nome do arquivo de imagem
void changeImageButton(QPushButton *btn, char *fileName)
{
char style[200];
// Montamos o array com o estilo do botão inserindo a nova imagem no atributo image
sprintf(style, "background-color: transparent;image: url(/home/pi/Desktop/Automacao/Automacao/images/%s); background: transparent;border: none;", fileName);
// Setamos o novo estilo do push button
btn->setStyleSheet(style);
}
Evento do botão do ventilador
void MainWindow::on_imgFan_clicked()
{
// Iniciamos ou pausamos o giff de acordo com o estado atual do pino
// Os relés possuem lógica inversa
// LOW = Ligado
// HIGH = Desligado
// Se o estado atual estiver ligado pausamos o giff e se estiver desligado iniciamos o giff
if(digitalRead(POWER_PLUG) == LOW)
fanGiff->stop();
else
fanGiff->start();
// Mudamos o estado do pino, ligando ou desligando o ventilador
digitalWrite(POWER_PLUG, !digitalRead(POWER_PLUG));
}
Evento do checkbox que exibe ou não o cursor do mouse
// Evento de mudança de estado do check box de exibição/ocultação do mouse
void MainWindow::on_ckbShowCursor_stateChanged(int arg1)
{
// Se estiver checado exibimos o cursor e vice versa
if(arg1 == Qt::Checked)
this->setCursor(Qt::ArrowCursor);
else
if(arg1 == Qt::Unchecked)
this->setCursor(Qt::BlankCursor);
}













1 Comentários
Vídeo e apresentação de excelente qualidade. Muito bom. Ocorre que, apesar de ter a informação de que todos os desenhos estarem no blog, eu ainda não consegui ver onde estão. É possível a orientação de onde encontrá-los?
ResponderExcluir