A linguagem C foi criada nos anos de 1970 e embora um pouco antiga, ainda é amplamente usada nos dias de hoje. É considerada uma das linguagens de uso geral mais populares. O público que utiliza essa linguagem varia desde entusiastas e hobbystas construindo projetos em casa até profissionais da indústria que ganham seu pão de cada dia programando em C.
Podemos encontrar a linguagem C em diversos lugares. Pequenos dispositivos como relógios digitais e cafeteiras como também grandes sistemas de software sendo executados em máquinas industriais, são apenas alguns exemplos do uso desta poderosa linguagem. Se você já usou Linux deve saber que grande parte do sistema foi e é escrito em linguagem C. Até mesmo parte do sistema da Raspberry Pi, o Raspbian, é escrito em C.
Neste tutorial iremos apresentar como configurar a Raspberry Pi para desenvolvimento em linguagem C mostrando alguns exemplos básicos como piscar um LED e ler botões.
Materiais necessários
Para realizar os exemplos deste tutorial você irá precisar dos seguintes materiais:
- Placa Raspberry Pi (qualquer modelo)
- Fonte 5V 3A para Raspberry Pi
- LED Azul
- Resistores de 330Ω, 470Ω ou 510Ω
- Chave push button
- Jumpers macho fêmea
- Protoboard
- Cartão micro SD
É necessário instalar a imagem Raspbian com Desktop no cartão micro SD. Para gravar imagem no cartão recomendamos o software Etcher pois é bem fácil de usar.
Circuito Eletrônico
O circuito utilizado para este tutorial é bem simples e de fácil montagem. Monte conforme a figura a seguir:
IDE Geany para desenvolvimento em linguagem C
Os programas chamados IDE (Integrated Development Environment) nos permitem desenvolver aplicações, executá-las, achar possíveis erros no código, além de outras facilidades no decorrer do desenvolvimento da aplicação.
Existem IDEs que suportam diversos tipos de linguagem. Para este tutorial usaremos a IDE Geany que já vem inclusa na imagem Desktop da Raspberry Pi. No Geany iremos escrever, compilar e executar nossas aplicações em linguagem C.
A IDE Geany se encontra na seção Programming no menu iniciar.
No editor de código insira o seguinte programa “Hello World”:
#include <stdio.h> int main() { printf("Hello World!\n"); return 0; }
Salve o programa em alguma pasta do sistema com algum nome terminado em “.c” como hello_world.c. Para isso clique em File -> Save, digite o nome do arquivo terminado em “.c”, escolha a pasta e clique em Save.
Para executar a aplicação selecione o menu Build -> Build e depois Build -> Execute ou pressione F9 e então F5. Um terminal deverá abrir com a mensagem “Hello World!”.
Você pode verificar que foi gerado um arquivo binário de nome hello_world na mesma pasta onde o programa foi salvo. Abrindo um terminal é possível executar o programa utilizando o seguinte comando:
./hello_world
E veremos a mensagem “Hello World!” no terminal.
Pronto! Agora você já sabe como desenvolver aplicações em linguagem C na Raspberry Pi.
Biblioteca WiringPi
Para quem já programou Arduino vai achar bem fácil a biblioteca WiringPi. Ela foi desenvolvida para facilitar o acesso e controle dos pinos GPIO da Raspberry Pi. É uma biblioteca feita para uso em programas de linguagem C ou C++. Assim como a IDE Geany, a biblioteca WiringPi já vem instalada no sistema bastando apenas incluir a biblioteca em seu programa com a linha “#include <wiringPi.h>“. Caso a biblioteca não esteja instalada por padrão, seguir os passos de instalação encontrados aqui.
WiringPi também vem com um programa de linha de comando chamado gpio que também pode ser utilizado para pequenos testes. Executando o comando “gpio readall” podemos ver uma tabela com a organização dos pinos. Veja a seguir:
A coluna marcada em azul indica a numeração que será usada nas funções da biblioteca. As colunas em amarelo indicam se o pino está configurado como entrada ou saída. A coluna central em verde mostra a numeração dos pinos físicos da Raspberry Pi.
As funções principais da biblioteca são as seguintes:
void pinMode (int pin, int mode)
Configura um GPIO como entrada, saída ou saída PWM. “int mode” pode ter os valores INPUT, OUTPUT ou PWM_OUTPUT.
void pullUpDnControl (int pin, int pud)
Configura os resistores internos de pull-up ou pull-down. “int pud” pode ter os valores PUD_OFF (sem resistor interno), PUD_UP(resistor pull-up 3,3V) e PUD_DOWN(resistor pull-down GND).
void digitalWrite (int pin, int value)
Escreve valores HIGH ou LOW (1 ou 0) em um determinado pino configurado anteriormente como saída.
void pwmWrite (int pin, int value)
Escreve um valor de PWM(0-1024) em um determinado pino.
int digitalRead (int pin)
Retorna o valor lido em um determinado pino podendo ser HIGH ou LOW (1 ou 0).
Três Exemplos com a Biblioteca WiringPi
Mostraremos 3 exemplos básicos em linguagem C utilizando a biblioteca WiringPi. O primeiro é o Hello World da eletrônica, um pisca LED. No segundo exemplo utilizaremos uma chave push button para acender e apagar o LED. No terceiro exemplo utilizaremos PWM para controlar o LED.
Importante! Para que os programas compilem e executem corretamente é necessário indicar ao Geany que utilizaremos a biblioteca WiringPi e executaremos a aplicação como sudo. Para isso clique no menu Build -> Set Build Commands e nos campos Compile, Build e Execute adicione “-l wiringPi” e “sudo” como na figura abaixo. Caso execute os binários pela linha de comando, lembrar de utilizar “sudo ./nomePrograma“.
Exemplo 1 – Pisca LED
Neste exemplo faremos um LED piscar de 1 em 1 segundo. Crie um novo programa no Geany com o nome “pisca_led.c” e copie o seguinte código fonte:
#include <stdio.h> #include <wiringPi.h> int main() { wiringPiSetup(); // inicia a biblioteca WiringPi pinMode(1, OUTPUT); // configura o pino 1 como saída printf("Exemplo 1 - Pisca LED\n"); //imprime mensagem na tela while(1) { digitalWrite(1, HIGH); // liga o pino 1 delay(1000); // espera 1 segundo digitalWrite(1, LOW); // desliga o pino 1 delay(1000); // espera 1 segundo } return 0; }
Importante! O pino 1 se refere ao pino da biblioteca que na verdade é o pino físico 12 da barra de pinos da Raspberry.
Salve o arquivo e aperte F9(Build) e depois F5(Execute) para executar o programa. Você verá o LED piscando como a seguir.
Exemplo 2 – Controle do LED com chave Push Button
Neste exemplo iremos ligar e desligar o LED pela chave push button.
#include <stdio.h> #include <wiringPi.h> int main() { wiringPiSetup(); // inicia biblioteca wiringPi pinMode(1, OUTPUT); // configura pino 1 como saida pinMode(7, INPUT); // configura pino 7 como entrada pullUpDnControl(7, PUD_UP); // configura resistor pull-up no pino 7 int estadoLED = 0; printf("Exemplo 2 - Controle do LED com chave push button\n"); //imprime mensagem na tela while(1) { if(digitalRead(7) == LOW) // detecta se a chave foi pressionada { estadoLED = !estadoLED; // inverte o estado do LED digitalWrite(1, estadoLED); // controla o LED conforme estado if(estadoLED == 1) printf("LED aceso\n"); // imprime estado do LED if(estadoLED == 0) printf("LED apagado\n"); // imprime estado do LED delay(20); while(digitalRead(7) == LOW); // aguarda enquato chave ainda esta pressionada delay(20); } } return 0; }
Exemplo 3 – Controlando LED por PWM
Neste exemplo iremos acender e apagar o LED utilizando PWM.
#include <stdio.h> #include <wiringPi.h> int main() { wiringPiSetup(); // inicia a biblioteca WiringPi pinMode(1, PWM_OUTPUT); // configura o pino 1 como saída PWM int i; // declara variável para o loop for printf("Exemplo 3 - Controlando LED por PWM\n"); //imprime mensagem na tela while(1) { for(i=0;i<=1024;i+=4) // faz um loop mudando valor de i de 0 a 1024 com um passo de 4 { pwmWrite(1, i); // escreve 0-1024 a cada iteração delay(3); } for(i=1024;i>=0;i-=4) // faz um loop mudando valor de i de 1024 a 0 com um passo de 4 { pwmWrite(1, i); // escreve 1024-0 a cada iteração delay(3); } } return 0; }
O código fonte e o binário pré-compilado dos três exemplos podem ser encontrados no GitHub da MakerHero.
Neste post você aprendeu os primeiros passos para programar em linguagem C usando a Raspberry Pi. Com os conceitos aqui apresentados e utilizando a biblioteca WiringPi é possível controlar motores, ler sensores e muito mais! Para você que quer se aprofundar na linguagem C, veja o post Raspberry Pi e ThingSpeak onde Pedro Bertoleti apresenta um programa desenvolvido em C que envia valores para a nuvem sendo mostrados em um gráfico na plataforma ThingSpeak. Acesse também a revista MagPi ensinando muito mais sobre linguagem C.
Gostou de programar em linguagem C? Deixe seu comentário logo abaixo.
Aprendi a programar no C Progressivo (https://www.cprogressivo.net/), me ajudou muito a entender o tutorial de vocês também
Prezado
Eu preciso desenvolver uma aplicação em C ou C++ no eclipse na plataforma Windows 10 e posteriormente transferir para o raspberry. Eu já instalei um Cross compiler bem como realizei um belo word e transferi para raspberry….funcionou ok usando apenas a porta HDMI.
Eu agora preciso ter acesso aos GPIO mas a biblioteca wiringPi para o eclipse eu não encontro….o site oficial está fora do ar…você sabe alguma alternativa?
Parabéns pelo seu trabalho
Att
Prof. Wagner Ideali
Instituto federal SP
Boa noite, meu led nao liga, o botao funciona, utilizando o segundo exemplo, ele detecta quando eu aperto o botao porem o led nunca liga.
Estou sem acentos, me desculpem.
Resovido, o led estava invertido 🙁
OBAA!!! Cara muito bom! Fiz os três exemplos em menos de 30min!
Agora uma dificuldade bem boba. Alterei o programa para acionar um outro pino, tentei o 4, 5, 28 ou o 29.
Não tive resultados. o código que usei foi:
#include
#include
int main()
{
wiringPiSetup(); // inicia a biblioteca WiringPi
pinMode(28, PWM_OUTPUT); // configura o pino 28 como saída PWM
int i; // declara variáveis para o loop for
printf(“Exemplo 3 – Controlando 3 LED por PWM\n”); //imprime mensagem na tela
while(1)
{
for(i=0;i=0;i-=4) // faz um loop mudando valor de i de 1024 a 0 com um passo de 4
{
pwmWrite(28, i); // escreve 1024-0 a cada iteração
delay(3);
}
}
return 0;
}
Apenas o pino 1 (conforme o wiringPi) é acionado.
Saberia dizer o por quê?
WiringPi _______BCM
GPIO.1_______(BCM 18)
GPIO.23______(BCM 13)
GPIO.24______(BCM 24)
GPIO.26______(BCM 12)
Conforme:
https://www.raspberrypi.org/forums/viewtopic.php?t=151086
Olá, Fernando!
Pelas configurações aqui, diria que apenas esses pinos funcionam o PWM? Nesse caso, ao acionar o 28 (que não consta na lista), ele não funciona o PWM por não suportar.
Caso fique alguma dúvida, ou deseja uma visão mais detalhada, você pode acionar nosso fórum 😉
Abraços!
Diogo – Equipe MakerHero
Boa noite! Ótimo trabalho, parabéns! Com base no teu projeto, fiz um na qual aciono os leds de acordo com a opção do usuário, coletando essa opção com Scanf e usando condicionais If para o acionamento, mas após fechar a execução, os pinos acionados ficam sempre em nível lógico alto. Como faço para os pinos voltarem para nivel lógico baixo após encerrar a execução? Abraço.
Olá Rafael!
Veja se o seguinte funciona para você: https://linux.die.net/man/3/atexit
Você poderia registrar uma função para ser chamada antes do programa terminar. Nessa função você poderia colocar pra desligar os LEDs.
Olá! Excelente Tutorial! Como faço para configurar os pinos Gpio como entrada ou saída? É possível fazer pelo terminal? Obrigado.
Olá Marcelo!
É possível fazer pelo terminal sim.
Estude os seguintes tutoriais:
https://sites.google.com/site/semilleroadt/raspberry-pi-tutorials/gpio
WiringPi também tem uma aplicação chamada gpio que pode ser usada para manipular os GPIOs via terminal.
Bons estudos!
Obrigado, foram dicas muito úteis! Estou usando o exemplo do Pisca Led. Estou com a seguinte dificuldade: Notei que as alterações que faço no programa não respondem na hora que rodo! Ex: trocar a mensagem do Printf; quando rodo, está sempre mostrando a mensagem original do exemplo. Porém, se há algum erro de sintaxe, a plataforma reconhece. Mas nas alterações, mesmo deixando a programação toda comentada com //, o programa roda!
Outra coisa, o pino 7 (físico) é o que está respondendo a função do Blink, independente da configuração no Gpio/pinMode da programação. Parece que a Raspberry está sempre executando o mesmo programa independente do que altero no Geany. Alguma ajuda sobre? Obrigado.
Opa. Sobre a dúvida anterior acabei resolvendo. Não basta compilar, mas toda a vez que se faz alguma alteração é necessário clicar no botão “Construir”, aí sim ele aceita as alterações que se faz na programação. Nem é necessário alterar pelo Gpio. Obrigado!
Boa tarde. Estou procurando bibliotecas do Raspberry para Linux, sabe onde posso encontrar? Grato.
Olá Mario!
Que tipo de biblioteca está procurando?
Alguma biblioteca específica para algum dispositivo/sensor?
O Github tem inúmeras bibliotecas em diversas linguagens inclusive C.
Olá, tudo bem? Gostei dessa possibilidade de usar a linguagem C para programação em Raspberry Pi, sei que também é possível com a linguagem Python. No entanto, gostaria de saber se você conhece algum livro que aborde este tema, programar em C ou Python no Raspberry PI, que nos oriente sobre bibliotecas, comandos e funções que possamos usar para controlar elementos externos, como motores, LEDs, sensores… Você conheceria alguma bibliografia? Obrigado
Olá Leandro,
Pesquisando no google encontrei alguns
https://www.amazon.com/Programming-Raspberry-Pi-Getting-Started/dp/0071807837
https://www.amazon.com.br/Learning-Python-Raspberry-Alex-Bradbury/dp/1118717058
https://www.adafruit.com/product/1089
Mas tem muito conteúdo totalmente gratuito na internet. Basta fazer algumas pesquisas no Blog MakerHero, Google, Hackster.io, instructables, Portal Embarcados, Adafruit, Sparkfun, etc… Todos sites com conteúdo sobre Raspberry Pi e controle de dispositivos.
Segue alguns exemplos:
https://www.makerhero.com/blog/campainha-iot-com-raspberry-pi-zero-w/
https://www.makerhero.com/blog/text-to-speech-com-a-raspberry-pi-3b/
https://www.makerhero.com/blog/raspberry-pi-controlar-o-nodemcu-parte-1/
https://www.makerhero.com/blog/informacoes-cpu-raspberry-pi-zero-w-com-display-oled/
https://www.makerhero.com/blog/automacao-basica-bluetooth-ble-na-raspberry-pi/
Agora é pesquisar mais na internet, ter a placa em mãos e colocar a mão na massa!
Muito obrigado
Boa tarde, estou precisando desenvolver um sistema no qual envolve um banco de dados. Segue o passo a passo:
Uma pessoa encosta uma carteirinha em um RFID, liberando o sistema para funcionar, irá passar um material na frente de um sensor fazendo essa contagem e mandando para o banco de dados e quando o usuário parar de inserir material, o sistema salva essa contagem, e quando o usuário voltasse a inserir o cartão no sistema e colocasse o material, continuasse essa contagem. Gostaria se seria possível alguém me ajudar.
Olá André, vc já resolveu seu problema? A solução poderia ser usando outro dispositivo que não seja o raspberry? Tipo o ESP8266 ou ESP32 ?
Boa noite.
Primeiramente parabens pelo artigo. Gostaria de tirar uma duvida, poque eu nao estou conseguindo executar o codigo? Me retorna este erro.
gcc -Wall -o “Pisca_Led” “Pisca_Led”-l wiringPi (in directory: /home/pi/Documents/Study/C)
gcc: error: Pisca_Led-l: No such file or directory
gcc: error: wiringPi: No such file or directory
gcc: fatal error: no input files
compilation terminated.
Compilation failed.
Olá Adriano! obrigado pela leitura.
Veja se não faltou um espaço ali entre o nome do arquivo e ‘-l wiringPi’
“Pisca_Led” -l wiringPi
Isso você deve ter configurado nessa parte do post:
“Importante! Para que os programas compilem e executem corretamente é necessário indicar ao Geany que utilizaremos a biblioteca WiringPi e executaremos a aplicação como sudo. Para isso clique no menu Build -> Set Build Commands e nos campos Compile, Build e Execute adicione “-l wiringPi” e “sudo” como na figura abaixo. Caso execute os binários pela linha de comando, lembrar de utilizar “sudo ./nomePrograma“.”
Deve ficar assim:
Compile: gcc -Wall -c “%f” -l wiringPi
Build: gcc -Wall -o “%e” “%f” -l wiringPi
o meu esta exactamente com esta configuração e não esta funcionado pode me ajudar?
gcc -Wall -c “teste5.c” -l wiringPi (no diretório: /home/pi)
gcc: error: “teste5.c”: Arquivo ou diretório inexistente
Perfeito!!!!
Parabéns pelo tutorial! muito bom mesmo! Dúvida :Configura os resistores internos de pull-up ou pull-down. Tem pinos específicos para rodar em pull-up ou qualquer pino pode usar?
Outra dúvida, é add bibliotecas como ultrassonic, dht, entre outros , igual na ide do arduino?
Valeu, obrigado!
Olá Pedro!
Obrigado pela leitura!
Todos os GPIOs tem resistores internos que você pode ativar/desativar via software. Mas seria legal dar uma olhada no datasheet do processador.
As bibliotecas do Arduino não irão servir diretamente, mas o princípio de funcionamento é o mesmo. Você talvez precisaria entender como uma biblioteca Arduino funciona por debaixo dos panos e implementar o princípio na Raspberry Pi.
Mas provavelmente você encontra pela internet várias bibliotecas prontas.
Esse tutorial por exemplo, usou uma biblioteca lcd.h
http://www.circuitbasics.com/raspberry-pi-lcd-set-up-and-programming-in-c-with-wiringpi
Esse outro implementou a leitura do sensor DHT11 diretamente, usando apenas a biblioteca WiringPi
http://www.circuitbasics.com/how-to-set-up-the-dht11-humidity-sensor-on-the-raspberry-pi/
Um outro exemplo, embora não seja de lingaugem C, é a biblioteca em Python para o sensor DHT11
https://github.com/adafruit/Adafruit_Python_DHT
Com WiringPi você também consegue utilizar protocolos I2C e SPI.