Programação em C Sistemas Embarcados (ARDUINO)
IFSP - Programação I Prof. Fernando Paes Landim
Sumário
1
Introdução .................................................................................................................................. 3
2
Linguagem de Programação ...................................................................................................... 3
3
Arduino IDE................................................................................................................................ 4
4
Programando no ARDUINO IDE ................................................................................................ 6 4.1
Simbologia .......................................................................................................................... 6
4.2
Função void setup( ) ........................................................................................................... 6
4.3
Função pinMode( ) .............................................................................................................. 7
4.4
Função void loop( ) ............................................................................................................. 7
4.5
Funções Digitais de INPUT / OUTPUT................................................................................ 8
4.5.1
Função digitalWrite( ) ................................................................................................... 8
4.5.2
Função digitalRead( ) ................................................................................................... 8
4.5.3
Função delay() ............................................................................................................. 9
4.6
5
Estruturas de Controle ........................................................................................................ 9
4.6.1
Estrutura de Controle If (Se) ........................................................................................ 9
4.6.2
Estrutura de Controle If .. Else (Se .. senão) .............................................................. 10
Exemplos de programas comentados ...................................................................................... 12 5.1
Pisca LED ......................................................................................................................... 12
5.2
Semáforo .......................................................................................................................... 13
5.3
Botão e LED ..................................................................................................................... 14
2
1 Introdução Nesta matéria iremos abordar a Linguagem de Programação C voltada para Sistemas Embarcados, especificamente para a plataforma ARDUINO. Lembrando que a linguagem C para sistemas embarcados é uma adaptação do C criado para desktop com a finalidade de gerar um programa ( f i r m w a r e ) para embarcarmos no nosso microcontrolador. Com isso, os desenvolvedores do ARDUINO criaram o ARDUINO IDE (Integrated Development Environment ), que é o ambiente de desenvolvimento do programa que iremos embarcar no nosso ARDUINO. Essa IDE foi inspirada em C , desenvolvida com funções préprogramadas a fim de facilitar seu uso, mantendo as funções de controle de fluxo herdadas do C .
Mas por que C ? Evidente que a Linguagem C é a principal Linguagem de Programação, sendo a linguagem mais utilizada, direta ou indiretamente, desde sua criação. Diversas outras linguagens muito utilizadas hoje, tiveram sua base em C , assim como: C++, C#, JAVA, entre outras. Assim também como há indícios de que os principais Sistemas Operacionais ( Windows, Mac OS e Linux ) foram desenvolvidos em C . Então por isso a Linguagem C é importantíssima para começarmos a aprender programação.
2 Linguagem de Programação Podemos imaginar o computador como uma super calculadora capaz de realizar cálculos muito mais rápido do que nós, mas para isso, devemos dizer ao computador o que deve ser calculado e como deve ser calculado. A função das linguagens de programação é exatamente essa, ou seja, servir de um meio de comunicação entre computadores e humanos. Existem dois tipos de linguagens de programação: as de baixo nível e as de alto nível. Os computadores interpretam tudo como números em base binária, ou seja, só entendem zero e um. As linguagens de baixo nível são interpretadas diretamente pelo computador, tendo um resultado rápido, porém é muito difícil e incômodo de se trabalhar com elas. Exemplos de linguagens de baixo nível são: a linguagem binária e a linguagem A s s e m b l y .
3
Exemplo de código em A s s e m b l y : MOV AX,WORD1 ;movimenta o conteúdo da posição de memória WORD1 para o registrador AX MOV AH,’A’
;tr ansfere o caracter ASCII ‘A’ para AH
MOV AH,41h
;idem anterior: 41h corresponde ao caracter A
MOV AH,BL
;move o conteúdo do byte baixo de BX o byte alto de AX
MOV AX,CS
;transfere uma cópia do conteúdo de CS para AX
Como pode-se notar, é uma linguagem bastante complicada. Já as linguagens de alto nível são mais fáceis de se trabalhar e de entender, as ações são representadas por palavras de ordem (exemplo : faça, imprima, etc) geralmente em inglês, foram feitos assim para facilitar a memorização e a lógica. Elas não são interpretadas diretamente pelo computador, sendo necessário traduzi-las para linguagem binária utilizando-se de um programa chamado compilador . Quando programamos em uma linguagem de programação de alto nível, primeiramente criamos um arquivo de texto comum contendo a lógica do programa, ou seja, é onde falamos ao computador como deve ser feito o que queremos. Este arquivo de texto é chamado de códigofonte, cada palavra de ordem dentro do código-fonte é chamada de instrução. Após criarmos o código-fonte devemos traduzir este arquivo para linguagem binária usando o compilador correspondente com a linguagem na qual estamos programando. O compilador irá gerar um segundo arquivo que chamamos de executável ou programa, este arquivo gerado é interpretado diretamente pelo computador.
3 Arduino IDE Agora daremos introdução a nossa plataforma de desenvolvimento, conhecer um pouco do ambiente e seus principais recursos. Lembrando que o compilador do ARDUINO pode ser gratuitamente baixado no site arduino.cc .
4
Figura 1 - Imagem do Arduino IDE
Por padrão, o nome do nosso arquivo vem nomeado como sketch_data, que em inglês pode significar esboço ou rascunho, mas pode ser facilmente alterado quando salvamos nosso arquivo no disco. - Verificar : Compila nosso código, verificando se existe algum erro de instrução ou sintaxe. - Carregar : Verifica e embarca nosso programa para o Arduino, quando o mesmo estiver conectado ao computador. - Novo : Cria um novo arquivo. - Abrir : Abri um arquivo existente. - Salvar : Salva o arquivo atual.
5
4 Programando no ARDUINO IDE Para cada programa teremos apenas uma função void setup( ) e uma função void loop( ). Funções em linguagem de programação são como sub-rotinas ou procedimentos; são pequenos blocos de programas usados para montar o programa principal. Elas são escritas pelo programador para realizar tarefas repetitivas, ou podem ser importadas prontas para o programa em forma de bibliotecas.
4.1
Simbologia { } - Dentro das chaves vão os procedimentos que a função deve executar ; - O ponto e vírgula é usado para marcar o final de uma instrução. // - comentário de uma linha: qualquer caractere depois das duas barras é ignorado pelo
compilador. /* comentário de várias linhas */ - qualquer texto colocado entre esses símbolos também é ignorado pelo compilador.
4.2
Função void setup( ) A função void setup( ), será responsável por determinar as configurações dos pinos
utilizados no nosso programa logo quando inicia, e é executada apenas essa primeira vez. Exemplo: void setup( ){ pinMode(0,OUTPUT); // Define o pino 0 como saída pinMode(1,INPUT); // Define o pino 1 como entrada } A função void setup( ) começa na " { " (chave aberta) e termina na " } " (chave fechada), e todas as configurações de pinos devem ser feitas dentro dessas chaves. Percebam que as palavras utilizadas pelo compilador ficam em cores diferentes, por isso é importante diferenciar maiúsculas de minúsculas. Como por exemplo a instrução " pinMode ", se digitarmos tudo minúsculo " pinmode ", nosso compilador não irá entender qual instrução deve realizar e dará erro de compilação.
6
4.3
Função pinMode( ) Sintaxe: pinMode(pino,MODO)
pino : se refere ao número do pino do ARDUINO que iremos configurar.
MODO : estado do pino, podendo ser INPUT (entrada de dados), OUTPUT (saída de dados) ou INPUT_PULLUP (entrada de dados com resistores de pull-up internos).
Exemplos: pinMode(13,OUTPUT); // Configurando o pino 13 como saída de dados pinMode(0,INPUT);
// Configurando o pino 0 como entrada de dados
Isso significa que no pino 13, o microcontrolador irá enviar uma tensão de 0 Volt ou 5 Volts, sendo 0 Volt nível lógico baixo e 5 Volts nível lógico alto. Já no pino 0 iremos receber uma tensão entre 0 Volt e 5 Volts, considerando uma leitura próxima a 0 Volt como nível lógico baixo e leitura próxima a 5 Volts como nível lógico alto.
4.4
Função void loop( ) A função void loop( ) é chamada logo a seguir da função void setup( ), e todas as funções
embarcadas nela são repetidamente executadas. Ela fica lendo os pinos de entrada do Arduino, comandando os pinos de saída e a porta serial. Dentro dela que desenvolveremos o programa para embarcarmos no Arduino a fim de controlar logicamente e sequencialmente os dispositivos conectados na plataforma. Basicamente a principal função da linguagem C já composta por um laço de repetição infinito. Exemplo em linguagem C:
Exemplo no Arduino IDE:
void main(){ // Função principal
void loop(){ // Função principal com laço de repetição /* Espaço destinado
while(1){ // Função de repetição infinita /* Espaço destinado
ao desenvolvimento do programa */
ao desenvolvimento do programa */ } // Fim da função while
} /* Fim da função principal, volta à primeira instrução da função void loop() */
} // Fim da função principal
7
4.5
Funções Digitais de INPUT / OUTPUT
Como vimos na função pinMode( ), as instruções INPUT e OUTPUT são as funções de entrada e saída de dados. Após configurarmos os pinos, utilizaremos as funções digitalWrite( ) e digitalRead( ).
4.5.1
Função digitalWrite( )
A função digitalWrite( ) é utilizada para escrever um valor na saída do pino digital. Sintaxe: digitalWrite(pino, VALOR)
pino: Esse pino deverá estar configurado como OUTPUT, e assim estamos indicando em qual pino iremos escrever um valor.
VALOR: Valor do pino, podendo ser HIGH (nível lógico alto) ou LOW (nível lógico baixo).
Exemplo: digitalWrite(13, HIGH); // Pino 13 como nível lógico alto digitalWrite(12, LOW); // Pino 12 como nível lógico baixo
Com essa função conseguimos acionar dispositivos externos de 5 Volts ou chavear um transistor no caso de tensões maiores.
4.5.2
Função digitalRead( )
A função digitalRead( ) é utilizada para ler um valor na entrada do pino. Sintaxe: digitalRead(pino)
pino: Esse pino deverá estar configurado como INPUT, e assim estamos indicando qual pino queremos fazer a leitura.
Exemplo: digitalRead(5); // Realiza a leitura do pino 5
8
4.5.3
Função delay()
A função delay( ) é utilizada para gerar um atraso no programa. Sintaxe: delay(tempo)
tempo: valor em milissegundos que determinará o atraso naquele instante do programa.
Exemplo: delay(1000); // Atraso de 1 segundo delay(500); // Atraso de 0,5 segundo
4.6
Estruturas de Controle São utilizadas para tomar decisões lógica durante o programa dependendo dos valores
obtidos.
4.6.1
Estrutura de Controle If (Se)
If é um controle de fluxo usado para selecionar uma ou mais instruções baseadas no resultado de um teste de comparação. Todas as instruções entre as chaves { e } são executadas somente se o resultado desse teste for verdadeiro; se não, essas instruções não são executadas. Verdadeiro é qualquer resultado diferente de zero, mesmo negativo. Falso é um resultado zero.
Figura 2 - Estrutura If
9
Sintaxe: if (teste lógico){ // bloco a ser realizado caso o teste lógico retorne Verdadeiro } Exemplo: if (digitalRead(5) == 1){ // Se leitura do pino 5 for igual a 1 digitalWrite(13,HIGH); // Pino 13 vai pra nível lógico alto } // Fim da função If
Operadores de Comparação: Podemos utilizar os seguintes símbolos como operadores de comparação: == - Compara se os dois valores são iguais. != - Compara se os dois valores são diferentes. < - Compara se o primeiro valor é menor que o segundo. <= - Compara se o primeiro valor é menor ou igual ao segundo. > - Compara se o primeiro valor é maior que o segundo. >= - Compara se o primeiro valor é maior ou igual ao segundo.
4.6.2
Estrutura de Controle If .. Else (Se .. senão)
Ao acrescentar mais um bloco de instruções na função do comando if, pode-se criar o comando if .. else, para fazer um teste novo caso o resultado da expressão retorne falso.
Figura 3 - Estrutura If .. Else
10
Sintaxe: if (teste lógico){ // bloco a ser realizado caso o teste lógico retorne Verdadeiro } else{ // bloco a ser realizado caso o teste lógico retorne Falso } Exemplo: if (digitalRead(5) == 1){ // Se leitura do pino 5 for igual a 1 digitalWrite(13,HIGH); // Pino 13 vai pra nível lógico alto } else{ digitalWrite(13,LOW); // Pino 13 vai pra nível lógico baixo }
11
5 Exemplos de programas comentados 5.1
Pisca LED
Figura 4 - Nível lógico alto
Figura 5 - Nível lógico baixo
Dado o circuito acima criaremos um programa para piscar um LED a cada 1 segundo, com isso também conseguimos fornecer um sinal digital com frequência de 1 Hz.
void setup( ){ pinMode(10, OUTPUT); // Define pino 10 como saída de dados } void loop( ){ digitalWrite(10,HIGH); // Coloca pino 10 em nível alto delay(1000); // Atraso de 1000 milissegundos ou 1 segundo digitalWrite(10,LOW); // Coloca pino 10 em nível alto delay(1000); // Atraso de 1000 milissegundos ou 1 segundo }
12
5.2
Semáforo
Figura 6 - Semáforo
int led_verde = 0; // Cria variável led_verde do tipo inteiro e atribui valor 0 int led_amarelo = 1; // Cria variável led_amarelo do tipo inteiro e atribui valor 1 int led_vermelho = 2; // Cria variável led_vermelho do tipo inteiro e atribui valor 2 // Variáveis do tipo INTEIRO podem receber valores inteiro entre -32768 e +32767
void setup( ){ pinMode(led_verde,OUTPUT); // Configura pino do led_verde como saída pinMode(led_amarelo,OUTPUT); // Configura pino do led_amarelo como saída pinMode(led_vermelho,OUTPUT); // Configura pino do led_vermelho como saída }
void loop( ){ digitalWrite(led_verde,HIGH); // led_verde para nível alto delay(1000); // Atraso de 1 segundo digitalWrite(led_verde,LOW); // led_verde para nível baixo digitalWrite(led_amarelo,HIGH); // led_amarelo para nível alto delay(500); // Atraso de 0,5 (meio) segundo digitalWrite(led_amarelo,LOW); // led_amarelo para nível baixo digitalWrite(led_vermelho,HIGH); // led_vermelho para nível alto delay(1000); // Atraso de 1 segundo digitalWrite(led_vermelho,LOW); // led_vermelho para nível baixo }
13
5.3
Botão e LED
Figura 7 - Botão solto
Figura 8 - Botão pressionado
Para o circuito acima queremos acionar um dispositivo, no nosso caso um LED, usando um botão do tipo push_button (solto = 0 e pressionado = 1). int botao = 13; // Cria variável botao do tipo inteiro e atribui valor 13 int led = 0; // Cria variável led do tipo inteiro e atribui valor 0
void setup(){ pinMode(botao, INPUT); // Configura botao como entrada de dados pinMode(led, OUTPUT); // Configura led como saída de dados } void loop(){ if (digitalRead(botao) == 1){ // Se leitura do botao for igual a 1 digitalWrite(led,HIGH); // Acende led } else{ // Senão, se leitura do botão for igual a 0 digitalWrite(led,LOW); // Apaga o led } }
14