{ "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 }