目次
前
次
ライントレーサ制御基板テスト
大学での非常勤講師を担当しているときは
学生の興味をひくように、ライントレーサ
の制御を取り入れています。
センサーからの情報を入力し、モータにパラメータを
与えて、ラインをなぞります。
ライントレーサを制御するために、使う基板は以下。
この基板は、2000年前後に設計、開発したものですが
発注者からは、コネクタを使い、どんなコンピュータ
でも接続できるようにという要求がありました。
LEDからテストしていきます。
ポートB、Cに0を出力して、方向は出力に。
0 PORTB c!{enter}
0 PORTC c!{enter}
$ff DDRB c!{enter}
$ff DDRC c!{enter}
LEDは負論理を採用しています。
次のタイピングで動作確認。
1 $ff xor dup PORTB c! PORTC c!{enter}
2 $ff xor dup PORTB c! PORTC c!{enter}
4 $ff xor dup PORTB c! PORTC c!{enter}
8 $ff xor dup PORTB c! PORTC c!{enter}
16 $ff xor dup PORTB c! PORTC c!{enter}
32 $ff xor dup PORTB c! PORTC c!{enter}
動作確認できたならば、ワードを定義して
テストを自動化しておきます。
: chk.led 33 0 do i dup . cr $ff xor dup PORTB c! PORTC c! loop ;
LSBからMSBに向けて、点灯となるLEDを変化させます。
単純動作を実現するワードですが、基板上の部品や
結線を確認するのには必須なのです。
ハードウエアが正しく動作して、はじめてソフトウエアが
活きるので、単純動作のワードであってもテストデバッグ
ができることは、トラブルシューティングの重要アイテム。
今回は、赤LEDブロックに電源が供給されていない
ことを発見するのに、役に立ちました。
Arduino互換基板から、10ピンワイヤーケーブルで電源と
信号を渡しています。
電源のプラス側の配線が切れた状態であったので半田付け
して修正できました。
AmForthはATmega328を利用しているので、内蔵タイマーを
利用したPWM波形を生成できます。
PWM波形を生成すると、制御基板上にあるモータードライブ
回路とLEDの動作をテストできます。
制御基板上の等価回路は、以下。
ATmega328は、ポートBにタイマー出力を持っています。
タイマー出力を使い、PWM波形をMOSFETかLEDに接続すると
モータの回転、LEDの点滅を確認できることに。
ピン配置は、制御基板に合わせなければなりませんが
10ピンケーブルとブレッドワイヤーを使い、両方基板
での半田付けによる信号線の付け替えをしません。
10ピンケーブルとブレッドボードワイヤーは
以下のものを使うことに。
ATmega328と制御基板の接続は、以下とします。
ケーブルとワイヤーを用意したなら、AmForthでの
タイマー処理を考えます。AmForthに関係するWEB
サイトでタイマー0の動かし方のサンプルワード
を見つけました。
\ TIMER_0 example
\
\ provides
\ timer0.tick -- increasing ticker
variable timer0.tick
: timer0.isr
1 timer0.tick +!
;
: timer0.init ( preload -- )
0 timer0.tick !
6 TCNT0 c! \ preload
['] timer0.isr TIMER0_OVFAddr int!
;
\ some settings for 8bit timer to get 1ms ticks
\ f_cpu prescaler preload
\ 16MHz 64 6
: timer0.start
0 timer0.tick !
$03 TCCR0B c! \ prescaler 64
$01 TIMSK0 c! \ enable overflow interrupt
;
: timer0.stop
$00 TCCR0B c! \ stop timer
$00 TIMSK0 c! \ stop interrupt
;
これらのワードでは、変数timer0.tickを1ms周期でインクリメント。
変数timer0.tickの値を参照すれば、どのくらいの時間が経過したかを
計時可能。
オーバーフロー割り込みを利用する他に、PWM波形を
生成できるので、その機能を使ってみます。
PWM波形を生成する場合、OCR1A、OCR1Bを使い
1周期のどこで'0'を出力にするかを指定します。
周期を生成するのは、ICR1を利用。
TCNT1の値が、ICR1と一致するとTCNT1はゼロに戻り
入力クロックで+1していきます。
図で見ると、以下。
PWM波形を出力する場合、DUTY比(1周期中の'1'の
比率)を指定すればよいので、1周期40000カウント
にして、OCR1A、OCR1BはDUTY比の400倍を設定。
2レジスタにDUTY比を設定するワードは、次のように定義。
: set.dutya 400 * OCR1A ! ;
: set.dutyb 400 * OCR1B ! ;
ポートBの1、2ビットがタイマー1のアウトプット
コンペアレジスタの出力になっているので、DDRBで
出力に設定。
$06 DDRB c@ or DDRB c! {enter}
一致したときに'0'を出力する仕様で使うならば
TCCR1Aの上位4ビットには、%1010を設定。
%10100000 TCCR1A c! {enter}
タイマー1を、位相基準PWMモードで使いたいので
TCCR1A、TCCR1Bの該当ビットにWGM13、WGM12、WGM11
WGM10の4ビットの組み合わせを設定。
(WGM13,WGM12,WGM11,WGM10)=(1,0,1,0)となるように
値を設定
%10 TCCR1A c@ or TCCR1A c! {enter}
%10 3 lshift TCCR1B c! {enter}
タイマー1のモジュールにクロックを与えるには
プリスケーラの値を決めればよいので、64分周で
考えます。
%10 3 lshift %11 or TCCR1B c! {enter}
初期化を含めて、必要なワードを定義。
: init.timer1
$06 DDRB c@ or DDRB c!
19999 ICR1 !
%10100010 TCCR1A c! \ both pin impress low on compare matched
%10 3 lshift %11 or TCCR1B c! \ /64 = 250kHz
;
: set.dutya 400 * OCR1A ! ;
: set.dutyb 400 * OCR1B ! ;
利用するときは、次のように入力。
5 set.dutya {enter}
5 set.dutyb {enter}
init.timer1 {enter}
DUTY比の設定値を変更すると、モータの回転数や
LEDの輝度が変化するのを確認できます。
制御基板には、2種のスイッチがあります。
回路は以下。
接続するのは、sw_aだけなので、ポートBの0ビット目の
論理値を取出し、表示すると動作テストになります。
$fe DDRB c@ and DDRB c! {enter}
PINB c@ $01 and . {enter}
制御基板のテストのためのワードをまとめます。
\ test LED array
: init.leds
$ff PORTC c!
$ff DDRC c!
;
\ set LED state
: snd.leds $ff xor PORTC c!
\ initialize port b
: init.control
$38 PORTB c!
$fe DDRB c!
;
\ initialize timer1
: init.timer1
$06 DDRB c@ or DDRB c!
19999 ICR1 !
%10100010 TCCR1A c! \ both pin impress low on compare matched
%10 3 lshift %11 or TCCR1B c! \ /64 = 250kHz
;
\ set duty ratio type A
: set.dutya 400 * OCR1A ! ;
\ set duty ratio type B
: set.dutyb 400 * OCR1B ! ;
\ show switch state
: get_sw PINB c@ 1 and . ;
\ turn on LED #A
: leda.set $08 PORTB c@ or PORTB c! ;
\ turn off LED #A
: leda.clr $f7 PORTB c@ and PORTB c! ;
\ turn on LED #B
: ledb.set $10 PORTB c@ or PORTB c! ;
\ turn off LED #B
: ledb.clr $ef PORTB c@ and PORTB c! ;
これらのワードを入力して、使えば制御基板の
テストとデバッグが可能になります。
目次
前
次