1.1 試作ボードとArduino
システムの開発当初は、上図のようにArduinoボードとステッピングモータドライバを使用したボードを考えてボードを試作しました。しかし、この場合、新規にドライバボードを起こすのであればなんの問題もないのですが、開発コストや製造コストを考えた場合にあまり有用とは言えないことは自明の理です。そのため、メインボートはARMまたはそれと同等のMCUが載ったものを想定し、ドライバは既製のものを使用するということを前提としました。
メインボードにPICなどが載ったものを選定しなかった訳は、単にMCU性能がARMなどに比して非常に低いことと、メインボードの選定に苦しむということによります。日本においては、PIC 方がよりポピュラーなMCUで、作成例も多いのはわかっていましたが、ARM系のほうがより開発環境に自由度があることと、開発環境そのものもほとんどが無料で手に入れられることが決め手になった訳です。
また、ARM系のMCUは今後もより多くの器機で使われる可能性が高く、かつ低価格で高性能という様々な利点もあります。ArduinoにはAtmelのチップが載っていますが、このチップは仕様的に見て内部アーキテクチャがARMそのものなので両者の間に共通点が多いことに気づきます。さらに開発環境も同じフリーのコンパイラ(GNU)がベースとなっていますから、ポーティングが比較的容易ということになります。事実、Ejan赤道儀制御システムはARM版とArduino版の二種類がありますがポーティングそのものはそれほどむつかしいものではありませんでした。
要するに、Arduino版は下位バージョンで、ARM版は上位バージョンという位置付けです。機能的に相違はありませんが、機能拡張という面でARMのほうがやや有利というだけです。
<試作ボードの形状:Arduino版>
上側がChibiDuinoというArduino互換ボードで下側は後で説明するEasyDriver-ドライバ(A3967)を使用したモータドライバボードということになります。
このステッピングモータドライバは要するにArduino用のシールドとほぼ同じ機能ということになり、自らが制作するか、シールドを採用するかといった選択肢を迫られることになります。結果的に、私の場合はシールドを選択することにしました。その作例はのちの章で説明していますから、詳細はそちらを参照してください。
さて、最近になって後で示すような複数のステッピングモータを駆動できるシールドが出始めたので、今一度これらを採用したシステムを再考してみようということになりました。それらは3Dプリンタ用に開発されたシールドで、Arduino UNO、MEGAとの相性が良いのです。また、子息ボードで形成された回路をすべて含んでいるわけですから自らこれらのボードを作成する理由が見つかりません。
いずれにせよ、Arduino UNOはメモリ容量と制御ピン数の制限の関係であまり高度で複雑な処理を行うファームウエアには向きませんが、2軸制御できるモータシールドを採用できれば、少なくとも配線の煩雑さの呪縛からは解放されるだけでなく、システムそのものをモジュール化することが可能になります。つまり、簡易自動導入又は追尾制御装置の基板としては非常にコンパクトで価格的にも比較的安価なのは、これらの装置を自作の装置などに組み込むことができる点では非常に好都合なのです。
現在発売されているステッピングモータ・シールドのドライバ・チップとしては、比較的マイクロステップ機能の低いもの、例えばA3967(max 1/8)、A4988(max 1/16)、DRV8825(max 1/32)といったものが主に使われています。これらは、ステッピングモータの駆動能力がやや小さめとはいっても、民生用の汎用コントローラとして実用上問題のないレベルにあるものばかりです。
このような2軸以上の軸制御ができるシールドの場合は、Arduinoボード上のI/Oソケットに乗せることになるので、モータに対する結線以外の配線が基本的に不要になります。その場合、各ソケットに対応したGPIOピンからステッピングモータの信号をダイレクトに操作することができるのでソフトウエア的には非常に好都合なのです。
それでも、このようなモータ・シールドにも問題点が全く無いというわけではありません。というのも、Arduino UNOをメインボードに採用した場合は、前述のように制御ピンに余裕がないのでモータ制御以外の機能を追加することが難しくなってきます。更に、シールド制御機能のピン配置は固定なので、ピン配置が重なるシールド同士は同時に使用することが基本的にできません。もしも、LCD等のシールドを採用することができたとしても、上下方向に3段のボードが重なることになり制御ボックスに入れる場合にはサイズ的に不利になります。
<Arduino UNOの問題点>
1.モータ制御以外の機能を追加するためのGPIOが少ない
2.LCDシールドとステッピングモータとの共存が難しい
3.制御ボックスの形状に制限がある(又は大きくなる)
これらの問題点の内で、少なくとも1と2についてはArduino MEGAボードを採用すれば解消される問題です。しかしながら、その場合でもボックスのサイズが更に大きくなってしまうだけでなく、製作単価も倍くらいになってしまいます。
ということで、Arduino UNOと2軸ステッピングモータ・シールドを採用する赤道儀制御システムを次の様に位置づけて開発したいと考えます。
<Arduino UNOシステムの位置づけ>
1.配布用の入門システムとしての位置づけ
・天体の自動導入と追尾の機能は、上位システムと全く同じです
2.自作のためのキット
・ドイツ式、フォーク及びポンセット等の小型赤道儀の自作用キット
・モータ及びギアの自由な組み合わせの提案
3.上位システムへのスムースな移行への橋渡し
・自動追尾、自動設定、ハンドセットなどを採用したシステムを上位として位置づけ
ます
・上位システムでは、ARMコアのMCUチップの載ったメインボードを採用し、高
機能な性能とステッピングモータ及びドライバの組み合わせが提案されます
このように、機能そのものを限定し小型赤道儀のみを対象とすることをシステムコンセプトに規定してしまえば、前述のようなArduinoとステッピングモータ・ドライバのシールドを採用することで、非常にコンパクトで利用しやすいシステムをユーザに提供できるのではないかと考えます。
8.4 Arduioボードとシールドで赤道儀コントローラを製作
8.4.1 最も単純な赤道儀コントローラを製作する
LCDシールドを使用しない最も単純な構成の赤道儀コントローラは、ステッピングモータを駆動するためのシールドをArduinoボードの上にスタックすることで構成されます。
ArduinoボードはUSB端子を介して上位パソコンと接続され、同時にUSBからの電源とGND信号で駆動されます。ステッピングモータシールドのロジック電源は、Arduinoボードの電源ピンが接続されていることから、パソコン側からの電力がArduinoとシールドの各ボードに供給されることになります。
この形態の制御装置は最もシンプルな構成で製作も簡単ですが、表示装置とキー入力機構がないために、そのままでは手動での赤道儀の回転制御ができません。つまり、手動で赤道儀の回転を行おうとするならば、前述のハンドコントローラをシリアル通信で接続しなくてはならなくなります。更にオートガイダの端子はアナログピン或いはデジタルピンのいずれかを使用することになります。
この形式の制御装置は最もシンプルな構成で製作も簡単です。Arduinoボードの上にステッピングモータ・シールドがスタックされています。この構成では表示装置とキー入力の機構がないことから、このままでは上位パソコンからの自動導入処理と追尾処理を行うだけになってしまいます。もちろん、上位アプリケーションにある手動回転ボタンを使用したソフト的な赤動機の回転操作は可能です。
LCD付きのハンドコントローラをシリアルで本装置につないだ時は、赤道儀の赤経・赤緯両軸の回転操作をハンドコントローラ上のボタンて行うことができるようになります。
図 最も単純な赤道儀コントローラの実体結線図
ピン接続の定義に関しては、ステッピング・モータシールドの仕様を優先に決定しなくてはなりませんが、赤道儀の制御はX,Yの2軸のみで良いので、Z軸やスピンドルモータ用の制御ピンは利用可能なのです。機能追加を行う場合のピン配置はこれら未使用のものに対して行なわなくてはなりません。
また、他のシステムで配置されているハードシリアル通信線( RX 受信信号線,TX 送信信号線)の信号ピンD2,D3は、このハード構成ではシールドのモータの制御(ステップ、回転)信号に使われていますから使用することができなくなっています。
そのため、ハードシリアル通信線(RX:受信信号線,TX:送信信号線)の信号ピンを新たに設定しなくてはなりません。ピンは当然のことながら空きポートが対象になるのですが、できる限りモータ等の出力信号ピンに隣接してシールド上に出ているほうが好ましいのです。このことから、使用できそうなピンはD4,D7のペアか、D11,D12のペアのいずれかということになります。どちらの組み合わせでも本来かまわないのですが、他のシステムとの整合性からD4,D7のペアの信号ピンを使用することにします。これらの信号ピンの出力位置は、X,Yモータ制御ピンのすぐ横に位置していますから、結線的にも好ましい位置にあります。(D11,D12の信号ピンはこれらの反対側の基板位置にあります)
表 最も単純な赤道儀コントローラのピン定義例
<Arduinoピン番号> <表記> <操 作 仕 様>
デジタル ピン0 D0 シリアル通信 RX 受信信号線
デジタル ピン1 D1 シリアル通信 TX 送信信号線
デジタル ピン2 D2 X軸 ステップ信号:X軸回転ステップ信号出力ポート
デジタル ピン3 D3 Y軸 ステップ信号:Y軸回転ステップ信号出力ポート
デジタル ピン4 D4 ハードシリアル通信 RX受信信号線(Z軸ステップ信号)
デジタル ピン5 D5 X軸 回転方向信号: X軸回転方向信号の出力ポート
デジタル ピン6 D6 Y軸 回転方向信号: Y軸回転方向信号の出力ポート
デジタル ピン7 D7 ハードシリアル通信 TX送信信号線(Z軸回転方向信号)
デジタル ピン8 D8 イネーブル信号:High信号で全機能が有効になります
デジタル ピン9 D9 未使用:X軸 エンドストップ:X軸の終端位置に達した
デジタル ピン10 D10 未使用:Y軸 エンドストップ:Y軸の終端位置に達した
デジタル ピン11 D11 未使用:Z軸 エンドストップ:Z軸の終端位置に達した
デジタル ピン12 D12 未使用:スピンドルモータ イネーブル信号
デジタル ピン13 D13 未使用:スピンドルモータ 回転方向
アナログ ピン0 A0/D14 未設定:アボート信号・デジタル信号の他用途で使用可能
アナログ ピン1 A1/D15 未設定:ホールド信号・デジタル信号の他用途で使用可能
アナログ ピン2 A2/D16 未設定:レジューム信号・デジタル信号の他用途で使用可能
アナログ ピン3 A3/D17 未設定:クーラント信号・デジタル信号の他用途で使用可能
アナログ ピン4 A4/D18 未設定:アナログ/デジタル信号の他用途で使用可能
アナログ ピン5 A5/D19 未設定:アナログ/デジタル信号の他用途で使用可能
GND 共通GND信号
Arduino: Pin4,Pin7 ------- ハードシリアル信号 使用予定
Pin9~Pin19------- 未使用,任意機能の設定可能
*ステッピングモータの制御はモータシールドからの出力ピンで制御します。
更にメイン電源はUSBコントローラから供給されます。
< Arduino Megaの最も単純な赤道儀コントローラの実体結線図 >
Arduino Megaボードの上にステッピングモータシールドが積み重ねられており、シールドはMegaのボートのUnoと互換部分上にスタックされてピン接続されてています。
Mega ボードはUnoよりも幾分サイズが大きくなっています。
この形式の制御装置は最もシンプルな構成で製作も簡単です。表示装置とキー入力の機構がないことから、このままでは上位パソコンからの自動導入処理と追尾処理を行うだけになってしまいます。もちろん、上位アプリケーションにある手動回転ボタンを使用したソフト的な赤動機の回転操作は可能です。
LCD付きのハンドコントローラをシリアルで本装置につないだ時は、赤道儀の赤経・赤緯両軸の回転操作をハンドコントローラ上のボタンて行うことができるようになります。
Arduino Megaボードとの組み合わせの最大の利点は、プログラム用のフラッシュ領域が大きく、EEPROM利用域も拡大していることです。このため、Unoにあるようなシステム開発におけるファームサイズの制約がなくなり、様々な機能追加が可能になります。
E-Zeusシステムではオブジェクトサイズそのものが比較的小さいので、このメモリの問題はありません。しかし、LX200システムではコントローラ側で行なう処理が多いために、rduino Unoを採用するシステムでは天体の自動導入と追尾の機能しか提供できません。
8.4.2 DFrobot LCDシールドとキースイッチ制御
ArduinoのLCDシールドには、下図 に示すようなタクトスイッチ形式の入力スイッチのあるものがあります。このボタンはタクトスイッチと抵抗で構成された入力電圧の検出によりキー判定を行うものです。5V電源とGNDの間には所定の抵抗が直列に入れられ、その抵抗間にそれぞれ各ボタン端子が入り、R2の終端にアナログA0ピンが接続されています。
キースイッチは5つあり、便宜上RIGHT(右),LEFT(左),UP(上),DOWN(下),SERECT(選択)というように表記付けされていますが、実質的な機能には何ら規定はありませんからユーザが任意の処理をしても良いということは言うまでもありません。要するに、キーボタンの位置を示す必要性からこれらの名前が付けらりたものと思えばよいのです。
さて、図 のA/D変換回路にあるように各キーボタンが押されると、VCCに対してR2と各ボタンまでの抵抗値で分圧された所定の電圧がA0にかかります。LCDシールド用のファームウエアはこのときのA0にかかる電圧をA/D変換したデジタル値からボタン位置を検出するわけです。その時のキーボタンのデジタル値は抵抗の組み合わせで確定検出の値が異なることになります。
図 DFrobot LCDシールドの形状と拡張端子の形態
< LCDシールドとキースイッチのピン配置 >
<LCDシールド Ver.1.1のA/D変換回路>
<LCDシールド Ver.1.0 のデジタル変換値>
RIGHT = 0
UP = R3 / (R2+R3)*1023 = 98
DOWN = (R3+R4) / (R2+R3+R4)*1023 = 254
LEFT = (R3+R4+R5) / (R2+R3+R4+R5)*1023 = 408
SELECT = (R3+R4+R5+R6) / (R2+R3+R4+R5+R6)*1023 = 639
<LCDシールド Ver.1.1 のデジタル変換値>
RIGHT = 0
UP = R3 / (R2+R3)*1023 = 330 / (2330)*1023 = 144
DOWN = (R3+R4) / (R2+R3+R4)*1023 = 950 / (2950)*1023 = 329
LEFT = (R3+R4+R5) / (R2+R3+R4+R5)*1023 = 1950 / (3950)*1023 = 505
SELECT = (R3+R4+R5+R6) / (R2+R3+R4+R5+R6)*1023 = 5250 / (7250)*1023 = 740
LCDシールドVer.1.0の抵抗値は不明ですが、Ver.1.1は仕様が分かりましたのでその値で実計算してみました。
この計算のようにシールドでA/D変換されたデジタル値は各ボタンとGND間に入れられた抵抗の値により変化します。上図 には LCDシールド Ver.1.1のA/D変換回路図が載っていますが、この抵抗値から計算された各ボタン押下時のデジタル値が計算されています。
Arduinoのシールドは必ずしも仕様統一になっているわけではなく、デファクト(業界標準)的な機器のバージョン設計に準拠しているだけなので、メーカーによりこのデジタル値が若干異なっているかもしれません。特に互換機メーカのものは、オープンハードの回路図が標準的に使用されていても、個々の細かい仕様が規定されてはいませんから必ずしも同じ仕様で作成されているとはかぎりません。そのような場合には以下で示す<LCDの表示とキースイッチのA/D変換値検査テスト>スケッチで簡単にキースイッチの値を確認することができます。実際に使用するシールドのバージョンが分かっている場合でも、一度各キーの変換値を確認しておくとよいでしょう。
DFrobotのLCDシールドは下表 で示す通り、Arduinoにスタックした場合のピン番号はD4からD7の4ピンを使用して表示データを4ビットずつ転送し、ピン番号D8からD10まではLCDの制御信号に使っています。A0ピンは上述の5つのキースイッチ入力用に使用されています。それ以外の使用可能なピンについては、前図 で示すように基板上にそれらの信号がまとめて出力されています。
表 DFrobotのLCDシールドのピン定義
<Arduinoピン番号> A0 <機能> アナログ端子A0
<詳細> 上下左右選択ボタン:A0端子の電圧を10ビットAD変換した値Adnで入力されたキーを判定する。(10ビット変換は0V~5Vを0~1023の値に変換する)
Adn <50(50) ・・・・ RIGHT(右)ボタンが押下された
Adn <195(250)・・・・ Up(右)ボタンが押下された
Adn <380(450)・・・・ DOUN(下)ボタンが押下された
Adn <555(650)・・・・ LEFT(左)ボタンが押下された
Adn <790(850)・・・・ SELECT(選択)ボタンが押下された
Ver.1.1(Ver.1.0)での制御値を表しています
<Arduinoピン番号> D4~D7 <機能> DB4~DB7
<詳細> 4ビット転送時のデータビットポート
<Arduinoピン番号> D8 <機能> RS
データかコマンドセクション下の種別
<Arduinoピン番号> D9 <機能> イネーブル(enable)
’1’:LCD有効, ’0’:LCD無効
<Arduinoピン番号> D10 <機能> バックライト制御
バックライト輝度調整 255(高輝度)~0:バックライトオフ
D/A変換によって輝度の調整を行っている
<Arduinoピン番号> D0 <機能> RX(シリアル受信)
<詳細> 未接続:LCDシールドでは使用されていないデジタルポート。
図 に示すようにこれらのピンは、本シールドで使われていないGPIOピンが出力されている。前図の右上部に拡張用に7ピン(2.54ピッチ)分がまとめて配置されている。
<Arduinoピン番号> D1 <機能> TX(シリアル送信)
<Arduinoピン番号> D2,D3
<Arduinoピン番号> D11~D13
<Arduinoピン番号> A1~A5 <機能> アナログ端子
<詳細> 未接続:LCDシールドでは使用されていないアナログポート。
図の右下部に拡張用の端子が5ピン(2.54ピッチ)分が配置されている
Arduinoの良い点はこれらのポートを直接制御することなく、LCDライブラリとアナログ関数を使用することで間接的にシールドの操作を行うことができることです。様々なデバイスに対する組み込み的な処理手法は学べませんが、それでもとりあえず動くものは作ることでできます。
前述のシールドのキー入力によるA/D変換に関しても、押下キーの判別に関しても非常に簡単な方法でおこなうことができます。入力されたキーはシールドからのA0ピンに印加する電圧として認識され、その電圧をA/D変換した値をanalogRead()関数を使用して取得した後にその値の大きさでキー判定を行います。
analogRead()関数を使用した例が関数仕様に示されており、このプログラムによるキー入力のA/D値が前表のLCDシールド Ver.1.0のデジタル変換値で示された値です。このシールドは互換シールドでかつやや古いもののようなのでこのような結果になりました。現在販売中のシールドにおけるキー入力の値はLCDシールド Ver.1.1のデジタル変換値で示す値になっています。
<関数の機能> 指定したアナログピン(pin)からデジタル変換された値を読み取ります。
Arduinoボードは6チャネル(miniは8チャネル、Megaは16チャネル)の10ビットA/Dコンバータを搭載しています(ADはAnalog to Digitalの略)。
これにより、0から5ボルトのアナログ入力電圧を0から1023のデジタル数値に変換することができます。分解能は1変換単位あたり4.4mVとなります。
また、変換処理にかかる時間は約100μ秒(0.0001秒)で、つまり、毎秒1万回が読み取りレートの上限ということになります。
<構文> analogRead(pin)
<引数> pin : アナログ電圧の読み取りに使いたいデジタルピンの番号を整数で指定します。
ほとんどのArduinoボードでは0から5が有効な数値です。
Arduino miniのようなQFPタイプのATmega168を搭載しているボードでは、0から7のピン番号が有効です。
<戻り値> 0から5ボルトのアナログ入力電圧が、デジタル変換された0から1023までの整数値
< 使 用 例>
// LCDの表示とキースイッチのA/D変換値検査テスト
// キーが押されている間だけそのキーのA/D変換値が表示されます
// create by Unicof Y. Odanaga 2015/09/29
#include <LiquidCrystal.h>
// LCD制御ピンの設定
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
// 入力キーデータ
int pre_keyin = 0; // 直前キーデータ
int adc_keyin = 0; // 入力キーデータ
void setup()
{
lcd.begin(16, 2); // 16文字×2行に設定
lcd.setCursor(0,0); // カーソル(描画開始)位置
lcd.print("LCD Key ADC Test"); // LCD表示 "LCD Key ADC Test"
pre_keyin = analogRead(0); // A0データ読み込み(初期値)
}
void loop()
{
delay(50); // 50mS 遅延
adc_keyin = analogRead(0); // A0データ読み込み
lcd.setCursor(0,1); // 0文字、一行目カーソル移動
if (pre_keyin != adc_keyin ) {
lcd.setCursor(0,1); // 0文字、一行目カーソル移動
lcd.print(" "); // 行クリア
lcd.setCursor(0,1); // 0文字、一行目カーソル移動
//
if (adc_keyin > 1000) {
lcd.print("Non key "); // キー
} else {
lcd.print("Push key "); // キー押下
}
lcd.print(adc_keyin); // A0データ読み込み値の表示
pre_keyin = adc_keyin; // 直前読み込みデータの設定
}
}
<関数の機能> 指定したアナログピン(pin:パラメータの項を参照する)に所定のデューティー値(value:パラメータの項を参照)でアナログ信号を出力します。
下記の例にあるようにLEDのバックライト輝度の増減やアナログモータの回転制御に利用することができます。
アナログピンの電圧はPWM操作によりデューティーで指定された電圧の矩形波を出力し続けます。
大方のアナログピンPWM信号の周波数はおよそ490Hzです。
ただし、ピン番号5,6のPWM信号の周波数はおよそ980Hzです。
Leonaldのピン番号3,11のPWM信号の周波数はおよそ980Hzです。
通常、ピンはデジタルピンとして扱われますのでアナログ出力を行う様にピン設定を行う必要がありますが、このコマンドを使用する限りピン機能の設定関数pinMode()を使用しなくても良いので便利です。
<構文> analogWrite( pin, value )
<引数> pin : アナログ電圧の出力に使いたいデジタルピンの番号を整数で指定します。
Arduinoボードに搭載されたMPUにより有効なピン値は異なっています。
・ATmega8の場合は、ピン番号9,10,11が使用できます
・ATmega168の場合は、ピン番号3,5,6,9,10,11が使用できます
・ATmega328の場合は、ピン番号3,5,6,9,10,11が使用できます
・ATmega Megaの場合は、ピン番号2~13が使用できます
Arduino Dueボードににおいてはピン番号2~13の他にDAC0とDAC1がサポートされ、これらのポートはPWM操作ではなくDA(Digital to Analog)アナログコンバータによる純粋なアナログ出力が可能になっています。
Value : PWM操作のデューティー比で、電源電圧が5Vの場合は0(0V)から255(5V)までの値を指定できます。電源電圧が3.3Vの場合は0(0V)から255(3.3V)の値として電圧出力されます。
<戻り値> なし
<使 用 例 >
//-----------------------------------------------------------------
// LCDの表示とキースイッチのA/D変換値検査テスト
// キーが押されている間だけそのキーのA/D変換値が表示されます
// UPキーでLCDの輝度が増加するように動作します
// DOUNキーでLCDの輝度が減少するように動作します
// created by Unicof Y. Odanaga 2015/10/01
//-----------------------------------------------------------------
#include <LiquidCrystal.h>
//-----------------------------------------------------------------
// LCD制御ピンの番号設定
#define BACKLIGHT 10 // Minimum Back light ADC count
#define RIGHT_KEY 1 // Key No. RIGHT KEY
#define UP_KEY 2 // Key No. UP KEY
#define DOWN_KEY 3 // Key No. DOWN KEY
#define LEFT_KEY 4 // Key No. LEFT KEY
#define SELECT_KEY 5 // Key No. SELECT KEY
#define NONE_KEY 0 // Key No. NON KEY
//-----------------------------------------------------------------
// LCD Version 1.00 or 1.1
#define LCD_VERSION 100 // シールドのバージョン
#define ACD_NONE_KEY 1000 // キーが押されないときの検査値
#if LCD_VERSION == 100
#define ACD_RIGHT_KEY 50 // Ver. 1.00 ADC count of RIGHT KET
#define ACD_UP_KEY 195 // Ver. 1.00 ADC count of UP KET
#define ACD_DOWN_KEY 380 // Ver. 1.00 ADC count of DOWN KET
#define ACD_LEFT_KEY 555 // Ver. 1.00 ADC count of LEFT KET
#define ACD_SELECT_KEY 790 // Ver. 1.00 ADC count of SELECT KET
#else
#define ACD_RIGHT_KEY 50 // Ver. 1.10 ADC count of RIGHT KET
#define ACD_UP_KEY 250 // Ver. 1.10 ADC count of UP KET
#define ACD_DOWN_KEY 450 // Ver. 1.10 ADC count of DOWN KE
#define ACD_LEFT_KEY 650 // Ver. 1.10 ADC count of LEFT KET
#define ACD_SELECT_KEY 850 // Ver. 1.10 ADC count of SELECT KET
#endif
//-----------------------------------------------------------------
//LCD pIN select
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
//-----------------------------------------------------------------
// 入力キーデータ
int brightness = 255;//バックライト輝度
int pre_keyin = 0; // 直前キーデータ
int adc_keyin = 0; // 入力キーデータ// read the buttons
int LCD_Keyin()
{
int keytype;
//
adc_keyin = analogRead(0); // A0データ読み込み
lcd.setCursor(0,1); // 0文字、一行目カーソル移動
if (pre_keyin != adc_keyin ) {
lcd.setCursor(0,1); // 0文字、一行目カーソル移動
lcd.print(" "); // 行クリア
lcd.setCursor(0,1); // 0文字、一行目カーソル移動
//
if (adc_keyin > ACD_NONE_KEY) {
lcd.print("None key "); // キー
keytype = NONE_KEY;
} else {
lcd.print("Push key "); // キー押下
if (adc_keyin < ACD_RIGHT_KEY) {
keytype = RIGHT_KEY;
} else if (adc_keyin < ACD_UP_KEY) {
keytype = UP_KEY;
} else if (adc_keyin < ACD_DOWN_KEY) {
keytype = DOWN_KEY;
} else if (adc_keyin < ACD_LEFT_KEY) {
keytype = LEFT_KEY;
} else {
keytype = SELECT_KEY;
}
}
lcd.print(adc_keyin); // A0データ読み込み値の表示
pre_keyin = adc_keyin; // 直前読み込みデータの設定
}
return( keytype );
}
//-----------------------------------------------------------------
void setup()
{
lcd.begin(16, 2); // 16文字×2行に設定
lcd.setCursor(0,0); // カーソル(描画開始)位置
lcd.print("LCD BL Test "); // LCD表示 "LCD Key ADC Test"
pre_keyin = analogRead(0); // A0データ読み込み(初期値)
analogWrite(BACKLIGHT, brightness);
lcd.setCursor(12,0); // カーソル(描画開始)位置
lcd.print( brightness ); // LCD表示 輝度値表示
}
//-----------------------------------------------------------------
// バックライトの輝度調整テスト & 入力キーADC変換値表示
//
void loop()
{
delay(200); // 遅延
switch ( LCD_Keyin() )
{
case RIGHT_KEY:
break;
case UP_KEY :
brightness += 10;
if (brightness > 255) brightness = 255;
analogWrite(BACKLIGHT, brightness);
lcd.setCursor(12,0); // カーソル(描画開始)位置
lcd.print( " " ); // データ消去
lcd.setCursor(12,0); // カーソル(描画開始)位置
lcd.print( brightness ); // LCD表示 輝度値表示
break;
case DOWN_KEY :
brightness -= 10;
if (brightness < 10) brightness = 10;
analogWrite(BACKLIGHT, brightness);
lcd.setCursor(12,0); // カーソル(描画開始)位置
lcd.print( " " ); // データ消去
lcd.setCursor(12,0); // カーソル(描画開始)位置
lcd.print( brightness ); // LCD表示 輝度値表示
break;
case LEFT_KEY : break;
case SELECT_KEY : break;
default: break;
}
}
analogWrite()関数を用いることで、ピン位置はMCUにより固定されていますが、デジタル情報値をアナログ信号電圧に変換して出力することができます。アナログ信号はこの関数の第2パラメータvalue変化させることで特定な電圧の矩形信号を出力し続けることができます。概ねvalue値(0~255)で電源電圧を分割した値の電圧をこれらのピンに出力することができます。上記analogWrite()関数の使用例はキーUPとDOWNに合わせてこの電圧変化によりLCDのバックライト輝度を増減するようにプログラムされています。これはLCDシールドのバックライト調整信号線がピン番号10に接続されているために可能となっています。天体観測における機器のライト制御は必要なことなので、そのような機能として利用法することができそうです。
また、アナログ系のモータは電圧制御により回転速度を変化させることができますから、この機能を使ってモータ回転制御を行うことができます。
0コメント