【C,C++,Python,JavaScript】EdisonでLチカ

組込みerなら，何でも初めはLチカから．

# プログラム
## MRAAライブラリの導入
EdisonのIOを制御するために，Intelが[MRAAという抽象化ライブラリ](http://iotdk.intel.com/docs/master/mraa/)を提供しています．[ソースコードはこちら](https://github.com/intel-iot-devkit/mraa)．
このライブラリは，購入直後や，Intel発行のバイナリを書き込んだ場合には，既に導入されており，特にインストールすることなく使用できます．[ubilinux](http://www.emutexlabs.com/ubilinux)など，自分でLinuxをインストールした場合は，以下のように **先にGitHubから最新版のswigをインストールし，** 次にmraaをインストールしてください．

(\#は管理者権限で行うコマンドです)
\# opkg install git cmake # Yocto Linuxの場合
\# apt-get install git cmake autoconf byacc yodl # Debianの場合
$ git clone https://github.com/swig/swig.git
$ cd swig
$ ./autogen.sh
$ ./configure
$ make 
\# make install
$ cd ../../

$ git clone https://github.com/intel-iot-devkit/mraa.git
$ cd mraa
$ mkdir build
$ cd build
$ cmake -DBUILDSWIGNODE=OFF ..
$ make
\# make install

## C言語でLチカ
APIの説明は[こちら](http://iotdk.intel.com/docs/master/mraa/gpio_8h.html)．サンプルは，[こちら](https://github.com/intel-iot-devkit/mraa/blob/master/examples/blink-io.c)．

```c:led_c.c
#include <stdio.h>
#include <unistd.h>
#include <mraa.h>

int main(int argc, char *argv[])
{
	mraa_result_t ret;

	// MRAAの初期化処理（ハードウェアの同定）
	mraa_init();

	// MRAAのバージョン出力
	fprintf(stdout, "Hello mraa.\nVersion: %s\n", mraa_get_version());

	// MRAAの20番ポート(=BreakoutボードのJ18-7ピン)初期化
	mraa_gpio_context gpio;
	gpio = mraa_gpio_init(20);
	if(gpio == NULL){
		return 1;
	}

	// ポートを出力に設定
	ret = mraa_gpio_dir(gpio, MRAA_GPIO_OUT);
	if(ret != MRAA_SUCCESS){
		return 1;
	}

	int i;
	for(i=0;i<10;i++){
		// ポートに1(H電圧)を出力
		mraa_gpio_write(gpio, 1);
		usleep(1000*1000);

		// ポートに0(L電圧)を出力
		mraa_gpio_write(gpio, 0);
		usleep(1000*1000);
	}

	// ポートを入力に設定
	mraa_gpio_dir(gpio, MRAA_GPIO_IN);

	// MRAAの終了処理
	mraa_deinit();

	return ret;
}

```

これを，以下のMakefileでビルドします．

```Bash:Makefile
CC = g++
MRAALIBS = -lmraa

.PHONY: all clean led_c led_cpp

all: led_c led_cpp

clean:
	rm -f ./*.o
	rm -f led_c led_cpp

led_c: led_c.o
	$(CC) -O4 $(MRAALIBS) -o $@ $^

led_cpp: led_cpp.o
	$(CC) -O4 $(MRAALIBS) -o $@ $^

%.o: %.c
	$(CC) -Wall -g -c $<
```

**make** を実行すると，led_cという実行ファイルが生成されます．

\# ./led_c
で実行します．（要，管理者権限）

## C++でLチカ
APIの説明は[こちら](http://iotdk.intel.com/docs/master/mraa/classmraa_1_1_gpio.html)．サンプルは，[こちら](https://github.com/intel-iot-devkit/mraa/blob/master/examples/c%2B%2B/Blink-IO.cpp)．
中でやっていることは，C言語のものとほぼ同じです．

```cpp:led_cpp.cpp
#include <stdio.h>
#include <unistd.h>
#include <mraa/gpio.hpp>
#include <mraa/common.hpp>

int main(int argc, char *argv[])
{
	mraa_result_t ret;

	fprintf(stdout, "Hello mraa.\nVersion: %s\n", mraa_get_version());

	mraa::Gpio *gpio = new mraa::Gpio(20);
	if(gpio == NULL){
		return MRAA_ERROR_UNSPECIFIED;
	}

	ret = gpio->dir(mraa::DIR_OUT);
	if(ret != MRAA_SUCCESS){
		mraa::printError(ret);
		return 1;
	}

	for(int i=0;i<5;i++){
		gpio->write(1);
		usleep(1000*1000);

		gpio->write(0);
		usleep(1000*1000);
	}

	gpio->dir(mraa::DIR_IN);

	delete gpio;

	return ret;
}

```

Makefileは，C言語のものと同じです．led_cppという実行ファイルが生成されます．

\# ./led_cpp
で実行．（要，管理者権限）

## PythonでLチカ
サンプルは，[こちら](https://github.com/intel-iot-devkit/mraa/blob/master/examples/python/blink-io8.py)．
中でやっていることは，C/C++のものとほぼ同じです．

```python:led_py.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-

import mraa
import time

print("Hello mraa\nVersion: %s" % mraa.getVersion())

gpio = mraa.Gpio(20)
gpio.dir(mraa.DIR_OUT)

for i in range(5):
	gpio.write(1)
	time.sleep(1)

	gpio.write(0)
	time.sleep(1)

gpio.dir(mraa.DIR_IN)
```

ファイルを作成したら，
$ chmod +x ./led_py.py

で，実行権限を付与してください．

\# ./led_py.py
で実行できます．

## JavaScriptでLチカ
サンプルは，[こちら](https://github.com/intel-iot-devkit/mraa/blob/master/examples/javascript/Blink-IO.js)．
中でやっていることは，C/C++/Pythonのものと，ほぼ同じです．

```Javascript:led_js.js
var m = require("mraa");
console.log("Hello mraa.\nVersion: " + m.getVersion());

var gpio = new m.Gpio(20);
gpio.dir(m.DIR_OUT);

var state = true;
var counter = 20;
                   
periodicActivity();
                            
function periodicActivity(){  
        gpio.write(state?1:0);
        state = !state;                   
        if(counter--)                     
                setTimeout(periodicActivity, 1000)
}
```

\# node ./led_js.js
で実行できます．

# 回路
![Active High回路](https://pbs.twimg.com/media/B3ssgsECQAIcz97.png "回路(Active High)")

EdisonのGNDピン（J19-3）は，内層GNDと接続していると思われ，とてもハンダ付けしにくいです．30[W]以上級の協力なハンダこてを使うのを推奨します．

# 実験
それでは，実際に配線して実験してみます．
分かりやすいように，Breakoutボードに直接リードをハンダ付けしました（手抜き）．
追実験する際は，危ないので，ちゃんとハンダ付けしてくださいね！！

![Active High実装](https://pbs.twimg.com/media/B3srqCbCQAADvn1.jpg "実装(Active High)")

これで，先ほどのプログラムを走らせてみると・・．

[動画](https://vine.co/v/OnUaVATxMrg)

あれ？なんだか暗いような・・・．

それもそのはず，Edisonからは1.8[V]の電圧レベルの信号しか出力できません．赤や緑といった色のLEDであれば，順方向効果電圧(VF)が低いので暗く点灯しますが，青や白のLEDはとても駆動できません．
実際に実験してみたのが，以下の動画です．

[動画](https://vine.co/v/OnF3vixxL0v)

あらら，困ったね．

# 回路やりなおし
H電圧で1.8[V]しか出力できないなら，回路を工夫しましょう．
先ほどの回路は，Active Highと呼ばれる，ポートに1を出力すると，負荷（今回の場合はLED）に電流が流れる回路でしたが，これをActive Lowという，ポートに0を出力すると，負荷に電流が流れる回路に変更します．

![Active Low回路](https://pbs.twimg.com/media/B3ssgsECYAEgLno.png "回路(Active Low)")

このようにすると，ポートに1を出力している間は，LEDに 3.3 - 1.8 の 1.5[V]がかかることになり，これがLEDの順方向電圧より低い場合，LEDはほぼ光りません．そして，ポートに0を出力すると，LEDに3.3[V]の電圧がかかることになり，LEDが光ります．

![Active High実装](https://pbs.twimg.com/media/B3srqyeCUAASZdB.jpg "実装(Active Low)")

実際の実験の様子は以下に．

[動画](https://vine.co/v/OnFLQxVpb2F)

# まとめ
+ EdisonでポートON/OFFは，MRAAライブラリを使う，
+ MRAAライブラリには，C/C++/Python/JavaScriptから叩けるAPIが用意されている．
+ Edisonのピンから出力できる電圧は，1.8[V]．
+ Active HighだとLEDの駆動も厳しいけど，Active Lowならなんとかなる．