目次

ライントレーサ制御基板テスト

 大学での非常勤講師を担当しているときは
 学生の興味をひくように、ライントレーサ
 の制御を取り入れています。




 センサーからの情報を入力し、モータにパラメータを
 与えて、ラインをなぞります。

 ライントレーサを制御するために、使う基板は以下。




 この基板は、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! ;

 これらのワードを入力して、使えば制御基板の
 テストとデバッグが可能になります。


目次

inserted by FC2 system