A WandBoard é um Single Board Computer de baixo custo, com alto poder de processamento, principalmente gráfico. Ela é pode ser encontrada em 3 diferentes versões, solo, dual e quad, cujo a principal diferença entre elas está no número de cores do processador e tamanho da memória RAM, elas tem 1 (solo), 2 (dual) ou 4 (quad) cores é 512, 1Gb ou 2Gb de memória respectivamente. Outro ponto forte da Wand é seu grande número e dispositivos I/O (que vão desde HDMI a pinos de gpio) e conectividade (wifi, ethernet, Bluetooth, USB).
Neste Post iremos ensinar a programação para dispositivos de I/O da Wand, em especial para as portas de gpios, para isso usaremos uma placa com um sistema operacional ubuntu em funcionamento, descrevemos como colocar o ubuntu em outro post.
Portas gpios
As portas gpios são portas programáveis para entrada e saída de dados, elas fornecem uma interface de comunicação direta de microprocessadores com periféricos, servindo como uma porta de comunicação entre hardwares. Com elas podemos ler ou enviar sinais binários (0,1) de periféricos, isto nos dá uma infinidade de possibilidades de programação como, por exemplo, ler dados de um microfone (a partir da frequência dados, zeros e uns, enviado por eles) ou acender e apagar um led (enviando sinais 1 para acender ou 0 para apagar).
Vários dispositivos de programa para sistemas embargados contam com portas gpios de fácil programação, um exemplo famoso é o arduino, e normalmente a programação para a mesma e muito simples, precisando somente setar a direção que ela será usada, ou seja, se será usada para entrada ou para saida de dados, e partir disso utilizá-la, caso seja setada como entrada lendo seus dados, ou, caso seja usada para saída, enviar dados a ela.
Portas Gpio WandBoard
Na WandaBoard as portas Gpios, são dívidas em 4 grupos (Jp4,Jp3,Jp2, Jp1), cada um com 20 entradas, porém não todas que são programáveis, alguma são de corrente contínua ou GND, na imagem abaixo está descrito detalhadamente cada uma destas portas.
E importante saber exatamente em porta trabalharemos, porém como pode se ver seus nomes não são tão indutivos, para isto e bom verificar a tabela abaixo na hora de programa para uma porta.
Programando para GPIO na WandaBoard
Como disse na maioria do casos programação para portas são bem simples, apenas setamos a direção e a utilizamos conforme ela, na Wand isso também é assim. Resumindo para comunicar com elas precisamos somente de editar um arquivo de texto, algo que podemos fazer de várias maneiras, seja através de programa, ou ate mesmo por comando do shell linux.
Neste post demonstraremos como comunicar com as portas de dois modos, pelo shell linux e por um programa em c, disponibilizaremos no final um scrip para linux e uma classe C com vários tipos de comando possíveis para a programação em GPIO.
Comunicando a partir de comando do shell
Iniciamente precisamos de que criar a conexão com a porta, para isso vamos ter que escrever a porta utilizada no arquivo export (no diretorio /sys/class/gpio/). Para escrever em arquivos no shell bastamos fazer o comando echo e passar o queremos escrever, no caso de exemplo usaremos a porta 91 (que é a porta 6 do JP4), assim faremos o seguinte comando :
[code language=”shell”]
echo 91 > /sys/class/gpio/export
[/code]
Feito criaremos uma pasta gpioXX (XX é o número da porta), neles trabalharemos a partir de agora. O próximo passo é setar a direção no arquivo direction, ela pode ser entrada ‘in’ ou saida ‘out’, neste exemplo vamos fazer uma porta de entrada.
[code language=”shell”]
echo out > /sys/class/gpio/gpio91/direction
[/code]
com a porta setada como saida nosso próximo passado e dar comando a ela, que são comando 1 ou 0, isso pode ser feito escrevendo o valor no arquivo value como demonstrado a seguir.
[code language=”shell”]
echo 1 > /sys/class/gpio/gpio91/value // enviando sinal 1
echo 0 > /sys/class/gpio/gpio91/value // enviando sinal 0
[/code]
Ja no caso de uma porta de entrada ou inves de enviarmos iremos ler o dados da porta, para isso temos de setar a direção como ‘in’, e nescecitamos somente ler o valor que estiver no arquivo value. Podemos usar os seguintes comandos:
[code language=”shell”]
echo in > /sys/class/gpio/gpio24/direction<a href="http://www2.decom.ufop.br/imobilis/wp-content/uploads/2014/10/Wandboard-dual.jpg">
</a>
/sys/class/gpio/gpio24/value
[/code]
Pronto, temos um sistema de comunicação com as gpios via shell, abaixo esta um scrip completo com essas funcionalidades:
Apesar do shell ser muito bom para teste, na mairia dos casos utilizamos essas portas em nossos programa. Assim para facilitar na programação iremos descrever a seguir como utilizar as portas por meio de comandos em C;
Programando as portas com comando C
Para utilizar gpios em programas C podemos utilizar comando shell em programas através de scrip ou da função ‘system’ do c, porem ,além de não ser eficiente, esta não é uma solução elegante, o melhor modo de fazê-lo e através de comando C diretos.
Vamos ensinar como fazer esta comunicação e ao final deste post forneceremos uma classe bem completa para comandar as portas.
Como foi dito para fazer a comunicação e necessário somente editar alguns arquivos, o que pode ser facilmente feito em C. O primeiro arquivo a editar e export, no qual temos que enviar a porta que sera utilizada, abaixo segue um codigo de como podemos fazer isto:
[code language=”c”]
int port = 91;
string exportPath = "/sys/class/gpio/export"; //caminho ate o arquivo a ser editado
int exportFile = open(exportPath.c_str(), O_WRONLY); //Abrindo arquivo
if (exportFile < 0) { //Caso não abra retorne uma mensagem de erro
cout << "Não foi possível abrir o arquivo export para a porta/ " << port << "." << endl;
return;
}
char buffer[3];
sprintf(buffer, "%d", port); //Passando o inteiro com o numero da porta para char*
write(exportFile,buffer, 4); //Escrevendo no arquivo export
close(exportFile); //Fechando o arquivos
[/code]
Em seguida temos que editar os arquivos direction e value, a comando e semelhante ao anterior, eles estão descritos a seguir.
Setando direção
[code language=”c”]
char* direction = “out”;
string directionPath;
ostringstream ss;
ss << port;
string strPort = ss.str();
directionPath = "/sys/class/gpio/gpio" + strPort + "/direction"; //caminho do arquivo direction
int directionFile = open(directionPath.c_str(), O_WRONLY); //abrindo arquivo
if (directionFile < 0) { //Verificando se o arquivo foi aberto corretamente
cout << "não foi possível abrir arquivo direction" << port << "." << endl;
return;
}
write(directionFile,direction.c_str(), 4); //Escrevendo no arquivo
close(directionFile); //fechando o arquivo
[/code]
Setando valor
[code language=”c”]
string valuePath;
ostringstream ss;
ss << port;
string strPort = ss.str();
valuePath = "/sys/class/gpio/gpio" + strPort + "/value"; //caminho do arquivo value
int valueFile = open(valuePath.c_str(), O_WRONLY); //abrindo arquivo
if (valueFile < 0) { //verificando se o arquivo foi aberto corretamente
cout << "Não foi possível abrir arquivo value " << port << "." << endl; //
return;
}
write(valueFile,"1", 4); //escrevendo valor 1 no arquivo
close(valueFile); //fechando arquivo
[/code]
Para ler os valores da porta de saída precisamos apenas ler do arquivo value e setar a direção para ‘in’, para modificar a direção podemos usar o codigo anterior, mas mudando de ‘out’ para ‘in’, já para ler o arquivo temos uma ideia similar com pequenas mudanças, o codigo de leitura poderar ser semelhante ao seguinte:
[code language=”c”]
if (direction == "out"){ //verificando se o arquivos esta para estrada
cout << "Could not read value, because gpio is only for write"; </span>
return -1;
}
int valor;
string valuePath;
ostringstream ss;
ss << port;
string strPort = ss.str();
valuePath = "/sys/class/gpio/gpio" + strPort + "/value"; //caminho do arquivo
ifstream infile;
infile.open(valuePath.c_str()); //abrindo arquivo
if (!infile.is_open()) { //verificando se o arquivo foi aberto
cout << "não possível abrir arquivo Value " << port << "." << endl;
return -1;
}
infile >> value; //lendo valor que esta no arquivo e salvando na variavel valor
[/code]
Para facilitar o uso das Gpios fizemos uma classe que faz todos os comandos passado, ela chama WBGpioPin, e tem como parametros a porta que sera lida e a direção, entre suas funções esta ler o valor de uma porta, ou escrever um valor High (1) ou Low(0) em uma porta, assim como tambem escrever um valor (0 ou 1) na porta por um intervalo de tempo passado.
Para baixar a classe clique aqui;
Agradecimentos ao Ricardo Camara pela ajuda nos codigos.