Manual
do
Maker
.
com
No artigo anterior discorri a respeito desse sensor de cores, utilizando um sketch de exemplo da própria biblioteca. Eu gostaria de ter feito um video mostrando a correspondência em um LED RGB, mas (não por acaso) não encontrei meus LEDs RGB. Então resolvi fazer um programa gráfico pra ler no computador o resultado da leitura do sensor e exibir em um color picker.
Para programar interfaces gráficas, eu sempre utilizo o Qt, que é um framework de C++, mas que facilita tanto, mas tanto que nem parece programação C++ de tão simples e tão rápido. Pra ter uma ideia, levei menos de 2 horas para escrever esse programa, mas isso porque dei uma pesquisada antes em quais recursos eu iria utilizar. De código mesmo, o programa tem umas 80 linhas no máximo.
O Qt é multiplataforma, você pode utilizá-lo para programar para Windows, Linux, BSDs, MAC, Android, Raspberry etc. O mais legal é que você pode fazer no seu computador pessoal, executar, testar e depois só compilar na plataforma de destino (ou fazer cross-compiling).
Dê uma passada pelo site do Qt e baixe a versão para Windows, se for sua plataforma. Ainda, você pode baixar um instalador para Linux, ou instalar a partir dos repositórios de sua distribuição.
Existe versão paga se desejar modificar o código do Qt em sí, mas você faz qualquer coisa com a versão opensource.
Se quiser baixar esse programa de exemplo que fiz, pegue-o em meu repositório no github.
Tem dois bugs, um é um pico que de vez em quando dá na cor verde. O outro era esperado, porque eu iniciei a serial dentro do fluxo da janela principal do programa, mas fiz de propósito porque não quis escrever uma thread para essa tarefa simples. Nesse caso, a janela fica bloqueada pela thread da serial, mas como essa tarefa está com o controle da janela, a aplicação de cores na paleta acontece sem maiores complicações.
Só pra ter uma ideia da simplicidade, estou colocando apenas o código da MainWindow com alguns comentários.
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
/*Uma instância do controlador da porta serial*/
this->serialPort = new QSerialPort;
QStringList ports;
//pegar portas disponiveis e alimentar o combobox
const auto serialPortInfos = QSerialPortInfo::availablePorts();
//criar uma lista com as portas disponíveis para alimentar o combobox
int i = 0;
for (const QSerialPortInfo &serialPortInfo : serialPortInfos) {
ports.insert(i, serialPortInfo.portName());
i++;
}
//alimentar o combobox com a lista de portas
ui->comboBox_port->insertItems(0,ports);
//criar lista de velocidades pro combobox
QStringList bauds;
bauds << "9600" << "19200" << "38400" << "57600" << "115200";
ui->comboBox_baud->insertItems(0,bauds);
//mostrar o diálogo de cores, que é um widget pronto
this->showColor = new QColorDialog;
this->showColor->show();
//esse recurso se chama SIGNALS&SLOTS, que pretendo falar a respeito
//fazendo tutoriais de Qt em video
connect(this,SIGNAL(startReading(bool)),this,SLOT(mySerialReader()));
connect(ui->pushButton_connect,SIGNAL(clicked(bool)),this,SLOT(connectToSerial()));
}
//método executado quando clicar em "Conectar"
void MainWindow::connectToSerial()
{
if (this->isConnected){
this->serialPort->close();
ui->label_status->setText("Não conectado");
this->isConnected = false;
ui->pushButton_connect->setText("Conectar");
return;
}
//configurar a porta serial
this->serialPort->setPortName(ui->comboBox_port->currentText());
this->serialPort->setBaudRate(ui->comboBox_baud->currentText().toUInt());
//conectar à porta serial
if (!this->serialPort->open(QIODevice::ReadOnly)){
ui->label_status->setText("Falha ao tentar conectar :-(");
return;
}
ui->label_status->setText("Conectado! :-)");
ui->pushButton_connect->setText("Desconectar");
this->isConnected = true;
emit startReading(true);
}
//método para fazer a leitura da porta serial e atribuir a cor
//ao color picker.
void MainWindow::mySerialReader()
{
QByteArray readData = this->serialPort->readAll();
while (this->serialPort->waitForReadyRead(5000)){
readData = this->serialPort->readAll();
if (readData.contains("\r\n")){
readData = readData.replace("\r\n","");
QStringList TCS;
TCS << QString(readData).split(" ");
qDebug() << TCS;
if (TCS.length() == 3){
QColor myColor;
myColor.setBlue(TCS.at(2).toInt());
myColor.setRed(TCS.at(0).toInt());
myColor.setGreen(TCS.at(1).toInt());
this->showColor->setCurrentColor(myColor);
}
}
}
}
//destrutor da classe
MainWindow::~MainWindow()
{
delete ui;
}
Repare que o programa ficou mais ou menos do mesmo tamanho que o programa para o Arduino (falando em linhas de código, claro).
Não sou nenhum guru em Qt, mas já fiz coisas interessantes e pensei em fazer videos tutoriais desde o básico, para interagirmos com Raspberry, Arduino, ESP, MIPS etc. Podemos fazer a comunicação por SSH, serial, MQTT etc.
Se tiver interesse, se inscreva em nosso canal no Youtube e deixe seu like ou comentário (ou preferencialmente os dois) para que eu tenha um feedback sobre essa ideia de tutoriais de programação em Qt.
No Arduino, utilizei o seguinte código, baseado no sketch de exemplo:
#include <Wire.h>
#include "Adafruit_TCS34725.h"
// Pick analog outputs, for the UNO these three work well
// use ~560 ohm resistor between Red & Blue, ~1K for green (its brighter)
#define redpin 3
#define greenpin 5
#define bluepin 6
// for a common anode LED, connect the common pin to +5V
// for common cathode, connect the common to ground
// set to false if using a common cathode LED
#define commonAnode true
// our RGB -> eye-recognized gamma color
byte gammatable[256];
Adafruit_TCS34725 tcs = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_50MS, TCS34725_GAIN_4X);
void setup() {
Serial.begin(115200);
if (!tcs.begin()) {
Serial.println("No TCS34725 found ... check your connections");
while (1); // halt!
}
// use these three pins to drive an LED
pinMode(redpin, OUTPUT);
pinMode(greenpin, OUTPUT);
pinMode(bluepin, OUTPUT);
// thanks PhilB for this gamma table!
// it helps convert RGB colors to what humans see
for (int i=0; i<256; i++) {
float x = i;
x /= 255;
x = pow(x, 2.5);
x *= 255;
if (commonAnode) {
gammatable[i] = 255 - x;
} else {
gammatable[i] = x;
}
//Serial.println(gammatable[i]);
}
}
void loop() {
uint16_t clear, red, green, blue;
tcs.setInterrupt(false); // turn on LED
delay(60); // takes 50ms to read
tcs.getRawData(&red, &green, &blue, &clear);
tcs.setInterrupt(true); // turn off LED
// Figure out some basic hex code for visualization
uint32_t sum = clear;
float r, g, b;
r = red; r /= sum;
g = green; g /= sum;
b = blue; b /= sum;
r *= 256; g *= 256; b *= 256;
Serial.print((int)r);
Serial.print(" ");
Serial.print((int)g);
Serial.print(" ");
Serial.println((int)b);
analogWrite(redpin, gammatable[(int)r]);
analogWrite(greenpin, gammatable[(int)g]);
analogWrite(bluepin, gammatable[(int)b]);
}
No artigo anterior discorro sobre os detalhes da biblioteca.
Esse sensor de cores está disponível no Baú da Eletrônica, cujo sensor escrevi o tutorial introdutório nesse outro artigo. Achei ele bem interessante e mesmo sem ter feito um acoplamento, o resultado da detecção está sendo bastante satisfatório!
Fiz um video utilizando uma série de objetos com cores variadas.. O resultado você vê nesse teste.
Inscreva-se no nosso canal Manual do Maker no YouTube.
Também estamos no Instagram.
Autor do blog "Do bit Ao Byte / Manual do Maker".
Viciado em embarcados desde 2006.
LinuxUser 158.760, desde 1997.