{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"オリジナルの作成: 2014/12/13"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 07-LEDで文字を表示する\n",
"今回はクリスマスも近くなので、参加者の皆さんと話し合ってLEDで文字を表示してみようと いうことになりました。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 文字を表示するブレッドボード\n",
"文字を表示するために、7個のLEDを使います。\n",
"\n",
"以下の様に、Arduino Mini Pro, LED, 抵抗1\n",
"を配線します。\n",
"\n",
"LEDとArduinoとの間は、手元にある線の長さで自由につないで下さい。 図では、分かりやすいように順番でつないでいます。\n",
"\n",
""
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### LEDがきちんと点灯するか確かめる\n",
"一番右(振るときには一番上)のLEDから0〜6番と番号を付けて、各LEDがつながっているデジタルピンの 番号をledsにセットします。\n",
"\n",
"以下のスケッチでLEDが順番に点灯し、最後にすべて点灯するか確かめて下さい。\n",
"\n",
"```C++\n",
"#define NUM_OF_LED (7)\n",
"#define NUM_OF_CHARS (8)\n",
"\n",
"static int mojiStr[][NUM_OF_LED] = {\n",
" {1,0,0,0,0,0,0},\n",
" {0,1,0,0,0,0,0},\n",
" {0,0,1,0,0,0,0},\n",
" {0,0,0,1,0,0,0},\n",
" {0,0,0,0,1,0,0},\n",
" {0,0,0,0,0,1,0},\n",
" {0,0,0,0,0,0,1},\n",
" {1,1,1,1,1,1,1}\n",
" };\n",
" \n",
"static int leds[] = {3,4,5,6,9,8,7}; \n",
"\n",
"void setup() {\n",
" for (int i = 0; i < NUM_OF_LED; i++) {\n",
" pinMode(leds[i], OUTPUT);\n",
" }\n",
"}\n",
"\n",
"void loop() {\n",
" for (int i = 0; i < NUM_OF_CHARS; i++) {\n",
" for (int j = 0; j < NUM_OF_LED; j++) {\n",
" digitalWrite(leds[j], mojiStr[i][j]);\n",
" }\n",
" delay(500);\n",
" }\n",
"}\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 配列の話し\n",
"ledsやmojiStrは配列と呼ばれるものです。\n",
"\n",
"これまで、配列についてきちんと説明していなかったので、 ここで改めて配列って何なのか説明します。\n",
"\n",
"配列は、複数の値を連続した領域に保存したもので、[]の中に添え字と呼ばれる数値または変数を 使って配列の中の値を読み込んだり、セットしたりすることができます。\n",
"\n",
"ledsは、1個の[]で定義された1次元配列です。 ledsという変数は、数値3, 4, 5, 6, 9, 8, 7が連続して保存された領域を指し、添え字を使って値を取って きます。\n",
"\n",
"配列の添え字は、0からはじまっており、配列ledsから2番目の4の値を取ってくるときには、\n",
"\n",
"```C++\n",
"leds[1]\n",
"```\n",
"\n",
"のように書きます。\n",
"\n",
"先ほどのスケッチのsetup関数では、変数iを使ってledsに入っているデジタルピン番号を使って pinModeをOUTPUTにしています。\n",
"\n",
"```C++\n",
" for (int i = 0; i < NUM_OF_LED; i++) {\n",
" pinMode(leds[i], OUTPUT);\n",
" }\n",
"```\n",
"\n",
"\n",
"\n",
"次に2個の[]で定義された2次元配列mojiStrをみてみましょう。 mojiStrの値は、以下の様にセットされています。\n",
"\n",
"\n",
"\n",
"2次元配列は、1次元配列を縦にしたものと各行の値を持っている2つの領域に保存されています。\n",
"\n",
"mojiStr[0]と指定すると一番上の1,0,0,0,0,0,0が入った領域を指し、mojiStr[0][0]と1番上の行の最初の値1を取ってきます。\n",
"\n",
"このようにして、7個のLEDの値を添え字jのループでセットしているのが、loop関数の以下の部分です。\n",
"\n",
"```C++\n",
" for (int j = 0; j < NUM_OF_LED; j++) {\n",
" digitalWrite(leds[j], mojiStr[i][j]);\n",
" }\n",
"```\n",
"\n",
"少しずつ点灯しているLEDを変えることで、文字のが形を作り出すのが今回の目的です。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 左右対称の文字の表示 \n",
"縦に並んだLEDを左右に振ることで、文字のような形を写しだしてみましょう。\n",
"\n",
"表示する文字(図形)は、左右対称であれば何でもかまいません。\n",
"\n",
"以下のスケッチでは、「TAO」を表示してみます。\n",
"\n",
"```C++\n",
"#define NUM_OF_LED (7)\n",
"#define NUM_OF_HEIGHT NUM_OF_LED\n",
"#define NUM_OF_WIDTH (5)\n",
"#define NUM_OF_CHARS (3)\n",
"static int mojiStr[][NUM_OF_HEIGHT][NUM_OF_WIDTH] = {\n",
" // TAO\n",
" { {1,1,1,1,1},\n",
" {0,0,1,0,0},\n",
" {0,0,1,0,0},\n",
" {0,0,1,0,0},\n",
" {0,0,1,0,0},\n",
" {0,0,1,0,0},\n",
" {0,0,1,0,0} },\n",
"\n",
" { {0,0,1,0,0},\n",
" {0,1,0,1,0},\n",
" {1,0,0,0,1},\n",
" {1,0,0,0,1},\n",
" {1,1,1,1,1},\n",
" {1,0,0,0,1},\n",
" {1,0,0,0,1} },\n",
"\n",
" { {0,1,1,1,0},\n",
" {1,0,0,0,1},\n",
" {1,0,0,0,1},\n",
" {1,0,0,0,1},\n",
" {1,0,0,0,1},\n",
" {1,0,0,0,1},\n",
" {0,1,1,1,0} }\n",
"}; \n",
" \n",
"static int leds[] = {3,4,5,6,9,8,7}; \n",
"\n",
"void setup() {\n",
" for (int i = 0; i < NUM_OF_LED; i++) {\n",
" pinMode(leds[i], OUTPUT);\n",
" }\n",
"}\n",
"\n",
"void loop() {\n",
" for (int i = 0; i < NUM_OF_CHARS; i++) {\n",
" for (int j = 0; j < NUM_OF_WIDTH; j++) {\n",
" for (int k = 0; k < NUM_OF_HEIGHT; k++) {\n",
" digitalWrite(leds[k], mojiStr[i][k][j]);\n",
" }\n",
" delay(4);\n",
" }\n",
" delay(8);\n",
" }\n",
"}\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### スケッチの説明 \n",
"できるだけ、文字の形を確認しながら動かしたいので、mojiStrには3次元の配列にしました。\n",
"\n",
"3次元の配列は、2次元の配列が何枚も重なっているようなものをイメージすると分かりやすいと思います。\n",
"\n",
"loop関数のforループの一番内側では、i, j, kの添え字が、i, k, jとなっているところがポイントです。\n",
"\n",
"```C++\n",
" digitalWrite(leds[k], mojiStr[i][k][j]);\n",
"```\n",
"\n",
"このようにループの順番を変えることで、表示順と定義の順番を入れ替えています。\n",
"\n",
"LEDを左右に振ると何となくT, O, Aに似た文字が出てくると思います。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 振る方向で表示の順番を変える\n",
"3軸の加速度をアナログ電圧で出力するセンサーKXM52-1050\n",
"2\n",
"を使ってY軸(横方向)の加速度から振る方向を判断して、文字を表示する順番を変えてみました。\n",
"\n",
"以下の様にKXM52-1050をつなぎます。\n",
"\n",
"\n",
"\n",
"ブレッドボードは、以下の様に作成しました。\n",
"\n",
""
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### スケッチ\n",
"まだ、完成とまでは言えませんが、現段階のスケッチを以下に示します。\n",
"\n",
"```C++\n",
"#define NUM_OF_LED (7)\n",
"#define NUM_OF_HEIGHT NUM_OF_LED\n",
"#define NUM_OF_WIDTH (5)\n",
"#define NUM_OF_CHARS (3)\n",
"#define ZERO 505\n",
"#define SHIKI_CHI 200\n",
"static int mojiStr[][NUM_OF_HEIGHT][NUM_OF_WIDTH] = {\n",
" // TAO\n",
" { {1,1,1,1,1},\n",
" {0,0,1,0,0},\n",
" {0,0,1,0,0},\n",
" {0,0,1,0,0},\n",
" {0,0,1,0,0},\n",
" {0,0,1,0,0},\n",
" {0,0,1,0,0} },\n",
"\n",
" { {0,0,1,0,0},\n",
" {0,1,0,1,0},\n",
" {1,0,0,0,1},\n",
" {1,0,0,0,1},\n",
" {1,1,1,1,1},\n",
" {1,0,0,0,1},\n",
" {1,0,0,0,1} },\n",
"\n",
" { {0,1,1,1,0},\n",
" {1,0,0,0,1},\n",
" {1,0,0,0,1},\n",
" {1,0,0,0,1},\n",
" {1,0,0,0,1},\n",
" {1,0,0,0,1},\n",
" {0,1,1,1,0} }\n",
"}; \n",
" \n",
"static int leds[] = {3,4,5,6,9,8,7}; \n",
"int dir = 1;\n",
"int start_i = 0;\n",
"int start_j = 0;\n",
"static int accPin = A1;\n",
"\n",
"void setup() {\n",
" Serial.begin(9600);\n",
" Serial.println(\"Output acc value\");\n",
" for (int i = 0; i < NUM_OF_LED; i++) {\n",
" pinMode(leds[i], OUTPUT);\n",
" }\n",
"}\n",
"\n",
"void loop() {\n",
" int value = analogRead(accPin);\n",
" // Serial.println(value);\n",
" // delay(100);\n",
" if (abs(value - ZERO) >= SHIKI_CHI) {\n",
" // 方向に合わせて順序を変える\n",
" if (value - ZERO > 0) {\n",
" dir = -1;\n",
" start_j = NUM_OF_WIDTH-1;\n",
" start_i = NUM_OF_CHARS-1;\n",
" }\n",
" else {\n",
" dir = 1;\n",
" start_j = 0;\n",
" start_i = 0;\n",
" }\n",
" int ii = 0;\n",
" int jj = 0;\n",
" for (int i = 0; i < NUM_OF_CHARS; i++) {\n",
" ii = dir < 0 ? start_i - i : 0;\n",
" for (int j = 0; j < NUM_OF_WIDTH; j++) {\n",
" jj = dir < 0 ? start_j - j : 0;\n",
" for (int k = 0; k < NUM_OF_HEIGHT; k++) {\n",
" digitalWrite(leds[k], mojiStr[ii][k][jj]);\n",
" }\n",
" delay(4);\n",
" }\n",
" // 消灯\n",
" for (int k = 0; k < NUM_OF_HEIGHT; k++) {\n",
" digitalWrite(leds[k], 0);\n",
" }\n",
" delay(4);\n",
" }\n",
" // 消灯\n",
" for (int k = 0; k < NUM_OF_HEIGHT; k++) {\n",
" digitalWrite(leds[k], 0);\n",
" }\n",
" }\n",
"}\n",
"```\n",
"\n",
"文字は、はっきりしませんが、以下の様にでました。\n",
"\n",
""
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": true
},
"source": [
"## 脚注\n",
"\n",
"- 1 手元にあった470Ωを使っています\n",
"- 2 秋月のXSC7-2050等も使用可能、ただし軸のピンの配置が異なります"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 2",
"language": "python",
"name": "python2"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.13"
}
},
"nbformat": 4,
"nbformat_minor": 0
}