Chaîne d'outils de développement Arduino pour les connaisseurs de ligne de commande: PlatformIO ou comment cesser d'utiliser l'IDE Arduino


Au cours de la dernière année, j'ai écrit pas mal de code pour Arduino et changé simultanément plusieurs outils de développement. L'article mentionne les options que j'ai essayées et plus en détail sur ce à quoi je me suis arrêté. Il s'agira d'un ensemble d'outils pour le cas où> 10 projets pour différentes cartes et un peu sur le développement et l'installation de bibliothèques.


Environnement de développement


Quel est le problème?


Probablement parce que Arduino n'est pas axé sur les développeurs professionnels, l'écosystème autour de l'IDE standard se distingue par l'absence des outils habituels pour moi:
  • Ce n'est que dans les versions récentes qu'une sorte de gestion de bibliothèque est apparue, sans la similitude de Gemfile / requirements.txt / package.json, c'est-à-dire qu'il est impossible pour le projet de spécifier quelles versions sont utilisées
  • aucune intégration avec git ou autres vcs
  • un éditeur de texte ne se compare pas à mon éditeur de texte préféré
  • il n'y a aucun moyen de sauvegarder la sélection du conseil d'administration dans le projet
  • sortie gênante des erreurs de compilation

Le site Web Arduino a une liste d'outils de développement alternatifs . Dans cette liste, il existe des options que, pour diverses raisons, je n'ai pas essayées. Par exemple, Atmel Studio et Visual Studio CE n'ont pas pris en compte. Je voulais trouver un outil supportant le travail à partir de la ligne de commande.


Ce qui a essayé


Ino


Ino - un projet de la société russe Amperka, un utilitaire de ligne de commande pour le firmware Arduino.
Le projet était assez populaire,> 200 fourchettes. Le dernier commit date d'avril 2014, il ne fonctionne donc pas avec les dernières versions de l'IDE (il semble depuis la 1.5).
Il y a un fork live d' Arturo , je l'ai utilisé un peu, mais il y avait des problèmes dans certains cas exotiques.


Arduino-makefile


Arduino-Makefile - compiler et télécharger avec make. Arduino Due, Zero et les autres cartes 32 bits ne sont pas prises en charge. La différence avec l'IDE standard est que les méthodes doivent être déclarées avant utilisation, donc lors du transfert de projets terminés, vous devrez peut-être modifier la source. Si je me souviens bien, je n'ai pas pu me lier d'amitié avec Arduino-Makefile et SparkFun Pro Micro.


Ce que j'utilise


PlatformIO


PlatformIO est un excellent projet créé par des développeurs ukrainiens. Il comprend un utilitaire de ligne de commande grâce auquel vous pouvez commencer à compiler et télécharger des programmes vers plusieurs familles de microcontrôleurs (Atmel AVR, Atmel SAM, ST STM32, TI MSP430 et autres). Dans le même temps, différents ensembles de bibliothèques sont pris en charge (sur le site Web PlatformIO, ils sont appelés cadres): Arduino, Energia, mbed, ainsi que le code natif pour Atmel AVR, espressif, MSP430.
PlatformIO était initialement orienté pour fonctionner à partir de la ligne de commande, il existe également des plugins pour l'intégration avec les éditeurs de texte et les IDE: Atom, CLion, Eclipse, Emacs, NetBeans, Qt Creator, Sublime Text, Vim et Visual Studio
PlatformIO est particulièrement adapté si vous avez:
  • un projet pour plusieurs conseils, c'est-à-dire le même code devrait compiler pour différentes cartes
  • , .. ,
  • ssh, PlatformIO Raspberry Pi

image


Arduino

Je ne reviendrai pas sur la documentation, voici les instructions d'installation , pour l'utilisation, voir la section Démarrage rapide .
La structure des dossiers du projet pour PlatformIO diffère du projet Arduino IDE, chaque projet contient un fichier platformio.ini qui indique quelles cartes sont utilisées. Ainsi, vous n'avez pas à choisir la bonne planche à chaque fois.
Je vais vous donner un exemple de la façon dont j'utilise PlatformIO lors du développement d'une bibliothèque pour Arduino. La bibliothèque a deux exemples, chacun d'eux est un projet au format PlatformIO. Le fichier de paramètres du projet platformio.ini répertorie toutes les cartes sur lesquelles la bibliothèque doit s'exécuter:
[env:nanoatmega328]
platform = atmelavr
framework = arduino
board = nanoatmega328

[env:sparkfun_promicro16]
platform = atmelavr
framework = arduino
board = sparkfun_promicro16

[env:due]
platform = atmelsam
framework = arduino
board = due

[env:teensy31]
platform = teensy
framework = arduino
board = teensy31

[env:nodemcu]
platform = espressif
framework = arduino
board = nodemcu

[env:uno]
platform = atmelavr
framework = arduino
board = uno

Vous pouvez compiler un exemple pour toutes les cartes avec la commande:
platformio run

Vous pouvez compiler uniquement pour uno comme ceci:
platformio run -e uno

Téléchargez le firmware sur uno:
platformio run --target upload -e uno

Lancez le moniteur de port série:
platformio serialports monitor

Ajout d'alias à .zshrc pour raccourcir les commandes:
alias compile="platformio run"
alias upload="platformio run --target upload"
alias serial="platformio serialports monitor"

Avec eux la même séquence d'actions:
compile         #    
compile -e uno  #   uno
upload  -e uno  #  uno
serial          #   

Il y a aussi une intégration avec Travis CI et d'autres outils CI, plus de détails ici .
En fait, l'IDE Arduino a une interface en ligne de commande , mais elle est loin d'être parfaite.


PlatformIO Nuances

PlatformIO accélère le travail; c'est un outil plus flexible que l'IDE Arduino et facilite l'automatisation des tâches de routine. Il y a plusieurs points à considérer:
  • la compilation dans PlatformIO n'est pas toujours équivalente à la compilation dans Arduino IDE, ce qui a été compilé dans PlatformIO peut ne pas compiler dans Arduino IDE et vice versa
  • la structure du dossier du projet ne correspond pas à la structure de l'IDE Arduino
  • toutes les bibliothèques ne sont pas disponibles pour l'installation via platformio lib

Serial.print ("Pourrait être mieux");


Quel est le problème?


Le Serial.print () standard est légèrement gênant si vous devez imprimer le
nom et la valeur de la variable, par exemple, pour afficher "pin_2 = <état pin 2>, pin_3 = <état broche 3>", vous devez le faire:
Serial.print("pin_2 = ");
Serial.print(digitalRead(2));

Serial.print(", pin_3 = ");
Serial.println(digitalRead(3));

Parfois, je souhaite désactiver partiellement ou complètement la sortie de la série, par exemple, si elle est utilisée uniquement pour le débogage. Bien sûr, vous pouvez commenter les appels à Serial.print () pour cela, mais je voudrais une option plus élégante.


Ce qui a essayé


arduinoLogging


Cette bibliothèque utilise une syntaxe semblable à printf pour l'impression et vous permet également de définir LOGLEVEL et ainsi de désactiver la sortie de certains ou de tous les messages. Les messages sont affichés à l'aide des méthodes Error, Info, Debug et Verbose.
Un exemple:
  #include "Logging.h"

  // LOGLEVEL   LOG_LEVEL_X,  X ∈ { NOOUTPUT, ERRORS, INFOS, DEBUG, VERBOSE }
  #define LOGLEVEL LOG_LEVEL_INFOS

  void setup() {
    Serial.begin(9600);
    Log.Init(LOGLEVEL, &Serial);

    //   
    Log.Info("pin_2 = %d, pin_3 = %d"CR, digitalRead(2), digitalRead(3));

    //    
    Log.Debug("   ,   LOGLEVEL = LOG_LEVEL_INFOS");
  }

Modificateurs disponibles

caractère génériquecommenterExemple
% sreplace with an string (char*)Log.Info("String %s", myString);
%creplace with an characterLog.Info("use %c as input", myChar)
%dreplace with an integer valueLog.Info("current value %d",myValue);
%lreplace with an long valueLog.Info("current long %l", myLong);
%xreplace and convert integer value into hexLog.Info ("as hex %x), myValue);
%Xlike %x but combine with 0x123ABLog.Info ("as hex %X), myValue);
%breplace and convert integer value into binaryLog.Info ("as bin %b), myValue);
%Blike %x but combine with 0b10100011Log.Info ("as bin %B), myValue);
%treplace and convert boolean value into "t" or "f"Log.Info ("is it true? %t), myBool);
%Tlike %t but convert into "true" or "false"Log.Info ("is it true? %T), myBool);


advancedSerial


Les noms des niveaux de message Erreur, Info, Débogage et Verbose dans arduinoLogging ne sont pas neutres. L'erreur ne produit pas nécessairement une erreur, c'est juste un message qui s'affiche sur n'importe quel LOGLEVEL (sauf NOOUTPUT).
Compte tenu également des inconvénients de printf, j'ai écrit ma propre version, advancedSerial .
En fait, advancedSerial est deux choses: la possibilité d'appeler print () et println () dans les niveaux de chaîne et de message.
  int a = 1;
  int b = 2;

  aSerial.print("a = ").print(a).print("b = ").println(b);

  //     
  aSerial.p("a = ").p(a).p("b = ").pln(b);

Exemple complet de Basic.ino
Étant donné que les noms des méthodes coïncident avec les noms des méthodes standard Serial.print () et Serial.println (), vous pouvez éventuellement remplacer Serial par aSerial dans les sources.
Pour le nom des niveaux de message, j'ai choisi v, vv, vvv, vvvv, une manière assez courante d'indiquer les niveaux de détail des messages affichés, généralement trouvés comme les drapeaux -v, -vv, etc.
Avec ces noms, il est plus facile de modifier un niveau à un autre, par exemple vv -> vvv est plus facile que Info -> Debug.
  #include "advancedSerial.h"

  void setup() {
    Serial.begin(9600);

    aSerial.setPrinter(Serial);    //      

    //  ,      v  vv,  vvv  vvvv   
    aSerial.setFilter(Level::vv);
  }

   void loop() {
     aSerial.l(Level::vv).pln(" ");
     aSerial.l(Level::vvv).pln("  ");

     delay(3000);
   }

Exemple complet de Advanced.ino


Économie de mémoire

Si vous encapsulez la chaîne dans la macro F (), elle ne sera pas chargée en mémoire (SRAM), donc pour économiser de la mémoire, utilisez F ():
  aSerial.print(F(" 16 "));

Bien sûr, l'utilisation de advancedSerial ajoute des frais généraux par rapport au Serial standard, j'ai essayé d'estimer grossièrement lequel. Ci-dessous, je présente les résultats de la compilation pour Arduino Uno, car il dispose de 2 Ko de mémoire et c'est le minimum parmi les cartes que j'utilise habituellement.

Série normale, sans aucune bibliothèque:
  void setup() {
   Serial.begin(9600);
  }

  void loop() {
    Serial.print("test");
    Serial.println("test");
  }

espace de stockage: 5% de
mémoire dynamique: 9%

avancé
  #include <advancedSerial.h>

  void setup() {
   Serial.begin(9600);

   aSerial.setPrinter(Serial);
   aSerial.setFilter(Level::vv);
  }

  void loop() {
    aSerial.print("test").println("test");
  }

espace de stockage: 5%
mémoire dynamique: 10%

exemples / Advanced.ino
espace de stockage: 9%
mémoire dynamique: 26%

exemples / Advanced.ino en utilisant la macro F ()
espace de stockage: 9%
mémoire dynamique: 10%
Il s'avère que l'utilisation de la mémoire augmente légèrement. Mais advancedSerial n'est pas une solution optimale en termes de ressources, il existe des implémentations alternatives, par exemple Debug .


Installation de la bibliothèque


Quel est le problème?


Par défaut, l'IDE Arduino installe les bibliothèques globalement et l'esquisse n'enregistre pas exactement quelles bibliothèques sont utilisées (à l'exception des directives #include, bien sûr) et quelles versions. Pour cette raison, afin de compiler l'esquisse sur un autre ordinateur, vous devez savoir où télécharger les bibliothèques requises, encore une fois les versions de bibliothèque doivent également être spécifiées. Pour éviter de tels problèmes, j'installe les bibliothèques uniquement localement, à l'intérieur du dossier d'esquisse. Vous trouverez ci-dessous deux façons d'installer des bibliothèques localement pour l'IDE Arduino et PlatformIO.


Arduino IDE


J'utilise rarement l'IDE Arduino, il y a peut-être une meilleure façon. La méthode est la suivante: installez les bibliothèques dans un sous-dossier de votre projet et placez des liens symboliques (raccourcis?) Pour chaque bibliothèque dans le dossier des bibliothèques (dans le dossier où les bibliothèques Arduino IDE sont installées).
Soit dit en passant, si je me souviens bien, l'IDE Arduino compile toutes les bibliothèques du dossier des bibliothèques lors de la compilation de n'importe quelle esquisse, donc le temps de compilation augmente s'il y a beaucoup de bibliothèques dans les bibliothèques. Une autre raison de ne pas utiliser l'IDE Arduino.


PlatformIO


Chaque projet PlatformIO a un sous-dossier lib dans lequel les bibliothèques peuvent être placées. C'est lors de l'installation manuelle des bibliothèques. PlatformIO a également une commande distincte pour l'installation des bibliothèques lib platformio, malheureusement il installe les bibliothèques globalement par défaut, de sorte que les bibliothèques sont installées localement dans le sous-dossier lib, vous devez ajouter dans le projet platformio.ini:
[platformio]
lib_dir = ./lib

Pour plus d'informations sur platformio lib, consultez la documentation .

Source: https://habr.com/ru/post/fr392639/


All Articles