ブロックとしての考え方
実験編 でサーボモーターを動かし、ボリュームでのAD変換も試しました。それをもっと実用向きに作り変えてみます。
・ボリュームでのAD変換は いろいろなものに使用できるツマミ入力機器に。
→①ボリュームブロック
・サーボ制御ももっと幅広い入力を受けて回転する
→②サーボ動作ブロック
①ボリュームブロックは ボリューム回転に応じた数値を出力するブロック
②サーボ動作ブロックは 数値入力を受けて、サーボが入力数値に応じて回転するブロック
2つのブロックに分けて その結果、2つの出力と入力をつなげてボリュームのツマミの入力を受けてサーボ回転を制御するに改良します。
モジュールに分ける
●考え方
実験編での ● A/D変換機能を使う
で行った可変抵抗(ボリューム)のAD変換は
単純に AD変換
ボリュームを回す → 回し加減で LEDの点灯が変わる
というものでした。
これをもう少し幅広い用途に使えるようボリュームAD変換を改良します。
このような機能にします。
AD変換して
ボリュームを回す → 回し加減に応じた数値を出力する
→ 0~63 など
つまり、ツマミを回せば数値が出力される
ボリュームAD変換を、1つのツマミの入力機器にしてしまう考えです。
単純に、 「ツマミを回せば、その回し加減での数値が出てくる」 というだけですが、
このボリュームAD変換の改良で何が良くなるかというと、より汎用的に使えるようになります。
ボリュームを回す → AD変換値を受け LEDの点灯が変わる
の方法で作ると、ボリュームでモーターを回そうとするときはやってくるAD変換値は モーターとLEDでは同じように動作を調整できないわけで、
ボリュームを回す → AD変換値を受け モーターの回転が変わる
モーター用に回転がうまく変わるよう調節する必要があります
これを各ブロックにして作る
AD変換で数値出力
- ボリュームを回す → 0~63 など
-
- その数値0~64を サーボ動作ブロックに 入れると
- ↓
- 0~64 → サーボ動作ブロック → サーボが64段階に回転
-
出力をモーターへ振り替えて DCモーターブロックに入れると
→ DCモーター速度を調節
のように、 いろいろなブロックに放り込むと、対象を変えられて汎用性があります。
同時に
開発、調整 もブロック(モジュール)ごとにできるので、切り分けが出来てまとまりよくなり、 トラブルもどこに原因があるか わかりやすくなり、保守、改良もしやすくなります。
ボリューム入力のモジュール
単に、ボリュームを回せば、数値が出てくる
このようなものを作るだけで 大して難しいことはないのです
上図では
ツマミを 全閉→全開 にすると出力する数値が 0 → 63 のようになります。
この回した角度の応じて出力する数値を変更できるようにします。
機能
- 入力 : ボリュームを回転させる
- 出力 : ボリュームの回転に応じた数値を出力
- 調節 : 引数で出力数値の範囲を変更できる
AD変換で作成したプログラムを改良します。
- 初期化関数
-
ここでAD変換のレジスタなど初期設定、入力チャンネルを設定します。
入力チャンネルは、AD1、AD2などつなぐチャンネル数なども この関数の引数で簡単に設定できるようにすれば使いやすそうですが、今回は定型の設定をするだけにします
設定は A/D変換機能を使う と同じにします
入力チャンネルは AD1 だけでその初期化設定をする。 - AD変換値出力関数
-
回されたボリュームに応じた数値を返す関数です。
出力は 関数への引数の入力値の設定で7通りの出力範囲 設定 出力値 0~3 0~7 0~15 0~31 0~63 0~127 0~255
回路図
プログラム
FQ_adv_ADsarvo
#include<3664.h>
#include
void ini_AD(void){
AD.ADCSR.BYTE = 0x38; /* 0011 1000*/
/* A/D変換開始 */
/* スキャンモード */
/* 高速変換 */
/* AN0 */
}
int AD_Vlm(int div){
/**************************************
引数 : div (VLキザミ値)
4,8,16,32,64,128,256 で指定
返値 : 0~div を返す
VLボリュームの回転に応じて
**************************************/
int i;
switch(div){
case 4: i=14; break;
case 8: i=13; break;
case 16: i=12; break;
case 32: i=11; break;
case 64: i=10; break;
case 128: i=9 ; break;
case 256: i=8; break;
default: i=14;
}
while(AD.ADCSR.BIT.ADF==0); // 変換結果がでるまで待つ
return( (int)( AD.ADDRA>> i ) ); // ビットシフト(i桁ずらす)
}
void main()
{
int ledp=0 ;
LCD_init( 16 ); //LCD初期化
ini_AD(); //AD変換初期化
while(1){
/*** AD変換関数 ***/
ledp = AD_Vlm( 256 ) ;
/*** AD変換関数 ***/
//LCD表示
LCD_locate(1,2);
LCD_dataout(ledp );
}
}
ツマミの回し量を0~64の数値でLCDに表示するプログラムです。
設定は、AD変換の原理は A/D変換機能を使う と同様です。
- レジスタ関連の設定を ini_AD() にまとめました。
- AD_Vlm( 64 ) でツマミの回し量が数値になり得られます。
引数 64 の数値を以下のように変えることで、出力のキザミ値を変えることができます。
7通りの出力範囲 設定 | |||||||
引数 | 4 | 8 | 16 | 32 | 64 | 128 | 256 |
出力値 | 0~3 | 0~7 | 0~15 | 0~31 | 0~63 | 0~127 | 0~255 |
AD_Vlm( 4 ) とすると
0~3までの出力値、 ツマミをいっぱいまで回しても3の出力値 という具合です。
AD変換の数値化の部分は実験編と同様で、ビットシフトする桁数を変更することで、回した量に応じた出力する数値を変えています。
最後に数値を 確認用にLCDに表示しました。
LCDに表示するためには LCD液晶表示をつける で作った myfunc.h が必要になります。
実行結果
関数 AD_Vlm( 64 ) の64の数値を 上の表の引数のどれかにすることで、出力値範囲を変えられます。
8、16など変えて試すときれいにその範囲になります。256 などにすると、境い目でやはり多少不安定で末桁に振れが見られます。もっと正確さを求めるのなら、改善する必要がありそうです。
* オシロで見たところ、ボリュームからの入力電圧には10mV程度の振れがあります。ハードでやるなら小さな振れなので部品付け足しのような変更では止まらず、電圧入力回路全体を変える必要があるでしょう。
まとめ
ボリュームAD変換関数
- ini_AD() 初期化関数
-
スキャンモード
高速変換
AN0 - AD_Vlm( div ) ボリュームAD変換関数
-
<機能>
入力動作 : ボリュームの回転
出力 : ボリュームの回転に応じた出力値
調節 : 引数divで出力数値の範囲を変更できる
7通りの出力範囲 設定 | |||||||
引数div | 4 | 8 | 16 | 32 | 64 | 128 | 256 |
出力値 | 0~3 | 0~7 | 0~15 | 0~31 | 0~63 | 0~127 | 0~255 |
H8の市販の書籍に、同様のモジュール化を解説した書籍もありますが、本記事群の内容は、それ以前に公開したもの。モジュール,汎化は大規模開発では取り立てて珍しい方法でもありませんが、
その書籍の内容をここで同じように解説したものではないこととは、ここに記しておきます
(6月/2015)
- twtter
- google+
- hatena