在MacOS终端下使用Ino进行Arduino开发

虽然我算不上真正的Vimer,但我还是惊叹与vim的强大,也正慢慢学习vim的使用,经朋友介绍可以用命令行工具Ino进行Arduino开发,那么就可以在终端中使用vim进行Arduino的coding了。其实我使用了好长时间了,觉得不错,适合喜欢用终端敲命令的朋友,所以在此写一下安装和使用。

Ino工具安装

Ino依赖于Arduino IDE,所以使用Ino之前保证已经安装了Arduino IDE,有了Ino你可以做以下事情:

  • 快速新建Arduino工程。
  • 编译工程。
  • 上传工程到Arduino开发板。
  • 串口通信。

安装

可以通过下载最新的源码进行安装,不过这里我还是建议用工具进行安装,Ino使用python实现的,一般mac上都安装了python,所以不用担心,那么Ino可以用Python的包管理工具进行安装,pip或者easy_insyall。这里我们用pip,需要安装pip:

$ curl https://bootstrap.pypa.io/ez_setup.py -o - | sudo python
$ sudo easy_install pip

pip可以用来安装、更新或卸载python软件包,那么我们就可以安装Ino了:

$ sudo pip isntall ino

依赖

要正常使用Ino,依赖于以下工具:

  • Python 2.6+
  • Arduino IDE
  • picocom,用来进行串口通信

第一个Python需求macOS天然满足,Arduino IDE我们需要自己去官网下载,友情提示一定要安装1.0.x版本的,1.6.x或更新的有问题。

picocom工具的话,我们可以用macOS下的homebrew进行安装,在这之前先来安装强大的mac软件包管理工具Homebrew,它的能力类似与Ubuntu Linux的apt-get。

安装Homebrew

$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

安装picocom

$ brew install picocom

ino的使用

如果安装成功了,顺利的话,终端下敲命令ino --helpino -h,会出现简单的使用说明:

$ ino -h
usage: ino [-h] {list-models,preproc,upload,init,build,clean,serial} ...

Ino is a command-line toolkit for working with Arduino hardware.

It is intended to replace Arduino IDE UI for those who prefer to work in
terminal or want to integrate Arduino development in a 3rd party IDE.

Ino can build sketches, libraries, upload firmwares, establish
serial-communication. For this it is split in a bunch of subcommands, like git
or mercurial do. The full list is provided below. You may run any of them with
--help to get further help. E.g.:

    ino build --help

positional arguments:
  {list-models,preproc,upload,init,build,clean,serial}
    build               Build firmware from the current directory project
    clean               Remove intermediate compilation files completely
    init                Setup a new project in the current directory
    list-models         List supported Arduino board models
    preproc             Transform a sketch file into valid C++ source
    serial              Open a serial monitor
    upload              Upload built firmware to the device

optional arguments:
  -h, --help            show this help message and exit

命令表如下:

命令 含义
build 编译当前目录下的工程
clean 删除编译生成的中间文件
init 在当前目录下新建工程
list-model 列出所有支持的Arduino开发板
preproc 将工程文件转换为有效c++文件
serial 打开串口监视器
upload 给Arduino设备上传程序

也可以访问http://inotool.org/quickstart简单了解Ino的使用,这里简单说一下使用。

查看Arduino型号

查看一下是否有支持的Arduino开发板。

$ ino list-models
Searching for Board description file (boards.txt) ... /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/boards.txt
         uno: [DEFAULT] Arduino Uno
   atmega328: Arduino Duemilanove w/ ATmega328
   diecimila: Arduino Diecimila or Duemilanove w/ ATmega168
     nano328: Arduino Nano w/ ATmega328
        nano: Arduino Nano w/ ATmega168
    mega2560: Arduino Mega 2560 or Mega ADK
        mega: Arduino Mega (ATmega1280)
    leonardo: Arduino Leonardo
     esplora: Arduino Esplora
       micro: Arduino Micro
     mini328: Arduino Mini w/ ATmega328
        mini: Arduino Mini w/ ATmega168
    ethernet: Arduino Ethernet
         fio: Arduino Fio
       bt328: Arduino BT w/ ATmega328
          bt: Arduino BT w/ ATmega168
  LilyPadUSB: LilyPad Arduino USB
  lilypad328: LilyPad Arduino w/ ATmega328
     lilypad: LilyPad Arduino w/ ATmega168
    pro5v328: Arduino Pro or Pro Mini (5V, 16 MHz) w/ ATmega328
       pro5v: Arduino Pro or Pro Mini (5V, 16 MHz) w/ ATmega168
      pro328: Arduino Pro or Pro Mini (3.3V, 8 MHz) w/ ATmega328
         pro: Arduino Pro or Pro Mini (3.3V, 8 MHz) w/ ATmega168
   atmega168: Arduino NG or older w/ ATmega168
     atmega8: Arduino NG or older w/ ATmega8
robotControl: Arduino Robot Control
  robotMotor: Arduino Robot Motor

上面就是支持的所有型号的开发板,冒号前的是我们用到配置文件中的,我的开发板是Arduino Pro Mini (5V, 16MHz) w/ ATmega328,所以对应的是pro5v328,你可以找到自己的板型,编译和上传的时候会用到,默认的是uno,所以一定要搞清楚自己的是哪一个型号。

新建Ino工程

可以用blink模板新建工程,这之前需要创建自己的工程目录,比如blink

$ mkdir blink
$ cd blink
$ ino init -t blink

可以用tree命令列出文件树(tree命令可以用homebrew安装brew install tree):

$ tree
.
├── lib
└── src
    └── sketch.ino

2 directories, 1 file

可以看到生成了两个目录,一个是lib一个是src,lib用来放第三方arduino的库,而src存放我们自己的代码,这里因为用了模板,所以生成了一个sketch.ino,可以查看其内容:

$ cat src/sketch.ino

#define LED_PIN 13

void setup()
{
    pinMode(LED_PIN, OUTPUT);
}

void loop()
{
    digitalWrite(LED_PIN, HIGH);
    delay(100);
    digitalWrite(LED_PIN, LOW);
    delay(900);
}

这样我们就可以用vim进行coding了,修改sketch.ino即可,当然,我们也可以将其改成其他的名字,比如blink.ino。

编译工程

用ino build编译工程时,其实相关的是板子的mcu型号,所以使用此命令可以加-m参数指定开发板型号,就是我们之前看到的,我的是pro5v328,如果不指定-m参数的话,命令会使用默认的板型,就是list-model结果中带有**[DEFAULT]**标识的,一般为uno。

$ ino build -m pro5v328
Searching for Board description file (boards.txt) ... /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/boards.txt
Searching for Arduino lib version file (version.txt) ... /Applications/Arduino.app/Contents/Resources/Java/lib/version.txt
Detecting Arduino software version ...  1.0.6 (1.0.6)
Searching for Arduino core library ... /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino
Searching for Arduino variants directory ... /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/variants
Searching for Arduino standard libraries ... /Applications/Arduino.app/Contents/Resources/Java/libraries
Searching for make ... /Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/bin/make
Searching for avr-gcc ... /Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/bin/avr-gcc
Searching for avr-g++ ... /Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/bin/avr-g++
Searching for avr-ar ... /Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/bin/avr-ar
Searching for avr-objcopy ... /Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/bin/avr-objcopy
src/sketch.ino
Searching for Arduino lib version file (version.txt) ... /Applications/Arduino.app/Contents/Resources/Java/lib/version.txt
Detecting Arduino software version ...  1.0.6 (1.0.6)
Scanning dependencies of src
Scanning dependencies of arduino
src/sketch.cpp
arduino/avr-libc/malloc.c
arduino/avr-libc/realloc.c
arduino/WInterrupts.c
arduino/wiring.c
arduino/wiring_analog.c
arduino/wiring_digital.c
arduino/wiring_pulse.c
arduino/wiring_shift.c
arduino/CDC.cpp
arduino/HardwareSerial.cpp
arduino/HID.cpp
arduino/IPAddress.cpp
arduino/main.cpp
arduino/new.cpp
arduino/Print.cpp
arduino/Stream.cpp
arduino/Tone.cpp
arduino/USBCore.cpp
arduino/WMath.cpp
arduino/WString.cpp
Linking libarduino.a
Linking firmware.elf
Converting to firmware.hex

当然我们还有另一种方法指定板子型号,就是添加配置文件,有三种类型的配置文件:

配置文件 作用域 优先级
/etc/ino.ini 对mac中所有用户下的所有ino工程有效 最低
~/.inorc 对当前用户下的所有工程有效 次之
./ino.ini 对当前工程有效 最高

ino build不指定-m时,工具会优先查看当前工程目录下是否有ino.ini,如果有的话依据配置文件中的参数设置进行编译,如果没有,在去常看当前mac用户$HOME目录下是否有.inorc文件,如果有则据此文件中的配置编译,如果没有,再继续查找系统配置中是否有ino.ini文件,如果有则按配置编译,如果没有则按照默认板型uno进行编译,上传命令ino upload和调用串口监视器ino serial同样是此规则。

所以建议在每个工程下添加适配的配置文件:

$ touch ino.ini

配置文件中可以指定build、upload和serial这三个功能的参数,用vim编辑ino.ini文件,内容如下:

[build]
board-model = pro5v328

[upload]
board-model = pro5v328
serial-port = /dev/tty.wchusbserial1470

[serial]
serial-port = /dev/tty.wchusbserial1470

上面的serial和upload参数用于后面。

这样的话,我们每次在自己的工程里只需执行命令ino build即可。

工程目录下加入配置文件后的文件树如下:

$ tree
.
├── ino.ini
├── lib
└── src
    └── sketch.ino

	2 directories, 2 files

上传程序

上传程序会使用到串口,我用的串口工具,在系统中识别为tty.wchusbserial1470,所以配置文件中改为我们自己对应的串口,如果你不知道自己的串口是什么,可以查看/dev/目录下以tty为前缀的串口:

$ ls /dev/tty.*
/dev/tty.Bluetooth-Incoming-Port /dev/tty.wchusbserial1470

可以看到有效的串口,mac一般都会有蓝牙,其中有一个是蓝牙,那么另一个就是我们的串口***,所以这里配置文件就是/dev/tty.wchusbserial1470

其实上传命令可以使用两个参数,一个是-m(同上)来指定板子型号,另一个是-p,用来指定使用串口,所以这里可以指定参数来上传程序到arduino设备:

$ ino upload -m pro5v328 -p /dev/tty.wchusbserial1470

如果不指定-p参数的话就会按照之前提到的规则去查找配置文件,使用配置文件中指定的串口进行上传,所以执行ino upload命令就可以了:

$ ino upload
Searching for stty ... /bin/stty
Searching for avrdude ... /Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/bin/avrdude
Searching for avrdude.conf ... /Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/etc/avrdude.conf

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.02s

avrdude: Device signature = 0x1e950f
avrdude: reading input file ".build/pro5v328/firmware.hex"
avrdude: writing flash (1082 bytes):

Writing | ################################################## | 100% 0.72s

avrdude: 1082 bytes of flash written
avrdude: verifying flash memory against .build/pro5v328/firmware.hex:
avrdude: load data flash data from input file .build/pro5v328/firmware.hex:
avrdude: input file .build/pro5v328/firmware.hex contains 1082 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 0.63s

avrdude: verifying ...
avrdude: 1082 bytes of flash verified

avrdude: safemode: Fuses OK

avrdude done.  Thank you.)""

使用库文件

如果要使用第三方库的话,可以将库放到工程目录的lib目录下,比如这里我们使用定时器来触发led的blink,用到定时器的库**MsTimer2**,下载下来将库放到lib目录下即可,此时文件树类似如下:

$ tree
.
├── ino.ini
├── lib
│   └── MsTimer2
│       ├── MsTimer2.cpp
│       ├── MsTimer2.h
│       └── examples
│           └── FlashLed
│               └── FlashLed.pde
└── src
    └── sketch.ino

	5 directories, 5 files

然后修改我们的sketch.ino来使用库,可以修改为如下的内容:

#include <MsTimer2.h>

// Switch on LED on pin 13 each second

void flash() {
	static boolean output = HIGH;
	digitalWrite(13, output);
	output = !output;
}

void setup() {
	pinMode(13, OUTPUT);

	MsTimer2::set(500, flash); // 500ms period
	MsTimer2::start();
}

void loop() {

}

然后我们就可以再次编译了,编译之前也可以先清除一下上一次编译生成的中间文件:

$ ino clean

然后再进行编译和上传即可。

vim配合Ino

进行Arduino开发使用Ino可以用vim进行代码编辑,为了更方便,我们可以为vim配置快捷键来完成工程的编译、清除和上传(即build\clean\upload),在~/.vimrc中添加配置即可,我的Vim配置如下:

nmap <F5>b :!ino build<CR>
nmap <F5>c :!ino clean<CR>
nmap <F5>u :!ino upload<CR>

这样就可以在用vim编辑sketch.ino时,普通模式下按下键+b来进行编译,按下键+u键进行上传,按下键+c键进行清除编译生成的中间文件。