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:
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.
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!
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:
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!
Olá Mauro,
ResponderExcluirEste 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.
me ajuda aqui fdp
ExcluirBoas, 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.
ResponderExcluirPaulo, só vi esse seu post hoje. A rotina foi criada por mim, para esse projeto.
Excluircara muito legal esse post, eu estava procurando algo assim e já estava me conformando em ter que aprender c++ para criar libs.
ResponderExcluirVou testar em casa se é possível criar links simbólicos para os arquivos, assim o arquivo nunca ficaria desatualizado, valeu mesmo
Ailson, que bom que foi-lhe útil.
ExcluirNão entendi a ideia dos links simbólicos...
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:
ResponderExcluir1º 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
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"?
ResponderExcluiruse extern na frente da variável...
ExcluirBoa 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
ResponderExcluirBom dia.
ResponderExcluirNã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
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.
ResponderExcluirOi Paulo, quem sabe isso lhe ajuda: https://www.filipeflop.com/blog/como-juntar-dois-projetos-em-arduino/
ExcluirO segundo programa não precisa de setup e loop ?
ResponderExcluirvariáveis definidas no segundo programa servem no primeiro e vice versa ?