面向命令行行家的Arduino开发工具链:PlatformIO或如何停止使用Arduino IDE


在过去的一年中,我为Arduino写了很多代码,同时更改了一些开发工具。本文提到了我尝试过的选项,并详细介绍了我停止的目标。如果有超过10个针对不同电路板的项目,而有关库的开发和安装,则将涉及一套工具。


开发环境


怎么了


可能是因为Arduino不专注于专业开发人员,所以标准IDE周围的生态系统因缺少我常用的工具而著称:
  • 仅在最近的版本中出现了某种类型的库管理,而没有Gemfile / requirements.txt / package.json的相似性,也就是说,该项目无法指定所使用的版本
  • 没有与git或其他vcs集成
  • 文本编辑器无法与我最喜欢的文本编辑器进行比较
  • 无法在项目中保存董事会选择
  • 不方便输出编译错误

Arduino网站上有一系列替代开发工具在此列表中,出于各种原因,我没有尝试过。例如,没有考虑Atmel Studio和Visual Studio CE。我想从命令行中找到支持工作的工具。


尝试了什么


井野


伊诺 -俄罗斯公司Amperka,为Arduino的固件的命令行工具的一个项目。
该项目非常受欢迎,> 200个分叉。上一次提交是在2014年4月,因此它不适用于最新版本的IDE(似乎从1.5开始)。
有一个Arturo的活叉,我用了一点,但是在某些特殊情况下有问题。


Arduino的makefile


Arduino-Makefile-使用make进行编译和下载。不支持Arduino Due,Zero和其他32位板。与标准IDE的区别在于,必须在使用之前声明方法,因此,在传输完成的项目时,可能需要编辑源代码。如果我没记错的话,我无法与Arduino-Makefile和SparkFun Pro Micro交朋友。


我用什么


PlatformIO


PlatformIO是由乌克兰开发人员创建的优秀项目。它包含一个命令行实用程序,您可以通过该实用程序开始编译程序并将其下载到多个微控制器系列(Atmel AVR,Atmel SAM,ST STM32,TI MSP430等)。同时,支持不同的库集(在PlatformIO网站上称为框架):Arduino,Energia,mbed,以及Atmel AVR,espressif,MSP430的本机代码。
PlatformIO最初旨在从命令行工作,还有一些插件可与文本编辑器和IDE集成:Atom,CLion,Eclipse,Emacs,NetBeans,Qt Creator,Sublime Text,Vim和Visual Studio
如果您有以下条件,PlatformIO特别适合:
  • 一个用于多个委员会的项目,即 相同的代码应为不同的板编译
  • , .. ,
  • ssh, PlatformIO Raspberry Pi

图片


Arduino

我不会讲文档,这里是安装说明,要使用,请参见快速入门部分
。PlatformIO项目的文件夹结构与Arduino IDE项目不同,每个项目都包含一个platformio.ini文件,该文件指示使用了哪些板。因此,您不必每次都选择正确的板。
我将举例说明在为Arduino开发库时如何使用PlatformIO。该库有两个示例,每个示例都是PlatformIO格式的项目。platformio.ini项目设置文件列出了运行该库的所有板:
[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

您可以使用以下命令为所有板编译示例:
platformio run

您只能像这样编译uno:
platformio run -e uno

在uno上下载固件:
platformio run --target upload -e uno

启动串行端口监视器:
platformio serialports monitor

为.zshrc添加了别名以使命令更短:
alias compile="platformio run"
alias upload="platformio run --target upload"
alias serial="platformio serialports monitor"

与他们相同的动作顺序:
compile         #    
compile -e uno  #   uno
upload  -e uno  #  uno
serial          #   

还与Travis CI和其他CI工具集成在一起,请参见此处的更多详细信息
实际上,Arduino IDE具有命令行界面,但这远非完美。


PlatformIO细微差别

PlatformIO加快了工作速度;与Arduino IDE相比,它是更灵活的工具,使自动执行日常任务变得更加容易。有几点要考虑:
  • 在PlatformIO中进行编译并不总是等同于在Arduino IDE中进行编译,在PlatformIO中进行的编译可能无法在Arduino IDE中进行编译,反之亦然
  • 项目文件夹结构与Arduino IDE的结构不匹配
  • 并非所有库都可通过platformio lib安装

Serial.print(“可能更好”);


怎么了


如果需要打印
变量名称和值,例如,要显示“ pin_2 = <状态引脚2>,pin_3 = <状态引脚3>” ,则标准Serial.print()会带来一些不便,您必须执行以下操作:
Serial.print("pin_2 = ");
Serial.print(digitalRead(2));

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

有时我还是想部分或完全禁用该系列的输出,例如,如果仅将其用于调试。当然,您可以为此在对Serial.print()的调用上进行评论,但是我想要一个更优雅的选择。


尝试了什么


arduino日志记录


该库使用类似于printf的语法进行打印,还允许您设置LOGLEVEL,从而禁用某些或所有消息的输出。使用Error,Info,Debug和Verbose方法显示消息。
一个例子:
  #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");
  }

可用的修饰符

通配符评论例子
%秒replace 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


arduinoLogging中的错误,信息,调试和详细消息级别的名称不是中性的。错误不一定会产生错误,它只是在任何LOGLEVEL(NOOUTPUT除外)上显示的一条消息。
考虑到printf的一些不便,我编写了自己的版本advancedSerial
实际上,advancedSerial是两件事:在链和消息级别中调用print()和println()的能力。
  int a = 1;
  int b = 2;

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

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

Basic.ino的 完整示例
由于方法的名称与标准方法Serial.print()和Serial.println()的名称一致,因此可以选择在源代码中将Serial替换为aSerial。
对于消息级别的名称,我选择了v,vv,vvv,vvvv,这是一种相当常见的方式来指示所显示消息的详细程度,通常以-v,-vv等标记出现。
使用这些名称,可以更轻松地将一个级别编辑到另一个级别,例如vv-> vvv比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);
   }

Advanced.ino的 完整示例


节省内存

如果将字符串包装在宏F()中,则不会将其加载到内存(SRAM)中,因此要保存内存,请使用F():
  aSerial.print(F(" 16 "));

当然,与标准Serial相比,使用advancedSerial会增加一些开销,我试图粗略估算出哪一个。下面我介绍了Arduino Uno的编译结果,因为它具有2KB的内存,这是我通常使用的板中最小的。

普通系列,无任何库:
  void setup() {
   Serial.begin(9600);
  }

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

存储空间:5%
动态内存:9%

高级序列号:
  #include <advancedSerial.h>

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

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

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

存储空间:5%
动态内存:10%

示例/ Advanced.ino
存储空间:9%
动态内存:26%

示例/ Advanced.ino使用F()宏
存储空间:9%
动态内存:10%
事实证明,内存使用情况略有增加。但是AdvancedSerial就资源而言不是最佳解决方案,还有其他实现,例如Debug


库安装


怎么了


默认情况下,Arduino IDE会全局安装库,并且草图不会准确记录所使用的库(当然,#include指令除外)以及哪个版本。因此,为了在另一台计算机上编译草图,您需要知道在哪里下载所需的库,再次需要指定库版本。为避免此类问题,我仅在本地在草图文件夹中安装库。以下是在本地为Arduino IDE和PlatformIO安装库的两种方法。


Arduino IDE


我很少使用Arduino IDE,也许有更好的方法。方法是这样的:将库安装在项目的子文件夹中,并在库文件夹(安装Arduino IDE库的文件夹中)中为每个库放置符号链接(快捷方式?)。
顺便说一句,如果我没记错的话,Arduino IDE在编译任何草图时都会编译来自librarys文件夹的所有库,因此如果库中有很多库,则编译时间会增加。不使用Arduino IDE的另一个原因。


PlatformIO


每个PlatformIO项目都有一个lib子文件夹,可以在其中放置库。这是在手动安装库时。PlatformIO还具有用于安装platformio lib库的单独命令,不幸的是,它默认情况下是全局全局安装的,因此这些库是本地安装在lib子文件夹中的,您需要在项目platformio.ini中添加:
[platformio]
lib_dir = ./lib

有关platformio lib的更多信息,请参见文档

Source: https://habr.com/ru/post/zh-CN392639/


All Articles