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