quinta-feira, março 30, 2017

Vamos Falar de Arduino? Parte 3

Fechando a série, vamos falar um pouco sobre o software.


A origem da IDE do Arduino é o Processing, que é um ambiente de programação voltado para não programadores. O Processing original se baseava na linguagem Java, que também foi usada na escrita da IDE. Esta IDE foi alterada no Wiring  para trabalhar com código C/C++; bootloader, runtime e bibliotecas permitem executar a aplicação em um microcontrolador. A IDE do Arduino é um fork do Wiring e manteve o mesmo aspecto básico até a versão 1.5, quando a necessidade de suportar novos microcontroladores levaram a algumas mudanças mais profundas. Os comentários abaixo se referem mais ao uso de placas usando microcontroladores ATmega.


É comum encontrarmos uma certa confusão sobre qual a linguagem usada na IDE do Arduino. O primeiro ponto a frisar é que quem irá gerar o código a executar no microcontrolador é um compilador C/C++; no caso das placas que usam ATmega, este compilador é o avr-gcc.  O editor de código da IDE do Arduino possui recursos de colorização de sintaxe, pareamento de delimitadores e identação para a linguagem C++. Quando é solicitada a compilação, a IDE gera um fonte com pequenas adições ao que o programador escreveu (como includes e  declarações para as funções). Ao fazer o link do programa, são grudados ao código uma rotina de iniciação (que inclui o tradicional main() do C/C++) e bibliotecas. O resultado é que a programação na IDE é feita em C/C++ com pequenas facilidades, ao invés de codificar uma rotina main() é necessário codificar uma rotina setup() e uma rotina loop() e o programador conta com várias funções para interagir com os recursos específicos do microcontrolador.

Uma complicação para quem tenta olhar a programação Arduino de forma sistemática é a falta de padronização nas bibliotecas. As rotinas mais básicas (como digitalRead, digitalWrite, pinMode, etc) estão escritas em C. As rotinas de acesso a serial, EEProm e algumas outras coisas são escritas em C++ e você as usa chamando métodos de um objeto criado pelo runtime. Algumas outras bibliotecas, como LiquidCrystal são escritas em C++, mas apenas definem as classes, cabe ao programador criar um objeto a partir delas. E estou falando apenas das bibliotecas que vem com a IDE.

De um modo geral, escrever um primeiro programa simples na IDE do Arduino é simples e requer poucos conhecimentos. Entretanto, a evolução para se tornar um programador consciente de sistemas mais complexos não é suave. À medida em que você tenta entender o como e porque, surge a necessidade de entender conceitos mais completos de C++ e um pouco do funcionamento do microcontrolador. Um outro problema são as limitações da arquitetura de código que se aprende com o Blink, com setup(), loop() e delay().

2 comentários:

Rafael Cremm disse...

To co uma duvida aqui. To querendo saber qual a velocidade máxima do processador atmel328P. Eu fiz alguns simples scripts aqui, usando o arduino UNO, porém o que eu vi ficou longe do que eu esperava...

Os scrits fora esses:

Loop(){
digitalWrite(13,HIGH);
digitalWrite(13,LOW);
}
// Este a velocidade ficou em 150KHz, medidos em osciloscópio.

e o outro:
Loop(){
PORTB=0xff;
PORTB=0;
}
//Este ficou em 2.66MHz.

Bem é isso...

O primeiro exemplo eu imagino que seja por causa das rotinas do bootloader, mas o segundo eu não sei...(na verdade nem sei se da pra usar os registradores do micro direto pelo compilador do arduino.cc)
Eu esperava uma frequência maior que a dos PICs (que é 4 clocks para instruções simples).

Daniel Quadros disse...

Rafael,

No Arduino o ATmega roda a 16MHz. No baixo nível, a escrita em um registrador é feita em 2 ciclos e um jump usa 2 ciclos. Portanto dá 6 ciclos, que é exatamente o que você mediu no segundo caso (sim, você pode acessar os registradores direto).

No primeiro caso o overhead é da biblioteca do Arduino. É feita uma chamada à rotina digitalWrite, que precisa converter o valor 13 no registrador e bit corretos. Além disso, se lembro corretamente, esta rotina programa também o pino como saída.

Lembre-se que você pode gerar também sinais com os timers.