Toolchain pengembangan Arduino untuk para pecinta baris perintah: PlatformIO atau bagaimana cara berhenti menggunakan Arduino IDE


Selama setahun terakhir, saya telah menulis cukup banyak kode untuk Arduino dan secara bersamaan mengubah beberapa alat pengembangan. Artikel itu menyebutkan opsi yang saya coba dan lebih detail tentang apa yang saya hentikan. Ini akan menjadi tentang seperangkat alat untuk kasus ini ketika> 10 proyek untuk papan yang berbeda dan sedikit tentang pengembangan dan pemasangan perpustakaan.


Lingkungan pengembangan


Apa masalahnya?


Mungkin karena Arduino tidak fokus pada pengembang profesional, ekosistem di sekitar IDE standar dibedakan dengan tidak adanya alat yang biasa bagi saya:
  • Hanya dalam versi terbaru beberapa jenis manajemen perpustakaan muncul, sejauh ini tanpa kesamaan Gemfile / requirement.txt / package.json, yaitu, tidak mungkin bagi proyek untuk menentukan versi mana yang digunakan
  • tidak ada integrasi dengan git atau vcs lainnya
  • editor teks tidak dapat dibandingkan dengan editor teks favorit saya
  • tidak ada cara untuk menyimpan pemilihan dewan dalam proyek
  • output yang tidak nyaman dari kesalahan kompilasi

Situs web Arduino memiliki daftar alat pengembangan alternatif . Dalam daftar ini ada opsi yang karena berbagai alasan saya tidak mencoba. Misalnya, Atmel Studio dan Visual Studio CE tidak mempertimbangkan. Saya ingin menemukan alat yang mendukung pekerjaan dari baris perintah.


Apa yang mencoba


Ino


Ino - sebuah proyek dari perusahaan Rusia Amperka, sebuah utilitas baris perintah untuk firmware Arduino.
Proyek ini cukup populer,> 200 garpu. Komit terakhir adalah pada bulan April 2014, sehingga tidak berfungsi dengan versi terbaru dari IDE (tampaknya sejak 1,5).
Ada garpu hidup Arturo , saya menggunakannya sedikit, tetapi ada masalah dalam beberapa kasus eksotis.


Arduino-makefile


Arduino-Makefile - kompilasi dan unduh dengan make. Arduino Due, Zero, dan board 32-bit lainnya tidak didukung. Perbedaan dari IDE standar adalah bahwa metode harus dideklarasikan sebelum digunakan, jadi ketika mentransfer proyek yang sudah selesai, Anda mungkin perlu mengedit sumbernya. Jika saya ingat dengan benar, saya tidak bisa berteman dengan Arduino-Makefile dan SparkFun Pro Micro.


Apa yang saya gunakan


PlatformIO


PlatformIO adalah proyek luar biasa yang dibuat oleh pengembang dari Ukraina. Ini termasuk utilitas baris perintah di mana Anda dapat mulai mengkompilasi dan mengunduh program ke beberapa keluarga mikrokontroler (Atmel AVR, Atmel SAM, ST STM32, TI MSP430, dan lainnya). Pada saat yang sama, berbagai set perpustakaan didukung (di situs PlatformIO mereka disebut kerangka kerja): Arduino, Energia, mbed, serta kode asli untuk Atmel AVR, espressif, MSP430.
PlatformIO pada awalnya berorientasi untuk bekerja dari baris perintah, ada juga plugin untuk integrasi dengan editor teks dan IDE: Atom, CLion, Eclipse, Emacs, NetBeans, Qt Creator, Teks Sublime, Vim dan Visual Studio
PlatformIO sangat cocok jika Anda memiliki:
  • satu proyek untuk beberapa papan, mis. kode yang sama harus dikompilasi untuk papan yang berbeda
  • , .. ,
  • ssh, PlatformIO Raspberry Pi

gambar


Arduino

Saya tidak akan menceritakan kembali dokumentasi, di sini adalah petunjuk instalasi , untuk digunakan, lihat bagian Mulai Cepat .
Struktur folder proyek untuk PlatformIO berbeda dari proyek IDE Arduino, setiap proyek berisi file platformio.ini yang menunjukkan papan mana yang digunakan. Dengan demikian, Anda tidak harus memilih papan yang tepat setiap saat.
Saya akan memberi tahu Anda sebuah contoh tentang bagaimana saya menggunakan PlatformIO ketika mengembangkan perpustakaan untuk Arduino. Perpustakaan memiliki dua contoh, masing-masing adalah proyek dalam format PlatformIO. File pengaturan proyek platformio.ini mencantumkan semua papan tempat perpustakaan harus menjalankan:
[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

Anda dapat mengkompilasi contoh untuk semua papan dengan perintah:
platformio run

Anda hanya dapat mengkompilasi untuk uno seperti ini:
platformio run -e uno

Unduh firmware di uno:
platformio run --target upload -e uno

Luncurkan monitor port serial:
platformio serialports monitor

Menambahkan alias ke .zshrc untuk membuat perintah lebih pendek:
alias compile="platformio run"
alias upload="platformio run --target upload"
alias serial="platformio serialports monitor"

Dengan mereka urutan tindakan yang sama:
compile         #    
compile -e uno  #   uno
upload  -e uno  #  uno
serial          #   

Ada juga integrasi dengan Travis CI dan alat CI lainnya, lebih detail di sini .
Sebenarnya, Arduino IDE memiliki antarmuka baris perintah , tetapi jauh dari sempurna.


Nuansa PlatformIO

PlatformIO mempercepat pekerjaan, ini adalah alat yang lebih fleksibel dibandingkan dengan Arduino IDE dan membuatnya lebih mudah untuk mengotomatisasi tugas-tugas rutin. Ada beberapa hal yang perlu dipertimbangkan:
  • kompilasi di PlatformIO tidak selalu setara dengan kompilasi di Arduino IDE, apa yang dikompilasi di PlatformIO mungkin tidak dikompilasi di Arduino IDE dan sebaliknya
  • struktur folder proyek tidak cocok dengan struktur untuk Arduino IDE
  • tidak semua perpustakaan tersedia untuk instalasi melalui platformio lib

Serial.print ("Could be better");


Apa masalahnya?


Serial.print standar () sedikit tidak nyaman jika Anda perlu mencetak
nama dan nilai variabel, misalnya, untuk menampilkan "pin_2 = <state pin 2>, pin_3 = <state pin 3>" Anda harus melakukan ini:
Serial.print("pin_2 = ");
Serial.print(digitalRead(2));

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

Masih kadang-kadang saya ingin menonaktifkan sebagian atau sepenuhnya output untuk seri, misalnya, jika hanya digunakan untuk debugging. Tentu saja, Anda dapat mengomentari panggilan ke Serial.print () untuk ini, tapi saya ingin opsi yang lebih elegan.


Apa yang mencoba


arduinoLogging


Lib ini menggunakan sintaks seperti printf untuk mencetak, dan juga memungkinkan Anda untuk mengatur LOGLEVEL dan dengan demikian menonaktifkan output dari beberapa atau semua pesan. Pesan ditampilkan menggunakan metode Kesalahan, Info, Debug, dan Verbose.
Contoh:
  #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");
  }

Pengubah yang tersedia

wildcardkomentarContoh
% 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


Nama tingkat pesan Kesalahan, Info, Debug, dan Verbose di arduinoLogging tidak netral. Kesalahan tidak selalu menghasilkan kesalahan, itu hanya pesan yang ditampilkan pada LOGLEVEL apa pun (kecuali NOOUTPUT).
Diberikan juga beberapa ketidaknyamanan printf, saya menulis versi saya sendiri, AdvancedSerial .
Sebenarnya, advancedSerial adalah dua hal: kemampuan memanggil print () dan println () di level rantai dan pesan.
  int a = 1;
  int b = 2;

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

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

Contoh lengkap dari Basic.ino
Karena nama metode bertepatan dengan nama metode standar Serial.print () dan Serial.println (), Anda dapat secara opsional mengganti Serial dengan aSerial di sumber.
Untuk nama level pesan, saya memilih v, vv, vvv, vvvv, cara yang cukup umum untuk menunjukkan level detail dari pesan yang ditampilkan, biasanya ditemukan sebagai flag -v, -vv, dll.
Dengan nama-nama ini, lebih mudah untuk mengedit satu level ke level lain, misalnya vv -> vvv lebih mudah daripada 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);
   }

Contoh lengkap dari Advanced.ino


Hemat memori

Jika Anda membungkus string di makro F (), maka itu tidak akan dimuat ke dalam memori (SRAM), jadi untuk menghemat memori, gunakan F ():
  aSerial.print(F(" 16 "));

Tentu saja, dengan menggunakan advancedSerial menambahkan beberapa overhead dibandingkan dengan Serial standar, saya mencoba memperkirakan sekitar yang mana. Di bawah ini saya menyajikan hasil kompilasi untuk Arduino Uno, karena memiliki memori 2KB dan ini adalah minimum di antara papan yang biasanya saya gunakan.

Seri normal, tanpa pustaka:
  void setup() {
   Serial.begin(9600);
  }

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

ruang penyimpanan: 5%
memori dinamis: 9%

lanjutanSeri:
  #include <advancedSerial.h>

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

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

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

ruang penyimpanan: 5%
memori dinamis: 10%

contoh / Advanced.ino
ruang penyimpanan: 9%
memori dinamis: 26%

contoh / Advanced.ino menggunakan F ()
ruang penyimpanan makro : 9%
memori dinamis: 10%
Ternyata penggunaan memori sedikit meningkat. Tetapi advancedSerial bukan solusi optimal dalam hal sumber daya, ada implementasi alternatif, misalnya Debug .


Instalasi Perpustakaan


Apa masalahnya?


Secara default, Arduino IDE menginstal pustaka secara global dan sketsa tidak merekam perpustakaan mana yang digunakan (kecuali untuk arahan #include, tentu saja) dan versi apa. Karena itu, untuk mengkompilasi sketsa di komputer lain, Anda perlu tahu di mana untuk mengunduh pustaka yang diperlukan, lagi-lagi versi pustaka juga perlu ditentukan. Untuk menghindari masalah seperti itu, saya menginstal perpustakaan hanya secara lokal, di dalam folder sketsa. Di bawah ini adalah dua cara untuk menginstal perpustakaan secara lokal untuk Arduino IDE dan PlatformIO.


IDE Arduino


Saya jarang menggunakan IDE Arduino, mungkin ada cara yang lebih baik. Metode ini adalah ini: instal pustaka dalam subfolder proyek Anda dan letakkan symlink (pintas?) Untuk setiap pustaka di folder pustaka (dalam folder tempat pustaka IDE Arduino diinstal).
Ngomong-ngomong, jika saya ingat dengan benar, Arduino IDE mengkompilasi semua pustaka dari folder pustaka saat mengkompilasi sketsa, jadi waktu kompilasi meningkat jika ada banyak pustaka di pustaka. Alasan lain untuk tidak menggunakan Arduino IDE.


PlatformIO


Setiap proyek PlatformIO memiliki subfolder lib di mana perpustakaan dapat ditempatkan. Ini adalah ketika menginstal perpustakaan secara manual. PlatformIO juga memiliki perintah terpisah untuk menginstal pustaka platformio lib, sayangnya ia menginstal pustaka secara global, sehingga pustaka diinstal secara lokal di subfolder lib, Anda perlu menambahkan di projectio.ini proyek:
[platformio]
lib_dir = ./lib

Untuk informasi lebih lanjut tentang platformio lib, lihat dokumentasi .

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


All Articles