Introdução ao Arduino

From Onda Technology Institute Wiki
Jump to: navigation, search

Detalhes

Os workshops de Introdução Arduino do Instituto Onda Technology são leccionados usando o Arduino Nano V3.0 com ATMega 328P.

Sobre o Kit

O Arduino incluído neste kit é o Arduino Nano (ou compatível). É um microcontrolador para sistemas embutidos, já com programador incluído na própria placa de circuito impresso e que necessita apenas de cabo USB. Pode ser programado directamente a partir do ambiente de desenvolvimento disponível no site oficial do Arduino.

Para que serve?

Para tudo. Desde que acoplado aos componentes certos, permite controlar luzes remotamente, saber o estado de um equipamento, controlar a abertura e fecho de portas, medir a luminosidade, temperatura e humidade, entre muitas outras coisas. É um computador muito pequenino e, apesar de substancialmente diferente dos computadores pessoais, o princípio de funcionamento é o mesmo - recebe dados e, de acordo com as instruções que lhe são dadas pelo utilizador, devolve resultados. A grande vantagem, é o fácil acesso a funcionalidades que permitem a interacção com o mundo exterior. Esse acesso é feito através das chamadas portas.

As portas

As portas são a forma que o microcontrolador tem para comunicar com o mundo exterior. Servem para funcionalidades que incluem comunicação de dados (com outros microcontroladores, computadores ou outros equipamentos), obter informações (como estado de sensores) e realizar acções (activar actuadores como relés). Estas portas estão ligadas directamente a pinos da placa de circuito impresso do microcontrolador, e podem ser ligadas a componentes e circuitos externos. Algumas portas são exclusivamente digitais (permitem apenas leitura ou escrita de valores binários 0 ou 1), outras são analógicas (tipicamente unicamente de entrada, também conhecidas como ADC ou Analog to Digital Converters ou Conversores Analógico-Digital). Estes tipos de conversores são avaliados com base em algumas características, algumas das mais importantes sendo a resolução (em número de bits, que também indica o número de valores diferentes que podem ser obtidos, sendo que quanto maior o número de bits, mais preciso é o conversor), a frequência de amostragem (em kHz e que indica o número de amostras que podem ser obtidas por segundo) e o valor máximo de entrada (em Volt, indicando o intervalo de amostragem). No caso do Arduino Nano, as portas são de 10 bit pelo que devolvem valores entre 0-1023 (210), e a tensão máxima de entrada é de 5V. Assim sendo, este microcontrolador consegue devolver 1024 intervalos diferentes de valores entre 0 e 5V e, assim, para calcular o valor de entrada basta apenas executar o seguinte cálculo:

tensão efectiva na entrada = (5V × valor obtido) / 1024

Como a divisão é feita por um valor que é potência de 2 (1024), pode optimizar-se o cálculo, algo muito importante em microcontroladores deste género em que é imperativo poupar recursos por se necessitar que o código seja pequeno, eficiente e poupe energia. As divisões e multiplicações são das operações aritméticas mais pesadas em computação digital, mas as operações bit a bit (AND, OR, XOR, NOT, Shift-left, Shift-right) são bastante rápidas. Uma divisão por uma potência de dois é sempre equivalente a executar um Shift-right (avançar o valor alguns bits para a direita) no número de bits ocupados por essa potência. O inverso directo aplica-se nas multiplicações. O novo cálculo seria então:

tensão efectivana entrada = (5V × valor obtido) ≫ 10

em que “>>” é o operador utilizado para representar um shift-right e 10 é o número a que é preciso elevar 2 para obter o valor 1024.

As portas digitais permitem apenas ler estados de 0 ou 1, ou escrever esses mesmos estados. Algumas portas do Arduino são configuráveis, podendo mudar de modo e alternar entre leitura digital, escrita digital, leitura e escrita digitais ou leitura analógica.

Caso de uso: activar uma porta

É bastante fácil utilizar um Arduino para, por exemplo, colocar um LED a piscar. O circuito é bastante simples e o código também. Utilizando-se uma das portas digitais do Arduino, pode-se alimentar directamente um LED sem necessitar de fonte de alimentação externa, dado que os LEDs necessitam de muito pouca energia.

ExampleCircuit sch.png

Note-se que, segundo o esquema, o circuito tem uma resistência de 220Ω em série com o LED. Esta resistência serve para proteger o LED de corrente excessiva que o poderia danificar. Vejamos o caso de um LED vermelho que tipicamente tem uma queda de tensão fixa de 1.8V e tolera um máximo de 20-20mA de corrente. Se a tensão no pino for de 5V, e não havendo qualquer resistência, o LED seria alimentado com toda a corrente que o Arduino conseguisse fornecer. Dependendo do modelo de Arduino, poderá facilmente ultrapassar a corrente máxima que o LED conseguisse suportar. Mas para limitarmos a corrente a um valor inferior ao máximo suportado pelo LED, poderemos facilmente calcular qual o valor da resistência a aplicar. Se a queda de tensão é de 1.8V, então obtemos que a tensão que seria lida na resistência seria de 5V – 1.8V, ou seja, 3.2V. Como a tensão é calculada com a fórmula

V = R × I

então temos que:

R = V × I

Se tomarmos agora os valores originais, chegamos ao valor de resistência desejado:

R = 3.2 V = 160 × 0.020 A

No entanto não existem resistências de 160Ω. As resistências são produzidas em valores fixos padrão e a mais próxima é de 150Ω. Uma resistência de 150Ω, no entanto, originaria uma corrente superior ao desejável, já para além da tolerância do LED. Por outro lado, também não será necessário ter a luminosidade máxima do LED, podendo reduzir-se consumos energéticos. Assim pode aplicar-se uma resistência de valor superior, que reduz o brilho mas também a corrente que atravessa o LED e, por conseguinte, o consumo. Daí usar-se, por exemplo, uma resistência de 220Ω como na figura. Após determinada a resistência apropriada, pode então passar-se ao código. Apresenta-se, de seguida, um exemplo de código que coloca o LED a brilhar:

  1.  
  2.  
  3. void setup()
  4. {
  5. // inicializar o pino do LED em formato de saída digital
  6. // o nome LED_BUILTIN existe já na biblioteca de Arduino e corresponde a um
  7. // pino específico em cada modelo de Arduino diferente
  8. pinMode(LED_BUILTIN, OUTPUT);
  9. }
  10.  
  11. // função loop – é executada repetidamente até o Arduino ser desligado
  12. void loop()
  13. {
  14. digitalWrite(LED_BUILTIN, HIGH); // activar o pino, colocando o seu valor em HIGH
  15. delay(1000); // esperar um segundo (1000 milissegundos)
  16. digitalWrite(LED_BUILTIN, LOW); // desactivar o pino
  17. delay(1000); // esperar mais um segundo
  18. }
  19.  
  20.  

O código para programar o Arduino é construindo utilizando as linguagens C ou C++. São linguagens de programação estruturadas (o C++, para além de estruturada é uma linguagem orientada a objectos). Isto quer dizer que são organizadas em blocos chamados funções (em C++ funções e métodos). As funções são blocos isolados de linhas de código que servem para executar uma determinada acção. A execução do código é sequencial, o que quer dizer que as instruções são executadas na ordem em que estão colocadas no código, apesar de serem permitidos saltos (instruções que permitem entregar o ponto de execução do programa a outra instrução, para trás ou para a frente). As funções podem também chamar-se a si mesmas ou chamar outras funções. No caso do Arduino, e utilizando o ambiente de desenvolvimento padrão, há duas funções importantes que devem ser declaradas, a função setup() e a função loop(). A função setup() é executada uma única vez quando o Arduino é ligado e serve para realizar vários tipos de preparação e inicialização como, no exemplo deste caso, configurar o pino como sendo de saída digital. Já a função loop, que também é necessária, é executada continuamente enquanto o Arduino está activo e só deixa de ser executada quando o mesmo é desligado. O próprio Arduino é que é responsável por executá-la repetidamente. Por esse motivo é que o LED fica a piscar indefinidamente enquanto o Arduino estiver ligado, assim que for programado. Assim que a função loop() chega à sua última instrução (“delay(1000);”), a função termina e o próprio Arduino recomeça a sua execução, retornando à sua primeira instrução.

Caso de uso: estado de foto-díodos

Os foto-díodos podem funcionar em dois modos distintos. São células foto-eléctricas e podem funcionar em modo condutivo (controlo da condução eléctrica) ou modo gerador (geração de energia eléctrica a partir da luz que recebe). Quando configurados em modo condutivo, consegue a medir-se a tensão observável num dos pinos do sensor, cujo valor absoluto será tanto maior quanto a intensidade luminosa que o atinge, dado que a sua resistência diminui com a intensidade luminosa. Quando utilizados em modo gerador, está a medir-se a corrente eléctrica gerada pelo componente. Para se ler o valor do foto-díodo, é necessário conectá-lo a uma das portas analógicas do Arduino. Neste caso, se o interesse for obter a intensidade luminosa em percentagem, com 100% a ser equivalente à luminosidade máxima do foto-díodo, em vez de se pensar em termos de tensão, pensa-se directamente em termos de percentagem. O circuito recomendável para se utilizar o fotodíodo seria o seguinte:

Pd-s1.png

Este circuito mostra o positivo da fonte de alimentação como + VCC no topo, o foto-díodo percorrido pela corrente Ip, a resistência RLOAD ligada ao neutro e a saída VOUT, que será ligada à porta analógica do Arduino. Há, no entanto, dois aspectos que é importante considerar. O primeiro é que quanto maior for a resistência RLOAD, maior é a sensibilidade do circuito. Com sensibilidade a mais pode obter-se mais ruído de interferência. Quanto menor for a resistência, mais corrente passará, pelo que se irá verificar maior consumo energético. O segundo aspecto é que um foto-díodo tem, tipicamente, uma queda de tensão mínima que, dependendo do modelo, poderá variar entre 0.4V e 2.2V (frequentemente 0.7V), pelo que o valor lido em VOUT nunca poderá ser de 5V. A queda de tensão causada pelo díodo é, no entanto, sempre fixa para um determinado modelo. Representando a queda de tensão do foto-díodo por VP, então a tensão VOUT será sempre no máximo 5V - VP . Tal significa também que se irá perder precisão na leitura do valor de intensidade luminosa, porque o valor máximo que se pode obter na porta analógica já não será 1023, mas sim o valor que se obtém do seguinte cálculo:

valor máximo = ((5V − Vp)/5) × 1024

Optimizando para poder ser calculado em tempo real pelo micro-controlador, obtém-se a seguinte fórmula:

valor máximo = 1024 − (Vp ≪ 10) / 5

Eliminando-se, assim, uma multiplicação. No entanto, este é um cálculo que dificilmente será necessário fazer-se em tempo real, podendo o valor máximo ser obtido previamente por cálculo directo e embutido no próprio programa. Imaginando que o VP fosse 0.7, este cálculo iria resultar no valor 880 (de notar que o resultado final está propositadamente a ser aproximado a inteiros).

Para se obter então em percentagem, será uma questão de dividir o valor VOUT pelo valor máximo (representado agora por VAMAX de Analog Max) e multiplicar por 100, para se obter a intensidade luminosa em percentagem (Lum):

Lum = (VOUT/VAMAX) × 100

No entanto, como estamos a processar inteiros, e para reduzir as perdas de precisão pelas aproximações de inteiros, o ideal é realizar a multiplicação por 100 antes da divisão:

Lum = (100 × VOUT) / VAMAX

E assim obtém-se o valor desejado, que o código de exemplo abaixo poderá ler e devolver via porta de série:

  1.  
  2. // pretendemos ler o valor do pino 0
  3. #define PIN0 0
  4. void setup(void)
  5. {
  6. Serial.begin(9600);
  7. Serial.println();
  8. }
  9.  
  10. void loop(void)
  11. {
  12. // ler o valor do pino
  13. int Vout = analogRead(PIN0);
  14.  
  15. // calcular o valor em percentagem
  16. int Lum = 100 * Vout / 880;
  17.  
  18. // enviar o valor via porta de série
  19. Serial.print(Lum);
  20. Serial.println();
  21.  
  22. // aguardar 100 milissegundos entre leituras
  23. delay(100);
  24. }
  25.  
  26.  

Fora algumas outras inicializações, não será necessário muito mais do que isto para ser ler o estado do foto-díodo.

Recomendação importante

Não tente alimentar relés usando o Arduino directamente. Use sempre a fonte de alimentação (YwRobot), dado que a placa de relés necessita de bastante mais corrente do que o Arduino consegue fornecer quando só ligado à porta USB do computador. Caso tente alimentar a carta de relés com a porta USB através do Arduino, corre o risco de danificar o computador, no melhor dos casos queimando a porta USB.


Links de interesse