Arduino

2017/01/12更新

対応バージョン: Node.js 4.2.6, Johnny-Five 0.9.58

Node.jsでArduino Unoにつないだタクトスイッチの状態を読み取って内蔵LEDを点灯・点滅させる。

Node.jsを動かす母艦はUbuntu 16.04とする。

結線

結線は以下の通りで、タクトスイッチとGNDの間に10kΩのプルダウン抵抗を挟む。タクトスイッチの状態はデジタル2ピンを使って取得し、スイッチの状態によって内蔵LEDを制御する。

押した状態(press)

LED点灯

離した状態(release)

LED消灯

押しっ放し(hold)

LED点滅

ソース

以下のようなコードを書きNode.jsで実行する。タクトスイッチを離した時の処理としてstop(点滅を点灯に変更)とoff(消灯)を両方指定する必要があることに注意する。

button.js
var five = require("johnny-five");
var board = new five.Board();

board.on("ready", function() {
  var button = new five.Button(2);      // スイッチ状態
  var led    = new five.Led(13);        // LED

  // 押す
  button.on("press", function() {
    led.on();
  });

  // 離す
  button.on("release", function() {
    led.stop();         // for strobe()
    led.off();          // for on()
  });

  // 長押し
  button.on("hold", function() {
    led.strobe(500);
  });

});
実行
% node button.js
1484147909373 Device(s) /dev/ttyACM0  
1484147909404 Connected /dev/ttyACM0  
1484147912650 Repl Initialized  
>>

関連資料・記事

参考サイト

2017/04/16更新

対応バージョン: Node.js 4.2.6, Johnny-Five 0.10.6

Node.jsでArduino Unoにつないだ7セグメントLEDシリアルドライバキット(DIP化キット)を使ってシフトレジスタ(74HC595)経由で7セグLED(OSL10561-LRA)を0〜9までカウントアップ表示させる。

Node.jsを動かす母艦はUbuntu 16.04とする。

結線

本キット上の回路は以下のようになっている。

一番右のCN1がキットの基板の上5ピン、CN2がキットの基板の下5ピンとなるので制御に必要なピンは以下のようになる。

VDD ... 電源

CN1の1ピンかCN2の4ピン

GND ... グランド

CN1の2ピンかCN2の5ピン

SDI(シフトレジスタのSER) ... シリアルデータ入力

CN1の4ピン

SCK(シフトレジスタのSRCLK) ... HIGHでシリアルデータシフト

CN1の3ピン

LATCH(シフトレジスタのRCLK) ... HIGHで8ビット分のパラレルデータ出力

CN2の2ピン

これをふまえて結線は以下の通りとする。

参考までに、同じ内容の結線でもキットを使わずシフトレジスタと7セグLEDを自分で結線すると以下のような複雑なものになる。

ソース

コードはキットを使わずに結線した場合と同じものが使用できるので以下を参照のこと。

関連資料・記事

このコードをNode.jsで実行するとキットを使わない時と同様に7セグLEDを0〜9までカウントアップ表示させることができる。

関連資料・記事

参考サイト

2017/03/26更新

対応バージョン: Node.js 4.2.6, Johnny-Five 0.10.6

Node.jsでArduino Unoにつないだ8ビットシフトレジスタ(SN74HC595N)を使って7セグLEDを0〜9までカウントアップ表示させる。

Node.jsを動かす母艦はUbuntu 16.04とする。

結線

まずArduino - シフトレジスタ間の結線は以下と同様とする。

関連資料・記事

次にシフトレジスタ - 7セグLED間の結線は以下の通りとする。

・QA: 7ピン(LED-a)

・QB: 6ピン(LED-b)

・QC: 4ピン(LED-c)

・QD: 2ピン(LED-d)

・QE: 1ピン(LED-e)

・QF: 9ピン(LED-f)

・QG: 10ピン(LED-g)

これをふまえて結線は以下の通りとする。

ソース

以下のようなコードを書きNode.jsで実行する。

シフトレジスタに0〜9までのLEDパターンを順番に送信することでカウントアップしているように見せる。

sn74hc595n_7seg.js
// ピン定義
//
// -- ピン配列 ----------------------
//       a(7)
//     +-----+
// f(9)|     |b(6)
//     +g(10)+
// e(1)|     |c(4)
//     +-----+
//       d(2) []DP(5)
//
// -- 値 ----------------------------
// gfedcba <- ピン配列
var led_list = [
  '0111111',  // 0
  '0000110',  // 1
  '1011011',  // 2
  '1001111',  // 3
  '1100110',  // 4
  '1101101',  // 5
  '1111101',  // 6
  '0000111',  // 7
  '1111111',  // 8
  '1101111',  // 9
  '0000000',  // 消灯
];

// メインループ
var five = require("johnny-five");
var board = new five.Board();

board.on('ready', function() {
  var register = new five.ShiftRegister({
    'pins' : {
      'data'  : 2,
      'clock' : 3,
      'latch' : 4
    }
  });

  var i = 0;

  // LEDに表示する数字を1桁ずつカウントアップ
  this.loop(500, function() {
    num = parseInt(led_list[i], 2);  // 2進数 -> 10進数
    register.send(num);              // シフトレジスタに送信
    i++;
    if (i >= led_list.length) {
      i = 0;
    }
  });
});
実行
% node sn74hc595n_7seg.js
1485094276071 Device(s) /dev/ttyACM0  
1485094276078 Connected /dev/ttyACM0  
>>

関連資料・記事

参考サイト

2017/03/22更新

対応バージョン: Node.js 4.2.6, Johnny-Five 0.10.6

Node.jsでArduino Unoにつないだ8ビットシフトレジスタ(SN74HC595N)を使って8ビットの各ビットを8個のLEDそれぞれに割り当てて点灯させる。

Node.jsを動かす母艦はUbuntu 16.04とする。

結線

シフトレジスタの各ピンは以下の割り当てになっている。

・QA(15ピン),QB〜QH(1〜7ピン): LED1〜8

・QH'(9ピン): シフトレジスタを数珠つなぎにする場合に結線

・Vcc(16ピン), SRCLR(10ピン): 電源

・GND(8ピン), OE(13ピン): GND

・SER(14ピン): シリアルデータ入力(現在のアドレスにHIGH/LOWを入力する。最大8ビット分)

・RCLK(12ピン): レジスタクロック(8ビット分のデータを入力してHIGHにするとQA〜QHからパラレルデータが出力される)

・SRCLK(11ピン): シフトレジスタクロック(HIGHにするとデータの入力先が次のアドレスに移る)

これをふまえて結線は以下のとおりとする。

ソース

以下のようなコードを書きNode.jsで実行する。

シフトレジスタに0〜255までの数字を順番に送信し、8個のLEDがその数字を2進数で表した時の各ピットのON/OFF状態を示すように点灯させる。

sn74hc595n.js
var five = require("johnny-five");
var board = new five.Board();

board.on('ready', function() {
  var register = new five.ShiftRegister({
    'pins' : {
      'data'  : 2,
      'clock' : 3,
      'latch' : 4
    }
  });

  var number = 0;

  this.loop(100, function() {
    register.send(number++);
    if (number > 255) {
      number = 0;
    }
  });
});
実行
% node sn74hc595n.js
1485094276071 Device(s) /dev/ttyACM0  
1485094276078 Connected /dev/ttyACM0  
>>

関連資料・記事

参考サイト

2017/1/14更新

対応バージョン: Node.js 4.2.6, Johnny-Five 0.10.6, Socket.IO 1.7.2

Node.jsでSocket.IOを使ってArduino UnoにつないだRGBフルカラーLED(OSTA5131A)(カソードコモン)をWebページから操作する。

Node.jsを動かす母艦はUbuntu 16.04とする。

Johnny-FiveのインストールやLED結線などの事前準備は以下を参照のこと。

関連資料・記事

Socket.IOインストール

まずSocket.IOをインストールする。Socket.IOはnpmを使って簡単にインストールできる。

% sudo npm install -g socket.io

ソース

次に以下のJavaScriptコードとHTMLを書きNode.jsで実行する。

socketio.js
var fs = require("fs");
var http = require("http");
var server = http.createServer();

var five = require("johnny-five");
var board = new five.Board();

board.on("ready", function() {
  // Server
  server.on("request", function(req, res) {
    var stream = fs.createReadStream("index.html");
    res.writeHead(200, {
      "Content-Type": "text/html"
    });
    stream.pipe(res);
  });

  // Socket.IO
  var io = require("socket.io").listen(server);
  server.listen(8000);

  // LED
  var led = new five.Led.RGB({
    pins: {
      red: 6,
      green: 5,
      blue: 3
    }
  });

  // Control
  io.on("connection", function(socket) {
    socket.on("msg", function(color) {
      console.log(color);

      if (color == "off") {
        led.off();
      } else {
        led.color(color);
      }
    });
  });
});
index.html
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>arduino-socket.io</title>
  <script src="/socket.io/socket.io.js"></script>
  <script src="//code.jquery.com/jquery-2.1.3.min.js"></script>
</head>

<body>
  <form>
    <p>
      <input type="radio" name="color" value="red">RED</input>
      <input type="radio" name="color" value="green">GREEN</input>
      <input type="radio" name="color" value="blue">BLUE</input>
      <input type="radio" name="color" value="off">(OFF)</input>
    </p>
    <p>
      <input type="submit" value="submit" />
    </p>
  </form>

  <script type="text/javascript">
    var socket = io();
    $('form').submit(function() {
      socket.emit("msg", $("input[name=color]:checked").val());
      return false;
    });
  </script>
</body>
</html>
実行
% node socketio.js 
1484404749919 Device(s) /dev/ttyACM0  
1484404749927 Connected /dev/ttyACM0  
1484404753174 Repl Initialized  
>>
Webブラウザからアクセス

localhost:8000にアクセスし、ラジオボタンで色を指定してsubmitをクリックすると指定した色でLEDが点灯する。OFFを選ぶと消灯する。

関連資料・記事

参考サイト

2019/07/07更新

対応バージョン: Arduino IDE 1.8.9 + Ubuntu 18.04

株式会社SOCINNOが提供する「IoT電子工作 スマートリモコン製作キット」は基礎からWi-Fi利用、クラウド接続まで順を追って丁寧に解説されている秀逸な教材である。

このキットをArduino IDE 1.8.9 + Ubuntu 18.04環境で使う際にいくつか追加で作業する必要があったので補足する。

以下、同キット向けのIoT電子工作ガイドの章立てに沿って説明する。

2-1 電子部品利用 > LED点滅

スケッチコンパイルエラー

スケッチコンパイル時に以下のようなエラーが発生する場合。

:
Pyserial is not installed for /usr/bin/python. Check the README for installation instructions.Traceback (most recent call last):

  File "/home/neo/.arduino15/packages/esp32/tools/esptool_py/2.6.1/esptool.py", line 37, in <module>
    import serial

ImportError: No module named serial
exit status 1
Error compiling for board ESP32 Dev Module.

python-serialパッケージをインストールすればエラーが発生しなくなる。

$ sudo apt install python-serial

2-3 電子部品利用 > 温湿度センサ

スケッチコンパイルエラー

スケッチコンパイル時に以下のようなエラーが発生する場合。

:
In file included from /home/ard/Arduino/libraries/DHT_sensor_library/DHT_U.cpp:22:0:
/home/ard/Arduino/libraries/DHT_sensor_library/DHT_U.h:25:29: fatal error: Adafruit_Sensor.h: No such file or directory
 #include <Adafruit_Sensor.h>

                             ^
compilation terminated.
Using library DHT_sensor_library at version 1.3.4 in folder: /home/ard/Arduino/libraries/DHT_sensor_library 
exit status 1
Error compiling for board ESP32 Dev Module.

ライブラリマネージャから「Adafruit Unified Sensor」をインストールすればエラーが発生しなくなる。

3-2 Wi-Fi利用 > Webサーバ機能

スケッチコンパイルエラー

スケッチコンパイル時に以下のようなエラーが発生する場合。

:
Multiple libraries were found for "WiFi.h"
Blink:2:31: error: ESPAsyncWebServer.h: No such file or directory
compilation terminated.
 Used: /home/ard/.arduino15/packages/esp32/hardware/esp32/1.0.2/libraries/WiFi
 Not used: /home/ard/opt/arduino-1.8.9/libraries/WiFi
exit status 1
ESPAsyncWebServer.h: No such file or directory

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

以下の2つをダウンロードして[Sketch] > [Include Library] > [Add .ZIP Library...]でそれぞれインストールすればエラーが発生しなくなる。

DHCPサーバ利用

IPアドレス情報をDHCPサーバから動的に受け取る場合は以下のIPアドレス設定は不要。(以降の章も同様)

IPAddress ip(192, 168, 1, 123);     // IPアドレス(本機が利用するIP)
IPAddress gateway(192, 168, 1, 1);  // デフォルトゲートウェイ
IPAddress subnet(255, 255, 255, 0); // サブネットマスク
:
void setup() {
:
  WiFi.config( ip, gateway, subnet );
:

4-2 データ利用 > SPIFFSによるファイル操作

SPIFFSマウントエラー

プログラム実行時に以下のようなエラーが発生する場合。

E (36) SPIFFS: mount failed, -10025

SPIFFS.hだけでなくFS.hもincludeすればエラーが発生しなくなる。

#include <FS.h> <--- 追加
#include <SPIFFS.h>

それ以降

上記の対応を経て、無事リモコンが動作した。

リモコン設定(ON/OFF信号記録)
リモコン操作(ON/OFF信号発信)

関連記事

2017/01/23更新

対応バージョン: Node.js 4.2.6, Johnny-Five 0.10.6

Node.jsでArduino Unoにつないだ超音波距離センサー(HC-SR04)の値を読み取る。

Node.jsを動かす母艦はUbuntu 16.04とする。

PingFirmata書き込み

HC-SR04の値を読み取るのにJohnny-Fiveを使用する場合、標準のFirmataでは動作しないので以下の手順でPingFirmataをArduinoに書き込む。

% wget https://gist.githubusercontent.com/rwaldron/0519fcd5c48bfe43b827/raw/f17fb09b92ed04722953823d9416649ff380c35b/PingFirmata.ino
% arduino --upload PingFirmata.ino 

結線

Arduino IDEのスケッチでなくJohnny-Fiveを使用する場合、4つのピンのうちTrig(出力)とEcho(入力)はまとめてよい。VccとGndはそれぞれ5VとGNDに接続する。

ソース

以下のようなコードを書きNode.jsで実行する。

echo.js
var five = require("johnny-five");
var board = new five.Board();

board.on("ready", function() {
  var proximity = new five.Proximity({
    controller: "HCSR04",
    pin: 7
  });

  proximity.on("change", function() {
    console.log(this.cm + " cm");
  });
});
実行
% node echo.js
1485094276071 Device(s) /dev/ttyACM0  
1485094276078 Connected /dev/ttyACM0  
1485094279831 Repl Initialized  
>> 277.388 cm
277.835 cm
277.904 cm
277.027 cm
:
(障害物を近づけた時)
13.093 cm
11.684 cm
12.519 cm
:

関連資料・記事

参考サイト

2017/01/21更新

対応バージョン: Node.js 4.2.6, Johnny-Five 0.9.58

Johnny-Fiveは様々な温度センサーをサポートしているので対象センサーであれば以下のようにThermometerクラスを使って簡単に温度を取得することができる。

var five = require("johnny-five");
var board = new five.Board();

board.on("ready", function() {
  var temp = new five.Thermometer({
    controller: "LM35",
    pin: "A0"
  });

  temp.on("change", function() {
    console.log(this.celsius + "°C", this.fahrenheit + "°F");
  });
});

しかしJohnny-Fiveでサポートされていない温度センサーの値を温度に変換するにはそのセンサーのデータシートを見てThermometerクラスのtoCelsiusオプションで計算式を定義する必要がある。

ここではLM61BIZを使用する場合の計算式を示す。

上記ページからデータシートを参照すると出力電圧のオフセット値が0.6Vであることが分かる。

これを以下の式に当てはめれば温度が計算できる。

((センサー値 * 電源電圧 / 1024) - 出力電圧のオフセット値) * 100
= ((センサー値 * 5 / 1024) - 0.6) * 100

この計算式をThermometerクラスのtoCelsiusオプションに定義してデフォルト定義をオーバーライドすればよい。

結線

ソース

lm61.js
var five = require("johnny-five");
var board = new five.Board();

board.on("ready", function() {
  var temp = new five.Thermometer({
    pin: "A0",
    toCelsius: function(raw) {
      var val = ((raw * 5 / 1024) - 0.6) * 100;  // 温度計算
      return Math.round(val * 10) / 10;          // 小数点第2位以下四捨五入
    }
  });

  temp.on("change", function() { 
    console.log(this.celsius + "°C");
  });
});
実行
% node lm61.js 
1485009719195 Device(s) /dev/ttyACM0  
1485009719202 Connected /dev/ttyACM0  
1485009722449 Repl Initialized  
>> 19.6
19.1
19.6
19.1
19.6
19.1
:

関連資料・記事

参考サイト

2016/12/24更新

対応バージョン: Node.js 4.2.6, Johnny-Five 0.9.58

Node.jsでArduino Unoにつないだフォトリフレクタ(RPR-220)の値を読み取る。

Node.jsを動かす母艦はUbuntu 16.04とする。

結線

このセンサーは刻印面に向かって左が赤外線LED(出力側)、右が対象物からの反射を受けるフォトトランジスタ(入力側)になっている。

ピンは4つで左の赤外線LEDは手前がアノード(長いピン)で奥がカソード(短いピン)、右のフォトトランジスタは手前がコレクタ(短いピン)で奥がエミッタ(長いピン)である。

結線はそれぞれ以下のようになる。

赤外線LED

Arduinoの5V電源ピン → 330Ω抵抗(*1) → アノード(長いピン) → カソード(短いピン) → ArduinoのGNDピン

フォトトランジスタ

Arduinoの5V電源ピン → コレクタ(長いピン) → エミッタ(短いピン) → Arduinoのアナログ"A0"ピン → 1kΩ抵抗(*2) → ArduinoのGNDピン

抵抗値の計算方法については、データシートの絶対最大定格によると赤外線LEDの順電流が50mAでフォトトランジスタのコレクタ電流が30mAなので最低限必要な抵抗値はそれぞれ以下のようになる。

(*1) 赤外線LED側

抵抗 = (電源電圧5V - 順電圧1.34V) / 順電流50mA

= 3.66 / 0.050

= 73 (→ ここでは330Ωを使用)

(*2) フォトトランジスタ側

抵抗 = 電源電圧5V / コレクタ電流30mA

= 5 / 0.030

= 166 (→ ここでは1kΩを使用)

ソース

以下のようなコードを書きNode.jsで実行する。

sensor.js
var five = require("johnny-five");
var board = new five.Board();

board.on("ready", function() {
  var sensor = new five.Sensor("A0");   

  sensor.on("change", function() {
    var val = this.value;
    console.log(val);
  });
});
実行
% node sensor.js
1483360780654 Device(s) /dev/ttyACM0  
1483360780661 Connected /dev/ttyACM0  
>> 0

色によって反射率が異なるので例えば白は光が反射するのでセンサーが反応し、黒は光が吸収されるのでセンサーが反応しなくなる。

関連資料・記事

参考サイト

2016/12/24更新

対応バージョン: Node.js 4.2.6, Johnny-Five 0.9.58

Node.jsでArduino Unoにつないだ光センサー(LLS05-A)やCdSセル(GL5528)の値を読み取り、一定の暗さになったらLEDを点灯する仕組みを作る。

Node.jsを動かす母艦はUbuntu 16.04とする。

結線

センサー(ブレッドボードの右上)

光センサーの場合

Arduinoの5V電源ピン → 光センサーのアノード(長いピン) → 光センサーのカソード(短いピン) → Arduinoのアナログ"A0"ピン及び10KΩ抵抗経由のArduinoのGNDピン

CdSセルの場合

Arduinoの5V電源ピン → CdSセル → Arduinoのアナログ"A0"ピン及び10KΩ抵抗経由のArduinoのGNDピン

LED(ブレッドボードの左下)

Arduinoのデジタル13番ピン(5V) → 抵抗(330Ω) → LEDのアノード(長いピン) → LEDのカソード(短いピン) → ArduinoのGNDピン

※回路図と写真は光センサーのものだがCdSセルの場合も同じ。

ソース

以下のようなコードを書きNode.jsで実行する。

sensor.js
var five = require("johnny-five");
var board = new five.Board();

var before = 0;                         // 前回値

board.on("ready", function() {
  var sensor = new five.Sensor("A0");   // センサーデータ
  var led    = new five.Led(13);        // LED

  // センサーデータ取得
  sensor.on("change", function() {
    var val = this.value;               // センサーデータ
    console.log(before + " -> " + val); // センサーデータ出力(前回 + 今回)

    // センサーデータが前回値と変わったら
    if (val != before) {
      // センサーデータが10未満ならLED点灯、それ以上なら消灯
      if (val < 10) {
        led.on();
      } else {
        led.off();
      }
    }

    // センサーデータ退避
    before = val; 
  });
});
実行
% node sensor.js
1483183307714 Device(s) /dev/ttyACM0  
1483183307744 Connected /dev/ttyACM0  
1483183311010 Repl Initialized  
>> 0 -> 253
253 -> 249
249 -> 244
244 -> 243
243 -> 245
:

プログラムを実行するとセンサーデータの前回値と今回値が左右に表示されるのでセンサーを覆って暗くすると(センサーデータが10を下回ると)LEDが点灯する。

Node.jsおよびJohnny-Fiveの導入については「Node.jsのJohnny-Fiveフレームワークを使ってArduino UnoでLチカ」を参照のこと。

関連資料・記事

参考サイト

2016/12/24更新

対応バージョン: Arduino IDE 1.8.0

Arduinoで温度センサー(LM61BIZ)の値を読み取る。

Arduino IDEを動かす母艦はUbuntu 16.04とする。

結線

センサーのピンは3つで刻印面に向かって左から+Vs(電源電圧)、Vout(出力電圧)、GND(グラウンド)。これをArduinoの5V、A0、GNDにそれぞれ接続する。

ソース

Vout(出力電圧)は0℃の時600mVで1℃あたり10mV変化するので例えば20℃の室温の場合、Voutは以下の値になる。

Vout = 600(mV) + (10(mV/℃) * 20(℃)) = 800(mV)

温度を求めるにはセンサーから取得した値、出力電圧、温度それぞれ取り得る値を相互変換すればよい。

具体的にはまずセンサー値(0〜1023)を電圧(0〜5000)に変換し、次にこのセンサーの計測範囲の電圧(300〜1600)を温度(-30〜100)に変換する。

センサー値を電圧に変換
map(センサー値, 0, 1023, 0, 5000)
電圧を温度に変換
map(電圧, 300, 1600, -30, 100)

上記をコードにすると以下のようになるのでArduino IDEでコンパイルしてArduinoに書き込む。

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

void loop() {
  int val = analogRead(A0);
  float volt = map(val, 0, 1023, 0, 5000);
  float temp = map(volt, 300, 1600, -30, 100);
  Serial.println("val = " + String(val) + ", volt = " + String(volt) + ", temp = " + String(temp));
  delay(1000);
}

Arduino IDEのシリアルモニターには1秒おきに以下のような内容が出力される。

このセンサーに指を触れると体温でセンサーが温まって温度が上昇する。

関連資料・記事

参考サイト

2017/04/23更新

対応バージョン: ruby 2.3.1, arduino_firmata 2.3

RubyでArduinoをコントロールするにはarduino_firmataというgemを使えば簡単である。

ここではサンプルとしてLチカをやってみる。

Rubyを動かす母艦はUbuntu 16.04とする。

Firmata書き込み

arduino_firmataはFirmataプロトコルを使ってArduinoと通信するので最初にFirmataのプログラムをArduinoに書き込んでおく。

この手順は以下の資料に示してあるので割愛する(Arduino IDEを使うかgortコマンドにて書き込む)。

関連資料・記事

arduino_firmataインストール

次にarduino_firmataをインストールする。arduino_firmataはgemを使って簡単にインストールできる。

% sudo gem install arduino_firmata

結線

Lチカ用にこのような簡単な結線を行う。

アノード側には330Ωの抵抗を挟む。

arduino_firmata動作確認(Lチカ)

以下のようなコードを書いて実行すれば簡単にLチカができ、その他にもArduinoの様々な操作ができる。

尚、ArduinoFirmata.connectで接続するポートは環境によって異なるので使用している環境に合わせて指定する。

led.rb
require "rubygems"
require "arduino_firmata"

arduino = ArduinoFirmata.connect "/dev/ttyACM0"

puts "firmata version #{arduino.version}"

while true
  arduino.digital_write 13, true
  sleep 1
  arduino.digital_write 13, false
  sleep 1
end
実行
% ruby led.rb
firmata version 2.3

関連資料・記事

参考サイト

2017/02/27更新

対応バージョン: Node.js 4.2.6, Johnny-Five 0.10.6

Node.jsで可変抵抗器を使ってLEDの明るさを調整する。

Node.jsを動かす母艦はUbuntu 16.04とする。

結線

可変抵抗器のピンは向かって左側から電源、抵抗値出力、GNDになっているのでそれぞれ5V、A0ピン、GNDに接続する。

LEDはデジタル3番ピンをPWM出力用として使用する。

ソース

以下のようなコードを書きNode.jsで実行する。

registor.js
var five = require("johnny-five");
var board = new five.Board();

var pin_out = 3;     // LED用ピン(出力)
var pin_in  = "A0";  // 抵抗値用ピン(入力)

board.on("ready", function() {
  board.pinMode(pin_out, five.Pin.PWM);    // LED用ピンをPWM(アナログ出力)に設定

  var sensor = new five.Sensor(pin_in);    // 抵抗値取得用オブジェクト定義

  sensor.on("change", function() {         // 抵抗値が変わったら
    var val = Math.floor(this.value / 4);  // 抵抗値(0-1023)をPWM値(0-255)に変換
    board.analogWrite(pin_out, val);       // LED用ピンにPWM値を出力
  });
});
実行
% node registor.js
1487422161958 Device(s) /dev/ttyACM0  
1487422161965 Connected /dev/ttyACM0  
1487422165206 Repl Initialized  
>>

関連資料・記事

参考サイト

2019/07/24更新

対応バージョン: Arduino IDE 1.8.9 + Processing 3.5.3

Arduinoと母艦のOSとの間でやり取りするシリアルデータに対して母艦側でProcessingを使って制御すると、例えばマウスやタッチパネル式ディスプレイを使ってArduinoを操作したり、逆にArduino側のセンサーで取得したデータの可視化をリッチにしたりすることができる。

ここではProcessingからの入力をArduinoに連携する方法と、Arduinoからの入力をProcessingに連携する方法をそれぞれ簡単なサンプルで示す。

それぞれの開発環境は公式サイトで入手できる。

また言語リファレンスもしっかり整備されている。

Processing → Arduino

まずProcessingからの入力をArduinoに連携する方法を示す。

例としてProcessingでマウスクリックの状態を取得してArduinoの内蔵LEDを点灯/消灯させる簡単なプログラムを書いてみる。

尚、この例ではArduinoボードはUno(Rev3)を使い、シリアルポートは/dev/ttyACM0、通信速度は9600bpsとする。

流れとしてはまずArduinoでシリアルポートから受け取ったデータによってLEDに加える電圧を高くしたり(点灯)、低くしたり(消灯)するプログラムをArduinoに書き込んでおく。

#define led LED_BUILTIN		// 内蔵LED

void setup() {
  Serial.begin(9600);
  pinMode(led, OUTPUT);		// LEDを出力用に
}

void loop() {
  // シリアルポートからデータを受け取ったら
  if (Serial.available() > 0) {

    // 受信したデータを読み込む
    char data = Serial.read();

    // データが'1'ならLED点灯
    if (data == '1') {
      digitalWrite(led, HIGH);
    }

    // データが'0'ならLED消灯
    if (data == '0') {
      digitalWrite(led, LOW);
    }
  }
}

次にProcessingでマウスの左と右のクリックに応じてシリアルポートにデータを送信するプログラムを書いて実行する。

import processing.serial.*;

Serial port;

void setup() {
  size(300, 300);
  port = new Serial(this, "/dev/ttyACM0", 9600);
}

void draw() {
  // マウスの左クリックボタンが押されたらシリアルポートに'1'を送信
  if (mousePressed && (mouseButton == LEFT)) {
    port.write('1');
    println("left");
  }

  // マウスの右クリックボタンが押されたらシリアルポートに'0'を送信
  if (mousePressed && (mouseButton == RIGHT)) {
    port.write('0');
    println("right");
  }
}

これでマウスを左クリックするとArduinoの内蔵LEDが点灯し、右クリックすると消灯する。

CLIで実行したい場合は以下のようにする。

$ tree .
.
├── p2a_a
│   └── p2a_a.ino
└── p2a_p
    └── p2a_p.pde

$ arduino --board arduino:avr:uno --port /dev/ttyACM0 --upload p2a_a/p2a_a.ino

$ processing-java --sketch=$(pwd)/p2a_p --run

Arduino → Processing

今度は逆にArduino側で取得したデータをProcessingに連携する方法を示す。

例としてArduinoに光センサー(CdSセル)を接続し、取得した値をProcessingに連携して可視化する。

流れとしてはまずArduinoで光センサーの値を取得する簡単な回路を作っておく。(CdSセルはGL5528、抵抗は10kΩ)

次にこの回路を使って光センサーから取得したデータをシリアルポートに送信する。

送信するデータは一度に1byte分(0〜255)しか送れないが、光センサーから取得した値は0〜1023なので2bytesに分けて送ってもよいが、作りを簡単にするためにmap()関数を使って0〜255に丸める。このプログラムをArduinoに書き込んでおく。

int val = 0;

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

void loop() {
  // センサーの値を取得
  val = analogRead(0);

  // 一度に送れるデータ(1byte)に変換
  map(val, 0, 1023, 0, 255);

  // シリアルデータ送信
  Serial.write(val);

  delay(50);
}

Processing側ではこの値を取り出して円の直径がリアルタイムに変わるような描画を行う。

import processing.serial.*;

Serial port;

float x;
float y;

int in_data;

void setup() {
  size(300, 300);
  port = new Serial(this, "/dev/ttyACM0", 9600);
  background(0, 0, 0);
}

void draw() {
  // 描画エリア設定
  fill(255, 10);
  noStroke();
  rect(0, 0, width, height);

  // シリアルポートからデータを受け取ったら
  if (port.available() > 0 ) {
    // シリアルデータ受信
    in_data = port.read();

    // 描画
    x = width  / 2 + random(-3, 3);
    y = height / 2 + random(-3, 3);

    noFill();

    stroke(random(255), random(255), 255);

    ellipse(x, y, in_data, in_data);
  }
}

CLIで実行したい場合は以下のようにする。

$ tree .
.
├── a2p_a
│   └── a2p_a.ino
└── a2p_p
    └── a2p_p.pde

$ arduino --board arduino:avr:uno --port /dev/ttyACM0 --upload a2p_a/a2p_a.ino

$ processing-java --sketch=$(pwd)/a2p_p --run

実行結果は以下のようになる。

ArduinoとProcessingの組み合わせでリッチな表現が簡単に実現できるのでインタラクティブコンテンツやメディアアートなどにも応用できる。

参考サイト

2016/12/24更新

対応バージョン: Arduino IDE 1.7.11, Node.js 4.2.6, Johnny-Five 0.9.58

Arduinoの操作はArduino IDEを使うのが一般的だが、以下のステップが常に必要になり面倒である。

Arduino IDEを起動
スケッチ(プログラム)を作成
スケッチをコンパイル
スケッチをマイコンに書き込む

そこでNode.jsから直接Arduinoを操作できるようにJohnny-Fiveというフレームワークを導入する手順を示す。

Arduino IDEやNode.jsを動かす母艦はUbuntu 16.04とする。

Firmata書き込み

Johnny-FiveはFirmataプロトコルを使ってArduinoと通信するので最初にFirmataのプログラムをArduinoに書き込んでおく。

このプログラムはArduino IDEのスケッチの例に用意されているのでArduino IDEを起動して[ファイル] > [スケッチの例] > [Firmata] > [StandardFirmata]を選択してスケッチを表示し、コンパイルとArduinoへの書き込みを行う。

ただこのままだとコンパイル時に「SoftwareSerial.hがない」というエラーが発生する。

In file included from /foo/bar/arduino-1.7.11-linux64/libraries/Firmata/utility/SerialFirmata.cpp:20:0:
/foo/bar/arduino-1.7.11-linux64/libraries/Firmata/utility/SerialFirmata.h:30:28: fatal error: SoftwareSerial.h: No such file or directory

SoftwareSerial.hは存在するが置かれているパスが違うので以下の手順でSoftwareSerial.hを見に行く場所にシンボリックリンクを張る。これでコンパイルがうまくいく。

% cd /foo/bar/arduino-1.7.11-linux64
% ln -s `pwd`/hardware/arduino/avr/libraries/SoftwareSerial/SoftwareSerial.h libraries/Firmata

Arduino IDEを使わずにFirmataを書き込む場合は以下の手順を参照のこと。

関連資料・記事

Johnny-Fiveインストール

次にJohnny-Fiveをインストールする。Johnny-Fiveはnpmを使って簡単にインストールできる。

% sudo npm install -g johnny-five

Johnny-Five動作確認(Lチカ)

Johnny-Fiveの公式サイトに載っているサンプルを実行してLチカがうまくいけば今後Node.jsからArduinoの様々な操作ができる。

sample.js
var five = require("johnny-five");
var board = new five.Board();

board.on("ready", function() {
  var led = new five.Led(13);
  led.blink(500);
});
実行
% node sample.js
1482503689500 Device(s) /dev/ttyACM0  
1482503689507 Connected /dev/ttyACM0  
1482503693257 Repl Initialized  
>>

関連資料・記事

参考サイト

2017/01/13更新

対応バージョン: Node.js 4.2.6, Johnny-Five 0.9.58

Node.jsでArduino UnoにつないだRGBフルカラーLED(OSTA5131A)(カソードコモン)を色を変えつつ点灯させる。

Node.jsを動かす母艦はUbuntu 16.04とする。

結線

結線は以下の通り。一番長いピンが左から2番目に位置する見え方の場合、左からR(Red)、GND、B(Blue)、G(Green)という並びになり、GND以外のピンはそれぞれ330Ωの抵抗を挟んでArduinoの6(R)、5(G)、3(B)ピンと接続する。

ソース

以下のようなコードを書きNode.jsで実行する。LEDの色が一秒おきに赤→緑→青と変わって最後に消灯する。

led_rgb.js
var five = require("johnny-five");
var board = new five.Board();

board.on("ready", function() {
  var led = new five.Led.RGB({
    pins: {
      red: 6,
      green: 5,
      blue: 3
    }
  });

  led.on();

  led.color("red");

  setTimeout(function() {
    led.color("green");
  }, 1000);

  setTimeout(function() {
    led.color("blue");
  }, 2000);

  setTimeout(function() {
    led.off();
  }, 3000);

});
実行
% node led_rgb.js
1484147909373 Device(s) /dev/ttyACM0  
1484147909404 Connected /dev/ttyACM0  
>>

関連資料・記事

参考サイト

2017/05/05更新

対応バージョン: Arduino IDE 1.8.2

Arduino Unoにつないだ8x8マトリクスLED(OSL641505-BRA)をダイナミック点灯により点灯する。

Arduino IDEを動かす母艦はUbuntu 16.04とする。

結線

結線は以下の通り。ここで使用しているOSL641505-BRAはアノードコモンなのでカソードコモンのOSL641505-ARAとの違いに注意する。

ソース

以下のようなコードを書き実行する。ここではハートのパターンを表示してみる。

led_matrix.ino
// OSL641505-BRA
//
// --- pin番号 ---
//  16 .. 9
// +--------+
// |        |
// |        |
// +--------+
//   1 .. 8 
//
// --- ROW(行)/COL(列) : pin番号 -> Arduino接続先 ---
// ROW(行)
//  1 : pin 9 -> Arduino digital 2
//  2 : pin14 -> Arduino digital 3
//  3 : pin 8 -> Arduino digital 4
//  4 : pin12 -> Arduino digital 5
//  5 : pin 1 -> Arduino didital 6
//  6 : pin 7 -> Arduino digital 7
//  7 : pin 2 -> Arduino digital 8
//  8 : pin 5 -> Arduino digital 9
//
// COL(列)
//  1 : pin13 -> Arduino digital 10
//  2 : pin 3 -> Arduino digital 11
//  3 : pin 4 -> Arduino digital 12
//  4 : pin10 -> Arduino digital 13
//  5 : pin 6 -> Arduino  analog A0(14相当)
//  6 : pin11 -> Arduino  analog A1(15相当)
//  7 : pin15 -> Arduino  analog A2(16相当)
//  8 : pin16 -> Arduino  analog A3(17相当)

// 出力パターン
// * OSL641505-BxはOSL641505-Axと異なりアノードとカソードが逆なので
//   プログラム中で1と0を反転させる
boolean matrix[8][8] = {
  {0,0,0,0,0,0,0,0},
  {0,1,1,0,0,1,1,0},
  {1,1,1,1,1,1,1,1},
  {1,1,1,1,1,1,1,1},
  {1,1,1,1,1,1,1,1},
  {0,1,1,1,1,1,1,0},
  {0,0,1,1,1,1,0,0},
  {0,0,0,1,1,0,0,0}
};

void setup(){
  // 2~17ピン出力設定
  for(int i = 2; i <= 17; i++) {
    pinMode(i, OUTPUT);
    digitalWrite(i, LOW);
  }
}

void loop(){
  // 点灯/消灯スイッチ
  int onoff;

  // 行ループ(2~9ピン)
  for(int row = 2 ; row <= 9 ; row++) {

    // 対象行を点灯対象に
    digitalWrite(row, HIGH);

    // 列ループ(10~17ピン)
    for(int col = 10 ; col <= 17 ; col++){
      
      // 対象列の点灯(0)/消灯(1)を決定
      // 出力パターンと点灯/消灯の指示が逆転しているので反転(1 - パターン)
      int onoff = 1 - matrix[row - 2][col - 10];

      // 対象列を点灯/消灯
      digitalWrite(col, onoff);

      // 待機
      delayMicroseconds(200);

      // 対象列を消灯
      digitalWrite(col, HIGH);
    }
    // 対象行を消灯
    digitalWrite(row, LOW);
  }
}

関連資料・記事

参考サイト

2017/01/28更新

Arduino UnoにつないだRGBイルミネーションフルカラーLEDを点灯させる。

このLEDにはRGB三原色とICが内蔵されているので通電すればキレイにイルミネーション表示される。

結線

ここでは4つのLEDを光らせる。1つのLEDにつき5V電源 → 330Ω抵抗 → アノード → カソード → GNDという結線をし、それを4組作る。

点灯

特にプログラミングの必要もなく、単に通電すればよい(動画だとうまく撮影できなかったので写真のみ載せる。実際には色が少しずつ変わりながらイルミネーション表示される)。

関連資料・記事

参考サイト

2017/03/04更新

対応バージョン: Node.js 4.2.6, Johnny-Five 0.10.6

Node.jsでArduino Unoにつないだ3桁7セグLEDをダイナミック点灯方式を用いて3桁同時に表示する(ように見せかける)。

Node.jsを動かす母艦はUbuntu 16.04とする。

抵抗値計算

IF(順電流): 20mA
VF(順電圧): 2.2V
抵抗 = (電源電圧5V - 順電圧2.2V) / 順電流20mA
     = 2.8V / 0.02A
     = 140Ω 

抵抗はこの値より大きければ問題ないのでここでは220Ωの抵抗を使用する。

結線

結線は以下の通り。12,9,8番ピンはアノードコモンでその他のピンは抵抗を挟んでそれぞれ同じ番号のソケットに接続する。ただ1番ピンを接続する1番ソケットは動作しなかったので13番ソケットにつないでいる。

ソース

ダイナミックドライブによる表示が主目的なのでここでは表示する数字をプログラム中に直書きすることとする。プログラムの流れは以下の通り。

各桁出力制御用の8,9,12番ピンへのON/OFFパターンを配列で定義(digit_list[][])
各セグメント出力用ピンのON/OFFパターンを配列で定義(led_list[][])
LED出力用の関数(lighting)を定義
表示したい数字を各桁に分解して配列に格納(num_per_digit[])
各桁出力のON/OFFパターンと表示したい数字をセットにしてLED出力用の関数(lighting)を呼び出す処理をsetInterval()で5ミリ秒毎に高速に切り替える

上記を実装したコードを書きNode.jsで実行する。

7seg_3digit.js
// ピン定義(アノードコモン)
//
// -- ピン配列 ---------------------------------
//
// DIG.1(12)  DIG.2(9)   DIG.3(8)
//     |          |          |
// +-------+  +-------+  +-------+
//  A-G, DP    A-G, DP    A-G, DP
// +-------+  +-------+  +-------+
//
//        A(11)
//      +------+
// F(10)|      |B(7)
//      +-G(5)-+
//  E(1)|      |C(4)
//      +------+
//        D(2)  []DP(3)
//
// -- 各桁出力制御用ピンパターン ---------------
// 1
// 2 9 8
// ---------------------------------------------
var digit_list = [
  [0,0,0],  // 消灯
  [1,0,0],  // DIG.1
  [0,1,0],  // DIG.2
  [0,0,1],  // DIG.3
];

// 
// -- 各セグメント出力用ピンパターン -----------
// 0: LOW (点灯)
// 1: HIGH(消灯)
// 9: 未使用
//
// *) 0,6ピンは存在しないので未使用(=9)
// *) ArduinoのDIGITAL 1が動作しないので未使用(=9)とし、DIGITAL 13に接続
// *) 3ピン(DP)は常時消灯(=1)
// *) 8,9,12ピンは各桁出力制御用なので未使用(=9)
//
//                     1 1 1 1
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3
// ---------------------------------------------
var led_list = [
  [9,9,0,1,0,1,9,0,9,9,0,0,9,0],  // 0
  [9,9,1,1,0,1,9,0,9,9,1,1,9,1],  // 1
  [9,9,0,1,1,0,9,0,9,9,1,0,9,0],  // 2
  [9,9,0,1,0,0,9,0,9,9,1,0,9,1],  // 3
  [9,9,1,1,0,0,9,0,9,9,0,1,9,1],  // 4
  [9,9,0,1,0,0,9,1,9,9,0,0,9,1],  // 5
  [9,9,0,1,0,0,9,1,9,9,0,0,9,0],  // 6
  [9,9,1,1,0,1,9,0,9,9,1,0,9,1],  // 7
  [9,9,0,1,0,0,9,0,9,9,0,0,9,0],  // 8
  [9,9,0,1,0,0,9,0,9,9,0,0,9,1],  // 9
  [9,9,1,1,1,1,9,1,9,9,1,1,9,1]   // 消灯
];

// メインループ
var five = require("johnny-five");
var board = new five.Board();

board.on("ready", function() {

  // LED出力(桁, 数値)
  var lighting = function(digit, num) {
    // 各桁出力制御
    board.digitalWrite(12, digit_list[digit][0]);  // DIG.1
    board.digitalWrite( 9, digit_list[digit][1]);  // DIG.2
    board.digitalWrite( 8, digit_list[digit][2]);  // DIG.3

    // 各セグメント出力
    // - 8,9,12ピンは制御用なので未使用(=9)
    // - 1ピンは13ピンで代替
    for (var i = 1; i <= 13; i++) {
      onoff = led_list[num][i];
      if (onoff == 9) {
        continue;
      }
      board.digitalWrite(i, onoff);
    }
  }

  // 出力データ準備
  cnt = 123;

  num = ('000' + cnt).slice(-3);  // ゼロパディング

  // 3桁の値を1桁ずつ分解して配列に格納
  num_per_digit = new Array();

  for(var i = 0; i < 3; i++) {
    num_per_digit[i + 1] = num.toString().substr(i,1);
  }

  // ダイナミックドライブ(ダイナミック点灯)
  var n = 0;

  setInterval(() => {
    digit = n % 3 + 1;  // 1,2,3の桁を繰り返す

    lighting(digit, num_per_digit[digit]);  // 各桁出力
    lighting(0, 10);                        // いったん消灯

    n++;
  }, 5);
});
実行
% 7seg_3digit.js
1486305432162 Device(s) /dev/ttyACM0  
1486305432169 Connected /dev/ttyACM0  
1486305435411 Repl Initialized  
>>

*) 画像では各桁が順番に表示されているように見えるが実際は同時に表示されているように見える。

関連資料・記事

参考サイト

2017/02/07更新

対応バージョン: Node.js 4.2.6, Johnny-Five 0.10.6

Node.jsでArduino Unoにつないだ7セグLEDを0〜9までカウントアップ表示させる。

Node.jsを動かす母艦はUbuntu 16.04とする。

抵抗値計算

IF(順電流): 20mA
VF(順電圧): 2.2V
抵抗 = (電源電圧5V - 順電圧2.2V) / 順電流20mA
     = 2.8V / 0.02A
     = 140Ω 

抵抗はこの値より大きければ問題ないのでここでは220Ωの抵抗を使用する。

結線

結線は以下の通り。3番ピンと8番ピンはカソードコモンなのでGNDに接続し、その他のピンは抵抗を挟んでそれぞれ同じ番号のソケットに接続する。ただ1番ピンを接続する1番ソケットは動作しなかったので11番ソケットにつないでいる。

ソース

以下のようなコードを書きNode.jsで実行する。

各数字に対応したLEDのON/OFF状態を配列として定義しておき、0〜9まで順番に表示する。

7seg.js
// ピン定義
//
// -- ピン配列 ----------------------
//       a(7)
//     +-----+
// f(9)|     |b(6)
//     +g(10)+
// e(1)|     |c(4)
//     +-----+
//       d(2) []DP(5)
//
// -- 値 ----------------------------
// 0: LOW (消灯)
// 1: HIGH(点灯)
// 9: 未使用
//
// -- ピン番号 ----------------------
// *) 0ピンは存在しないので未使用(=9)
// *) 5ピン(DP)は常時消灯(=0)
// *) 1ピンが動作しないので11ピン使用
//                     1 1
// 0 1 2 3 4 5 6 7 8 9 0 1
// -------------------------
var led_list = [
  [9,9,1,9,1,0,1,1,9,1,0,1],  // 0
  [9,9,0,9,1,0,1,0,9,0,0,0],  // 1
  [9,9,1,9,0,0,1,1,9,0,1,1],  // 2
  [9,9,1,9,1,0,1,1,9,0,1,0],  // 3
  [9,9,0,9,1,0,1,0,9,1,1,0],  // 4
  [9,9,1,9,1,0,0,1,9,1,1,0],  // 5
  [9,9,1,9,1,0,0,1,9,1,1,1],  // 6
  [9,9,0,9,1,0,1,1,9,0,0,0],  // 7
  [9,9,1,9,1,0,1,1,9,1,1,1],  // 8
  [9,9,1,9,1,0,1,1,9,1,1,0],  // 9
  [9,9,0,9,0,0,0,0,9,0,0,0]   // 消灯
];

// メインループ
var five = require("johnny-five");
var board = new five.Board();

board.on("ready", function() {
  var num = 0;  // 表示する数字

  // 表示する数字毎に各セグメント(ピン)をON/OFF
  this.loop(500, function() {
    for (var i = 1; i <= 11; i++) {
      onoff = led_list[num][i];
      if (onoff == 0 || onoff == 1) {
        board.digitalWrite(i, onoff);
      }
    }
    num++;

    // 9の次はいったん消灯して0に戻る
    if (num > 10) {
      num = 0
    };
  });
});
実行
% node 7seg.js
1486305432162 Device(s) /dev/ttyACM0  
1486305432169 Connected /dev/ttyACM0  
1486305435411 Repl Initialized  
>>

関連資料・記事

参考サイト

2017/01/21更新

対応バージョン: Node.js 4.2.6, Johnny-Five 0.9.58

Node.jsでArduino UnoにつないだLEDに対してタクトスイッチを使って点灯、点滅、フェードイン・アウトを繰り返すプログラムを作る。

Node.jsを動かす母艦はUbuntu 16.04とする。

結線

結線は以下の通り。

ソース

以下のようなコードを書きNode.jsで実行する。タクトスイッチを押す毎にLEDが点灯→点滅→フェードイン・アウトに切り替わり、タクトスイッチの長押しで消灯する。

led.js
var five = require("johnny-five");
var board = new five.Board();

cnt = 0;

// LED点灯
function led_on(led) {
  switch(cnt % 3) {
    case 0:
      led.on();                         // 点灯
      break;
    case 1:
      led.strobe(500);                  // 点滅
      break;
    case 2:
      led.pulse(500);                   // フェードイン・アウト
  }

  cnt++;
}

// LED消灯
function led_off(led) {
  led.stop();
  led.off();
}

// メインループ
board.on("ready", function() {
  var button = new five.Button(2);      // スイッチ状態
  var led    = new five.Led(11);        // LED

  // 押す
  button.on("press", function() {
    led_on(led);
  });

  // 長押し
  button.on("hold", function() {
    led_off(led);
  });

});
実行
% node led.js
1484147909373 Device(s) /dev/ttyACM0  
1484147909404 Connected /dev/ttyACM0  
>>

関連資料・記事

参考サイト

2017/04/15更新

対応バージョン: Arduino IDE 1.8.2

I2C接続のLCDに文字列を表示させる。

このパーツはLCDモジュールAQM0802A-RN-GBWとピッチ変換基板AE-AQM0802を組み合わせたもので、コントローラICはST7032iが使われている。

このICをArduino IDEから簡単に扱えるライブラリをオレ工房さんが作成されているのでこれを利用する。

Arduino IDEを動かす母艦はUbuntu 16.04とする。

ST7032ライブラリインストール

まずこのST7032ライブラリをインストールする。

前述のオレ工房さんのGitHubリポジトリからファイル一式を入手し、arduino_ST7032-masterディレクトリの名前をST7032に変更してArduino IDEのlibrariesディレクトリ配下に配置する。

% wget https://github.com/tomozh/arduino_ST7032/archive/master.zip
% unzip master.zip
% mv arduino_ST7032-master ST7032
% mv ST7032 <Arduino IDEのインストールパス>/libraries
% rm master.zip

インストールはこれで完了である。

結線

次に結線を行うが、Node.jsを使って同様の処理を行う場合と同様なので割愛する。

関連資料・記事

ソース

以下のようなコードを書きArduino IDEでコンパイルしてArduinoに書き込む。

#include <Wire.h>
#include <ST7032.h>

ST7032 lcd;

void setup() {
  // LCD表示領域設定(8桁, 2行)
  lcd.begin(8, 2);

  // コントラスト設定(0〜63)
  lcd.setContrast(30);

  // LCD表示(1行目)
  lcd.setCursor(0, 0);
  lcd.print("I Love");

  // LCD表示(2行目)
  lcd.setCursor(0, 1);
  lcd.print("Arduino!");
}

void loop() {
}

LCDに以下のように出力される。コントラストを強め(大きな数値)に設定すると液晶の素子全体が発光してしまい画面全体が■で埋め尽くされたように見えてしまうので微調整が必要である。

関連資料・記事

参考サイト

2017/02/18更新

対応バージョン: Node.js 4.2.6, Johnny-Five 0.10.6

Node.jsでI2C接続のLCDに文字列を表示させる。

このパーツはLCDモジュールAQM0802A-RN-GBWとピッチ変換基板AE-AQM0802を組み合わせたもので、コントローラICはST7032iが使われている。

Node.jsを動かす母艦はUbuntu 16.04とする。

結線

ピッチ変換基板に対する結線は以下の通り。

VDD: 3.3Vに接続
RESET: (未使用)
SCL(クロック): A5に接続
SDA(データ): A4に接続
GND: GNDに接続

I2Cバスのプルアップ抵抗(10kΩ)はピッチ変換基盤側に用意されている(基盤のPUの2箇所がハンダでショートされている)ため改めて抵抗を使用する必要はない。

ソース

以下のようなコードを書きNode.jsで実行する。

データシートに従って細かい制御ができるものの、ここではいったん文字列を表示している。

lcd.js
// AQM0802A-RN-GBW - I2C接続小型液晶 8文字x2行
//
// ピン配置
//   1. VDD(3.3Vに接続)
//   2. RESET  (*)未使用
//   3. SCL(クロック)
//   4. SDA(データ)
//   5. GND

//
// 初期設定
//
var five = require("johnny-five");
var board = new five.Board();

var LCD_ADR = 0x3E;  // コントローラIC ST7032iのI2Cアドレス(固定)
var clm_list = [     // 送信コマンドを変えることで表示行を変える
  0x80,  // 0行目表示
  0xc0   // 1行目表示
];

//
// 関数定義
//

// LCD制御
var lcd_cmd = function(cmd) {
  board.io.i2cWrite(LCD_ADR, 0x00, cmd);
}

// データ送信
var lcd_data = function(lcd_data) {
  board.io.i2cWrite(LCD_ADR, 0x40, lcd_data);
}

// 出力位置指定(行, 列)
var lcd_setCursor = function(row, clm){
  lcd_cmd(clm_list[row] + clm);
}

// LCDクリア
var lcd_clear = function() {
  lcd_cmd(0x01);
}

// LCD初期化
// (*)コントラストは好みに応じて微調整するとよい
var lcd_init = function() {
  board.io.i2cConfig();

  lcd_cmd(0x38);  // 画面サイズ指定(8文字 x 2行)
  lcd_cmd(0x39);  // 拡張コマンド設定
  lcd_cmd(0x14);  // 内部OSC周波数
  lcd_cmd(0x7A);  // コントラスト
  lcd_cmd(0x56);  // 電源(3V)/アイコンOFF/コントラスト
  lcd_cmd(0x6A);  // フォロワー操作
  lcd_cmd(0x38);  // 拡張コマンド設定終了
  lcd_cmd(0x0C);  // 表示ON
  lcd_clear();    // LCDクリア
}

//
// メイン
//
board.on("ready", function() {
  // LCD出力
  var lcd_print = function(msg) {
    for(var i = 0; i < msg.length; i++) {
      lcd_data(msg.charCodeAt(i));  // 1文字出力
    }
  }

  lcd_init();           // LCD初期化
  lcd_clear();          // LCDクリア
  lcd_setCursor(0, 0);  // カーソル位置(行, 列)
  lcd_print("I Love");  // 表示文字列
  lcd_setCursor(1, 0);
  lcd_print("Arduino!");
});
実行
% node lcd.js
1487422161958 Device(s) /dev/ttyACM0  
1487422161965 Connected /dev/ttyACM0  
1487422165206 Repl Initialized  
>>

関連資料・記事

参考サイト

2018/08/07更新

対応バージョン: Arduino IDE 1.8.5

Arduinoは本体 + IDE(ソフトウェア)の組み合わせで一つの環境を構成する。

ここではArduino Uno R3にArduino IDEからスケッチ(Arduinoではプログラムのことをスケッチと呼ぶ)を送り込んで実行させる手順を示す。IDEを動かす母艦はUbuntu 18.04とする。

Arduino IDEインストール

次にArduino IDEをインストールする。arduino.orgからLinux(64bit)版をダウンロードし、任意の場所に展開する。

% tar xvf arduino-1.8.5-linux64.tar.xz

Arduino IDE起動、各種設定

arduino-1.8.5配下のarduinoを実行するとArduino IDEが起動する。

% cd arduino-1.8.5/
% ./arduino

Arduino IDEが起動したらArduinoをUSBポートに繋ぎ、[Tools] > [Port] > [/dev/ttyACM0(Arduino Uno)]を選択してシリアルポートの設定を行う。

この設定を行わないとスケッチをArduinoに送り込む際にデバイス指定誤りでエラーになる。

avrdude: ser_open(): can't open device "/dev/ttyS0": No such file or directory
Problem uploading to board.  See http://www.arduino.cc/en/Guide/Troubleshooting#upload for suggestions.

シリアルポートの設定を行っても以下のようなエラーになる場合はIDE利用ユーザがこのデバイスへの書き込み権を持っていないので適切な権限を与える。

avrdude: ser_open(): can't open device "/dev/ttyACM0": Permission denied
Problem uploading to board.  See http://www.arduino.cc/en/Guide/Troubleshooting#upload for suggestions.
% ls -l /dev/ttyACM0
crw-rw---- 1 root dialout 166, 0 12月 30 00:38 /dev/ttyACM0

% sudo gpasswd -a <user> dialout

(*) 上記権限を加えたらログインし直しが必要

サンプルスケッチ動作確認

Arduino IDEにはサンプルスケッチが多数用意されているので例として基板上のLEDを点滅させるスケッチを実行させてみる。

手順としてはまず[File] > [Examples] > [01.Basics] > [Blink]を選択してスケッチを表示し、画面左上のチェックボタン( )をクリックしてスケッチをコンパイルしてから隣の右矢印ボタン( )をクリックすればスケッチがArduinoに書き込まれて動作する。

これでスケッチをArduinoに送り込んで動作させる確認がとれたのであとはいろいろな用途に活用できる。

関連資料・記事

参考サイト

2019/04/24更新

対応バージョン: Arduino IDE 1.8.9

Arduino IDEは通常GUIで使用するが、バージョン1.5.0以降はCLIモードも提供されている。

似たものとして以下で紹介したarduino-cliもあるが、このArduino IDEのCLIモードは新たなモジュールをインストールすることなく純粋にArduino IDEをCLIで使えるのでより手軽に利用できる。

関連資料・記事

以下、使用方法を示す。

スケッチのコンパイル

--verifyオプションにソースファイル名を指定する。

% arduino --verify test.ino 

スケッチのコンパイル & Arduino転送

--boardオプションでArduinoボードの種類を「package:architecture:board」の形式で指定する。Arduino UNOであれば以下のようになる。また--portにて母艦側の接続ポートを指定する。

% arduino --board arduino:avr:uno --port /dev/ttyACM0 --upload test.ino 

搭載メモリや接続スピードなどのボード固有の情報はArduino IDEをインストールしたディレクトリ配下のhardware/arduino/avr/boards.txtに記載されている。

関連資料・記事

参考サイト

2016/12/30更新

対応バージョン: gort 0.6.2

ArduinoをNode.jsで操作するためには事前にArduinoにFirmataプログラムを書き込んでおく必要があるが、一般的なArduino IDEを使った方法だとIDEを起動してメニュー操作する手間がかかって面倒なのでGORTを使ってコマンドラインで書き込む手順を示す。

作業を行う母艦はUbuntu 16.04とする。

GORTインストール

まずGORTのダウンロードサイトから対象のパッケージをダウンロードする。

このファイルをdpkgコマンドを使ってインストールする。

% sudo dpkg -i gort_0.6.2_amd64.deb
% gort -v
gort version 0.6.2

シリアルポート確認 + ユーザ設定

次にArduinoをUSBケーブルで接続しているポートを確認する。この例では/dev/ttyACM0として認識されている。

% gort scan serial

1 serial port(s) found.

1. [/dev/ttyACM0] - [usb-Arduino_Srl_Arduino_Uno_75431343334351214222-if00]
  USB device:  Bus 003 Device 010: ID 2a03:0043 dog hunter AG Arduino Uno Rev3

このデバイスはrootユーザあるいはdialoutグループに属するユーザのみが使用できるので一般ユーザでこのデバイスを使用したい場合はそのユーザをdialoutグループに追加する。ログインユーザに対してこの作業を行った場合は設定を有効にするためにいったんログアウトしてログインし直す。

% ls -l /dev/ttyACM0
crw-rw---- 1 root dialout 166, 0 12月 30 00:38 /dev/ttyACM0

% sudo gpasswd -a <user> dialout

AVRDUDEインストール + Firmata書き込み

シリアルポートが使えるようになったらまずプログラムの書き込みに必要なAVR Downloader/UploaDErのAVRDUDEをインストールし、続けてこのAVRDUDEの機能を使ってFirmataプログラムを書き込む。

AVRDUDEインストール
% gort arduino install
Attempting to install avrdude with apt-get.
:
Firmata書き込み
% gort arduino upload firmata /dev/ttyACM0

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e950f (probably m328p)
avrdude: reading input file "/tmp/880691775"
avrdude: writing flash (11452 bytes):

Writing | ################################################## | 100% 1.84s

avrdude: 11452 bytes of flash written
avrdude: verifying flash memory against /tmp/880691775:
avrdude: load data flash data from input file /tmp/880691775:
avrdude: input file /tmp/880691775 contains 11452 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 1.47s

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

avrdude done.  Thank you.

これでNode.jsでArduinoが操作できるようになる。

関連資料・記事

参考サイト

2017/08/19更新

対応バージョン: Arduino IDE 1.8.2

ESP32(ESP-WROOM-32)でWi-Fiを使う手順を示す。

ここではESP32上にWebサーバを動作させて外部からHTTPでアクセスしてLEDをON/OFFさせてみる。

尚、この作業をするにはWi-Fiが利用できる(アクセスポイントに接続でき、かつDHCPサーバからIPアドレスが割り振られる)環境である必要がある。

また、Arduino IDEを動かす母艦はUbuntu 16.04とする。

準備

母艦側

まず最初に以下の資料をもとにArduino core for the ESP32ライブラリをインストールする。

関連資料・記事

esp32ディレクトリの中にlibraries/WiFi/examples/SimpleWiFiServer/SimpleWiFiServer.inoというファイルがありESP32をWebサーバとして動作させるスケッチなので、これを編集してWi-FiのSSIDとパスワードを設定する。

SimpleWiFiServer.ino
:
const char* ssid     = "yourssid"; <- SSIDを設定
const char* password = "yourpasswd"; <- パスワードを設定
:
void setup()
{
    Serial.begin(115200);
    pinMode(5, OUTPUT);      // set the LED pin mode
:

ESP32側

ここまでできたらESP32にLEDをつなぐ。結線は以下の通りとする。

IO 5 → 330Ω抵抗 → LED(アノード) → LED(カソード) → GND

ピン番号は任意でよいが、スケッチ上で5番を指定しているので変更する場合はスケッチも合わせて変更する。

動作確認

結線ができたらIDEの[ツール] > [シリアルモニタ]を開いておき、スケッチをESP32に書き込む。

書き込みが終わるとシリアルモニタにESP32の情報が出力され、最後にESP32のIPアドレスが表示される。

ets Jun  8 2016 00:22:57

rst:0x10 (RTCWDT_RTC_RESET),boot:0x12 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0010,len:4
load:0x3fff0014,len:708
load:0x40078000,len:0
load:0x40078000,len:11460
entry 0x400789f4


Connecting to xxxxx
....
WiFi connected.
IP address:
xxx.xxx.xxx.xxx

あとはこのIPアドレスに対してH(ON)かL(OFF)を指定すればLEDのON/OFFが制御できる。

http://xxx.xxx.xxx.xxx/H (ON)
http://xxx.xxx.xxx.xxx/L (OFF)

参考サイト

2017/06/20更新

対応バージョン: Arduino IDE 1.8.2

ESP32(ESP-WROOM-32)をArduino IDEから使うにはArduino core for the ESP32ライブラリをインストールする。

方法は簡単で、Arduino IDEが~/opt/arduinoにインストールされているとすると以下の手順でOKである。IDEを動かす母艦はUbuntu 16.04とする。

% mkdir -p ~/opt/arduino/hardware/espressif
% cd ~/opt/arduino/hardware/espressif
% git clone https://github.com/espressif/arduino-esp32 esp32
% cd esp32/tools
% python get.py
System: Linux, Info: Linux-4.4.0-79-generic-x86_64-with-Ubuntu-16.04-xenial
Platform: x86_64-pc-linux-gnu
Downloading xtensa-esp32-elf-linux64-1.22.0-61-gab8375a-5.2.0.tar.gz
Done
Extracting xtensa-esp32-elf-linux64-1.22.0-61-gab8375a-5.2.0.tar.gz
Done

尚、Arduino IDEのインストールについては以下を参照のこと。

関連資料・記事

IDEから認識

ライブラリがインストールできたら母艦にESP32を接続してIDEから認識させる。

ここではESP32-DevKitC ESP-WROOM-32開発ボードを使用する。

ボードは[ツール] > [ボード]から「ESP32 Dev Module」を選択し、その他設定は以下の通りとする。Upload Speedはもっと上げてもよいが転送エラーが発生する可能性があるので環境によって適切な値を設定する。

Flash Frequency: 80MHz
Upload Speed: 115200
Core Debug Level: なし
書込み装置: USBasp

Lチカ

ESP32がIDEから認識できたらLチカをやってみる。

結線は以下の通りとする。

IO 14 → 330Ω抵抗 → LED(アノード) → LED(カソード) → GND

結線したら以下のような単純なコードを書いて実行すればLEDが点滅する。

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

void loop() {
  digitalWrite(14, HIGH);
  delay(250);
  digitalWrite(14, LOW);
  delay(250);
}

参考サイト

2017/04/23更新

Arduinoのクラウド開発環境「Arduino Create」を使えばWebブラウザ上でスケッチの開発が可能になり、各種Arduinoライブラリの使用や他ユーザとのスケッチの共有、またインターネットを経由したArduino同士の相互通信などが可能になる。

ここではArduino Createのセットアップからオンライン上のエディタでスケッチを書いてLチカするまでを説明する。

尚、Arduino Createを動かすにはローカルにArduinoエディタプラグインを導入する必要がある。プラグインはWindows/macOS/Linux用が用意されているが、ローカル側がUbuntu 16.04なのでここではLinux版を使用する。

ユーザ登録

まずArduino Createのトップページにアクセスして右上のSIGN INからユーザ登録を行う。

Arduinoエディタプラグインインストール

ユーザ登録が終わったらトップ画面の[Getting Started]をクリックし、下記画面から[Setup the Arduino Editor Plugin]をクリックする。

Welcome画面が表示されるので[NEXT]をクリックする。

プラグインのプラットフォームを選ぶ画面が表示されるのでここではLinuxが選択されている状態で[DOWNLOAD PLUGIN]をクリックし、プラグインをダウンロードする。

ダウンロードが終わったら画面の指示に従ってプラグインをインストールする。

% tar xvf ArduinoCreateAgent-1.1-linux-x64-installer.tar.gz
% ./ArduinoCreateAgent-1.1-linux-x64-installer.run

インストーラはGUIなので迷うことはないだろう。

途中でインストール場所を聞かれるので任意の場所を指定する。デフォルトは~/ArduinoCreateAgent-1.1である。

インストールが完了したらダウンロードしたファイルを削除する。

% rm ArduinoCreateAgent-1.1-linux-x64-installer.*

Arduino Createでスケッチを書く

プラグインのインストールが完了するとタスクトレイにArduinoアイコンが追加されるので[Go to Arduino Create]をクリックする。

Arduino Createのトップ画面を表示されるので[Arduino Web Editor]をクリックすればWebエディタ画面になる。

Arduino IDEを使用する場合と同様に、最初にArduinoのボードと接続ポートを指定する。これであとはIDEと同じ使用感でスケッチが書ける。

結線

Lチカ用にアノード側に330Ωの抵抗を挟んだ簡単な結線を行う。

動作確認(Lチカ)

Webエディタ上で以下のようなコードを書いて実行すればLチカができる。

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

void loop() {
  digitalWrite(13, HIGH);
  delay(500);
  digitalWrite(13, LOW);
  delay(500);
}

関連資料・記事

参考サイト

2018/08/28更新

対応バージョン: 0.2.0-alpha.preview

Arduinoは通常GUIベースのIDEを使って開発を行うが、コマンドラインベースのarduino-cliがリリースされたのでまだプレビューながら内蔵LEDでLチカさせるまでの手順を示す。

Arduinoは一般的なArduino Uno R3を使用する。arduino-cliを動かす母艦のOSはLinux(Ubuntu 18.04 - 64bit)とする。

関連資料・記事

arduino-cliインストール

まず母艦のOSに合わせたarduino-cliのバイナリを以下からダウンロードする。ここではLinux(64bit)版をダウンロードする。

次にこれを展開して任意の場所にインストールする。

% tar xvf arduino-cli-0.2.0-alpha.preview-linux64.tar.bz2

% sudo install -m 755 arduino-cli-0.2.0-alpha.preview-linux64 /usr/local/bin/arduino-cli

% arduino-cli version
arduino-cli version 0.2.0-alpha.preview

arduino-cliには以下のサブコマンドが用意されているが、Lチカに必要な最低限のサブコマンドについて説明する。

% arduino-cli
Arduino Command Line Interface (arduino-cli).

Usage:
  arduino-cli [command]

Examples:
arduino <command> [flags...]

Available Commands:
  board         Arduino board commands.
  compile       Compiles Arduino sketches.
  config        Arduino Configuration Commands.
  core          Arduino Core operations.
  help          Help about any command
  lib           Arduino commands about libraries.
  sketch        Arduino CLI Sketch Commands.
  upload        Upload Arduino sketches.
  version       Shows version number of arduino CLI.

Flags:
      --config-file string   The custom config file (if not specified ./.cli-config.yml will be used).
      --debug                Enables debug output (super verbose, used to debug the CLI).
      --format string        The output format, can be [text|json]. (default "text")
  -h, --help                 help for arduino-cli

arduino-cli初期設定

arduino-cliを初めて使う場合、プラットフォーム一覧を更新する必要があるので以下のコマンドを実行する。

% arduino-cli core update-index
Updating index: package_index.json downloaded

このpackage_index.jsonは~/.arduino15に格納される。

ここでArduinoを母艦に接続する。接続したら以下のコマンドを実行するとボードの認識状態が確認できる。

% arduino-cli board list
FQBN            Port            ID              Board Name
arduino:avr:uno /dev/ttyACM0    2A03:0043       Arduino/Genuino Uno

スケッチはこのPortに接続されたFQBN(Fully Qualified Board Name)に対してアップロードする。

尚、スケッチとarduino-cliの各種設定はデフォルトでは以下のディレクトリに配置されるが、configサブコマンドで場所を変えることもできる。

スケッチ

$HOME/Arduino

各種設定

$HOME/.arduino15

configサブコマンドはdumpを使って現状の設定をYAMLで出力できるので、これを編集して上記パスを任意のパスに変更して使用できる。

% arduino-cli config dump > .cli-config.yml

% vi .cli-config.yml
proxy_type: auto
sketchbook_path: /home/neo/Arduino <--- スケッチの配置パス
arduino_data: /home/neo/.arduino15 <--- 各種設定の配置パス
board_manager: null

この設定を使用する場合は--config-fileオプションを付けてarduino-cliコマンドを実行する。

% arduino-cli --config-file .cli-config.yml <サブコマンド>

スケッチ動作確認(内蔵LEDでLチカ)

arduino-cliの初期設定ができたらArduino IDEに同梱されているサンプルスケッチ(基板上のLEDを点滅させる)と同じコードを実行させてみる。

手順としてはまずsketchサブコマンドのnewを使ってスケッチの格納ディレクトリと空のスケッチを作成する。

% arduino-cli sketch new test
Sketch created in: /home/neo/Arduino/test

% cat ~/Arduino/test/test.ino
void setup() {
}

void loop() {
}

この空のスケッチを以下のように編集し、サンプルスケッチと同じ内容にする。

% vi ~/Arduino/test/test.ino
void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
  digitalWrite(LED_BUILTIN, HIGH);
  delay(1000);
  digitalWrite(LED_BUILTIN, LOW);
  delay(1000);
}

スケッチが用意できたらコンパイルしてArduinoにアップロードする。

まずコンパイルは以下のようにする。アップロードするボードに合わせたバイナリを作る必要があるのでボード名を指定する。

% arduino-cli compile -b arduino:avr:uno Arduino/test
Sketch uses 928 bytes (2%) of program storage space. Maximum is 32256 bytes.
Global variables use 9 bytes (0%) of dynamic memory, leaving 2039 bytes for local variables. Maximum is 2048 bytes.

コンパイルが成功すると~/Arduino/testにelfとhexが作成される。

% ls -l ~/Arduino/test
合計 24
-rwxr-xr-x 1 neo docker 13240  8月 28 00:36 test.arduino.avr.uno.elf*
-rw-r--r-- 1 neo docker  2623  8月 28 00:36 test.arduino.avr.uno.hex
-rw-r--r-- 1 neo docker   163  8月 27 23:04 test.ino

ここまできたらuploadサブコマンドでバイナリをArduinoにアップロードすればスケッチが動作して内蔵LEDが点滅する。

% arduino-cli upload -p /dev/ttyACM0 -b arduino:avr:uno Arduino/test

尚、コンパイルやアップロードの際にボードの指定(-b)をするのが面倒な場合はboardサブコマンドのattachでスケッチとボードを紐付けておくことによってボード指定(-b)を省略することができる。(ポートの指定(-p)は省略できない)

% arduino-cli board attach serial:///dev/ttyACM0 Arduino/test

この設定は~/Arduino/test/sketch.jsonに保存されるので設定を取り消したい場合は単にsketch.jsonを削除すればよい。

% cat ~/Arduino/test/sketch.json
{"cpu":{"fqbn":"arduino:avr:uno","name":"Arduino/Genuino Uno","network":false,"type":"serial"}}

関連資料・記事

参考サイト

2017/03/25更新

対応バージョン: Node.js 4.2.6, Johnny-Five 0.10.6

IoTデバイスから収集したデータを蓄積して簡単にグラフ化できるAmbientというWebサービスを使ってArduinoにつないだ温度センサーから取得したデータをグラフ化してみる。非常に簡単なので実装手順を紹介する。

Node.jsを動かす母艦はUbuntu 16.04とする。

Ambient準備

まず以下のチュートリアルに従ってユーザ登録やデータの保存単位であるチャネルを作成する。プログラミング時にチャネルIDとライト(書込)キーが必要になるのでメモしておく。

次にプログラミングを行うが、事前にArduinoと温度センサーの結線を行う。

結線

ここでは温度センサーとしてLM61BIZを使用するので以下の記事を参考にして結線する。

関連資料・記事

ソース

結線が終わったらプログラムを書く。

先のチュートリアルではArduinoスケッチを使う場合の例が示されているのでNode.jsを使うには以下の資料に従って公式のライブラリを導入し、お作法にしたがってコードを書く。

lm61_ambient.js (チャネルIDとライトキーは自身のチャネル情報を記述する)
//
// 温度データ格納 -> Ambient
//
var five = require('johnny-five');
var ambient = require('ambient-lib');

var board = new five.Board();

// チャネル情報設定
var channel_id = <チャネルID>;
var write_key  = '<ライトキー>';

// Ambient接続
ambient.connect(channel_id, write_key);

//
// メイン
//
board.on('ready', function() {
  var temp = new five.Thermometer({
    pin: 'A0',
    freq: 5000,  // Ambientの最短の送信間隔(5秒)
    toCelsius: function(raw) {
      var val = ((raw * 5 / 1024) - 0.6) * 100;  // 温度計算
      return Math.round(val * 10) / 10;          // 小数点第2位以下四捨五入
    }
  });

  // センサーデータ取得
  temp.on('change', function() { 
    data = this.celsius;
    console.log(data + '°C');

    data = {d1: data};

    ambient.send(data, function(err, res, body) {
      if (err) {
        console.log(err);
      }
    }); 
  });
});
実行
% node lm61_ambient.js
1485094276071 Device(s) /dev/ttyACM0  
1485094276078 Connected /dev/ttyACM0  
>> 24.5°C
24°C
24.5°C
24°C
23.5°C
:

これでチャネル一覧ページの該当のチャネル名をクリックすれば温度センサーから取得したデータがグラフ化されているのが確認できる。

関連資料・記事

参考サイト

2018/04/21更新

対応バージョン: Arduino IDE 1.8.5

「Arduinoを始めたいんだけど何をどうしたらいいか分からない」というかたのために、Arduinoを初めて使う時に必要なもの(ハードウェア、ソフトウェア)と、簡単な実例集を示します。

この資料は以下のイベントと連動しています。

必要なハードウェア

まず以下のハードウェアを用意します。
Arduino本体(Arduino UNO R3)
Arduino本体とPCを接続するUSBケーブル(*1)
LEDやセンサーなどのパーツ
Arduinoとパーツを接続するためのケーブル(*2)
ブレッドボード

(*1) コネクタの形状はArduino側はType B、PC側は機種によってType AやType Cに分かれます。一部の新しいMacはType Cでそれ以外のMacやLinux PC・Windows PCはType Aが多いですが、お使いのPCのUSBがどのタイプなのかについてはWikipediaを参照して下さい。

(*2) このケーブルのことをジャンパワイヤと呼びます。ジャンパワイヤは両端にピンが出ている「オス - オス」と呼ばれるものを用意します。色によって機能や性能に違いはないので好きな色を使えばいいでしょう。

これらのハードウェアはそれぞれ個別に購入してもいいですが、よく分からない場合はArduino本体とケーブルと数種類のパーツがセットになった「Arduinoをはじめようキット」などを購入するのがいいでしょう。

店舗で購入するなら以下の3店舗が定番です。ネット通販でも購入できます。

関連資料・記事

ちなみにArduinoには純正品だけでなく互換機も含めたくさんの種類がありますが、以降の説明ではごく一般的に使われていてネットや書籍での情報も豊富なArduino UNO R3(R3はリビジョン3の意)を使用します。

上記の「Arduinoをはじめようキット」にもArduino UNO R3が同梱されています。

必要なソフトウェア

次にソフトウェアですが、Arduinoの制御に必要なのはarduino.ccが提供しているArduino IDE(無償)という開発環境です。

使用するPCのOS(macOS/Linux/Windows)に合ったArduino IDEを以下からダウンロードし、インストーラの指示に従ってインストールします。

参考書籍

Arduinoの解説本は数多く出版されていますが、僕的には以下の2冊がオススメです。

とっつきやすさ

「みんなのArduino入門」

より深堀りした内容と豊富な事例がほしい場合

「実践Arduino! 電子工作でアイデアを形にしよう」

ArduinoとPCの接続

ハードウェアとソフトウェアが揃ったらまずはArduinoとPCを接続してみましょう。

最低限必要なものはArduino本体と先ほどArduino IDE(以下 IDE)をインストールしたPC、そして両者をつなぐUSBケーブルです。

このケーブルを使ってPCからArduinoに電力を供給したりプログラムを送り込んだり、逆にArduinoで取得したセンサーデータをPC側で受信したりします。

流れとしてはまず最初にPC上でIDEを起動しておいて、次にArduinoとPCをUSBケーブルでつなぎます。

数秒〜数十秒待つとArduinoがシリアルデバイスとして認識されるので、続いてIDEで以下の作業を行います。

[ツール] > [ボード]から[Arduino/Genuino UNO]を選択
[ツール] > [シリアルポート]から先ほど認識させたArduinoのシリアルデバイスを選択

これでIDEからArduinoを制御することができるようになります。

IDEには初めからいろいろなサンプルプログラムが同梱されています。Arduinoの世界ではIDEで使用するプログラムのことを『スケッチ』と呼ぶので覚えておくとよいでしょう。

それでは実際にIDEを使ってArduinoを制御していきましょう。

内蔵LEDを光らせてみよう

まずは最も簡単な内蔵LEDを光らせるところから。これは先ほどの接続以外に特別な結線などは必要ありません。プログラムもIDEにサンプルプログラムとして用意されているのでIDEでそれを選択するだけでOKです。

IDEで[ファイル] > [スケッチ例] > [01.Basics] > [Blink]を選択してスケッチを表示し、画面左上のチェックボタン( )をクリックしてスケッチをマイコンが理解できるデータに変換(この行為をコンパイルと呼びます)してから隣の右矢印ボタン( )をクリックすればスケッチがArduinoに書き込まれて内蔵LEDが点滅します。

LEDがチカチカするので通称「Lチカ」と呼ばれ、電子工作で一番最初に行う入門的な作業になります。

LEDを光らせてみよう(Lチカ)

内蔵LEDの点滅に成功したら次はArduinoにLEDを接続して点滅させてみましょう。

用意するものは以下の5点です。

- ブレッドボード

- LED

- 抵抗(330Ω)

- Arduino本体とブレッドボードをつなぐジャンパワイヤ2本

LEDを扱う上で最初に一つ注意すべきことがあります。LEDは弱い電流で動作しますが、Arduinoからの電流をそのままLEDに流すと流量が多すぎてLEDが壊れてしまうので途中に抵抗というものを挟んで電流を弱める必要があります。

抵抗には電流をどのくらい弱くするかによって様々な値のものがあって単位はΩ(オーム)で表します。値(抵抗値)が大きくなればなるほど流れる電流を弱めることができます。ここでは深く考えずに330Ωの抵抗を使用します。(それより大きな値でも構いません)

抵抗の説明はこのくらいにして、ブレッドボードにLEDを刺しましょう。

LEDにはプラスとマイナスの極があって、ピンの長いほうがプラス、短いほうがマイナスです。(それぞれ『アノード』『カソード』と呼びます)

ブレッドボードは長辺の両端に「+」と「-」と書かれた線がありますが、この線に沿って電気的に内部で一列につながっています。その内側は逆に中心に向かって電気的に内部で一列につながっています。

ブレッドボードにLEDを刺す場合は右の写真のように電気的につながっていない場所(4の列と5の列)にプラスとマイナスを刺すようにします。

ここではプラス(ピンの長いほう)が右側になるように刺します。そしてプラスの線(4の列)上に抵抗を刺しておきます。抵抗に向きはありません。

ブレッドボード上の接続が終わったらArduino本体とつなげましょう。

Arduino側で使用するピンは電源を取るピン(ここでは7番ピンを使用)と、電流を逃がすアースとしてのGND(グランド)と書かれたピンの2ヶ所です。

この7番ピンにジャンパワイヤ(ここでは赤)を刺し、もう片方をブレッドボード上のLEDのプラス側(抵抗の反対側の1の列)に刺します。

そしてGNDピンにジャンパワイヤ(ここでは黒)を刺し、もう片方をブレッドボード上のLEDのマイナス側の線(5の列)上に刺します。

以上で接続は終わりです。

あとはLチカを行うスケッチを書いてArduinoに送り込めばLEDがチカチカします。

Lチカのスケッチは一から書く必要はなく、先ほど内蔵LEDを光らせた時のものを少し変更して使用できます。

「/*」〜「*/」で囲まれた部分や「//」で始まる文章はコメントなので無視して構いません。

このスケッチはArduinoの内蔵LEDをLチカさせるためのものなので、LEDのピンの指定を内蔵LED(LED_BUILTIN)から先ほどLEDを接続した7番ピン(7)に変えて をクリック(コンパイル)し、 をクリックすればスケッチがArduinoに書き込まれてLEDが点滅します。

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

void loop() {
  digitalWrite(7, HIGH);
  delay(1000);
  digitalWrite(7, LOW);
  delay(1000);
}

ここで少しスケッチの構造について説明しておきます。スケッチをよく見ると、

void setup() {
  .
  .
  .
}

void loop() {
  .
  .
  .
}

という2つの塊があり、一つ一つの塊を関数と呼びます。

setup()はプログラムが動き出して一回だけ実行される関数なのでここには初期設定などを書いておき、loop()は繰り返し実行される部分なのでここにメインの処理を書きます。

スケッチはArduinoに書き込まれたあと電源を切る(= USBケーブルを抜く)か他のスケッチを書き込むまで無限に動き続けるので途中で終了するという概念がありません。電源を切っても再度電源を入れ直すと以前書き込んだスケッチがまた動き始めます。

Arduinoはセンサーからデータを取得し続けたり何かのデータを出力し続けるといった用途に使うことが多いのでこのような構造になっています。

さて今回のLチカを行うスケッチの処理内容ですが、まずsetup()中のpinMode()で7番ピンを出力用(OUTPUT)に設定しています。入出力機器をつなぐポートはINPUTかOUTPUTのモードを持つので明示的に宣言することが大切です。

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

続いてloop()中のdigitalWrite()で先ほどモードを宣言した7番ピンの電圧レベルを高(HIGH)に設定すると、7番ピンからアース(GND)に向かって電流が流れ、LEDが点灯します。

次のdelay()で1000ミリ秒(= 1秒)待ってから7番ピンの電圧レベルを低(LOW)に設定すると電流が流れなくなってLEDが消灯します。

さらに1000ミリ秒待ってループの先頭に戻るので結果として1秒おきにLEDが点滅し続けるという動きになります。

void loop() {
  digitalWrite(7, HIGH);
  delay(1000);
  digitalWrite(7, LOW);
  delay(1000);
}

温度センサーで室温を測ってみよう

Lチカがうまくいったら次は温度センサーを使って室温を測ってみましょう。

ここでは簡単に扱える「LM61BIZ」という温度センサーを使います。

関連資料・記事

先ほどのLチカ用の接続を全て取り外し、温度センサーを刻印面を前にしてブレッドボードに刺したあと3本のピンを左からそれぞれArduinoの5V(赤)、A0ピン(白)、GND(黒)につなぎます。

そして以下のようなスケッチを書いてコンパイルし、Arduinoに書き込みます。

センサーから取得したデータを温度に変換するには以下のようにちょっとした計算が必要になりますが、最初はあまり深く考えずコピペして使い、おいおい動作原理を覚えていけばよいでしょう。

void setup() {
  // シリアルポートを9600bpsに設定
  Serial.begin(9600);
}

void loop() {
  // A0ピンからセンサーデータを取得
  int val = analogRead(0);

  // 取得したセンサーデータ(0〜1023)を電圧(0〜5000)に変換
  float volt = map(val, 0, 1023, 0, 5000);

  // このセンサーの計測範囲の電圧(300〜1600)を温度(-30〜100)に変換
  float temp = map(volt, 300, 1600, -30, 100);

  // 温度を出力
  Serial.println(String(temp));

  // 1000ミリ秒(1秒)待つ
  delay(1000);
}
計測した温度はIDEの[ツール] > [シリアルモニタ]で確認できます(左)。

また[ツール] > [シリアルプロッタ]でグラフとしても確認できます(右)。

この状態で温度センサーに手を触れると徐々に温度が上がっていくのが確認できると思います。

このように結果が視覚化されると分かりやすいですよね。

光センサーで明るさを測ってみよう

温度センサーに続いて光センサーを使ってみます。

光センサーは通称CdSセルと呼ばれます。ここでは「GL5528」というCdSセルを使います。

関連資料・記事

CdSセルはまわりが暗いとセンサー自体の抵抗値が大きくなり、まわりが明るいと抵抗値が低くなる性質を持っています。

これを利用して、写真のようにCdSセルの片方に5Vからの線(赤)、もう片方に10KΩの抵抗を挟んだうえでGND行きの線(黒)と抵抗値をA0ピンで取得する線(白)をそれぞれつなぎます。

そして以下のようなスケッチを書いてコンパイルし、Arduinoに書き込みます。取得した明るさは0〜1023の範囲の値になります。

int val = 0;

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

void loop() {
  val = analogRead(0);

  Serial.println(val);

  delay(500);
}

サーボモーターを使ってみよう

Arduinoは動くものも操作できます。ここではサーボモーターを操作してみましょう。

サーボモーターは数百円で購入できる安価な「SG90」というものを使います。このサーボモーターの可動範囲は0〜180度(半回転)です。

結線のしかたは簡単で、サーボモーターの3つの信号線をそれぞれ以下のようにつなげばOKです。

オレンジ(制御) -> Arduinoの9番ピンへ
赤(電源) -> Arduinoの5Vへ
茶(GND) -> ArduinoのGNDへ

スケッチもIDEにサンプルが用意されているので[ファイル] > [スケッチ例] > [Servo] > [Sweep]を選択してスケッチを表示し、コンパイルして実行すればサーボモーターが回転し始めます。

#include <Servo.h>

Servo myservo;

int pos = 0;

void setup() {
  myservo.attach(9);
}

void loop() {
  for (pos = 0; pos <= 180; pos += 1) {
    myservo.write(pos);
    delay(15);
  }
  for (pos = 180; pos >= 0; pos -= 1) {
    myservo.write(pos);
    delay(15);
  }
}

スケッチの中身を見るとまず0度から180度まで1度ずつモーターを回していって、

  for (pos = 0; pos <= 180; pos += 1) {
    myservo.write(pos);
    delay(15);
  }

次は逆に180度から0度まで1度ずつモーターを戻していくという単純な作りです。

  for (pos = 180; pos >= 0; pos -= 1) {
    myservo.write(pos);
    delay(15);
  }

ロボットを作るならサーボモーターは欠かせないパーツですね。

このように一つ一つの機能は単純ですが、それらをつないでプログラミングをすればいろいろな用途に使うことができます。

参考サイト