Dividindo um programa (sketch) do Arduino em mais de um arquivo

Impressionante, vira e mexe eu aprendo um troço útil sobre a plataforma Arduino!

Quando uma aplicação do Arduino começa a crescer muito, ou seja, os fontes passam das dezenas de linhas, começa a ficar incômodo lidar com aquele monte de instruções no mesmo texto. No Pascal, e depois no Delphi da Borland a gente tinha o recurso de dividir o fonte em diferentes arquivos e depois incluí-los em um deles usando-se o comando INCLUDE, dessa forma:

{$INCLUDE interface.pas}
{$INCLUDE calculos.pas}

Quando o compilador, ao compilar o fonte "principal" topava com um include desses, ele achava o arquivo e o incluía naquela posição, montando um arquivão contendo todos os includes.

Obs: não é um include como no C/C++, onde o include é só uma referência a um outro arquivo compilado que vai ser linkado pelo linker.

Procurei esse troço várias vezes no mundo Arduino, sem sucesso. Assim, quando queria dividir os fontes em mais de um arquivo, eu criava uma lib do arquivo e usava o include estilo C. Funcionar funciona, mas...
tem o inconveniente de que muitos projetos do Arduino podem muito bem ser organizados "proceduralmente", ou seja, criando-se simples procedures e não classes. Aí eu tinha que juntar numa classe métodos que não precisavam estar agrupados em uma para poder dividir os fontes.

Hoje no Automação no Parque o amigo Carlos, a.k.a. kbça me mostrou um projeto que baixou da net que parecia ser estruturado em vários arquivos sem a criação de libs/classes. Fomos destrinchando a coisa até que descobrimos o que segue abaixo. O exemplo que eu uso é de um arquivo pequeno, para facilitar a visualização. Na prática normalmente eu não dividiria um arquivo tão pequeno, mas sim arquivos maiores, com vários procedimentos e funções dentro.

- Se vc cria um arquivo .ino, como normalmente se faz com projetos Arduino, o editor do Arduino cria um diretório com o mesmo nome do seu projeto e coloca o arquivo .ino lá, como vc pode ver abaixo:


Aqui a gente tem o programa ControleMotorTransistor.ino no diretório D:\Atrium\Projects\Arduino\ControleMotorTransistor.

Abaixo, o programa, ainda "inteiro":

#define pinControl 10

void setup()
{
  Serial.begin(9600);
  pinMode(pinControl,OUTPUT);
}

void runAndWait(int pin, int speed, int interval)
{
  analogWrite(pin,speed);
  delay(interval);
}

void loop()
{
  runAndWait(pinControl,100,2000);
  runAndWait(pinControl,150,2000);
  runAndWait(pinControl,200,2000);
  runAndWait(pinControl,250,2000);
}

O programa roda um motor CC em quatro velocidades diferentes, usando PWM e um circuito com transistor TIP120 (mais sobre isso em outro post), cada velocidade sendo usada durante 2 segundos.

Para isso foi criada a rotina runAndWait que aciona o motor com os parâmetros pino, velocidade e intervalo de tempo.

Agora, vamos dizer que eu quisesse que o arquivo principal (o ControleMotorTransistor.ino)   contivesse somente o setup e o loop, sem o "miolo", no caso a rotina runAndWait. Para que isso funcione, eu tenho que criar um outro arquivo extensão ino, colocar a rotina dentro e salvar no mesmo diretório onde está o "programa principal" com extensão .ino. Aí os arquivos ficam assim, primeiro o arquivo ControleMotorTransistor.ino.

#define pinControl 10

void setup()
{
  Serial.begin(9600);
  pinMode(pinControl,OUTPUT);
}

void loop()
{
  runAndWait(pinControl,100,2000);
  runAndWait(pinControl,150,2000);
  runAndWait(pinControl,200,2000);
  runAndWait(pinControl,250,2000);
}
Observe que a rotina runAndWait sumiu, ficando só o setup e o loop. Abaixo segue o arquivo procs.ino, que contém a rotina "sumida" do arquivo acima:

void runAndWait(int pin, int speed, int interval)
{
  analogWrite(pin,speed);
  delay(interval);
}

Importante: como já foi dito, o arquivo procs.ino foi salvo no mesmo diretório da aplicação, como dá prá ver abaixo:

Ao abrir o arquivo .ino na IDE do Arduino, vemos:





































Observe que o aplicativo já abriu os dois arquivos .ino, cada um em uma "aba" conforme circulado em vermelho. Isso já indica que já foi identificada uma relação entre os dois arquivos.

Agora, é só compilar e enviar para o Arduino que funcionará.

Vc pode ter vários arquivos contendo rotinas no mesmo diretório. O "programa principal" será aquele que tem o mesmo nome do diretório.

Bom... é isso. Abracadabraço!

Comentários

  1. Olá Mauro,

    Este tópico foi show de bola. Mesmo sendo pequeno, gosto muitas vezes de trabalhar rotinas e funções em arquivos separados pois facilita a organização do processo lógico (mania de bancos de dados - rsrsrsrs). Vlw pela dica.

    ResponderExcluir
  2. Boas, tenho uma duvida de principiante, a rotina de nome "runAndWait" foi criada nes te projecto, ou pertence á linguagem de programalão arduino, um desde ja obrigado pela atenção.

    ResponderExcluir
    Respostas
    1. Paulo, só vi esse seu post hoje. A rotina foi criada por mim, para esse projeto.

      Excluir
  3. cara muito legal esse post, eu estava procurando algo assim e já estava me conformando em ter que aprender c++ para criar libs.
    Vou testar em casa se é possível criar links simbólicos para os arquivos, assim o arquivo nunca ficaria desatualizado, valeu mesmo

    ResponderExcluir
    Respostas
    1. Ailson, que bom que foi-lhe útil.
      Não entendi a ideia dos links simbólicos...

      Excluir
  4. Primeiramente, obrigado por esse post. Sou iniciante no Arduino e, gostaria de saber se você ou algum leitor poderia me ajudar no seguinte: como juntar 2 códigos sobre Matriz de Led 64x16 no Arduino, que seriam:
    1º código: dois textos estáticos, por exemplo, Welcome e Merry Christmas e após, 2º código: um texto rolante, por exemplo, (qualquer texto)
    Se você quiser, lhe envio os códigos;
    Obs.: Tenho dificuldades sobre códigos (sketches) no Arduino.
    Muito obrigado

    ResponderExcluir
  5. Boa noite.Alguém pode me ajudar? Eu tenho um programa arduino que roda em duas abas. Como faço pra pegar o valor de uma variavel de uma aba pra outra? Tipo :Aba 1 tem a int a=1. Aba 2 int b=8. Como faço pra fazer "a"recebe o valor de "b"?

    ResponderExcluir
  6. Boa noite Mauro, tudo bem? achei muito interessante as suas dicas de arduino e estou precisando de uma ajuda para o meu TCC. Será que poderia me passar um contato para tirar algumas duvidas? Fico no aguardo e muito obrigado! Meu nome é Marcelo Lopes, não consegui comentar com meu contato, apenas anonimo. Meu email é lopes_mu@uol.com.br

    ResponderExcluir
  7. Bom dia.
    Não domino de programação e tentei fazer o que disse mas não consegui.
    Tenho um sketch que controlo uma fechadura por senha e outro sketch que controlo a fechadura por cartão rfid.
    Tentei juntar os dois num outro sketch mas não estou conseguindo, então quando vi a sua publicação imaginei que conseguiria mas não consegui.
    Sabe me dizer se tem como eu criar um sketch, que faça um link como descreveu na sua publicação, só que para cada sketch que disse (sketch da senha e o outro sketch do rfid)?
    obrigado

    ResponderExcluir
  8. Rodrigo esta publicação ensina como dividir um sketch, para que o mesmo fica melhor apresentável/organizado. A sua dúvida é mais complexa, pois pra juntar dois sketch vc tem de encontrar uma maneira de os dois rolar em um após o outro ou em simultâneo ou um em função do outro. Pois os dois tem um início que não são comum mas vc tem de os colocar em comum.

    ResponderExcluir
    Respostas
    1. Oi Paulo, quem sabe isso lhe ajuda: https://www.filipeflop.com/blog/como-juntar-dois-projetos-em-arduino/

      Excluir
  9. O segundo programa não precisa de setup e loop ?
    variáveis definidas no segundo programa servem no primeiro e vice versa ?

    ResponderExcluir

Postar um comentário

Postagens mais visitadas deste blog

Controle PID de Potência em Corrente Alternada - Arduino e TRIAC - Parte III

Controle PID de Potência em Corrente Alternada - Arduino e TRIAC - Parte I