Programação Arduino
Página | 1
Sumário: Estrutura y y
void setup ().............................................5 void loop ()...............................................5
y y y
y y y y y y y y y y
Estruturas de controle if............................................................6 if...else...................................................7 for..........................................................8 switch case.............................................9 while.....................................................10 do... while..............................................10 break.....................................................69 continue.................................................11 return.....................................................11 goto.......................................................12
y y y y y
y y y y y
y y y y y y
y y y y y y
y y y y y y
y y y
Elementos de sintaxe ; (ponto e ví rgula)...................................13 rgula)...................................13 {} (chaves).............................................13 // (linha de comentário)...........................15 /* */ (bloco de comentário)......................15 #define..................................................16 #include.................................................17
y
Operadores de bits & (operador de bits AND)..............................22 AND)..............................22 | (operador de bits OR).................................22 OR).................................22 ^ (operador de bits XOR)..............................22 XOR)..............................22 ~ (operador de bits NOT)..............................24 NOT)..............................24 << (des vio à esquerda).............................. es querda).................................25 ...25 >> (des vio à direita).....................................25 &=(de bits composto AND)............................26 |=(de bits composto OR)...............................26 Operadores compostos ++ (incrementar).........................................28 -- (decrementar)..........................................28 += (adição composta).......................... composta)..................................28 ........28 -= (subtração composta)...............................28 *= (multiplicação composta)..........................28 /= (divisão composta)...................................28
Operadores aritméticos = (igualdade).........................................18 + (adição)..............................................18 - (subtração)..........................................18 * (multiplicação).....................................18 / (divisão)..............................................18 % (resto da di visão)...............................19 Operadores de comparação == (igual a)...........................................20 != (diferente de).....................................20 < (menor que).......................................20 > (maior que)........................................20 que)........................................20 <= (menor ou igual a)............................20 >= (maior ou igual a).............................20 Operadores booleanos && (e)....................................................21 || (ou)....................................................21 ! (não)....................................................21 Página | 2
Sumário: Estrutura y y
void setup ().............................................5 void loop ()...............................................5
y y y
y y y y y y y y y y
Estruturas de controle if............................................................6 if...else...................................................7 for..........................................................8 switch case.............................................9 while.....................................................10 do... while..............................................10 break.....................................................69 continue.................................................11 return.....................................................11 goto.......................................................12
y y y y y
y y y y y
y y y y y y
y y y y y y
y y y y y y
y y y
Elementos de sintaxe ; (ponto e ví rgula)...................................13 rgula)...................................13 {} (chaves).............................................13 // (linha de comentário)...........................15 /* */ (bloco de comentário)......................15 #define..................................................16 #include.................................................17
y
Operadores de bits & (operador de bits AND)..............................22 AND)..............................22 | (operador de bits OR).................................22 OR).................................22 ^ (operador de bits XOR)..............................22 XOR)..............................22 ~ (operador de bits NOT)..............................24 NOT)..............................24 << (des vio à esquerda).............................. es querda).................................25 ...25 >> (des vio à direita).....................................25 &=(de bits composto AND)............................26 |=(de bits composto OR)...............................26 Operadores compostos ++ (incrementar).........................................28 -- (decrementar)..........................................28 += (adição composta).......................... composta)..................................28 ........28 -= (subtração composta)...............................28 *= (multiplicação composta)..........................28 /= (divisão composta)...................................28
Operadores aritméticos = (igualdade).........................................18 + (adição)..............................................18 - (subtração)..........................................18 * (multiplicação).....................................18 / (divisão)..............................................18 % (resto da di visão)...............................19 Operadores de comparação == (igual a)...........................................20 != (diferente de).....................................20 < (menor que).......................................20 > (maior que)........................................20 que)........................................20 <= (menor ou igual a)............................20 >= (maior ou igual a).............................20 Operadores booleanos && (e)....................................................21 || (ou)....................................................21 ! (não)....................................................21 Página | 2
Variáveis Variáveis são expressões que você pode usar em
programas para armazenar valores como a leitura de um sensor em um pino analógico.
y y y y
y y y y y y y y y y y y
Constantes Constantes são valores particulares com significados espec í ficos. ficos. HIGH | LOW...........................................29 INPUT | OUTPUT....................................29 true | false.............................................29 Constantes inteiras.................................31 Tipos de dados Variáveis podem ser de vários tipos: boolean..................................................32 char.......................................................32 byte.......................................................33 int..........................................................33 unsigned int..................................... int. ...........................................34 .......34 long.......................................................34 unsigned long.........................................35 float........................................................36 double....................................................37 string......................................................37 array.......................................................39 void........................................................40
y
Conversão char()....................................................41 byte()....................................................41 int().......................................................41 long()....................................................41 float()....................................................42
y
Referência Tabela ASCII..........................................42
y y y y
Página | 3
unções
F
Entrada e saída digital y y y
pinMode (pin, mode).....................................43 digitalWrite (pin, value).................................44 int digitalRead (pin).......................................45
Comunicação serial
Entrada e saída analógica y y
y y
int analogRead (pin)......................................46 analogWrite (pin, value) PWM....................47 Entrada e saída avançada shiftOut (dataPin, clockPin, bitOrder, value).48 unsigned long pulseIn (pin, value).49
y y y y
Tempo y y y y
y y y y y y y y
unsigned long millis()....................................50 unsigned long micros()..50 delay(ms)..51 delayMicroseconds( s)..5 2
y y
Usado para comunicação entre a placa Arduino e um computador ou outros dispositi vos. Esta comunicação ocorre através dos conectores serial ou USB da placa Arduino e nos pinos digitais 0 (RX) e 1 (TX). Assim, se você utilizar estas funções não poderá utilizar os pinos 0 e 1 para entrada e sa í da digital. Serial.begin (speed)......................................62 int Serial.available ()63 int Serial.read ()64 Serial.flush ()..65 Serial.print (data)..........................................65 Serial.println (data).......................................68
Matemática min (x, y).....................................................54 max (x, y).55 abs (x).........................................................56 constrain (x, a, b).........................................56
map (v alue, fromLow, fromHigh, toLow, to High)57 pow (base, exponent)...................................58 sq (x)..58 sqrt (x).........................................................58 Trigonometria
y
sin (rad).......................................................59 cos (rad)......................................................59 tan (rad)......................................................59
y
Números aleatórios randomSeed (seed).60
y y
y y
long random (max).......................................61 long random (min, max)..61
Página | 4
setup() A função setup() é chamada quando um programa pomeça a rodar. Use esta função para ini cializar as sua variáveis, os modos dos pinos, declarar o uso de li vrarias, etc. Esta função será executada apenas uma vez após a placa Arduino ser ligada ou ressetada. Exemplo int buttonPin = 3; void setup() {
Serial.begin(9600); pinMode(buttonPin, INPUT); }
void loop() { //
...
}
loop() Após criar uma fução setup() que declara os valores iniciais, a função loop() faz exatamente o que seu nome sugere, entra em looping (executa sempre o mesmo bloco de código), permitindo ao seu programa fazer mudanças e responder. Use esta função para controlar ati vamente a placa Arduino. Exemplo int buttonPin = 3;
setup inicializa o serial e o pino do button (botão) void setup()
//
{
beginSerial(9600);
pinMode(buttonPin, INPUT); }
loop checa o botão a cada vez, // e envia o serial se ele for pressionado void loop() //
{
if (digitalRead(buttonPin) == HIGH) serialWrite('H'); else serialWrite('L'); delay(1000); }
Página | 5
if (condicional) e ==, !=, <, > (operadores de comparação) if, que é usado juntamente com um operador de comparação, verifica quando uma condição é satisfeita, como por exemplo um input acima de um determinado valor. O formato para uma verificação if é: if (algumaVariavel > 50) { // faça alguma coisa }
O programa checa se alguma Variavel (colocar acentos em nomes de variáveis não é uma boa idéia) é maior que 50. Se for, o programa realiza uma ação espec í fica. Colocado de outra maneira se a sentença que está dentro dos parêntesis é verdadeira o código que está dentro das cha ves roda; caso contrário o programa salta este bloco de código. As chaves podem ser omitidas após uma sentença if se só hou ver uma única linha de código (definida pelo ponto e ví rgula) que será executado de modo condicional: if (x > 120) digitalWrite(LEDpin, HIGH); if (x > 120) digitalWrite(LEDpin, HIGH); if (x > 120) {digitalWrite(LEDpin, HIGH);} // todos são corretos
A sentença que está sendo verificada necessita o uso de pelo menos um dos operadores: Operadores de comparação: x == y (x é igual a y) x != y (x é não igual a y) x < y (x é menor que y) x > y (x é maior que y) x <= y (x é menor ou igual a y) x >= y (x é maior ou igual a y) Cuidado:
Tenha precaução com o uso acidental de apenas um sinal de igual (e.g. if (x = 10) ). O sinal de igual simples é um operador de designação e coloca o valor 10 na variável x. Ao contrário o sinal de igal duplo (e.g. if (x == 10) ), que é um operador de comparação, verifica se x é igual a 10 ou não. A última senteça só é verdadeira se x for igual a 10, mas a anterior sempre será veraddeira. Isto ocorre por que a linguagem C (na qual o Arduino é baseado) atribui um valor à sentença (x=10) do seguinte modo: 10 é colocado na variável x (lembre o sinal de igual simples é um operador de designação), então x agora cont ém 10. Então o condicional 'if' atri bui um valor a 10, que será sempre verdadeiro (TRUE), desede que números diferentes de zero são sempre equiparados à verdadeiro. Consequentemente, if (x = 10) será sempre verdadeiro, que não é o que pretendemos quando usamos um 'if'. Adcionalmente o valor 10 será guardado na variável x que também não é o que pretendemos. if também pode ser usado como parte de uma estrutura de controle ramificada atra vés da construção if..else.
Página | 6
if / else if/else permite um controle maior so bre o fluxo de código do que a sentença if básica, tornando poss ível que múltiplos testes sejam agrupados. Por exemplo, uma entrada analógica poderia ser verificada e uma ação especí fica seria tomada se o valor de input fosse menor que 500 e outra ação seria tomada se o
input fosse 500 ou mais. O código seria assim: if (pinFiveInput < 500) { // ação A } else { // ação B } else pode preceder outro teste if , e assim mltiplos testes, mutuamente exclusi vos, podem ser realizados
ao mesmo tempo. Cada teste precede o próximo at é que um teste com vavlor verdadeiro é encontrado. Quando um teste
com valor verdadeiro é encontrado o seu bloco de código associado é execuatod e então o programa salta para a sequencia após todo o bloco if /else. Se a nenhum teste é atribuido o valor verdadeiro o bloco que estiver no else sozinho é executado, se hou ver algum. Note que um bloco else if pode ser usado com ou sem um bloco else final. Um número ilimitado destes ramos else if é permitido. if (pinFiveInput < 500) { // faça a coisa A } else if (pinFiveInput >= 1000) { // faça a coisa B } else { // faça a coisa C }
Outro modo de fazer testes de ramificações mutuamente exclusi vas é através da sentença switch case.
Página | 7
sentença for Descrição
A sentença for é utilizada para repetir um bloco de código delimitado por cha ves. Um contador com incremento normalmente é usado para controlar e finalizar o loop. A sentença for é util para quanquer operação repetiti va, e é frequentemente usada com arrays para operar em conjuntos de dados ou de pinos. Há três partes no cabeçalho do for:
for (inicialização; condição; incremento) { //sentença(s); }
A inicialização ocorre primeiro e apenas uma vez. Cada vez que o circuí to é executado a condição é verificada; se for verdadeira o bloco de código e o incremento são executados, e então a condição é testada novamente. Quando a condição se torna falsa o circu í to termina. Exemplo // Aumentar o brilho de um LED usando um pino PWM int PWMpin = 10; // um LED em série com um resisotr de 1k no pino 10 void setup() { // nenhum setup é necessário } void loop() { for (int i=0; i <= 255; i++){ analogWrite(PWMpin, i); delay(10); } } Dica de programação
Na linguagem C o circuito for é muito mais flexível que os circuitos for encontrados a algumas outras linguagens de programação, incluindo B ASIC. Qualquer dos elementos do ca beçalho pode ser omitido, embora os ";" sejam necessários. Qualquer destes elementos tam bém podem ser substituidos por qualquer sentença válida em C com varáveis não correlatas. Estes tipos não usuais de sentenças for as vezes podem ser a solucão para alguns pro blemas raros de programação.
Página | 8
sentença switch / case Do mesmo modo que as sentenças if, as switch / case controlam o fluxo dos programas. Switch/case permite ao programador construir uma lista de "casos" dentro de um bloco delimitado por cha ves. O programa checa cada caso com a vaiável de teste e executa o código se encontrar um valor idêntico. Switch / case é um pouco mais flexível que uma estrutura if/else de modo que o programador pode determinar se a estrutura switch deve continuar checando por valores idênticos na lista dos "caosos" após encontrar um valor idêntico. Se a sentença break não é encontrada após a execução do bloco de código selecionado por um dos "casos", então o programa vai continuar a checar por mais valores idênticos entre os "casos" restantes. Se uma sentença break é encontrada o código sai da estrutura do mesmo modo que em uma construção if/else if. Parâmetros y
y
y
var - a variável para a qual você busca valores idênticos
default - se nenhuma outra condição for satisfeita o código que está no default é executado break - sem o break a sentença switch vai continuar checando as outras sentenças case para quanquer outro possível valor idêntico. Se algum for encontrado será executado do mesmo modo, o que pode não ser o que você deseja. Break indica ao switch para parar de procurar por outros valores idênticos e sai da sentença switch. Exemplo switch (var) { case 1: //faça alguma coisa quando var == 1 break; // break is optional case 2: //faça alguma coisa quando == 2 break; default: // se nenhum valor for idêntico, faça o default // default é opcional }
Página | 9
while Descrição while fará com que o bloco de código entre cha ves se repita continua e indefinidamente at é que a expressão ente parentesis() se torne falsa. Algo tem que pro vocar uma mudança no valor da variável que está sendo verificada ou o código vai sempre ficar dando voltas dentro do while. Isto poderia ser o incremento de uma variável ou uma condição externa como o teste de um sensor. Syntax while(expressão){ // código } Parâmetros
expressão - uma sentença boolena em C que possa ser verificada como verdadeira ou falsa Exemplo var = 0; while(var < 200){ // algum código que se repete 200 vezes var++; }
do - while O do funciona da mesma maneira que o while loop, com a exceção de que a condição é testada no final do bloco de código. Enquanto no while, se a condição for falsa, o bloco de código não será executado, no do ele sempre será executado pelo menos uma vez. do { // bloco de código } while (condição); Exemplo do { delay(50); // espera para que os sensores se estabilizem x = readSensors(); // verifica o sensor } while (x < 100);
Página | 10
continue continue é usado para saltar porções de código em blocos do, for, ou while. Ele força com que o código avance at é o teste da condição saltando todo o demais. Exemplo for (x = 0; x < 255; x ++) { if (x > 40 && x < 120){ continue; }
// criar saltos de execução
digitalWrite(PWMpin, x); delay(50); }
return inaliza uma função e retorna um valor, se necessário.
F
Sintaxe:
return; return valor; // ambas formas são válidas Parâmetros valor: alguma variável ou constante
Exemplos:
Uma função para comparar o valor de um sensor com um limite int checkSensor(){ if (analogRead(0) > 400) { return 1; else{ return 0; } }
A palavra-chave return é útil para testar uma seção de código sem ter que transformar em "comentário" um grande e possi velmente defeituoso bloco de código. void loop(){ // aqui, uma brilhante idéia de programação return; // restante do bloco de código não funcional // este código nunca será executado } Página | 11
goto Transfere o fluxo do programa para um outro ponto etiquetado Sintaxe
label: goto etiqueta; // envia o fluxo do programa para etiqueta Dica
O uso do goto é desencorajado em programação C e inclusive alguns autores afirmam que o goto nunca é realmente necessário, mas usado com cautela pode simplificar alguns programas. A razão pela qual muitos programadores desapro vam seu uso é que com o uso indiscriminado é fácil de se criar um programa com um fluxo indefinido e muito dif í cil de ser depurado. No entanto, há casos em que o goto pode ser útil e simplificar o código. Uma destas situações é provocar uma saí da de um grupo de loops aglutinados ou de blocos lógicos if com uma determinada condição.
Exemplo for(byte r = 0; r < 255; r++){ for(byte g = 255; g > -1; g--){ for(byte b = 0; b < 255; b++){ if (analogRead(0) > 250){ goto bailout;} // more statements ... } } } bailout:
Página | 12
; ponto e vírgula Usada para terminar uma sentença. Exemplo int a = 13; Dica
Esquecer de finalizar uma linha com ponto e ví rgula causa um erro de compilação. O texto so bre o erro pode ser óbvio e se referir a um ponto e ví rgula faltando, ou não. Se ocorrer um erro de compilação impenetrável ou aparenetemente ilógico uma das primeiras coisas a checar é um ponto e ví rgula faltando na vizinhança, precedendo a linha indicada pelo compilador.
{} Chaves Chaves são uma parte essencial da linguagem de programação C. Elas são usadas em muitas construções
diferentes, descritas abaixo, e isto pode algumas vezes ser confuso para iniciantes. Uma chave abrindo "{" deve sempre ser seguida por uma fechando " }". Frequentemente nos referimos a esta condição como equili brio entre as chaves. A IDE (integrated de velopment environment ou ambiente de desen volvimento integrado) do Arduino inclui uma caracter í stica prática para checar o equili brio das chaves. Apenas com o selecionar de uma cha ve ou clicar no ponto imediatamente posterior f az com que sua companheira lógica seja destacada. No presente momento esta caracter í stica é um pouco defeituosa e a IDE frequentemente encontrará (incorretamente) uma cha ve em um bloco de texto que tenha sido comentado. Programadores principiantes e programadores vindos das linguagens C e do B ASIC frequentemente consideram o uso das cha ves confuso ou desalentador. Afinal as mesmas cha ves substituem a sentença RETURN em uma su brotina(função), a sentença END IF em uma condicional e a sentença NEXT em um FOR. Por que o uso das cha ves é tão variado, é uma boa prática de programação digitar o fecha -chaves "}" logo após digitar o a bre-chaves "{" quando estiver fazendo uma construção que as requer. Inserte então alguns "ENTER" entre as cha ves e comece a digitar o código. Agindo assim suas cha ves nunca ficarão desequilibradas. Chaves desequilibradas causam erros de comilação bastante enigmáticos e que podem ser dif í ceis de
rastrear em um programa longo. Por causa de seus usos variados, as chaves são também incrivelmente importantes para a sintaxe de um programa e mo ver uma chave uma ou duas linhas pode alterar completamente o seu significado.
Página | 13
Os principais usos das chaves Funções void myfunction(datatype argument){ sentença(s) } Loops while (expressão booleana) { sentença(s) } do { sentença(s) } while (expressão booleana); for (inicialização; condição de término; expressão de incremento) { sentença(s) } Sentenças condicionais if (expressão booleana) { sentença(s) } else if (expressão booleana) { sentença(s) } else { sentença(s) }
Página | 14
Comentários Comentários são linhas no programa que são usados para infor mar a você mesmo ou outras pessoas
sobre o modo como o progama trabalha. Elas são ignoradas pelo compilador e não são exportadas para o processador e portanto não ocupam a memória do chip ATmega. O único propósito dos comentários são ajudar a entender (ou relem brar) como o programa funciona. Há dois modos diferentes de marcar uma linha como um comentário. Exemplo x = 5; // Esta é uma linha simples de comentário. Qualquer coisa depois das barras é um comentário // até o fim da linha /* este é um bloco de comentário - usado para "comentar" blocos inteiros de código if (gwb == 0){ // não há problema em uma linha simples dentro de um bloco de comentário x = 3; /* mas outro bloco de comentário é inválido */ } // não esqueça de fechar o bloco de comentário, eles têm que ser equilibrados */ Dica
Quando estiver experimentando com o código "comentar" partes do programa é um modo conveniente de remover linhas que podem conter pro blemas. Este procedimento mant ém as linhas no código mas as trasnforma em comentários de modo que o compilador as ignora. Isto pode ser especialmente útil quando tentamos localizar um pro blema, ou quando um programa apresenta erros de compilação cujas explicações são obscuras ou inúteis.
Página | 15
#define #define é um componente muito útil da linguagem C que permite ao programador dar um nome a uma
constatnte antes que o programa seja compilado. Constantes definidas no Arduino não ocupam espaço em memória no chip. O compilador su bstitui referêancias a estas constantes pelo valor definido no momento da compilação. Isto pode causar alguns efeitos indesejáveis se, por exemplo, um nome de constante que tenha sido
defindo por um #define é incluido em alguma outra constante ou nome de variável. Neste caso o texto deve ser substituido pelo valor (ou texto) do #define. Em general, a palavra chave const é preferível para definir constatntes e de ve ser usada ao invés de #deine. A sintaxe do #define na linguagem Arduino é a mesma da linguagem C: Sintaxe #define nomeDeConstante valor Verifique que o # é necessário.
Exemplo #define ledPin 3 // O compilador vai substituir quanquer menção a ledPin pelo valor 3 no momento da compilação. Dica
Não há ponto e ví rgula após a declaração #define. Se você incluir um o compilador vai lançar erros crí ticos no final do programa. #define ledPin 3;
// isto é um erro
Do mesmo modo o compilador gerará erros se após o #define houver um =. #define ledPin = 3 // isto também é um erro
Página | 16
#include #include é usado para incluir outras bibliotecas no seu programa. Isto permite ao programador acessar um grande número de bibliotecas padrão da linguagem C (grupos de funções pr é-definidas), e também à bibliotecas desen volvidas especificamente para o Arduino.
A página principal de referência para as bibliotecas C A VR (A VR é a referência aos chips Atmel nos quais o Arduino está baseado) está aqui. Verifique que #include, de modo similar ao #define, não leva ponto e ví rgula no final.
Exemplo
Este exemplo inclui uma biblioteca que é utilizada para armazenar dados na memória flash ao i n vés de na ram. Isto economiza espaço na ram para as necessidades de memória dinâmica e torna o u so de grandes tabelas mais prático. #include
prog_uint16_t myConstants[] PROGMEM = {0, 21140, 702 , 9128, 0, 25764, 8456, 0,0,0,0,0,0,0,0,29810,8968,29762,29762,4500};
=
operador de designação (sinal de igual simples)
Armazena o valor do que está à direita do sinal de igual na variável que está à esquerda. O sinal de igual simples na linguagem de programação C é chamdo operador de designação. Ele tem um significado diferente daquele utilizado em álge bra, no qual indica uma equação ou iguladade. O operador de designação indica ao microcontrolador para calcular o valor da expressão à direita do sinal de igual e armazenar este valor na variável que está à esquerda. Exemplo int sensVal; // declera uma variavel do tipo inteiro com o nome de sensVal senVal = analogRead(0); // armazena o valor da voltagem (digitalizado) no pino analógico 0 em sensVal Dicas de programação A variável à esquerda necessita ser capaz de reter o valor que se quer armazenar. Se ela não for grande o suficiente o valor armazenado pode ser incorreto.
Não confunda o operador de designação [ = ] (sinal de igual simples) com o operador de comparação [ == ] (sinal de igual duplo), que calcula quando duas expressões são iguais ou não.
Página | 17
Adição,
subtração, multiplicação e divisão
Descrição
Estes operadores retornam a soma, diferença, profuto, ou quciente(respecti quciente(respecti vamente) de dois operandos. A operação é feita usando o tipo de dado dos operadores, assim, por exemplo 9 /4 resulta em 2, desde que 9 e 4 são inteiros. Isto também significa que uma operação pode extrapolar se o resultado for maior do que o que pode ser armazenado no tipo de dado. (e.g. adicionado 1 a um int com o valor de 32.767 resulta gi ves -32.768). Se os operandos forem de tipos de dados diferentes o tipo maior é usado no cálculo. Se um dos operandos for do tipo float fl oat ou do tipo dou ble, então a matemática de ponto flutuante flut uante será usada para o cálculo.
y
y
y
y
y
Exemplos y = y + 3; x = x - 7; i = j * 6; r = r / 5; Sintaxe result = value1 + value2; result = value1 - val ue2; result = value1 * value2; result = value1 / value2; Parâmetros: value1: qualquer variável ou constante value2: qualquer variável ou constante Dicas de programação Saiba que constantes inteiras são consideradas int, portanto alguns alguns cáculos com constantes podem extrapolar (e.g. 60 * 1000 resultará em um número negati vo). Escolha tamanhos de variáveis que sejam grandes o suficiente sufi ciente para reter os maiores resultados poss íveis
dos cálculos. Conheça o ponto em que sua variável pode "dar a volta" e também o que ocorre no sentido contrárioe.g. (0 - 1) ou (0 - 32768). Para matemática que necessita de frações use variáveis do tipo float, mas tenha em conta seus pontos negati vos: tamanho maior e menor velocidade de computação. Use o operador de modelagem para con verter diretamente um tipo de variável em outro e.g. (int)meuFloat.
Página | 18
%
(resto da divisão)
Descrição Calcula o resto da di visão quando um inteiro é dividido por outro. É útil para manter uma variável dentro
de um patamer espec í fico fico (e.g. o tamanho t amanho de um arra y). Sintaxe
resultado = dividendo % divisor Parâmetros dividendo: o número que será di vidido divisor: o número a di vidir por Retorna
o restante Exemplo x = 7 % 5; // x agora comtém 2 x = 9 % 5; // x agora comtém 4 x = 5 % 5; // x agora comtém 0 x = 4 % 5; // x agora comtém 4 Código de exemplo /* atualizar os valores de um array um de cada vez em um bloco */ int values[10]; int i = 0; void setup() {} void loop() { values[i] = analogRead(0); analogRead(0); i = (i + 1) % 10; 10; // operador de resto de divisão atualiza atualiza a variável } Dica O operador de resto da di visão não funciona com variáveis tipo float.
Página | 19
if (condicional) e ==, !=, <, > (operadores de comparação) if, que é usado juntamente com um operador o perador de comparação, verifica quando uma condição é satisfeita, como por exemplo um input acima de um determinado valor. O formato para uma verificação if é: if (algumaVariavel > 50) { // faça alguma coisa } O programa checa se alguma Variavel (colocar acentos em nomes de variáveis não é uma boa idéia) é maior que 50. Se for, o programa realiza uma ação espec í fica. fica. Colocado de outra maneira se a sentença que está dentro dos parêntesis é verdadeira o código que está dentro das cha ves roda; caso contrário o programa salta este bloco de código. As chaves podem ser omitidas após uma sentença if se só hou ver uma única linha de código (definida pelo ponto e ví rgula) rgula) que será executado de modo condicional: if (x > 120) digitalWrite(LEDpin, HIGH); if (x > 120) digitalWrite(LEDpin, HIGH); if (x > 120) {digitalWrite(LEDpin, HIGH);} // todos todos são corretos A sentença que está sendo verificada necessita o uso de pelo menos um dos operadores: Operadores Operadores de comparação: x == y (x é igual a y) x != y (x é não igual a y) x < y (x é menor que y) x > y (x é maior maior que y) x <= y (x é menor ou igual a y) x >= y (x é maior ou igual a y) Cuidado:
Tenha precaução com o uso acidental de apenas um sinal de igual (e.g. if (x = 10) ). O sinal si nal de igual simples é um operador de designação e coloca o valor 10 na variável x. Ao contrário o sinal de igal duplo (e.g. if (x == 10) ), que é um operador de comparação, verifica se x é igual a 10 ou não. A última senteça só é verdadeira se x for igual a 10, mas a anterior sempre será veraddeira. Isto ocorre por que a linguagem l inguagem C (na qual o Arduino é baseado) atribui um valor à sentença (x=10) do seguinte modo: 10 é colocado na variável x (lembre o sinal de igual simples é um operador de designação), então x agora cont ém 10. Então o condicional 'if' atri bui um valor a 10, que será sempre verdadeiro (TRUE), desede que números diferentes de zero são sempre equiparados à verdadeiro. Consequentemente, onsequentemente, if (x = 10) será sempre verdadeiro, que não é o que pretendemos quando usamos um 'if'. Adcionalmente o valor 10 será guardado na variável x que também não é o que pretendemos. if também pode ser usado como parte de uma estrutura de controle ramificada atra vés da construção if..else
Página | 20
Operadores
Booleanos
Estes operadores podem ser usados dentro da condição em uma sentença if. && ("E" lógico) Verdadeiro apenas se os dois operandos forem verdadeiros, ou seja a primeira condição "e" a segunda
forem verdadeiras, e.g. if (digitalRead(2) == 1 && digitalRead(3) == 1) { // ler dois interruptores // ... } é verdadeiro apenas se os dois interruptores estiverem fechados. || ("OU" lógico) Verdadeiro se algum dos operandos for verdadeiro, ou seja se a primeira "ou" a segunda condição for
verdadeira e.g.
if (x > 0 || y > 0) { // ... } é verdadeiro apenas se x ou y forem maiores que 0.
! (negação) Verdadeiro apenas se o operando for falso e.g.
if (!x) { // ... } é verdadeiro apenas se x for falso (i.e. se x for igual a 0). Cuidado Certifique-se de não confundir o operador booleano "E" representado por " &&" e o operador lógico de bits
"E" representado apenas por " &". Eles são animais completamente diferentes. Do mesmo modo não confunda o booleano "OU" representado por " ||" e o operador lógico de bits "|". O operador lógico de bits "NÃO" representado por um " ~" não se parece com o operador booleano "!", mas mesmo assim tenha certeza de estar usando o que você deseja. Exemplos if (a >= 10 && a <= 20){} // verdadeiro se a estiver entre 10 e 20
Página | 21
Operadores
de bits
AND
(&),
OR (|),
XOR (^)
Operadores de bits Os operadores de bits realizam cálculos ao n ível de bits das variáveis. Eles ajudama resolver uma grande quantidade de problemas de programação. Muito do material a baixo é de um excelente tutorial so bre este
tema que pode ser encontrado aqui. Operador de bits AND (&) O operador de bits AND (e) em C++ é um simples & usado entre duas outras expressões inteiras. Ele realiza uma operação entre cada bit de cada uma destas expresões de acordo com a seguinte regra: se os dois bits de entrada forem 1 o resultado da operação tam bém é 1, caso contrário é 0. Outro modo de expressar esta regra é: 0 0 1 1 operando1 0 1 0 1 operando2 ---------0 0 0 1 (operando1 & operando2) - resultado de retorno Em Arduino o tipo int (inteiro) é um valor de 16 bits, portanto usando & entre duas expressões int faz com
que ocorram 16 operações AND simultâneas. Em um fragmento de código: int a = 92; // em binario: 0000000001011100 int b = 101; // em binario: 0000000001100101 int c = a & b; // resultado: 0000000001000100, ou 68 em decimal. Cada um dos 16 bits em a AND b são processados usando este operador, e todos os 16 bits resultantes são armazenados em c resultado o valor 0000000001000100, que é 68 na notação decimal. Um dos usos mais comuns do operador de bits AND é selecionar alguns bits de um valor inteiro, freqüentemente chamado de máscara. Veja o exemplo abaixo para um exemplo. Operador de bits OR (|) O operador de bits OR (ou) em C++ é o sí mbolo de barra vertical, |. Como o operador & ele realiza cálculos com cada bit de duas expressões seguindo a seguinte regra: o resultado da opração é 1 se um dos bits de entrada for 1, caso contrário é 0. Em outras palavras: 0 0 1 1 operando1 0 1 0 1 operando2 ---------0 1 1 1 (operando1 | operando2) - resultado de retorno
Em um fragmento de código: int a = 92; // in binario: 0000000001011100 int b = 101; // in binario: 0000000001100101 int c = a | b; // resultado: 0000000001111101, ou 125 em decimal. Programa de Exemplo Um uso comum para os operadores de bits AND e OR é o que os programadores chamam Ler -ModificarEscrever em uma porta. Em microcontroladores uma porta é um número de 8 bits que representa algo sobre a condição dos pinos. Escrevendo em um controle de porta todos os pinos de uma vez. PORTD é uma constante pr é-construí da que se refere aos estados de sa í da dos pinos digitais 0,1,2,3,4,5,6,7. Se há um 1 em algum dos bits, então este pino está em HIGH. (os pinos ainda precisam ser defindos como pinos de sa í da pelo comando pinMode()). Deste modo se escre vemos PORTD = B00110001; o que fazemos é colocar os pinos 2,3 e 7 em HIGH. Um efeito colateral é que mudamos o
estado dos pinos 0 e 1 que são usados pelo Arduino na comunicação serial, ou seja, interferimos nesta comunicação.
Página | 22
y y
Nosso algoritmo para este programa de ve: Ler o PORTD e limpar somente os bits que queremos controlar (com o operador AND). Combinar o valor modificado de PORTD com o no vo valor dos pinos que queremos controlar (com o operador OR). int i; int j;
// variável do contador
void setup(){ DDRD = DDRD | B11111100; // marca a direcao dos bits para os pinos 2 a 7 deixando o 0 e o 1 intocados (xx | 00 == xx) // o mesmo que pinMode(pin, OUTPUT) para os pinos 2 a 7 Serial.begin(9600); } void loop(){ for (i=0; i<64; i++){ PORTD = PORTD & B00000011; // limpa os bits de 2 - 7, deixa os pinos 0 e 1 intocados (xx & 11 == xx) j = (i << 2); // desvia os bits da variavel 2 bits para a esquerda para evitar os pino 0 e1 PORTD = PORTD | j; // combina a informação da porta com a nova informação para os pinos dos LEDs Serial.println(PORTD, BIN); // debug para verificar a máscara delay(100); } } Operador de bits XOR (^) Há um operador um pouco raro em C++ chamado EX CLUSIVE OR (ou exclusi vo) também conhecido por
XOR (em inglês se pronuncia "equis -or"). Este operador é escrito com o sí mbolo do acento circunflexo ^. O resultado desta operação é 1 se os dois bits de entrada forem diferentes, caso contrário retorna 0: 0 0 1 1 0 1 0 1 ---------0 1 1 0
operando1 operando2 (operando1 ^ operando2) - resultado de retorno
Um simpples código de exemplo: int x = 12; // binario: 1100 int y = 10; // binario: 1010 int z = x ^ y; // binario: 0110, or decimal 6 O operador XOR é freqüentemente utilizado para in verter alguns dos bits de uma expressão inteira. Na máscara deste operador se há um 1 o bit correspondente é invertido, se há um zero o bit é mantido como está. Abaixo há um programa para piscar o pino digital 5. // Piscar_Pino_5 // demonstração para o Exclusive OR void setup(){ DDRD = DDRD | B00100000; // marca o pino digital 5 como saida. Serial.begin(9600); } Página | 23
void loop(){ PORTD = PORTD ^ B00100000; // inverte o bit 5 (digital pino 5), mantem os demais intocados. delay(100); }
Operador
de bits
NOT
(~)
O operador de bits NOT (não) em C++ é o acento til do português ~. Diferente dos operadores & e | este operador é aplicado sobre apenas 1 operando e retorna o valor inverso de cada bit. Por exemplo: 0 1 operando1 ---------1 0 ~ operando1 int a = 103; // binario: 0000000001100111 int b = ~a; // binario: 1111111110011000 = -104 Talvez você se surpreenda ao ver um número negati vo como resultado desta operação. Isto ocorre por que o bit mais elevado em uma variável int é chamdo de bi de sinal. Se este bit é 1 o número é negativo. Este modo de encodar positi vos e negati vos é chamado de complemento para dois. Mais informações
na Wikipedia. De modo complementar, é interessante notar que para qualquer inteiro x, ~x é o mesmo que -x-1. As vezes, o bit de sinal em uma expressão inteira pode causar algumas surpresas indesejadas.
Página | 24
desvio de bits para a esquerda (<<) e para a direita (>>) Há dois operadores de des vio de bits em C++: o de des vio para a esquerda << e o para a direita >>.
Estes operadores fazem com que os bits no operando da esquerda sejam des viados o número especificado de bits no operando da direita. Sintaxe variavel << numero_de_ bits variavel >> numero_de_ bits Parâmetros variavel - (byte, int, long) numero_de_bits inteiro <= 32 Exemplo: int a = 5; // binario: 0000000000000101 int b = a << 3; // binario: 0000000000101000, ou 40 em decimal int c = b >> 3; // binario: 0000000000000101, ou de volta ao 5 como no inicio Quando você desvia para a esquerda um valor x um y número de bits (x<
x são perdidos: int a = 5; // binario: 0000000000000101 int b = a << 14; // binario: 0100000000000000 - o primeiro 1 em 101 é descartado Se você tem certeza de que nenhum dos 1 em um valor vai ser deviado para fora do espaço , um modo simples de pensar no operador para a esquerda é que ele multiplica o operando da direita por 2 ele vado
ao operador da esquerda. Por exemplo para gerar potências de 2 as segintes expressões podem ser utilizadas: 1 << 0 == 1 1 << 1 == 2 1 << 2 == 4 1 << 3 == 8 ... 1 << 8 == 256 1 << 9 == 512 1 << 10 == 1024 ... Quando você desvia para a direita um valor x um y número de bits (x>>y), o comportamento depende do tipo de dados de x. Se x é do tipo int, o bit mais elevado é o bit de sinal que determina se x é negativo ou não. Neste caso o bit do sinal é copiado para os bits inferiores por razões históricas esot éricas: int x = -16; // binario: 1111111111110000 int y = x >> 3; // binario: 1111111111111110 Este comportamento é chamado extensão do sinal e freqüentemente não é o comportamento desejado. Entretanto, você pode desejar des viar preenchendo o espaço com zeros. Neste caso você deve utilizar
uma alteração do tipo de dados que possui uma regra diferente para inteiros não assinalados: int x = -16; // binario: 1111111111110000 int y = (unsigned int)x >> 3; // binario: 0001111111111110 Se você for cauteloso em e vitar a extensão do sinal, você pode usar o operador de des vio para a direita >> como um modo de di vidir um número por potências de 2. Por exemplo: int x = 1000; int y = x >> 3; // divisão inteira de 1000 por 8, resultado y=125.
Página | 25
operadores de bits compostos
AND
(&=) e OR (|=)
Os operadores de bits compostos realizam seus cálculos no n ível de bit das variáveis. São freqüentemente utilizados para limpar ou marcar bits especí ficos. Veja o operador de bits AND(&) e o operador de bits OR(|) para detalhes so bre seu funcionamento.
operador de bits composto AND (&=) Descrição
O operador de bits composto AND ( &=) é freqüentemente utilizado entre uma variável e uma constante para forçar que alguns bits em particular da variável sejam marcados como LOW (como 0). Este conceito aparece em manuais de programação como "limpeza" ou "resetting" de bits. Sintaxe: x &= y; // equivalente a x = x & y; Parâmetros: x: uma variável do tipo char, int ou long y: uma constante do tipo char, int, ou long Exemplo:
Primeiro, uma revisão do operador de bits AND (&) 0 0 1 1 0 1 0 1 ---------0 0 0 1
operando1 operando2 (operando1 & operando2) - resultado de retorno
Bits que passam pelo operador AND um operando 0 são limpados para 0. Posrt anto se m yByte é uma variável do tipo byte myByte & B00000000 = 0. Bits que passam pelo operador AND com um operando 1 se mat ém como estão. Portanto m yByte & B11111111 = myByte. Consequentemente para limpar (marcar como zero) alguns dos bits de uma variável deixando os demais
como estão é só usar o operador de bits composto AND ( &=) com uma constante por exemplo B11111100 1 0 1 0 1 0 1 0 variável 1 1 1 1 1 1 0 0 máscara ---------------------1 0 1 0 1 0 0 0 variável não modificada bits limpos
Aqui está a mesma representação com os bits da variável subtituidos pelo s í mbolo x x x x x x x x x variável 1 1 1 1 1 1 0 0 máscara ---------------------x x x x x x 0 0
Página | 26
variável não modificada bits limpos
portato se: myByte = 10101010; myByte &= B1111100 == B10101000;
operador de bits composto OR (|=) Descrição
O operador de bits composto OR (|=) é frequentemente utilizado entre uma variável e uma constatnte para forçar que alguns bits em particular sejam marcados como 1. Sintaxe: x |= y; // equivalente a x = x | y; Parâmetros x: uma variável do tipo char, int ou long y: uma constante do tipo char, int, ou long Exemplo: First, a review of the Bitwise OR ( |) operator 0 0 1 1 operando1 0 1 0 1 operando2 ---------0 1 1 1 (operando1 | operando2) - resultado de retorno Bits que passam pelo operador OR com um operando 0 são mantidos como estão, portanto se m yByte é uma variável tipo byte, myByte | B00000000 = myByte; Bytes que passam pelo operador OR com um operando 1 são marcados com 1: myByte & B11111111 = B11111111; Consequentemente para marcar os bits 0 e 1 de uma variável deixando o restante sem mudanças use o operador de bits composto OR (|=) com a constante B00000011 1 0 1 0 1 0 1 0 variável 0 0 0 0 0 0 1 1 máscara ---------------------1 0 1 0 1 0 1 1 variiável não modificada bits alterados
Aqui a mesma representação com as variáveis substituidas pelo s í mbolo x x x x x x x x x variável 0 0 0 0 0 0 1 1 máscara ---------------------x x x x x x 1 1 variiável não modificada bits alterados So if: myByte = B10101010; myByte |= B00000011 == B10101011;
Página | 27
++
(incremento) / -- (decremento)
Descrição Incrementar ou decrementar uma variável (adcionar ou su btrair 1)
Sintaxe x++; // incrementa x em 1 e retorna o antigo valor de x ++x; // incrementa x em 1 e retorna o novo vaor de x x-- ; // decrementa x em 1 e retorna o antigo valor de x --x ; // decrementa x em 1 e retorna o novo valor de x Parâmetros x: uma variavel do tipo integer ou long (possi velmente não assinalada) Retornos O original ou recentemente incrementedo / decrementedo valor da variável. Exemplos x = 2; y = ++x; // x agora contém 3, y contém 3 y = x--; // x contém 2 de novo, y ainda contém 3
+=
, -= , *= , /=
Descrição
Realiza uma operação matemática em uma variável com outra constante ou variável. O operador += (e os outros) são apenas abreviações práticas da sintaxe expandida listada a baixo: Sintaxe x += y; // equivalente à expressão x = x + y; x -= y; // equivalente à expressão x = x - y; x *= y; // equivalente à expressão x = x * y; x /= y; // equivalente à expressão x = x / y; Parâmetros x: qualquer tipo de variável y: qualquer tipo de variável ou constante Exemplos x = 2; x += 4; // x agora contém 6 x -= 3; // x agora contém 3 x *= 10; // x agora contém 30 x /= 2; // x agora contém 15
Página | 28
Constantes Constantes são variáveis pre-definidas na linguagem Arduino. Elas são usadas para tornar os programas
mais facilmente legíveis. Nós classificamos as constantes em grupos.
Definindo níveis lógicos, verdadeiro e falso (constantes booleanas) Há duas constantes usadas para representar verdade ou falsidade na linguagem
Arduino: true (verdadeiro), e false (falso).
false false é a mais simples das duas e é definida como 0 (zero).
true true é frequentemente definida como 1, o que é correto, mas true tem uma definição mais ampla. Qualquer inteiro que não é zero é TRUE, emum modo booleano. Assim, -1, 2 e -200 são todos definidos como true. Note que true e false são digitadas com minúsculas diferente de HIGH, LOW, INPUT, e OUTPUT.
Definindo níveis de pinos, HIGH e LOW Quando estamos lendo ou escre vendo em um pino digital há apenas dois valores que um pino pode ter: HIGH (alto) e LOW(baixo).
HIGH O significado de HIGH (em referência a um pino) pode variar um pouco dependendo se este pino é uma entrada (INPUT) ou saí da (OUTPUT). Quando um pino é configurado como INPUT com pinMode, e lido com um digitalRead, o microcontrolador considera como HIGH se a voltagem for de 3 volts ou mais. Um pino também pode ser configurado como um INPUT com o pinMode, e posteriormente rece ber um HIGH com um digitalWrite, isto vai "levantar" o resistor interno de 20K que vai manter a leitura do pino como HIGH a não ser que ela seja alterada para low por um circu í to externo. Quando um pino é configurado como OUTPUT com o pinMode, e marcado como HIGH com o digitalWrite, ele está a 5 volts. Neste estado ele pode en viar corrente como por exemplo acender um LED que está conectado com um resistor em s érie ao terra, ou a outro pino configurado como OUTPUT e marcado como LOW.
LOW O significado de LOW também pode variar dependendo do pino ser marcado como INPUT ou OUTPUT. QUando um pino é configurado como um INPUT com o pinMode, e lido com o digitalRead, o microcontrolador considera como LOW se a voltagem for de 2 volts ou menos. Quando um pino é configurado como OUTPUT com pinMode, e marcado como LOW com o digitalWrite, ele está a 0 volts. Neste estado ele pode "drenar" corrente como por exemplo para acender um LED que está conectado com um resistor em s érie ao +5 volts, ou a outro pino configurado como OUTPUT e marcado como HIGH.
Definindo pinos digitais, INPUT e OUTPUT Pinos digitais podem ser tanto de INPUT como de OUTPUT. Mudar um pino de INPUT para OUTPUT com pinMode() muda drasticamente o seu comportamento el étrico. Pinos configurados como Inputs
Os pinos do Arduino (Atmega) configurados como INPUT com pinMode() estão em um estado de alta impedância. Um modo de explicar é que os pinos configurados como INPUT fazem demandas Página | 29
extremamente pequenas ao circu í to do qual estão tomando amostras, algo como um resist or de 100 Megaohms em s érie com o pino. Sendo assim é útil para ler um sensor mas não para energizar um LED.
Pinos configurados como outputs Pinos configurados como OUTPUT com pinMode() estão em um estado de baixa impedância. Isto significa que eles podem fornecer grandes quantidades de corrente para outros circu í tos. Os pinos do Atmega podem fornecer corrente positi va ou drenar corrente negati va at é 40 mA (milliamperes) de /para outros dispositivos ou circuí tos. Isto faz com que eles sejam úteis para energizar um LED mas disfuncionais para a leitura de sensores. Pinos configurados como outputs t am bém podem ser danificados ou destruidos por curto-circuitos com o terra ou com outros pontos de 5 volts. A quantidade de corrente fornecida por um pino do Atmega tam bém não é suficiente para ati var muitos relês e motores e, neste caso, algum circu í to de interface será necessário.
Página | 30
Constantes inteiras Constantes inteiras são números usados diretamente no código. Por padrão estes números são tratatados
como int's, mas você pode alterar este comportamento com os modificadores U e L ( veja abaixo). Normalmente constantes inteiras são tratadas na base 10 (decimal), mas formatadores especiais podem ser usados para entrar números em outras bases. Base 10 (decimal) 2 (binário) 8 (octal)
Exemplo
Formatador
123
nenhum
B1111011 0173
Comentário
'B' inicial somente valores de 8 bits (0 a 255) caracteres válidos 0-1 '0' inicial
caractres válidos: 0-7
16 (hexadecimal) 0x7B '0x' inicial caractres válidos: 0-9 A-F, a-f Decimal são na base 10. Esta é a matemática do senso comum com a qual você está acostumado. Constatntes sem outros prefixos são asumidas como decimais.
Exemplo: 101 // o mesmo que 101 decimal ((1 * 10^2) + (0 * 10^1) + 1) Binários são na base 2. Apenas os caracteres 0 e 1 são válidos.
Exemplo: B101
// o memso que 5 decimal ((1 * 2^2) + (0 * 2^1) + 1) O formatador binário trabalha apenas com bytes (8 bits) entre 0 ( B0) e 255 (B11111111). Se for conveniente entrar um número de 16 bits na forma binária você pode fazer isso seguindo o algoritmo abaixo: The binary formatter only works on bytes (8 bits) between 0 (B0) and 255 (B11111111). If it is convenient to input an int (16 bits) in binary form you can do it a two -step procedure such as: myInt = B1100110010101010; // entrada inválida myInt = (B11001100 * 256) + B10101010; // B11001100 é o primeiro byte e B10101010 o segundo Octais são na base oito. Apenas caracteres entre 0 e 7 são válidos. Valores octais são indicados pelo
prefixo "0". Exemplo: 0101
// o mesmo que 65 decimal ((1 * 8^2) + (0 * 8^1) + 1)
Cuidado
É possivel gerar um erro dif íc il de encontrar (não intencional) incluindo um zero à frente de uma constatnte o que fará com que o compilador interprete o valor como octal. Hexadecimais (ou hex) são na base 16. Caracteres válidos são de 0 a 9 e as letras de A a F; A vale 10, B vale 11 at é F que vale 15. Valores hexadeciamis são indicados pelo prefixo "0x". Note A -F pode ser escrito tanto com maiusculas quanto com minúsculas (a -f). Exemplo: 0x101 // o mesmo que 257 decmal ((1 * 16^2) + (0 * 16^1) + 1) Formatadores U e L Por padrão uma constante inteira é tratada como um int com as limitações pertinentes nos valores. Para y y y
especificar uma constante inteira com outro tipo de dado proceda assim: um 'u' ou 'U' para forçar a constante como do tipo não assinalado (unsigned). Exemplo: 33u um 'l' ou 'L' para forçar a constante como do tipo longo (long). Exemplo: 100000L um 'ul' ou 'UL' para forçar a constante como do tipo longo não assinalado (unsigned long). Exemplo: 32767ul Página | 31
Variáveis
booleanas *
variáveis boolenas podem ter apenas dois valores verdadeiro (true) e falso (false).
Exemplo int LEDpin = 5; // LED no pino 5 int switchPin = 13; // interruptor no, outro lado conectado ao terra. boolean running = false; void setup() { pinMode(LEDpin, OUTPUT); pinMode(switchPin, INPUT); digitalWrite(switchPin, HIGH); }
// "levanta" o resistor
void loop() { if (digitalRead(switchPin) == LOW) { // interruptor é pressionado - resistor se mantém "levantado" delay(100); // espera para filtrar ruído da chave running = !running; // inverte o valor da variável running digitalWrite(LEDpin, running) // indica via LED } } * assim chamadas em homenagem a George Boole
char Descrição
Um tipo de dado que ocupa 1 byte de memória e armazena o valor de um caractere. Caracteres literais são escritos entre ' ' (em inglês estes caracteres se chamam single quotes, não consigo imaginar como possa ser em português) como este: 'A' (para cadeias de caracteres - strings - use aspas: "ABC"). Entretanto caracteres são armazenados como números. Você pode ver o código espec í fico na tabela ASCII. Isto significa que é possível realizar operações artim éticas com caracteres, nos quais o valor ASCII do caractere é utilizado (e.g. 'A' + 1 vale 66, desde que o valor ASCII do A máiusculo é 65). Veja a referencia do Serial.println para mais informação de como os caracteres são tr aduzidos em números. O tipo de dado char é também do tipo assinalado, isso quer dizer que é possível codificar números de -128 a 127. Para um tipo de dado não assinalado de 1 byte (8 bits) use o tipo de dado byte. Exemplo char myChar = 'A'; char myChar = 65;
// ambos são equivalentes
Página | 32
byte Descrição Um byte armazena um número de 8 bits não assinalado, de 0 a 255. Exemplo byte b = B10010; // "B" é o formatador binário (B10010 = 18 decimal)
int Descrição Inteiro é o principal tipo de dado para armazenamento num érico capaz de números de 2 bytes. Isto abrange a faixa de -32.768 a 32.767 (valor mí nimo de -2^15 e valor máximo de (2 ^15) -1). Ints armazenam números negati vos com uma t écnica chamada Complemento para dois. O bit mais alto, as vezes chamado de bit de "sinal", e sinaliza se o número é positivo ou negatico. O Arduino cuida da manipulação de números nagati vos para você, assim as operações aritm éticas
funcionam de modo transparente e esperado. Entretanto pode ocorrer uma complicação inesperada na manipulação operador para deslocar bits à direita ( >>).
y y
Exemplo int ledPin = 13; Sintaxe int var = val; var - o nome da variável int val - o valor designado para a variável Dica de programação Quando uma variável excede seu valor máximo de que é capaz ela "decai" ao valor mí nimo de que é
capaz. Note que isso ocorre nas duas direções. int x x = -32,768; x = x - 1; // x agora contém 32,767 - decaindo na direção negativa x = 32,767; x = x + 1;
// x agora contém -32,768 - decaido
Página | 33
int não assinalado (unsigned int) Descrição Ints não assinalados (inteiros sem sinal) são o mesmo que i nts no modo como armazenam valores de 2
bytes. Entretanto, ao in vés de armazenar números negati vos, armazenam somente valores positi vos abrangendo a faixa de 0 a 65.535 ((2 ^16)-1).
A diferença entre ints e ints não assinalados está no modo como o bit mais alto é interpretado.No Arduino o tipo int (que é assinalado), se o bit mais elevado é 1, o número é interpretado como negati vo.
y y
Exemplo unsigned int ledPin = 13; Sintaxe unsigned int var = val; var - nome da variável do tipo int não assinalado val - o valor designado para a variável Dica de programação Quando variáveis excedam sua capacidade máxima elas "decaem" para o valor de sua capacidade mí nima.
Note que isso ocorre nas duas direções. unsigned int x x = 0; x = x - 1; // x agora contém 65535 - decaindo na direção negati ca x = x + 1; // x now contains 0 - decaindo
long
y y
Descrição Variáveis do tipo Long têm um tamanho ampliado para armazenamento de números, e são capazes de armazenar 32 bits (4 bytes), de -2.147.483,648 a 2.147.483.647. Exemplo long speedOfLight = 186000L; // veja Constantes inteiras para a explicação do 'L' Sintaxe long var = val; var - o nome da variável de tipo long val - o valor designado para a variável
Página | 34
long não assinalado (unsigned long) Descrição
Longs não assinalados (longos sem sinal) são variáveis de tamanho ampliado para armazenamento numérico. Diferente dos longs padrão, os não assinalados não armazenam números negati vos, abrangendo a faixa de 0 a 4.294.967.295 (2 ^32 - 1). Exemplo unsigned long time; void setup() { Serial.begin(9600); }
y y
void loop() { Serial.print("Time: "); time = millis(); //imprime o tempo desde que o programa começou a rodar Serial.println(time); // espera um segundo de modo que o programa não envie quantidades absurdas de dados delay(1000); } Sintaxe unsigned long var = val; var - o nome de sua variável tipo long val - o valor designado para a variável
Página | 35
float Descrição
Tipo de dado para números de ponto flutuante, um número que tem um ponto decimal. Números de ponto flutuante são freqüentemente usados para aproximar valores análogos e cont ín uos porque têm mais resolução que os inteiros. Números de ponto flutuante a brangem a faixa de 3,4028235E+38 a 3,4028235E+38. Eles são armazenados em 32 bits (4 bytes) de informação. Números de ponto flutuante não são exatos e podem gerar resutados estranhos quando comparados. Por exemplo 6.0 / 3.0 pode não ser igua a 2.0. Você deve, em vez disso, verificar que o valor absoluto da diferença entre os números é menor que um valor pequeno pr é-determinado. A matemática de ponto flutuante tam bém é muito mais lenta que a dos inteiros na realização de cálculos, deve portanto ser evitada se, por exemplo, um loop tem que rodar a velocidade máxima para uma função em que o tempo é cr'tico. Programadares freqüentemente se esforçam para con verter cálculos com pontos flutuantes em matemática de inteiros para aumentar a velocidade.
y y
Exemplos float myfloat; float sensorCalbrate = 1.117; Sintaxe float var = val; var - o nome da sua variável de ponto flutuante val - o valor designado para a variável Código de exemplo int x; int y; float z; x = 1; y = x / 2; // y agora contém 0, inteiros não suportam frações z = (float)x / 2.0; // z agora contém .5 (voce deve usar 2.0, não 2) Dica de programação Serial.println() trunca os floats (despreza as frações) em inteiros quando en viando comunicação serial. Multiplique por potências de 10 para preser var a resolução.
Página | 36
double Descrição
Número de ponto flutuante de precisão dupla. Ocupa 4 bytes. A implementação do double no Arduino é atualmente exatamente a mesma do float, sem ganho de precisão. Dica
Usuários que utilizam códigos de outras fontes que incluem variávei do tipo dou ble devem examinar o código para para verificar se a precisão implicada é diferente daquela realmente alcançada pelo Arduino.
string
y y
y y
y y
Descrição Strings são representadas como arra ys do tipo de dado char e terminadas por null (nulo). Exemplos Todos os seguintes são declarações válidas de strings. char Str1[15]; char Str2[8] = {'a', 'r', 'd', 'u', 'i', 'n', 'o'}; char Str3[8] = {'a', 'r', 'd', 'u', 'i', 'n', 'o', '\0'}; char Str4[ ] = "arduino"; char Str5[8] = "arduino"; char Str6[15] = "arduino"; Possibilidades de declaração de strings Declarar um array de chars sem inicializar como em Str1 Declarar um array de chars (com um char a mais) e o compilador vai adcionar o caractere null necessário como em Str2 Adcionar explicitamente o caractere null como em Str3 Inicializar com uma string constante entre aspas ; o compilador determina o tamanho de modo a armazenar a string e o caractere null final como em Str4 Inicializar o array com uma string constante e o tamanho explicitos como em Str5 Inicializar o array deixando espaço extra para uma string maior como em Str6 Terminação em Null Geralmente strings são terminadas com o caractere null (código A SCII 0). Isto permite às funções (como Serial.print()) sa ber onde está o final da string. De outro modo elas continuariam lendo os bytes subsequentes da memória que de fato não pertencem à string. Isto significa que sua string de ve ter espaço para um caractere a mais do que o texto que ela cont ém. É por isso que Str2 e Str5 precisam ter 8 caracteres, em bora "arduino" tenha apenas 7 - a última posição é automaticamente preenchida com o caracatere null. Str4 terá o tamanho determinado automaticamente como 8 caracteres, um extra para o null. Na Str3 nós incluimos explicitamente o caractere null (escrito
como '\0'). Note que é possível ter uma string sem o caractere final null (e.g. se você tivesse especificado o tamanho da Str2 com sete ao invés de oito). Isto vai danificar a maioria das funções que usam strings, portanto você não deve fazer isso intencionalmente. Entretanto se você notar algo se comportando de maneira estranha (operações em caracteres que não pertencem à string) este poderia ser o pro blema. Aspas ou apóstrofos? Strings são sempre definidas com aspas ("A bc") e caracteres sempre definidos com apóstrofos('A'). Envolvendo strings longas Você pode envolver strings longas desse modo:
Página | 37
char myString[] = "This is the first line" " this is the second line" " etcetera"; Arrays de strings Freqüentemente é conveniente, quando se está tra balhando com grandes quantidades de texto, como em um projeto com um display de LCD, configurar um array de strings. Devido ao fato de as strings serem elas mesmas arrays, este é de fato um exemplo de um arra y bi-dimencional. No código abaixo os asteriscos após o tipo de dado char "char *" indica que se trata de um array de "ponteiros". Todos os nomes de arra y são de fato ponteiros, e assim são requeridos para se configurar um array de arrays. Ponteiros são uma das partes mais esot éricas da linguagem C que os principiantes têm que entender, mas é necessário entender os ponteiros em detalhe para f azer um uso efeti vo deles neste
caso. Exemplo char* myStrings[]={"This is string 1", "This is string 2", "This is string 3", "This is string 4", "This is string 5","This is string 6"}; void setup(){ Serial.begin(9600); } void loop(){ for (int i = 0; i < 6; i++){ Serial.println(myStrings[i]); delay(500); } }
Página | 38
Arrays Um array é uma coleção de variáveis que são acessadas com um í ndice numérico. Arrays na liguagem de programação C, na qual o Arduino é baseado, podem ser complicados, mas o uso de arra ys simples é relativamente operacionalizável. Criando (Declarando) um Array Todos os métodos abaixo são modos válidos para criar (declarar) um arra y. int myInts[6]; int myPins[] = {2, 4, 8, 3, 6}; int mySensVals[6] = {2, 4, -8, 3, 2}; char message[6] = "hello"; Você pode declarar um array sem inicializar como em m yInts. Em myPins declaramos um array sem escolher explicitamente um tamanho. O compilador conta os elementos e cria o arra y do tamanho apropriado. Finalmente, você pode inicializar e especificar o tamanho do arra y como em mySens Vals. Note que quando declarar um array do tipo char, um elemento a mais é necessário para armazenar o caractere null
de finalização. Acessando um Array Arrays são indexados a partir do zero, ou seja, fazendo referência à inicialização de arra ys acima, o primeiro elemento do arra y está no í ndice 0, assim: mySensVals[0] == 2, mySensVals[1] == 4,
e assim por diante. Isso também significa que em um arra y de 10 elementos o í ndice do último elemento é 9, assim:
int myArray[10]={9,3,2,4,3,2,7,8,9,11}; // myArray[9] contém 11 // myArray[10] é inválido e contém informação aleatória (outro endereço de memória) Por esta razão você deve acessar arrays cuidadosamente. Acessar um arra y após o seu final (usando um í ndice maior do que o declarado) é ler uma faixa de memória que está sendo utilizada para outros propósitos. Ler destes locais pro vavelmente não vai gerar nada al ém de dados in válidos. Escrever em locais de memória aleatórios decididamente não é uma boa idéia, e provavelmente conduzirá a maus resultados como malfuncionamento ou tra vamento do programa. Isto também pode ser um bug dif íc il de
rastrear. Diferente de algumas versões do B ASIC, o compilador C não checa para ver se um acesso a um arra y está dentro das margens legais do tamanho com que o arra y foi declarado. Designar um valor para um array: mySensVals[0] = 10; Recuperar um valor de um array: x = mySensVals[4]; Arrays e FOR Arrays são freqüentemente manipulados dentro da sentença for, nas quais o contador é usado com í ndice para cada elemento. Por exemplo, para imprimir os elementos de um arra y através da porta serial você
poderia fazer alguma coisa assim: int i; for (i = 0; i < 5; i = i + 1) { Serial.println(myPins[i]); }
Página | 39
void A palavra-chave void é usada apenas em declarações de funções. Ela indica que a função não de ve enviar nenhuma informação de retorno à função que a chamou. Exemplo: // ações são realizadas nas funções "setup" e "loop" // mas nenuma informação é enviada ao programa mais amplo void setup() { // ... } void loop() { // ... }
Página | 40
char() Descrição Converte um valor para o tipo de dado char. Sintaxe
char(x) Parâmetros x: um valor de qualquer tipo Retorno
char
byte() Descrição Converte um valor para o tipo de dado byte. Sintaxe byte(x) Parâmetros x: um valor de qualquer tipo Retorno byte
int() Descrição Converte um valor para o tipo de dado int. Sintaxe
int(x) Parâmetros x: um valor de qualquer tipo Retorno
int
long() Descrição Converte um valor para o tipo de dado long. Sintaxe
long(x) Parâmetros x: um valor de qualquer tipo Retorno
long
Página | 41
float() Descrição Converte um valor para o tipo de dado float. Sintaxe
float(x) Parâmetros x: um valor de qualquer tipo Retorno
float
Tabela ASCII O código ASCII (American Standard Code for Information Interchange) está em uso desde a d écada de 1960. Ele é o modo padrão para codificar texto numericamente. * Note que os primeiros 32 caracteres (0-31) são caracteres não imprim íveis, também chamados de caracteres de controle. Os caracteres mais importantes foram nomeados na ta bela abaixo: Valor Decimal 0 1 2 3 4 5 6 7 8 9 10 11 12 13 return 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
Caractere null
tab line feed carriage
Valor Decimal 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
Caractere Valor Decimal espaço ! " # $ % & ' ( ) * + , . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
Caractere Valor Decimal @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
Caractere ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~
Nota do tradutor: O código A SCII é um padrão para codificar texto numericamente e em bora tenha muita importância histórica, vem sendo gradativamente substituido por padrões mais amplos como o UT F, em suas di versas variantes, e os conjuntos de caracteres (charset) definidos pela ISO (International Organization for Standardization). *
Página | 42
pinMode() Descrição Configura o pino especificado para que se comporte ou como uma entrada (input) ou uma sa í da (output). Veja a descrição depinos digitais para mais detalhes.
Sintaxe
pinMode(pin, mode) Parâmetros
pin: o número do pin o qual você deseja predeterminar. mode: pode ser INPUT ou OUTPUT Retorno
Nenhum Exemplo int ledPin = 13;
// LED conectado ao pino digital 13
void setup() { pinMode(ledPin, OUTPUT); }
// predetermina o pino digital como uma saída
void loop() { digitalWrite(ledPin, HIGH); // acende o LED delay(1000); // espera um segundo digitalWrite(ledPin, LOW); // apaga o LED delay(1000); // espera um segundo } Nota
Os pinos de entrada analógica podem ser usados como pinos digitais e de vem ser referenciados com os números de 14 (entrada analógica 0) a 19 (entrada analógica 5).
Página | 43
digitalWrite() Descrição Escreve um valor HIGH ou um LOW em um pino digital. Se o pino foi configurado como uma saí da (output) com o pinMode(), sua voltagem será determinada ao valor correspondente: 5 V (ou 3.3 V nas
placas de 3.3 V) para HIGH, 0 V (terra) para LOW. Se o pino está configurado como uma entrada (input) escre ver um HIGH levantará o resistor interno de 20K t(utorial de pinos digitais). Escre ver um LOW rebaixará o resistor. Sintaxw
digitalWrite(pin, valor) Parâmetros
pin: o número do pin valor: HIGH oo LOW Retorno
nenhum Exemplo int ledPin = 13;
// LED conectado ao pino digital 13
void setup() { pinMode(ledPin, OUTPUT); }
// determia o pino digital como uma saída
void loop() { digitalWrite(ledPin, HIGH); // acende o LED delay(1000); // espera um segundo digitalWrite(ledPin, LOW); // apaga um led delay(1000); // espera um segundo } Nota
Os pinos de entrada analógica podem ser usados como pinos digitais e de vem ser referenciados com os números de 14 (entrada analógica 0) a 19 (entrada analógica 5).
Página | 44
digitalR ead() Descrição Lê o valor de um pino digital especificado, HIGH ou LOW. Sintaxe
digitalRead(pin) Parâmetros
pin: o número do pin digital que você quer ler (int) Retorno HIGH ou LOW
Exemplo int ledPin = 13; // LED conectado ao pino digital 13 int inPin = 7; // botão conectado ao pino digital 7 int val = 0; // variável para armazenar o valor lido void setup() { pinMode(ledPin, OUTPUT); // pré-determina o pino digital 13 como uma saída pinMode(inPin, INPUT); // pré-determina o pino dgital 7 como uma entrada } void loop() { val = digitalRead(inPin); // lê o pino de entrada digitalWrite(ledPin, val); // acende ou apaga o LED de acordo com o pino de entrada } Transfere para o pino 13 o valor lido no pino 7 que é uma entrada. Nota Se o pino não esti ver conectado a nada digitalRead() pode retornar t anto HIGH como LOW (e isso pode variar aleatoriamente). Os pinos de entrada analógica podem ser usados como pinos digitais e de vem ser referenciados com os
números de 14 (entrada analógica 0) a 19 (entrada analógica 5).
Página | 45
analogR ead() Descrição Lê o valor de um pino analógico especificado. A placa Arduino cont ém um conversor analógico-digital de 10 bits com 6 canais (8 canais no Mini e no Nano). Com isto ele pode mapear voltagens de entrada entre 0 e 5 volts para valores inteiros entre 0 e 1023. Isto permite uma resolução entre leituras de 5 volts / 1024 unidades ou 0,0049 volts (4.9 m V) por unidade. São necessários aproximadamente 100 s (0.0001 s) para ler uma entrada analógica, portanto a velocidade máxima de leitura é de aproximadamente 10.000 vezes por segundo. Sintaxe
analogRead(pin) Parâmetros
pin: o número do pino analógico que se deseja ler (0 a 5 na maioria das placas, 0 ta 7 no Mini e no Nano) Retorno
int (0 a 1023) Note Se o pino analógico não esti ver conectado a nada o valor de retorno do analogRead() vai variar de acordo com uma grande quantidade de fatores (e.g. os valores de outras entradas analógicas, a distância de sua mão à placa, etc.). Na prática é um valor aleatório. Exemplo int analogPin = 3; // perna do meio de um potenciómetro conectada ao pino analógico 3 // pernas externas conectadas ao terra e ao +5V int val = 0; // variável para armazenar o valor lido void setup() { Serial.begin(9600); // inicial a comunicação serial } void loop() { val = analogRead(analogPin); // lê o pino de entrada Serial.println(val); // informa o valor lido }
Página | 46
analogWrite() Descrição Escreve um valor analógico (onda PWM) em um pino. Pode s er usado para acender um LED variando o brilho ou girar um motor a velocidade variável. Depois de realizar um analogWrite(), o pino vai gerar uma onda quadrada está vel com o ciclo de rendimento especificado at é que o próximo analogWrite() seja realizado (ou que seja realizado um digitalRead() oudigitalWrite() no mesmo pino). A freqüência do sinal PWM é de aproximadamente 490Hz. Nas novas placas Arduino (incluindo o Mini e o BT) com o chip ATmega168 esta função é eficiente nos
pinos 3,5,6,9,10 e 11. Placas Arduino mais antigas com um ATmega8 suportam o analogWrite() apenas nos pinos 9,10 e 11. Sintaxe
analogWrite(pin, valor) Parâmetros
pin: o pino no qual se deseja escre ver valor: o rendimento do ciclo: entre 0 (sempre desligado) e 255 (sempre ligado). Retorno
nenhum Notas e problemas conhecidos Não é necessário realizar um pinMode() para pr é-determinar o comportamento do pino como sa í da antes
de realizar um analogWrite(). As saí das PWM geradas pelos pinos 5 e 6 terão rendimento de ciclo acima do esperado. Isto se deve às interações com as funções millis() e delay(), que compartilham o mesmo temporizador interno usado para gerar as saí das PWM. Exemplo Torna o brilho de um LED proporcional ao valor lido em um potenciómetro. int ledPin = 9; // LED conectado ao pino digital 9 int analogPin = 3; // potentiómetro conectado ao pino analógico 3 int val = 0; // variável para armazenar o valor lido void setup() { pinMode(ledPin, OUTPUT); // pré-determina o pino como saída } void loop() { val = analogRead(analogPin); // lê o pino de entrada analogWrite(ledPin, val / 4); // os valores do analogRead variam de 0 a 1023, os valores do analogWrite variam de 0 a 255 }
Página | 47
shiftOut() Descrição Envia um byte para a saí da um bit de cada vez. Pode começar tanto pelo bit mais significati vo (mais à esquerda) quano pelo menos significati vo (mais à direita). Os bits vão sendo escritos um de cada vez um pino de dados, em sincronia com as alterações de um pino de clock que indica que o próximo bit está dispon ível. Isto é conhecido como protocolo serial sincrônico e é um modo comumente usado para que os microcontroladores se comuniquem com sensores e com outros microcontroladores. Os dois s ispositi vos se mantêm sincronizados a velocidades próximas da máxima desde que am bos compartilhem a mesma linha de clock. Normamlemte esta caracter í stica é descrita comoSerial Peripheral Interface (SPI). na
documentação dos chips. Sintaxe
shiftOut(dataPin, clockPin, bitOrder, value) Parâmetros
dataPin: o pino no que será a sa í da de cada bit (int) clockPin: o pino que é alterado quando um no vo valor foi enviado ao dataPin (int) bitOrder: qual é a ordem de en vio dos bits, pode ser MSBFIRST LSBFIRST. (Mais significati vo primeiro ou menos significati vo primeiro) value: a informação a enviar para a saí da. (byte) Retorno
Nenhum Note O dataPin e clockPin devem estar configurados como output pela função pinMode(). Exemplo Para o circuí to de referência deste exemplo veja tutorial on controlling a 74 HC595 shift register. //**************************************************************// // Name : shiftOutCode, Hello World // // Author : Carlyn Maw,Tom Igoe // // Date : 25 Oct, 2006 // // Version : 1.0 // // Notes : Code for using a 74HC595 Shift Register // // : to count from 0 to 255 // //**************************************************************** //Pin connected to ST_CP of 74HC595 int latchPin = 8; //Pin connected to SH_CP of 74HC595 int clockPin = 12; ////Pin connected to DS of 74HC595 int dataPin = 11; void setup() { //set pins to output because they are addressed in the main loop pinMode(latchPin, OUTPUT); pinMode(clockPin, OUTPUT); pinMode(dataPin, OUTPUT); } Página | 48
void loop() { //count up routine for (int j = 0; j < 256; j++) { //ground latchPin and hold low for as long as you are transmitting digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, LSBFIRST, j); //return the latch pin high to signal chip that it //no longer needs to listen for information digitalWrite(latchPin, HIGH); delay(1000); } }
PulseIn() Descrição
Lê um pulso (tanto HIGH como LOW) em um pino. Por exemplo, se valor for HIGH, pulseIn() espera que o pino vá paraHIGH, inicia a cronometragem, e então espera que o pino vá para LOW e para a cronometragem. Retorna a duração do pulso em microsegundos. Desiste e retorna 0 se nenhum pulso iniciar dentro de um tempo especificado. O tempo desta função foi determinado empiricamente e pro vavelmente dará erro em pulsos longos. Funciona com pulsos entre 10 microsegundos e 3 minutos. Syntaxe
pulseIn(pino, valor) pulseIn(pino, valor, tempo) Parameters
pino: o número do pino no qual você deseja ler o pulso. (int) valor: tipo de pulso a ler: tanto HIGH como LOW. (int) tempo (opcional): o número de microsegundos a esperar para que o pulso co mece ; o padrão é um segundo (unsigned long) Returno
a duração do pulso (em microsegundos) ou 0 se nehum pulso in iciar antes do tempo especificado (unsigned long) Exemplo int pin = 7; unsigned long duration; void setup() { pinMode(pin, INPUT); } void loop() { duration = pulseIn(pin, HIGH); } Página | 49
millis() Descrição
Retorna o número de milisegundos desde que a placa Arduino começou a rodar o programa. Este número extrapolrá (voltará ao zero) depois de aproximamente 50 dias. Parâmetros
Nenhum Retorno
O número de milisegundos desde que o programa começou a rodar como um tipo longo n ão assinalado. Exemplo unsigned long time; void setup(){ Serial.begin(9600); } void loop(){ Serial.print("Time: "); time = millis(); //imprime o tempo desde que o programa começou Serial.println(time); // espera um segundo para não ficar enviando quantidades absurdas de dados delay(1000); } Dica: Verifique o retorno para o millis é um longo não assinalado. Erros podem ocorrer se um programador
tentar realizar cálculos com outros tipos de dados, como inteiros.
micros() Descrição
Retorna o número de microsegundos desde que a placa Arduino começou a rodar o programa. Este número extrapolrá (voltará ao zero) depois de aproximamente 70 minutos. Nas placas Arduino de 16 M Hz (e.g. Duemilano ve e Nano), esta função tem uma resolução de 4 microsegundos (o valor de retorno será sempre um múltiplo de 4) Nas placas Arduino de 8M Hz (e.g. LilyPad), esta função tem uma resolução de 8 microsegundos. Nota: em 1 milisegundo há 1.000 microsegundos e 1.000.000 de microsegundos em 1 segundo. Parâmetros Nenhum Retorno O número de microsegundos desde que o programa começou a rodar como um tipo longo não assinalado.
Página | 50
Exempl0 unsigned long time; void setup() { Serial.begin(9600); } void loop() { Serial.print("Time: "); time = micros(); //imprime o tempo desde que o programa começou a rodar Serial.println(time); //espera um segundo para não ficar enviando quantidades absurdas de dados delay(1000); }
delay(ms) Descrição Suspende a execução do programa pelo tempo (em milisegundos) especificado como parâmetro. (Em um
segundo há 1.000 milisegundos.) Parâmetros
ms (unsigned long): o número de milisegundos em que o programa ficará com a execução em suspenso. Retorno
nenhum Exemplo int ledPin = 13;
// LED conectado ao pino digital 13
void setup() { pinMode(ledPin, OUTPUT); }
// marca o pino digital como saída
void loop() { digitalWrite(ledPin, HIGH); // acende o LED delay(1000); // espera por um segundo digitalWrite(ledPin, LOW); // apaga o LED delay(1000); // espera por um segundo } Cuidado Embora seja fácil criar um LED piscando com a função dela y(), e muitos programas usam inter valos curtos para tarefas como a de filtrar ru í dos, o uso do dela y() em um programa tem aspectos negati vos
importantes. Nenhuma leitura de sensores, cálculo matemático, ou manipulação de pinos pode seguir durante a execução desta função, portanto muitas outras f unções ficam em espera. Para controles de tempo alternati vos veja a função millis() e e seu programa de exemplo. Programadores com mais conhecimento normalmente evitam o uso de dela y() para cronometrar eventos mais logos do que 10 milisegundos, a não ser que o programa seja muito si mples.
Página | 51
Algumas coisas de fato continuam acontecendo enquanto a função dela y() está controlando o chip ATmega porque as interrupções não são desa bilitadas. A comunicação que aparece no pino RX continua sendo gravada. os pinos e as leituras de PWM (analogWrite) são mantidos, e as interrupções continuam funcionando.
delayMicroseconds(s) Descrição Suspende a execução do programa pelo tempo (em microsegundos) especificado como parâmetro. Um 1
milisegundo há 1.000 microsegundos e em 1 segundo há 1 mil hão. Atualmente o maior valor que produzirá uma suspenção precisa é 16383. Isto pode mudar em distri buições futuras do Arduino. Para suspenções maiores que milhares de micr osegundo você deve utilizar a função delay(). Parâmetros s: o número de microsegundos da suspenção. Retorno
Nenhum Exemplo int outPin = 8;
// digital pino 8
void setup() { pinMode(outPin, OUTPUT); }
// marca o pino digital como saída
void loop() { digitalWrite(outPin, HIGH); // ativa o pino delayMicroseconds(50); // suspenção de 50 microsegundos digitalWrite(outPin, LOW); // desativa o pino delayMicroseconds(50); // suspenção de 50 microsegundos } configura o pino 8 para trabalhar como uma saí da. Envia uma cadeia de de pulsos com um per í odo de 100
microsegundos. Cuidados e problemas conhecidos Esta função funciona com bastante precisão na faixa dos 3 microsegundos e acima. Não podemos nos
assegurar que funcione com precisão para tempos de suspenção menores. Para assegurar suspenções mais precisas esta função desa bilita as interrupções durante sua operação. Isto significa que algumas coisas (como o rece bimento de informações seriais, ou que a atualização do valor de retorno da função mills() ) não funcionarão. Desse modo, você deve usar esta função apenas para suspenções curtas, e usar dela y() para as mais longas. delayMicroseconds(0) gerará uma suspanção muito maior do que a esperada ( ~1020 s) b em como se o parâmetro for um número negativo.
Página | 52
delayMicroseconds(s) Descrição Suspende a execução do programa pelo tempo (em microsegundos) especificado como parâmetro. Um 1
milisegundo há 1.000 microsegundos e em 1 segundo há 1 mil hão. Atualmente o maior valor que produzirá uma suspenção precisa é 16383. Isto pode mudar em distri buições futuras do Arduino. Para suspenções maiores que milhares de micr osegundo você deve utilizar a função delay(). Parâmetros s: o número de microsegundos da suspenção. Retorno
Nenhum Exemplo int outPin = 8;
// digital pino 8
void setup() { pinMode(outPin, OUTPUT); }
// marca o pino digital como saída
void loop() { digitalWrite(outPin, HIGH); // ativa o pino delayMicroseconds(50); // suspenção de 50 microsegundos digitalWrite(outPin, LOW); // desativa o pino delayMicroseconds(50); // suspenção de 50 microsegundos } configura o pino 8 para trabalhar como uma saí da. Envia uma cadeia de de pulsos com um per í odo de 100
microsegundos. Cuidados e problemas conhecidos Esta função funciona com bastante precisão na faixa dos 3 microsegundos e acima. Não podemos nos
assegurar que funcione com precisão para tempos de suspenção menores. Para assegurar suspenções mais precisas esta função desa bilita as interrupções durante sua operação. Isto significa que algumas coisas (como o rece bimento de informações seriais, ou que a atualização do valor de retorno da função mills() ) não funcionarão. Desse modo, você deve usar esta função apenas para suspenções curtas, e usar dela y() para as mais longas. delayMicroseconds(0) gerará uma suspanção muito maior do que a esperada ( ~1020 s) b em como se o parâmetro for um número negativo.
Página | 53
min(x, y) Descrição Calcula o mí nimo entre dois números.
Parâmetros
x: o primeiro número, de qualquer tipo de dado y: o segundo número, de qualquer tipo de dado Retorno
O menor dos dois números. Exemplos sensVal = min(sensVal, 100); // assinala à variável sensVal o mínimo entre seu prório valor e 100 // assegurando que seu valor nunca seja menor que 100 Nota Talvez, de modo não -intuiti vo, max() é frequentemente utilizado para restringir o valor mais baixo de uma variável, enquanto min() é utilizado para restringir o valor mais alto. Cuidado: Devido ao modo como a função min() foi implementada você deve evitar utilizar outras funções dentro dos parênteses, isto pode le var a resultados incorretos min(a++, 100); // evite isso a++; min(a, 100);
// usse isso, mantenha outros cálculos fora da função
Página | 54
max(x, y) Descrição Calcula o máximo entre dois números
Parâmetros
x: o primeiro número, de qualquer tipo de dado y: o segundo número, de qualquer tipo de dado Retorno
O maior dos dois números Exemplo sensVal = max(senVal, 20); // assi nala à variável sensVal o máximo entre seu prório valor e 20 // assegurando que seu valor seja pelo menos 20 Nota Talvez, de modo não -intuiti vo, max() é frequentemente utilizado para restringir o valor mais baixo de uma variável, enquanto min() é utilizado para restringir o valor mais alto. Cuidado Devido ao modo como a função max() foi implementada você deve evitar utilizar outras funções dentro dos parênteses, isto pode le var a resultados incorretos max(a--, 0); // evite isso a--; // use isso, mantenha outros cálculos fora da função max(a, 0);
Página | 55
abs(x) Descrição Calcula o valor absoluto de um número. Parâmetros
x: o número Retorno x: se x for maior ou igual a 0 -x: se x for menor que 0. Cuidado Devido ao modo como a função abs() foi implementada você deve evitar utilizar outras funções dentro dos parênteses, isto pode le var a resultados incorretos abs(a++); // evite isso a++; abs(a);
// use isso, mantenha outros cálculos fora da função
constrain(x, a, b) Descrição
Restring um número dentro de uma faixa. Parâmetros
x: o número a restringir, todos os tipos de dados a: o extremo inferior da faixa, todos os tipos de dados b: o extremo superior da faixa, todos os tipos de dados Retorno x: se x esti ver entre a e b a: se x for menor que a b: se x for mairo que b Exemplo sensVal = constrain(sensVal, 10, 150); // limita o valor da variável sensVal a valores entre 10 e 150
Página | 56
map(value, fromLow, fromHigh, toLow, toHigh) Descrição
Re-mapeia um número de uma faixa de valores para outra. Isto é, um valor de fromLow é mapeado para toLow, um valor fromHigh para toHigh, e valores intermediários da primeira faixa para a segunda faixa, mantendo-se a proporção entre eles. Não restringe valores dentro da faixa, porque valores que extrapolem podem ser úteis e intencionais. A função constrain() pode ser utilizada tantes antes como depois desta função se limites para as faixas forem necessários. Verifique que os limites inferiores de uma faixa podem ser maiores ou menores que os limites superiores. Desse modo a função map() pode ser utilizada para colocar em ordem re versa uma faixa de valores, como por exemplo: y = map(x, 1, 50, 50, 1); A função também pode utilizar números negati vos como neste exemplo: y = map(x, 1, 50, 50, -100); A função map() utiliza números inteiros e não gera frações. Quando o resultado for fracionário ele será truncado e não arredondado. Parâmetros value: o número a ser mapeado
fromLow: limite inferior da faixa atual de value fromHigh: limite superior da faixa atual de value toLow: limite inferior da faixa para a qual se quer mapear toHigh: limite superior da faixa para a qual se quer mapear Retorno O valor mapeado. Exemplo /* Mapear uma entrada analógica de 10 bits para uma saída analógica de 8 bits (0 a 255) */ void setup() {} void loop() { int val = analogRead(0); val = map(val, 0, 1023, 0, 255); analogWrite(9, val); } Apêndice
Para aqueles com inclinação matemática aqui está a função completa: long map(long x, long in_min, long in_max, long out_min, l ong out_max) { return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; }
Página | 57
pow(base, expoente) Descrição Calcula o valor de um número elevado a uma potência. Pow() pode ser utilizado com uma potência fracionária. É útil para gerar mapeamentos exponenciais de valores ou curvas. Parâmetros base: o número(float) expoente: a potência à qual a base é elevada (float) Retorno Oresultado da exponeciação (dou ble) Exemplo Veja a função fscale na bibliteca de código.
sq(x) Descrição Calcula o quadrado de um número. O número multiplicado por ele mesmo.
Parâmetros
x: o número, qualquer tipo de dado Retorno
o quadrado do número
sqrt(x) Descrição Calcula a raí z quadrada de um número.
Parâmetros
x: o número, qualquer tipo de dado Retorno double, a raí z quadrada do número.
Página | 58
sin(rad) Descrição Calcula o seno de um ângulo (em redianos). O resultado será entre -1 e 1.
Parâmetros
rad: o ângulo em radianos (float) Retorno
o seno do ângulo (dou ble) Nota Serial.print() e Serial.println() atualmente não suportam floats.
cos(rad) Descrição Calcula o cosseno de um ângulo (em redianos). O resultado será entre -1 e 1.
Parâmetros
rad: o ângulo em radianos (float) Retorno
o cosseno do ângulo (dou ble) Nota Serial.print() e Serial.println() atualmente não suportam floats.
tan(rad) Descrição Calcula a tangente de um ângulo (em redianos).
Parâmetros
rad: o ângulo em radianos (float) Retorno
a tangente do ângulo (dou ble) Nota Serial.print() e Serial.println() atualmente não suportam floats.
Página | 59
randomSeed(seed) Descrição randomSeed() inicializa um gerador de números pseudo -aleatórios, fazendo com que a seqüência gerada comece por um ponto ar bitrário de uma seqüência aleatória. Esta seqüência , em bora muito longa e aleatória, é sempre a mesma. Se for importante para uma seqüência de valores gerados pela função random() ser diferente, a cada execução de um programa, use randomSeed() para inicializar o gerador de números aleatórios a partir de um valor também aleatório, como um analogRead() de um pino que não esteja conectado.
De modo semelhante, pode ocasionalmente ser útil usar seqüências pseudo -aleatórias que se repetem exatamente a cada execução de um programa. Isto pode ser o btido atravéz da função randomSeed() de um número fixado, antes de se iniciar a seqüência aleatória. Parâmetros
long, int - um número para gerar o iní cio da seqüência. Retorno
nenhum Exemplo long randNumber; void setup(){ Serial.begin(9600); randomSeed(analogRead(0)); } void loop(){ randNumber = random(300); Serial.println(randNumber); delay(50); }
Página | 60
random() Descrição
A função random gera números pseudo -aleatórios. Sintaxe
long random(max) long random(min, max) Parâmetros
min - limite inferior do valor aleatório, inclusi vo (opcional) max - limite superior do valor aleatório, exclusi vo Retorno
long - um número aleatório entre min e (max-1) Note: Se for importante para uma seqüência de valores gerados pela função random() ser diferente, a cada execução de um programa, use randomSeed() para inicializar o gerador de números aleatórios a partir de um valor também aleatório, como um analogRead() de um pino que não esteja conectado.
De modo semelhante, pode ocasionalmente ser útil usar seqüências pseudo -aleatórias que se repetem exatamente a cada execução de um programa. Isto pode ser o btido atravéz da função randomSeed() de um número fixado, antes de se iniciar a seqüência aleatória. Exemplo long randNumber; void setup(){ Serial.begin(9600); // se o pino de entrada analógica 0 não estiver conectado, ruído analógico // aleatório fará com que a função randomSeed() gere // diferente números de início cada vez que o programa for executado. // randomSeed() irá embralhar a função random. randomSeed(analogRead(0)); } void loop() { // imprime um número aleatório entre 0 e 299 randNumber = random(300); Serial.println(randNumber); // imprime um número aleatório entre 10 e 19 randNumber = random(10, 20); Serial.println(randNumber); delay(50); }
Página | 61
Serial.be gin(int
velocidade)
Descrição
Ajusta o taxa de transferência em bits por segundo ( baud) para transmissão de dados pelo padrão serial. Para comunicação com um computador use uma destas taxas: 300, 1200, 2400, 48 00, 9600, 14400, 19200, 28800, 57600, 115200. Você pode, entretanto, especificar outras velocidades por exemplo para comunicação através dos pinos 0 e 1 com um componente que requer uma taxa espec í fica. Parameters int velocidade, em bits por segundo ( baud) Retorno
nenhum Exemplo: void setup() { Serial.begin(9600); // abre a porta serial e ajusta a taxa de transferência de dados para 9600 bps } void loop() {} Exemplo para o Arduino Mega: // Arduino Mega usando as quatro portas seriai s simultaneamente // (Serial, Serial1, Serial2, Serial3), // com diferentes taxas de transferência: void setup(){ Serial.begin(9600); Serial1.begin(38400); Serial2.begin(19200); Serial3.begin(4800); Serial.println("Hello Computer"); Serial1.println("Hello Serial 1"); Serial2.println("Hello Serial 2"); Serial3.println("Hello Serial 3"); } void loop() {}
Página | 62
int Serial.available() Descrição Obtem o número de bytes (caracteres) dispon íveis para leitura através da porta serial. Parâmetros
Nenhum Retorno
O número de bytes dispon íveis para leitura no buffer serial. O buffer serial pode armazenar at é 128 bytes. Exemplo int incomingByte = 0;
// para dados seriais que estão entrando
void setup() { Serial.begin(9600); // abre a porta serial e ajusta a taxa de transferência para 9600 bps } void loop() { // envia dados apenas quando dados forem também recebidos: if (Serial.available() > 0) { // lê o byte que está entrando: incomingByte = Serial.read(); // diga o que você recebeu: Serial.print("Eu recebi : "); Serial.println(incomingByte, DEC); } } Exemplo para o Arduino Mega: void setup() { Serial.begin(9600); Serial1.begin(9600); } void loop() { // lê na porta 0 e envia para a porta 1: if (Serial.available()) { int inByte = Serial.read(); Serial1.print(inByte, BYTE); } // lê na porta 1 e envia para a porta 0: if (Serial1.available()) { int inByte = Serial1.read(); Serial.print(inByte, BYTE); } }
Página | 63
int Serial.read() Descrição
Lê dados que estejam entrando pela porta serial. Parâmetros
Nenhum Retorno
o primeiro byte disponível na entrada da porta serial (ou -1 se não hover dados disponíveis) int Exemplo int incomingByte = 0;
// para entrada serial
void setup() { Serial.begin(9600); // abre a porta serial e ajusta a velocidade para 9600 bps } void loop() { // envia dados apenas quando recebe dados: if (Serial.available() > 0) { // lê o primeiro byte disponível: incomingByte = Serial.read(); // imprime na tela o byte recebido: Serial.print("Eu recebi: "); Serial.println(incomingByte, DEC); } }
Página | 64
Serial.flush() Descrição Esvasia o buffer de entrada da porta serial. Isto é, qualquer chamada à Serial.read() ou Serial.avaiable somente retornarão dados recebidos após a última chamada à Serial.flush(). Parâmetros
nenhum Returns
nenhum
Serial.print( data) Serial.print(data)
Descrição Envia dados pela porta serial. Parâmetro
data: todos os tipos inteiros incluindo caracteres Sintaxe
Este comando pode assumir di versas formas: Serial.print(b) sem nenhum formato especificado, imprime b como um número decimal em uma string ASCII. Por exemplo: int b = 79; Serial.print(b);
imprime a string A SCII "79". Serial.print(b, DEC) imprime b como um número decimal em uma string ASCII. Por exemplo: int b = 79; Serial.print(b, DEC); imprime a string A SCII "79". Serial.print(b, HEX) imprime b como um número hexadecimal em uma string A SCII. Por exemplo: int b = 79; Serial.print(b, HEX);
imprime a string string "4 F". Serial.print(b, OCT) imprime b como um número octal em uma string ASCII. Por exemplo: int b = 79; Serial.print(b, OCT);
imprime a string "117". Serial.print(b, BIN) imprime b como um número binário em uma string ASCII. Por exemplo: int b = 79; Serial.print(b, BIN);
imprime a string "1001111". Serial.print(b, BYTE) imprime b como um byte único. Por exemplo: int b = 79; Serial.print(b, BYTE);
imprime a string "O" que é o caract ér ASCII representado pelo valor 79. Para mais informações veja a Tabela ASCII.
Página | 65
Serial.print(str) se str for uma string ou um arra y de chars imprime uma string ASCII. Por exemplo: Serial.print("Hello World!");
imprime a string " Hello World!". Parâmetros b: o byte a imprimir, ou
str: a string a imprimir Retorno
Nenum Exemplo: /* Usa um bloco FOR para dados e imprime um número em vários formatos. */ int x = 0; // variável void setup() { Serial.begin(9600); }
// abre a porta serial e ajusta a velocidade para 9600 bps
void loop() { // imprime etiquetas Serial.print("SEM FORMATO"); // imprime uma etiqueta Serial.print("\t"); // imprime um tab Serial.print("DEC"); Serial.print("\t"); Serial.print("HEX"); Serial.print("\t"); Serial.print("OCT"); Serial.print("\t"); Serial.print("BIN"); Serial.print("\t"); Serial.println("BYTE"); for(x=0; x< 64; x++){
// apenas parte da tabela ASCII
// imprime em vários formatos Serial.print(x); // imprime um ASCII decimal - o mesmo que "DEC" Serial.print("\t"); // imprime um tab Serial.print(x, DEC); // imprime um ASCII decimal Serial.print("\t"); // imprime um tab Serial.print(x, HEX); // imprime um ASCII hexadecimal Serial.print("\t"); // imprime um tab
Página | 66
Serial.print(x, OCT); // imprime um ASCII octal Serial.print("\t"); // imprime um tab Serial.print(x, BIN); // imprime um ASCII binario Serial.print("\t"); // imprime um tab Serial.println(x, BYTE); // imprime como um byte único e adciona um "cariage return" // com o "println" delay(200); // espera 200 millisegundos } Serial.println(""); // imprime outro carriage return } Dicas de programação e problemas conhecidos Serial.print() não funciona com floats, portanto você precisa fazer uma con versão para um tipo inteiro, perdendo a informação dos valores fracionários. Em algumas situações é útil multiplicar um float por uma potência de 10 para preser var (ao menos em parte) a informação fracionária. Seja cuidadoso ao fazer cálculos desntro dos parêntesis e.g. Serial.print(x -2, DEC); Os tipos de dados unsigned char, e byte irão gerar resultados incorretos e atuar como se fossem do tipo
de dado assinalado. A função Serial.print envia os dados para um buffer. Ele esperará que um caractere seja en viado antes de seguir para o próximo. Entretanto a função envia o retorno antes de en viar o último caractere
Página | 67
Serial.println() Descrição Imprime os dados para a porta serial como legível texto ASCII seguido por um caractere retorno de carro
(ASCII 13, ou '\ r') e um caractere no va linha (ASCII 10, ou '\ n'). Este comando tem as mesmas formas como Serial.print (). Sintaxe Serial.println (val) Serial.println (val, formato)
Parâmetros val: o valor para impressão - qualquer tipo de dados
formato: especifica o número base (para tipos de dados integrais) ou o número de casas decimais (para tipos de ponto flutuante) Retorna
Nenhum Example: /* Analog input
reads an analog input on analog in 0, prints the value out. created 24 March 2006 by Tom Igoe */ int analogValue = 0;
// variable to hold the analog value
void setup() { // open the serial port at 9600 bps: Serial.begin(9600); } void loop() { // read the analog input on pin 0: analogValue = analogRead(0); // print it out in many formats: Serial.println(analogValue);
// print as an ASCII-encoded decimal
Serial.println(analogValue, DEC); // print as an ASCII-encoded decimal Serial.println(analogValue, HEX); // print as an ASCII-encoded hexadecimal Serial.println(analogValue, OCT); // print as an ASCII-encoded octal Página | 68
Serial.println(analogValue, BIN); // print as an ASCII-encoded binary Serial.println(analogValue, BYTE); // print as a raw byte value // delay 10 milli seconds before the next reading: delay(10); }
break break é usado para sair de um bloco do, for, ou while, se sobrepondo à condição normal de verificação. Também é usado para sair de uma sentença switch. Examplo for (x = 0; x < 255; x ++) { digitalWrite(PWMpin, x); sens = analogRead(sensorPin); if (sens > threshold){ // checar a detecção por um sensor x = 0; break; } delay(50); }
Página | 69