{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"オリジナルの作成:2014/12/29"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 0E-GMC4をArduinoで作ってみる\n",
"## GMC-4との出会い\n",
"私が最初にマイコンを見たのが、「秋葉原のBIT-INN」に展示されていたTK-80でした。\n",
"\n",
"\n",
"\n",
"この基板の上にテンキーと7セグメントLEDが8個付いたのが、コンピューターかと思われるかも 知れませんが、初期のマイコンはテンキーを使って直接マシン語を打ち込んでプログラムを 入力していました。 \n",
"\n",
"2009年6月に学研の「大人の科学Vol.24」 にTK-80を思わせる4-bitマイコンGMC-4が付録に付いてきたので、すぐに購入しました。\n",
"\n",
"\n",
"\n",
"そこで、GMC-4用にC言語ライクな簡易言語コンパイラーを作った記事が \n",
"[GMC-4コンパイラー](http://www.pwv.co.jp/~take/TakeWiki/index.php?GMC-4%E3%82%B3%E3%83%B3%E3%83%91%E3%82%A4%E3%83%A9%E3%83%BC)\n",
"です。\n",
"\n",
"この時は、アセンブラからマシン語に手で変換して、プログラムを組むことが大変だと思って 簡易言語のコンパイラーを1日仕事で作って公開しました。\n",
"\n",
"## Arduinoを使ってGMC-4を作る\n",
"Arduino勉強会で何を作りたいかと聞かれ、とっさに「GMC-4をArduinoで作ってみたい」と答えた のは、GMC-4を子供たちが作って、キーボードからプログラムを入力したら、マイコンのイメージ が変わるのではないかと思ったからです。\n",
"\n",
"### Arduino版GMC-4の部品\n",
"Arduino版GMC-4には、1個の7セグメントLEDと7個のLED、そして20個のタクトスイッチに 2個のトランジスタと10個の抵抗をユニバーサル基板に載せただけのとても簡単なものです。 後はArduinoのプログラムですべて処理します。\n",
"\n",
""
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 回路図\n",
"7セグメントの接続が画像と異なりますが、KiCADの練習で回路を書きました。\n",
"(ikkei blogの\n",
"[4×4のキーパッドを試してみた](http://blog.goo.ne.jp/jh3kxm/e/0a71a45afbed826346d605347b83ded0)\n",
"から引用)\n",
"\n",
"- [fileGMC-4_sch.pdf](data/GMC-4_sch.pdf)\n",
"\n",
"ついでに、プリント基板のパターンを作りました。\n",
"\n",
"\n",
"\n",
"現バージョンのボードの配線は、以下の通りです。\n",
"\n",
"\n",
"\n",
"\n",
"### キーボードは配線だけ \n",
"Arduinoのライブラリにkeypadがあり、これはタクトスイッチを以下の様に配線するだけで マトリックスキーボードを作ることができる素晴らしいクラスです。\n",
"\n",
""
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## スケッチの作成\n",
"ハードは下手くそでもソフトなら大丈夫ということで、以下のクラスを用意しました。\n",
"\n",
"- キーボード: KeyBoard.h\n",
"- 7セグメントLED: LED7Seg.h\n",
"- LEDアレイ: LEDArray.h\n",
"\n",
"### KeyBoard.h\n",
"KeyBoard.hでは、Keypadに渡す、キーマップと、入力文字から値を取り出すgetCode、キーが押されているかどうか 調べるisPressedメソッドを用意しました。\n",
"\n",
"- [KeyBoard.h](code/0E/KeyBoard.h)\n",
"\n",
"### LED7Seg.h\n",
"7セグメントLEDとLEDアレイは、交互に表示するため、on、offのメソッドと値をセットするdrawメソッド 用意しました。\n",
"\n",
"- [LED7Seg.h](code/0E/LED7Seg.h)\n",
"\n",
"### LEDArray.h\n",
"LEDアレイは、アドレスを表示するために使用するので、setAddressとgetAddressメソッドで値の読み書きをしています。\n",
"\n",
"- [LEDArray.h](code/0E/LEDArray.h)\n",
"\n",
"### GMC4.h\n",
"GMC4をシミュレーションしているのが、GMC4.hに定義されているGMC4クラスです。 この中の、stepメソッドが1命令毎に処理するメソッドです。\n",
"\n",
"GMC4.hの処理を理解するには、\n",
"[FX-マイコン・全マニュアル](http://otonanokagaku.net/magazine/vol24/pdf/vol24manual.pdf)\n",
"を参照してください。 \n",
"\n",
"- [GMC4.h](code/0E/GMC4.h)\n",
"\n",
"### メインのスケッチ\n",
"メインのスケッチだけ、ソースをそのまま示します。 処理としては、キーボードからの入力に対する処理の切替をしているだけですが、 一つだけオリジナルのGMC4と異なる点があります。\n",
"\n",
"それは、Arduinoのシリアルモニターを使ってGMC4用の機械語をパソコンから入力できることです。 これによってプログラムの確認がとても簡単になりました!\n",
"\n",
"```C++\n",
"#include \n",
"#include \n",
"#include \"GMC4.h\"\n",
"\n",
"SoftwareSerial mySerial(0, 11); // RX, TX\n",
"\n",
"LEDArray ledArray;\n",
"LED7Seg led7Seg;\n",
"KeyBoard keyBoard;\n",
"GMC4 gmc4(&keyBoard, &ledArray, &led7Seg);\n",
"\n",
"\n",
"byte lastCode;\n",
"byte addr;\n",
"byte mode;\n",
"byte key;\n",
"\n",
"void setup() {\n",
" mySerial.begin(9600);\n",
" lastCode = gmc4.resetAll();\n",
" ledArray.setAddress(0);\n",
" led7Seg.setValue(0xF);\n",
" mode = PROGRAM;\n",
"}\n",
"\n",
"void readProgram() {\n",
" while(mySerial.available()) {\n",
" key = mySerial.read();\n",
" if (key >= '0' && key <= '9')\n",
" lastCode = key - '0';\n",
" else if (key >= 'A' && key <= 'F')\n",
" lastCode = key - 'A' + 10;\n",
" else if (key == 'T') {\n",
" gmc4.longTone();\n",
" lastCode = gmc4.reset();\n",
" ledArray.setAddress(gmc4.getAddr());\n",
" led7Seg.setValue(lastCode);\n",
" mode = PROGRAM; \n",
" }\n",
" lastCode = gmc4.incr(lastCode);\n",
" ledArray.setAddress(gmc4.getAddr());\n",
" led7Seg.setValue(lastCode); \n",
" }\n",
"}\n",
"\n",
"void loop() {\n",
" if (mode == PROGRAM || mode == STEP_LedOffBeepOff || mode == STEP_LedOnBeepOn) {\n",
" if (mySerial.available())\n",
" readProgram();\n",
" else\n",
" key = gmc4.getKey();\n",
" \n",
" if (key != NO_KEY) {\n",
" if ((key >= '0' && key <= '9') || (key >= 'A' && key <= 'F')) {\n",
" addr = (lastCode > 0) ? lastCode << 4 : 0;\n",
" lastCode = gmc4.getCode();\n",
" addr += lastCode;\n",
" led7Seg.setValue(lastCode);\n",
" }\n",
" else {\n",
" switch (key) {\n",
" case 'S': // A SET\n",
" lastCode = gmc4.addrSet(addr);\n",
" ledArray.setAddress(gmc4.getAddr());\n",
" led7Seg.setValue(lastCode);\n",
" break;\n",
" case 'I': // INCR\n",
" if(mode == PROGRAM) {\n",
" lastCode = gmc4.incr(lastCode);\n",
" ledArray.setAddress(gmc4.getAddr());\n",
" led7Seg.setValue(lastCode); \n",
" }\n",
" else if (mode == STEP_LedOffBeepOff || mode == STEP_LedOnBeepOn) {\n",
" mode = gmc4.step();\n",
" if (mode == STEP_LedOnBeepOn)\n",
" ledArray.setAddress(gmc4.getAddr());\n",
" }\n",
" break;\n",
" case 'R': // RUN\n",
" switch (lastCode) {\n",
" case 1:\n",
" mode = RUN_LedOffBeepOff;\n",
" break;\n",
" case 2:\n",
" mode = RUN_LedOnBeepOff;\n",
" break;\n",
" case 5:\n",
" mode = STEP_LedOffBeepOff;\n",
" break;\n",
" case 6:\n",
" mode = STEP_LedOnBeepOn;\n",
" break;\n",
" default:\n",
" mode = RUN_LedOnBeepOn;\n",
" }\n",
" gmc4.reset();\n",
" ledArray.setAddress(gmc4.getAddr());\n",
" gmc4.setMode(mode);\n",
" break;\n",
" case 'T': // RESET\n",
" gmc4.longTone();\n",
" lastCode = gmc4.reset();\n",
" ledArray.setAddress(gmc4.getAddr());\n",
" led7Seg.setValue(lastCode);\n",
" mode = PROGRAM; \n",
" break; \n",
" }\n",
" addr = 0;\n",
" }\n",
" }\n",
" }\n",
" else {\n",
" mode = gmc4.step();\n",
" }\n",
" gmc4.draw();\n",
"}\n",
"```\n",
"\n",
"GMC4のスケッチは、以下のファイルをダウンロードしてください。\n",
"\n",
"- [GMC4Main.zip](data/GMC4Main.zip)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### デバッグの方法\n",
"GMC4のようなシミュレータをArduinoで作る場合、デバッグがとても大変になります。\n",
"\n",
"GMC4.hのデバッグは、MacOSのEclipseでダミーのKeyBoard, LED7Seg, LEDArrayを用意して 行いました。\n",
"\n",
"参考として以下にソースを置いておきます。\n",
"\n",
"- [GMC4_Mac.zip](data/GMC4_Mac.zip)\n",
"\n",
"### 動作確認\n",
"プログラムの動作を確認するため、FX-マイコン・全マニュアルの以下のサンプルで動作を確かめました。\n",
"\n",
"- No. 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32\n",
"- No. 43, 44, 45, 46, 47, 48, 49, 50, 67, 68, 69, 70, 71, 72, 73\n",
"\n",
"以下に大人の科学のProgram1 15秒カウンタを動かしたときの画像とFacebookの動画のURLを 示します。\n",
"\n",
"GMC4のプログラムは、以下の通りです。\n",
"\n",
" | アドレス\t | 命令記号\t | 命令コード | \n",
" |---|---|---|\n",
" | 01\t | TIY\t | A | \n",
" | 01\t | 1\t | 1 | \n",
" | 02\t | TIA\t | 8 | \n",
" | 03\t | 9\t | 9 | \n",
" | 04\t | CAL\t | E | \n",
" | 05\t | TIMR\t | C | \n",
" | 06\t | CY\t | 3 | \n",
" | 07\t | AO\t | 1 | \n",
" | 08\t | CY\t | 3 | \n",
" | 09\t | CAL\t | E | \n",
" | 0A\t | SHTS\t | 9 | \n",
" | 0B\t | AIY\t | B | \n",
" | 0C\t | 1\t | 1 | \n",
" | 0D\t | JUMP\t | F | \n",
" | 0E\t | 1\t | 1 | \n",
" | 0F\t | 3\t | 3 | \n",
" | 10\t | JUMP\t | F | \n",
" | 11\t | 0\t | 0 | \n",
" | 12\t | 2\t | 2 | \n",
" | 13\t | CAL\t | E | \n",
" | 14\t | ENDS\t | 7 | \n",
" | 15\t | JUMP\t | F | \n",
" | 16\t | 1\t | 1 | \n",
" | 17\t | 5\t | 5 | \n",
" \n",
"最後に、Resetボタンを押します。\n",
"\n",
"Arduinoのシリアルモニターから入力する場合には、上記の命令コードを並べて入力し、最後にTを付けます。\n",
"\n",
"```\n",
"A189EC313E9B1F13F02E7F15T\n",
"```\n",
"\n",
"実行するには、Runボタンを押します。\n",
"\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"facebook URL\n",
"- https://www.facebook.com/hiroshi.takemoto.94/videos/721780911262271/\n",
"\n",
"\n",
"## lbeDuinoを使った2号機\n",
"lbeDuinoを使った2号機の記事を以下にまとめました。\n",
"\n",
"- Arduino勉強会/0L-lbeDuinoで2代目GMC4を作ってみる"
]
},
{
"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
}