ArduinoのLCDシールドを作製

『ボクのArduino工作ノート改訂版』に記載されているLCDシールドを作製した。

連休中は引きこもることを強く決意し、とはいえ暇を持て余さないよう、いくつかのおもちゃを買った。まずはArduino。前述の書籍に記載されているLCD w/ SWシールドを作製した。購入リストは以下のとおり。

千石電商で購入したもの
商品名 商品コード 個数
Arduinoスターターキット SGK-ARD-KIT 1
ピンヘッダ1列×40P(ストレート・標準ピッチ) 2544-1×40 15.1 (9.6/3.0) 1
耐熱電子ワイヤー(単線) KQE 0.5L-10 黄 1
秋月電子通商で購入したもの
商品名 商品コード 個数
Arduino用ユニバーサル プロトシールド基板 P-07555 1
超小型LCDキャラクタディスプレイモジュール(16×2行バックライト緑) P-01675 1
半固定ボリューム(10 KΩ)103(10個入) P-02470 1
タクトスイッチ(白色) P-03648 1
タクトスイッチ(黒色) P-03647 1
小型スライドスイッチ1回路2接点SS12D01G4(4個入) P-02736 1
超小型スイッチングACアダプターGF12-US0913 M-01803 1
ブレッドボード・ジャンパー延長ワイヤ(メス-メス)15 cm(青) P-03476 1

はんだ付けは数年ぶりだったので、都度テスターで導通をとりながら進める。また、LCDモジュールは、短く切ったワイヤーとメス-メスジャンパーでピンヘッダーに接続して動作確認を行った後、基板に取り付けた。
作製したLCD w/ SWシールドの写真
動作確認に使用したスケッチは、書籍に記載されていたタクトスイッチの割り込み検出ライブラリーを借用した。同ライブラリーに従いGPL V3で公開する。

/*
 * LCD with SW Shield Test
 * Copyright 2014 FireWheel <firewheel@m40.coreserver.jp>
 * GNU General Public License V3
 * see <http://www.gnu.org/licenses/>
 */
#include <LiquidCrystal.h>
#include <SW.h>
/* less than 14 chars */
const char *TITLE = "direction:";
const int DELAY_msec = 400;
/* LEFT < RIGHT, TOP < BOTTOM */
const uint8_t LEFT   =  0;
const uint8_t RIGHT  = 15;
const uint8_t TOP    =  0;
const uint8_t BOTTOM =  1;
/* START_CHAR < END_CHAR */
const char SPACE       = 0x20;
const char LEFT_ARROW  = 0x7F;
const char RIGHT_ARROW = 0x7E;
const char START_CHAR  = 0x20;
const char END_CHAR    = 0x7F;

LiquidCrystal lcd(10, 9, 8, 3, 2, 4, 7);
/* RIGHT - LEFT + 1 + '\0' */
char string[RIGHT - LEFT + 2];
uint8_t direction = SW_LEFT;

void setup() {
  for (uint8_t i = LEFT; i <= RIGHT; i++)
    string[i] = START_CHAR;
  string[RIGHT + 1] = '\0';

  uint8_t rows  = RIGHT - LEFT + 1;
  uint8_t cols  = BOTTOM - TOP + 1;
  uint8_t start = (rows - strlen(TITLE)) / 2;

  lcd.begin(rows, cols);
  lcd.clear();
  lcd.setCursor(start, TOP);
  lcd.print(TITLE);
}

void loop() {
  _set_direction();

  switch(direction) {
    case SW_LEFT:
      _print_direction(LEFT_ARROW, SPACE);
      _flow_left();
      break;
    case SW_RIGHT:
      _print_direction(SPACE, RIGHT_ARROW);
      _flow_right();
      break;
    case SW_BOTH:
      _print_direction(LEFT_ARROW, RIGHT_ARROW);
    default:
      break;
  }

  delay(DELAY_msec);
}

void _set_direction() {
  switch(SW.status) {
    case SW_LEFT:
      direction = SW_LEFT;
      break;
    case SW_RIGHT:
      direction = SW_RIGHT;
      break;
    case SW_BOTH:
      direction = SW_BOTH;
      break;
    default:
      break;
  }
}

void _print_direction(char left_char, char right_char) {
  lcd.setCursor(LEFT, TOP);
  lcd.write(left_char);
  lcd.setCursor(RIGHT, TOP);
  lcd.write(right_char);
}

void _flow_left() {
  char final_char = string[RIGHT];
  char next_char  = final_char + 1;
  /* 0x80 == -128 in char type */
  if (next_char > END_CHAR || next_char < START_CHAR)
    next_char = START_CHAR;

  for (uint8_t i = LEFT; i < RIGHT; i++)
    string[i] = string[i + 1];
  string[RIGHT] = next_char;

  lcd.setCursor(LEFT, BOTTOM);
  lcd.print(string);
}

void _flow_right() {
  char beginning_char = string[LEFT];
  char next_char      = beginning_char - 1;
  if (next_char < START_CHAR)
    next_char = END_CHAR;

  for (uint8_t i = RIGHT; i > LEFT; i--)
    string[i] = string[i - 1];
  string[LEFT] = next_char;

  lcd.setCursor(LEFT, BOTTOM);
  lcd.print(string);
}

なお、SyntaxHighlighter EvolvedのSolarizedテーマはblog.remora.cxさんが公開されているCSSをほぼそのまま使用し、プラグイン作者の“Adding A New Theme”に従って登録した(Thank you for providing such an awesome plugin, Alex.)。記事中の’yourthemestub’に大文字を使用すると、追加したテーマが正しく認識されないようである。恐るべし、PHP。これに気づくまで1日近くを費やしてしまった・・・。

コメントをどうぞ