Arduino のシールド

Arduino のシールドに関する記事です。



シールド

Arduino 用のシールドには様々な種類のものがありますが、手持ちのものだけを紹介します。


プロトタイプシールド

スターターキットの多くに付属しているものの、最初は何をしていいか解らないと思われるシールド。"ユニバーサル基板みたいなシールド" ってのは想像できるでしょうが…。

リセットスイッチ (RESET) は Arduino 本体のリセットスイッチと同じ機能です。シールドをスタックするとリセットスイッチが押しにくくなりますからね。

    

このシールドの使い道が思いつかないようであれば、画像の赤丸の部分に余っているジャンパワイヤをハンダ付けしましょう (3本)。ピンヘッダでもいいですね。

上下の赤いコードは抵抗付きの LED として機能します。デジタルピンに挿せばLチカできますし、5V 或いは 3.3V に接続すれば動作中を示すインジケータとして使えます。オレンジ色のコードはスイッチとして使えますが、プルアップ抵抗を挟むか内部プルアップ抵抗を有効にする必要があります。

LED1 のコードをデジタルピンの 13 番、LED2 のコードを 3V または 5V、S1 のコードをデジタルピンの 7 番に挿して以下のスケッチを実行してみてください。"書籍 Arduino をはじめよう""Example 02: プッシュボタンを使って LED をコントロール" のスケッチと何が違うのか調べてみてください。

const int LED = 13;
const int BUTTON = 7;

int val = 0;

void setup() {
  pinMode(LED, OUTPUT);
  pinMode(BUTTON, INPUT_PULLUP); // 内部プルアップ抵抗を有効にして入力
}

void loop() {
  val = digitalRead(BUTTON); // プルアップなのでボタンが押されていたら LOW
  if (val == HIGH) {
    digitalWrite(LED, LOW);
  } else {
    digitalWrite(LED, HIGH);
  }  
}

LED2 は点灯したまま、LED1 はボタンを押した時だけ点灯すると思います。ちなみに、私のプロトタイプシールドは LED2 が壊れていたので、手持ちの赤色 LED と交換しました。

ぶっちゃけ、ハンダ付けするのならスイッチサイエンスのバニラシールドがいいかと思います。ユニバーサル基板はイロイロ出ていますが、スタックして使うつもりならば R3 対応かどうかをよく調べて購入しましょう。この製品は単体でも購入できますが、自由に部品を配置できる場所が限られているので…どうなんでしょうね?

See Also:


LCD + キーパッドシールド

LCD とプッシュボタンがコンボになっているシールドです。LCD のコントラストは左上の半固定抵抗 (RP1)で調整できます。

このシールドは 5V 専用となっており、SainSmart の UNO 互換機 (サインスマート改造バージョン) で使う場合にはスライドスイッチを 5V 側に設定しなければなりません。3.3V ではどうやっても SELECT ボタンの状態を検出できません。

ピンアウトは以下のようになっています。右上のピンヘッダはこのシールドで使われていないデジタルピン (#13~#11, #3~#0) + GND + VCC が出ており、右下のピンヘッダの S 列にはアナログピン #0 以外 (#1~#5) が出ています。

ピン 機能
Analog #0 ボタン (Right, Up, Down, Left, Select)
Digital #4 DB4
Digital #5 DB5
Digital #6 DB6
Digital #7 DB7
Digital #8 RS
Digital #9 Enable
Digital #10 バックライトコントロール

テストスケッチは以下のようになります。どのボタンが押されたかはアナログピン #0 の値を読んで閾値で判断します。分圧回路なので、理屈的にキーの同時押しには対応していません。

#include <LiquidCrystal.h>

LiquidCrystal lcd(894567);

const int NUM_KEYS = 5;
char msgs[NUM_KEYS][17] = // 16 桁だが NULL 終端のため 17
                   {"Right Key OK    ",
                    "Up Key OK       ",
                    "Down Key OK     ",
                    "Left Key OK     ",
                    "Select Key OK   " };
int adc_key_val[NUM_KEYS] ={70240420620880}; // キーの閾値 (個体によって値は異なる)
int adc_key_in;
int key = -1;
int oldkey = -1;

void setup() {
  Serial.begin(9600);
  lcd.begin(162);
  lcd.clear();
  lcd.print("KEYPAD testing... pressing");
}

void loop() {
  adc_key_in = analogRead(0);
  Serial.println(adc_key_in); // アナログ値
  key = get_key(adc_key_in);
  if (key != oldkey)
  {
    delay(50);
    adc_key_in = analogRead(0);
    key = get_key(adc_key_in);
    if (key != oldkey)
    {
      oldkey = key;
      if (key >= 0){
        lcd.setCursor(01);
        lcd.print(msgs[key]);
      }
    }
  }
}

int get_key(unsigned int input)
{
  int k;
  for (k = 0; k < NUM_KEYS; k++)
    if (input < adc_key_val[k])
      return k;
  if (k >= NUM_KEYS)
    k = -1;
  return k;
}

シリアルモニタを開いてキーを押すとそのキーのアナログ値が取得できます (RESET は除く)。このアナログ値は個体差があるため、adc_key_val[5] で設定されている閾値を調整する必要があります。押したキーと異なるキー名が表示される場合は閾値の調整不足です。

それと些細な事ですが、このシールドは LEFT ボタンの裏面の端子が Arduino の DC ジャックに干渉します。ほんのわずかですがシールドが浮いてしまうので、私は DC ジャックにピンバイスとハンドドリルで浅く穴を掘っています。

それでも電池ボックスや AC アダプタのプラグは SELECT ボタン裏の端子に干渉するのですが…(^^;A

See Also:



バニラシールド ver.2

何の事はない、ユニバーサル基板 (スルーホール) のシールドです。

自分で電子部品をハンダ付けしてシールドを作るためのシールドです。ver.2 は R3 に対応しています。ピンソケットは別売となっているので注意が必要です。

See Also:



サンハヤト UB-ARD03 / UB-ARD03-P

これもユニバーサル基板 (スルーホール) のシールドです。-P と付くのがピンソケット (とタクトスイッチ) が付属する製品です。但し、R3 で追加されたピンには対応していません。

若干短いユニバーサル基板なので段違いになります。これはこれで使い勝手があります…何故なら、UNO と同じサイズの基板は USB コネクタや DC ジャックに干渉する部品実装不能領域があるからです。UNO と同じサイズの製品もありますが、こちらも R3 対応ではないのでバニラシールドでいいかと思います。

また、UB-ARD03-P 付属のピンソケットは足がやや細く、Arduino に挿しやすいと言えば挿しやすいのですが、足が曲がりやすいって事でもあります。なので、気になる方はピンソケットの付属しない UB-ARD03 と、スイッチサイエンスの R3 対応でないピンソケットを購入してください。タクトスイッチ (リセットボタン) は…基板が短く本体のリセットボタンが押せるので使用しなくてもいいかと思います。

この基板のパターンを見れば解ると思うのですが、GND と VCC のラインがあるので、自由に部品を配置できる場所はそんなにありません。

See Also:



イーサーネットシールド2

新しいイーサーネットシールドです。PoE 給電可能なタイプとそうでないタイプがあります。このシールドを使うには arduino.org (Arduino Srl) の方の IDE が必要となります (1.7.3 以降)。

古いイーサーネットシールドは、

…という事で手を出しにくかったのですが、イーサーネットシールド2は安くてそれなりに在庫もあって MAC アドレスも付いています (背面にシールが貼ってあります)。

シールド上のコネクタは、

このようになっています。MicroSD カードスロットもあり、こちらはイーサーネットとは独立した別の機能となります。イーサーネット+ MicroSD カードなコンボシールドという事ですね。MicroSD カード単体の使い方はこちらにあります。

但し、このシールドは Leonardo には使えません。そのため、Leonardo + イーサーネットシールド2 な製品 (Arduino Leonardo Ethernet) があります。

See Also:



AVR ISP シールド

生の ATMEGA328P (ATMEGA328P-PU) に Arduino ブートローダーを書き込むのに使います。

生の ATMEGA328P を Arduino として使うためにはブートローダーを書き込む必要があります...ブートローダー書込済の ATMEGA328P も売られていますけれど。

ATMEGA328P は一番ピン側 (IC の窪みがある方) が向かって右側になるようにセットします。

また、左下に VCC 切替スイッチがありますので、Arduino UNO で使う場合には 5V 側にしておきます。

ブートローダーの書き込み手順は以下の通りです。

  1. AVR ISP シールドは Arduino から取り外しておく
  2. Arduino IDE で [ファイル | スケッチの例 | ArduinoISP]
  3. スケッチをコンパイル&転送
  4. AVR ISP シールドを Arduino に挿す
  5. ゼロプレッシャーソケットのレバーを起こす
  6. ゼロプレッシャーソケットに ATMEGA328P をセットする (向きに注意!)
  7. ゼロプレッシャーソケットのレバーを倒してロックする
  8. [ツール | ボード] で Arduino UNO を選択
  9. [ツール | 書き込み装置] で Arduino as ISP を選択
  10. [ツール |ブートローダを書き込む] でブートローダーを書き込む

とてもお手軽ですね。ちなみにブートローダー書き込みに AVR ISP シールドを使わない方法こちらになります。

See Also:


2.8 inch TFT タッチスクリーンシールド

TFT 液晶ディスプレイ + タッチスクリーン + microSD のコンボシールドで、5V / 3.3V での駆動及び LEONARDO での動作が可能です。タッチペンもオマケで付いてきます (購入時価格: ¥1,430)。

私の購入したものadafruit 2.8" TFT Touch Shield for Arduino のコピー品だと思われます。

パッケージには、

2.8寸UNO模块
駆动:ILI9341	息线: 8位并口
分辨率: 240X320	触摸: 有

とあります。日本語訳すると、

2.8 インチ UNO モジュール
コントローラ: ILI9341    バス: 8bit パラレル
解像度: 240x320 タッチパネル: 有

といった所でしょうか。以下の記事で使われているものと全く同じと思われます。

この記事の著者は、記事中で実行しているサンプルのソースコードをファイルとして提供しておらず、「動画に流れるソースコードを参考に写経しろ」 というマゾヒストです (写経した人のソースコードはこちら)。

このシールドを使うのに必要なライブラリは以下の3つです。Arduino IDE の libraries フォルダにコピーしてください (zip で取得したのであれば [スケッチ | ライブラリをインクルード | .zip 形式のライブラリをインストール...] からでも OK)。

最初のサンプルスケッチとしては、TFT ライブラリに含まれる graphicstest.pde がいいでしょう。しかしながらこのシールド、そのままサンプルスケッチを動作させても画面が真っ白になってしまうのです。

これは tft.readID() を実行すると ID として 0x0101 が返ってくるのですが、ライブラリがこの ID に対応していないからで、とりあえずの対策は Adafruit_TFTLCD.cpp の一部を書き換える事です。

// Ditto with the read/write port directions, as above.
uint16_t Adafruit_TFTLCD::readID(void) {

  ...

  id = hi; id <<= 8; id |= lo;
  return 0x9341;
}

このようになっている所を

// Ditto with the read/write port directions, as above.
uint16_t Adafruit_TFTLCD::readID(void) {

  ...

  id = hi; id <<= 8; id |= lo;
  if (id == 0x0101)
    return 0x9341;
  else
    return id;
}

こう書き換えるだけです。これだけですべてのサンプルスケッチが正しく動作するようになります。

サンプルスケッチを元に microSD カードから BMP 画像を読み込ませてみました。撮影技術がアレなのでイマイチな写りですが、実際にはそこそこキレイに表示されています。

なお、Amazon で出品者に「サンプルください!」と連絡すると MEGA 経由で K60-2.8inch_Arduino_ILI9341_V3.1.rar というファイルが貰えます。で、この中にも改変された Adafruit_TFTLCD.cpp があるのですが、資料を読んでびっくり。この製品の TFT コントローラは ILI9341 ではなく LGDP4535 なんだだそうです。パッケージやファイル名に ILI9341 とあるのは何だったのか。

このシールドでタッチパネルを使う場合には補正が必要です。ディスプレイの表示領域でのタッチパネルの最小値と最大値を確認してキャリブレーションを行う必要があります。

#include <stdint.h>
#include "TouchScreen.h"
#include <Adafruit_TFTLCD.h>

#define LCD_CS A3 // Chip Select goes to Analog 3
#define LCD_CD A2 // Command/Data goes to Analog 2
#define LCD_WR A1 // LCD Write goes to Analog 1
#define LCD_RD A0 // LCD Read goes to Analog 0
#define LCD_RESET A4 // Can alternately just connect to Arduino's reset pin

#define YP A2  // must be an analog pin, use "An" notation!
#define XM A3  // must be an analog pin, use "An" notation!
#define YM 8   // can be a digital pin
#define XP 9   // can be a digital pin

#define TS_MINX 170 // X Min Value (Raw)
#define TS_MAXX 940 // X Max Value (Raw)
#define TS_MINY 170 // Y Min Value (Raw)
#define TS_MAXY 910 // Y Max Value (Raw)

Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);

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

void loop(void) {
  TSPoint p = ts.getPoint();

  if (p.z > ts.pressureThreshhold) {
     Serial.print("("); 
     Serial.print(adjust_x(p.x)); 
     Serial.print(','); 
     Serial.print(adjust_y(p.y)); 
     Serial.print(")");
     Serial.print("\tX = "); Serial.print(p.x);
     Serial.print("\tY = "); Serial.print(p.y);
     Serial.print("\tPressure = "); Serial.println(p.z);
  }

  delay(100);
}

int adjust_x(int x) {

  int TFT_MAX = tft.width() - 1;
  return constrain(map(x, TS_MINX, TS_MAXX, 0, TFT_MAX), 0, TFT_MAX);

}

int adjust_y(int y) {

  int TFT_MAX = tft.height() - 1;
  return constrain(map(y, TS_MINY, TS_MAXY, 0, TFT_MAX), 0, TFT_MAX);

}

タッチした位置の情報がシリアルモニタに表示されます。(X, Y) の後に表示されている X= / Y= が抵抗膜の X / Y 値です。液晶の白く表示されている部分で X / Y それぞれの最小値と最大値を控えておき、ソースコードの TS_MINX / TS_MINY / TS_MAXX / TS_MAXY の値を書き換えます。再コンパイルして実行すると (X, Y) が TFT 液晶の座標に一致するようになります。

UNO とかだと目的のアプリケーションに (3DS にあるような) キャリブレーション機能を持たせる余裕はないと思うので、補正値をマジックナンバーで書き込むか、microSD 等から設定値を読み込むしかないかもしれません。

See Also:


ここにある情報が役に立って、「調べる手間が省けたからオマイに飯でもおごってやるよ」 というハートウォーミングな方がいらっしゃいましたら、下のボタンからどうぞ。

メニュー: