Blynk, SQLite3 com Raspberry Pi e C++

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!

Raspberry Pi na CurtoCircuito

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!

Instalando a base de dados SQLite3 no Raspberry

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

Instalando Blynk client no Raspberry

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.

Exemplo de SQLite3 com Raspberry Pi

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:

#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:

Compilando Blynk com Raspberry

Agora, vamos fazer outro programa. Esqueça a base de dados que você acabou de configurar por enquanto.

baixe a biblioteca

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() loop(), escrevendo seu código à vontade!

Como interagir com dados do Blynk?

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!

Djames Suhanko

Djames Suhanko é Perito Forense Digital. Já atuou com deployer em sistemas de missão critica em diversos países pelo mundão. Programador Shell, Python, C, C++ e Qt, tendo contato com embarcados ( ora profissionalmente, ora por lazer ) desde 2009.

Um comentário em “Blynk, SQLite3 com Raspberry Pi e C++

Fechado para comentários.