Manual
do
Maker
.
com
Esse artigo é o primeiro de uma série com Raspberry Pi, da CurtoCircuito. A série será longa, então melhor fazermos as coisas por partes, a começar pela utilização do Blynk, banco de dados SQLite3 com Raspberry Pi e C++. E é simples, acompanhe!
A CurtoCircuito também está trabalhando com Raspberry Pi a um preço bom, vale a pena adquirir com eles, ainda mais que estaremos iniciando uma série sobre sensores digitais em breve e, meu caro, prepare seu coração!
Primeiro de tudo, baixe o sqlite-autoconf:
sudo su
apt-get update
wget -c https://www.sqlite.org/2019/sqlite-autoconf-3270200.tar.gz
Descomprima a imagem e siga o padrão:
tar zxvf sqlite-autoconf-3270200.tar.gz
cd sqlite-autoconf-3270200
./configure
make -j2
make install
Já para rodar o Blynk, temos ambas as opções; server, para fazer uso à vontade, como descrito nesse artigo, e/ou o client, que vos descrevo agora com Python (mais abaixo, C).
Para que não falte e para que sobre (porque sobrar é melhor do que faltar), siga os passos:
sudo su #se já não estiver como root
curl -sL "https://deb.nodesource.com/setup_6.x" | sudo -E bash -
apt-get install -y nodejs
curl -sL https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
apt-get update && sudo apt-get install yarn
apt-get install npm
npm install -G onoff
npm install -G blynk-library
apt-get install git
git clone --recursive https://github.com/vshymanskyy/blynk-library-python.git
apt-get install python-pip python3-pip
pip install bpython
wget -c https://github.com/blynkkk/blynk-library/releases/download/v0.6.1/Blynk_Release_v0.6.1.zip
apt-get install doxygen
cd libraries/Blynk/linux
./build.sh raspberry
apt-get install libboost-thread-dev
Nesse ponto você já deverá ter o Blynk client compilado no diretório, o suporte a SQLite3 e um extra, que veremos mais adiante.
Eu não vou escrever uma grande aplicação agora, vou apenas criar uma situação que envolva o Blynk e o banco de dados, o resto fica por conta da sua criatividade, ok?
O código básico para criar uma base de dados e executar queries:
select * from teste;
#include <stdio.h>
#include <sqlite3.h>
#include <iostream>
#include <string.h>
using namespace std;
char db_dobitaobyte[70];
sqlite3 *db;
bool using_db = false;
void db_query(char *query, bool usedb);
static int callback(void *NotUsed, int argLen, char **query, char **azColName);
//query a ser feita, boolean para usar ou não a base de dados
void db_query(char *query, bool usedb){
cout << "first line" << endl;
memset(db_dobitaobyte,0,70);
strcpy(db_dobitaobyte,"db_dobitaobyte.sqlite3");
cout << "second line" << endl;
//para o caso de estar em um loop e depender de uma condição p/ atuar
if (!usedb){
return;
}
cout << "starting..." << endl;
char *zErrMsg = 0;
int rc;
//base de dados, objeto da base de dados
rc = sqlite3_open(db_dobitaobyte, &db);
if (rc){ //SQLITE_OK == 0 para ok
string msg = "Couldn't open database \n";
cout << "Erro ao tentar acessar a base de dados. Saindo";
sqlite3_close(db);
using_db = false;
return;
}
//Executa a query
if (sqlite3_exec(db, query, callback, 0, &zErrMsg)){
}
}
//callback da comunicação com o banco
static int callback(void *NotUsed, int argLen, char **query, char **azColName){
cout << "loop" << endl;
for(int i=0; i<argLen; i++){
printf("%s=%s\n", azColName[i], query[i] ? query[i] : "NULL");
}
cout << endl;
return 0;
}
int main(int argc, char **argv){
char q[70];
memset(q,0,70);
strcpy(q,"create table if not exists teste(id integer, message text)");
db_query(q,true);
db_query(argv[1],true);
}
Para compilar, use:
g++ -o sql sql.cpp -lsqlite3
Em main() temos uma query para criar uma tabela no banco, caso não exista. Passando a query por linha de comando, poderíamos criar outra tabela ou fazer quaisquer outras manipulações:
./sql "insert into teste(id, message) values(1,'ok')"
Depois, uma consulta na base de dados recém criada mostraria o resultado, caso tudo tenha ido bem:
Agora, vamos fazer outro programa. Esqueça a base de dados que você acabou de configurar por enquanto.
Vá até esse link e baixe o código para compilar no Raspberry. Por exemplo:
wget -c https://github.com/blynkkk/blynk-library/archive/v0.6.1.tar.gz
Descomprima a blibioteca e entre no diretório criado :
tar zxvf v0.6.1.tar.gz
cd blynk-library-0.6.1/linux
De forma similar a um procedimento supracitado, execute o build:
sudo su
./build
O binário será criado dentro do diretório, com o nome Blynk. Depois, se quiser recompilar, pode simplesmente digitar:
make
A partir de agora é só editar o código base; o main.cpp, que foi escrito de forma a se assemelhar a um sketch de Arduino:
//#define BLYNK_DEBUG
#define BLYNK_PRINT stdout
#ifdef RASPBERRY
#include <BlynkApiWiringPi.h>
#else
#include <BlynkApiLinux.h>
#endif
#include <BlynkSocket.h>
#include <BlynkOptionsParser.h>
static BlynkTransportSocket _blynkTransport;
BlynkSocket Blynk(_blynkTransport);
static const char *auth, *serv;
static uint16_t port;
#include <BlynkWidgets.h>
#include <string.h>
BlynkTimer tmr;
WidgetTerminal terminal(V1);
BLYNK_WRITE(V1)
{
printf("Got a value: %s\n", param[0].asStr());
string res = param[0].asStr();
if (res == "marco"){
terminal.write("polo",4);
terminal.flush();
}
}
void setup()
{
Blynk.begin(auth, serv, port);
tmr.setInterval(1000, [](){
Blynk.virtualWrite(V0, BlynkMillis()/1000);
});
}
void loop()
{
Blynk.run();
tmr.run();
}
int main(int argc, char* argv[])
{
parse_options(argc, argv, auth, serv, port);
setup();
while(true) {
loop();
}
return 0;
}
Então, se você é usuário de Arduino, não terá trabalho em migrar código, basta dar atenção ao **setup()**e loop(), escrevendo seu código à vontade!
Supondo que você ainda não tenha configurado o Blynk Server, proceda como descrito nesse artigo. Podemos ler dados enviados de sensores para o app do smartphone simplesmente utilizando o mesmo token no código que será compilado no Raspberry. Algo como descrito nesse outro artigo.
Se desejar comunicação entre tokens diferentes, pode usar o widget Bridge, como descrito aqui. Se quiser ver um bocado mais de recursos do Blynk, recomendo a leitura desse artigo.
Enfim, basicamente trata-se da configuração de um VirtualPin onde o dado é tratado e alguma ação é disparada. Com isso, podemos instanciar uma base de dados em qualquer lugar do programa e executar as queries dentro das chamadas desses VirtualPins.
Vou integrando cada vez mais os códigos, conforme os artigos forem sendo escritos. Sugiro que aproveite para fazer umas brincadeiras com o material de hoje para estar mais íntimo no momento em que formos construir uma aplicação mais robusta que poderá ser utilizada em um projeto com pouca modificação.
Até a próxima!
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.