Programação em Linguagem C com Raspberry Pi 26

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.

Controle de LED com Push Button

Materiais necessários

Para realizar os exemplos deste tutorial você irá precisar dos seguintes materiais:

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

Circuito exemplo

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.

Geany Linguagem C

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!”.

Execução programa 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.

Execução programa Hello World

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:

Tabela Pinagem WiringPi

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“.

Configuração comandos de build

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 1 - Pisca LED

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 2 - LED Push Button

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;
}

Exemplo 3 - LED PWM

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.

Faça seu comentário

Acesse sua conta e participe

26 Comentários

  1. Aprendi a programar no C Progressivo (https://www.cprogressivo.net/), me ajudou muito a entender o tutorial de vocês também

  2. 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

  3. 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.

    Paulo Eduardo Boeira Capeller
    1. Resovido, o led estava invertido 🙁

      Paulo Eduardo Boeira Capeller
  4. 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ê?

    1. 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

      1. 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

  5. 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.

    1. 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.

  6. Olá! Excelente Tutorial! Como faço para configurar os pinos Gpio como entrada ou saída? É possível fazer pelo terminal? Obrigado.

    1. 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!

      1. 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.

        1. 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!

  7. Boa tarde. Estou procurando bibliotecas do Raspberry para Linux, sabe onde posso encontrar? Grato.

    1. 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.

  8. 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

    1. 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!

  9. 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.

    1. 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 ?

  10. 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.

    1. 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

      1. 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

  11. 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!

    1. 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.