制御プログラム完成


7日は、とりあえず角度検出器をアルミシャシーに収めたものの接触不良が発生。夜中の2時半まで半田ごてを握って基板をいじくっていたら、半田ごてをお手玉してお気に入りのウインドブレーカーの袖に穴を開けた。結局、コネクタのコンタクト金具が開いていただけ・・・。

 その後、2日間は、夜更かし作業の疲れと県議会の視察やら会議やらで実験が手につかず。今日も日中は事務仕事と打ち合わせで終わったが、日が暮れてからクリーンブース(つむつむの『お城』なんて言われている)に籠ってプログラムを仕上げた。パソコンとRS232Cで繋いでターミナルソフトからコマンドを送るのだが、コマンド待ち状態になるとプロンプト”>”が表示されるようにして、マニュアル操作(3つのスイッチでフィルター番号を指定して駆動スイッチを押すと動く)のルーチンを追加した。問題なく動作したので、これでマイコンに最終書き込み。
(写真は後日)
 これでテスト用のベースボードの役割は終わったので実際のコントローラ基板を製作することになる。

最後にプログラムコードを公開!

'****************** AKI-PIC877 PIC-BASIC 「fltcntrl」 *****************
' VTOS用フィルター交換機構のステッピングモーターを角度制御する
'  モーターは200step(1.8deg/step)、角度検出はポテンショメータをAD変換(10bit)
'
'  Copy write 圓谷 文明(つむつむ電子工房)2006.11.10
'**********************************************************************
'
'<<<< port割り当て規則 >>>> ←この規則に従ってポート属性を指定すること
'port/channel RA0-3/AN0-3,RA5/AN4,RE0-2/AN5-7:INPUTまたはA/Dコンバータ(センサー入力)
'port RD0-7:OUTPUT(デジタルアウト8bitパラレルまで)
'port RB0,RC0-2:INPUT(スイッチ入力)
'port RA4,RC5:IO任意(スイッチ入力または出力)
'<<<< 予約済みport >>>> ←このポートは勝手に定義使用できない
'Port RB1:mode select(High=RUN mode, LOW=Program mode)
'Port RB2-7:LCD(液晶ディスプレイ)に接続
'Port RC3,4:外部EEPROM(外部メモリ)に接続
'Port RC6,7:ADM232(RS232Cレベル変換チップ)に接続

'-----------変数定義----------
Dim cmd As Byte
Dim filtn As Byte
Dim i As Byte
Dim count As Word
Dim phase As Word
'-----------------------------

'ユニットの初期化(Portは指定しない限りINPUT)
Input rb.Bit0 '駆動SW
Input rc.Bit0 'フィルター選択SW-bit0
Input rc.Bit1 'フィルター選択SW-bit1
Input rc.Bit2 'フィルター選択SW-bit2
Output rd.Bit0 '正転パルス出力
Output rd.Bit7 '逆転パルス出力
Initlcd 'LCDを初期化(RB2-7をOUTPUT)
Serclear 'RS232Cバッファクリア

'スタート画面表示
Setpos 0,0 'LCDのカーソルを(0,0)に
Putlcd "Controller Start" 'タイトル表示
Sleep 3000 '3秒間保持
Clearlcd


'状態変数の初期化
i = 0
count = 0
phase = 0

'原点復帰(filter0を選択)
Gosub filter0
'Gosub phchk

Serout pb9600,chr$(&H3E) 'コマンドプロンプト表示

main:
'コマンド変数の初期化
cmd = 0
filtn = 0

'マニュアル制御
If rb.Bit0=0 Then '駆動SW押下
Gosub manual
Endif

'リモート制御
Serin pb9600,2000,cmd,filtn 'コマンド入力待ち
If cmd=&H66 Then 'H66は"f"のコード
Serout pb9600,chr$(cmd),chr$(filtn) 'Echo
Serout pb9600,chr$(13),chr$(10) '改行
If filtn <> 0 Then
Gosub remote
Serout pb9600,chr$(&H3E) 'コマンドプロンプト表示
Endif
Endif
Serclear 'RS232Cバッファクリア

Goto main


phchk:
Clearlcd
For i=0 To 255
Adc 0,0,count '角度検出:AN0(RA0)の入力をモード0でAD変換、countに代入
'角度検出器のカウントを0-1024(10bit)のphase値に変換
If count < 105 Then
phase = 0
Else
phase = (count-105)*1023/918
Endif
Setpos 0,0
Putlcd "filter0"
Setpos 0,1 'LCDのカーソルを(0,1)に
Putlcd "Phase = ",phase," " 'LCDにphaseの値を表示
Next i
Return


manual:
'RC0-2 = b000 = 0
If rc.Bit0 = 0 Then
If rc.Bit1 = 0 Then
If rc.Bit2 = 0 Then
Setpos 0,0
Putlcd "Filter0"
Setpos 0,1
Putlcd " was selected"
Sleep 1000
Gosub filter0 '原点復帰
Endif
Endif
Endif

'RC0-2 = b001 = 1
If rc.Bit0 = 1 Then
If rc.Bit1 = 0 Then
If rc.Bit2 = 0 Then
Setpos 0,0
Putlcd "Filter1"
Setpos 0,1
Putlcd " was selected"
Sleep 1000
Gosub filter0 '原点復帰
Gosub filter1
Endif
Endif
Endif

'RC0-2 = b010 = 2
If rc.Bit0 = 0 Then
If rc.Bit1 = 1 Then
If rc.Bit2 = 0 Then
Setpos 0,0
Putlcd "Filter2"
Setpos 0,1
Putlcd " was selected"
Sleep 1000
Gosub filter0 '原点復帰
Gosub filter2
Endif
Endif
Endif

'RC0-2 = b011 = 3
If rc.Bit0 = 1 Then
If rc.Bit1 = 1 Then
If rc.Bit2 = 0 Then
Setpos 0,0
Putlcd "Filter3"
Setpos 0,1
Putlcd " was selected"
Sleep 1000
Gosub filter0 '原点復帰
Gosub filter3
Endif
Endif
Endif

'RC0-2 = b100 = 4
If rc.Bit0 = 0 Then
If rc.Bit1 = 0 Then
If rc.Bit2 = 1 Then
Setpos 0,0
Putlcd "Filter4"
Setpos 0,1
Putlcd " was selected"
Sleep 1000
Gosub filter0 '原点復帰
Gosub filter4
Endif
Endif
Endif

'RC0-2 = b101 = 5
If rc.Bit0 = 1 Then
If rc.Bit1 = 0 Then
If rc.Bit2 = 1 Then
Setpos 0,0
Putlcd "Filter5"
Setpos 0,1
Putlcd " was selected"
Sleep 1000
Gosub filter0 '原点復帰
Gosub filter5
Endif
Endif
Endif

'RC0-2 = b110 = 6
If rc.Bit0 = 0 Then
If rc.Bit1 = 1 Then
If rc.Bit2 = 1 Then
Setpos 0,0
Putlcd "Filter6"
Setpos 0,1
Putlcd " was selected"
Sleep 1000
Gosub filter0 '原点復帰
Gosub filter6
Endif
Endif
Endif

'RC0-2 = b111 = 7
If rc.Bit0 = 1 Then
If rc.Bit1 = 1 Then
If rc.Bit2 = 1 Then
Setpos 0,0
Putlcd "Filter7"
Setpos 0,1
Putlcd " was selected"
Sleep 1000
Gosub filter0 '原点復帰
Gosub filter7
Endif
Endif
Endif
Return


remote:
If filtn-48 = 0 Then 'filtn-48:0〜9の文字コードを数値に変換
Setpos 0,0
Putlcd "Filter",chr$(filtn)
Setpos 0,1
Putlcd " was selected"
Sleep 1000
Serout pb9600,chr$(&H43),chr$(&H6F),chr$(&H6D),chr$(&H6D),chr$(&H61),chr$(&H6E),chr$(&H64),chr$(&H20),chr$(&H61),chr$(&H63),chr$(&H63),chr$(&H65),chr$(&H70),chr$(&H74),chr$(&H65),chr$(&H64)
'Serialに文字列「Command accepted」を出力
Serout pb9600,chr$(13),chr$(10) '改行
Gosub filter0 '原点復帰
Endif

If filtn-48 = 1 Then 'filtn-48:0〜9の文字コードを数値に変換
Setpos 0,0
Putlcd "Filter",chr$(filtn)
Setpos 0,1
Putlcd " was selected"
Sleep 1000
Serout pb9600,chr$(&H43),chr$(&H6F),chr$(&H6D),chr$(&H6D),chr$(&H61),chr$(&H6E),chr$(&H64),chr$(&H20),chr$(&H61),chr$(&H63),chr$(&H63),chr$(&H65),chr$(&H70),chr$(&H74),chr$(&H65),chr$(&H64)
'Serialに文字列「Command accepted」を出力
Serout pb9600,chr$(13),chr$(10) '改行
Gosub filter0 '原点復帰
Gosub filter1
Endif

If filtn-48 = 2 Then
Setpos 0,0
Putlcd "Filter",chr$(filtn)
Setpos 0,1
Putlcd " was selected"
Sleep 1000
Serout pb9600,chr$(&H43),chr$(&H6F),chr$(&H6D),chr$(&H6D),chr$(&H61),chr$(&H6E),chr$(&H64),chr$(&H20),chr$(&H61),chr$(&H63),chr$(&H63),chr$(&H65),chr$(&H70),chr$(&H74),chr$(&H65),chr$(&H64)
'Serialに文字列「Command accepted」を出力
Serout pb9600,chr$(13),chr$(10) '改行
Gosub filter0 '原点復帰
Gosub filter2
Endif

If filtn-48 = 3 Then
Setpos 0,0
Putlcd "Filter",chr$(filtn)
Setpos 0,1
Putlcd " was selected"
Sleep 1000
Serout pb9600,chr$(&H43),chr$(&H6F),chr$(&H6D),chr$(&H6D),chr$(&H61),chr$(&H6E),chr$(&H64),chr$(&H20),chr$(&H61),chr$(&H63),chr$(&H63),chr$(&H65),chr$(&H70),chr$(&H74),chr$(&H65),chr$(&H64)
'Serialに文字列「Command accepted」を出力
Serout pb9600,chr$(13),chr$(10) '改行
Gosub filter0 '原点復帰
Gosub filter3
Endif

If filtn-48 = 4 Then
Setpos 0,0
Putlcd "Filter",chr$(filtn)
Setpos 0,1
Putlcd " was selected"
Sleep 1000
Serout pb9600,chr$(&H43),chr$(&H6F),chr$(&H6D),chr$(&H6D),chr$(&H61),chr$(&H6E),chr$(&H64),chr$(&H20),chr$(&H61),chr$(&H63),chr$(&H63),chr$(&H65),chr$(&H70),chr$(&H74),chr$(&H65),chr$(&H64)
'Serialに文字列「Command accepted」を出力
Serout pb9600,chr$(13),chr$(10) '改行
Gosub filter0 '原点復帰
Gosub filter4
Endif

If filtn-48 = 5 Then
Setpos 0,0
Putlcd "Filter",chr$(filtn)
Setpos 0,1
Putlcd " was selected"
Sleep 1000
Serout pb9600,chr$(&H43),chr$(&H6F),chr$(&H6D),chr$(&H6D),chr$(&H61),chr$(&H6E),chr$(&H64),chr$(&H20),chr$(&H61),chr$(&H63),chr$(&H63),chr$(&H65),chr$(&H70),chr$(&H74),chr$(&H65),chr$(&H64)
'Serialに文字列「Command accepted」を出力
Serout pb9600,chr$(13),chr$(10) '改行
Gosub filter0 '原点復帰
Gosub filter5
Endif

If filtn-48 = 6 Then
Setpos 0,0
Putlcd "Filter",chr$(filtn)
Setpos 0,1
Putlcd " was selected"
Sleep 1000
Serout pb9600,chr$(&H43),chr$(&H6F),chr$(&H6D),chr$(&H6D),chr$(&H61),chr$(&H6E),chr$(&H64),chr$(&H20),chr$(&H61),chr$(&H63),chr$(&H63),chr$(&H65),chr$(&H70),chr$(&H74),chr$(&H65),chr$(&H64)
'Serialに文字列「Command accepted」を出力
Serout pb9600,chr$(13),chr$(10) '改行
Gosub filter0 '原点復帰
Gosub filter6
Endif

If filtn-48 = 7 Then
Setpos 0,0
Putlcd "Filter",chr$(filtn)
Setpos 0,1
Putlcd " was selected"
Sleep 1000
Serout pb9600,chr$(&H43),chr$(&H6F),chr$(&H6D),chr$(&H6D),chr$(&H61),chr$(&H6E),chr$(&H64),chr$(&H20),chr$(&H61),chr$(&H63),chr$(&H63),chr$(&H65),chr$(&H70),chr$(&H74),chr$(&H65),chr$(&H64)
'Serialに文字列「Command accepted」を出力
Serout pb9600,chr$(13),chr$(10) '改行
Gosub filter0 '原点復帰
Gosub filter7
Endif
Return


filter0:
Clearlcd
Adc 0,0,count '角度検出:AN0(RA0)の入力をモード0でAD変換、countに代入
'角度検出器のカウントを0-1024(10bit)のphase値に変換
If count < 105 Then
phase = 0
Else
phase = (count-105)*1023/918
Endif
Setpos 0,0
Putlcd "filter0"
Setpos 0,1 'LCDのカーソルを(0,1)に
Putlcd "Phase = ",phase 'LCDにphaseの値を表示
While phase > 14 '14=8(offset)+6(1step)
Low rd.Bit7 '逆転:RD7にLowを出力し...
Sleep 20 '20msec保持
High rd.Bit7 'RD7にHighを出力し...
Sleep 20 '20msec保持
Adc 0,0,count '角度検出
'角度検出器のカウントを0-1024(10bit)のphase値に変換
If count < 105 Then
phase = 0
Else
phase = (count-105)*1023/918
Endif
Setpos 8,1 'LCDのカーソルを(8,1)に
Putlcd phase," " 'LCDにphaseの値を表示
Wend
While phase < 2 '2=8(offset)-6(1step)
Low rd.Bit0 '正転:RD0にLowを出力し...
Sleep 20 '20msec保持
High rd.Bit0 'RD0にHighを出力し...
Sleep 20 '20msec保持
Adc 0,0,count '角度検出
If count < 105 Then
phase = 0
Else
phase = (count-105)*1023/918
Endif
Setpos 8,1
Putlcd phase," "
Wend
Return


filter1:
Clearlcd
Setpos 0,0
Putlcd "filter1"
For i=1 To 25 '正転25step x filtn
Low rd.Bit0
Sleep 20
High rd.Bit0
Sleep 20
Next i
Adc 0,0,count '角度検出:AN0(RA0)の入力をモード0でAD変換、phaseに代入
If count < 105 Then
phase = 0
Else
phase = (count-105)*1023/918
Endif
Setpos 0,1 'LCDのカーソルを(0,1)に
Putlcd "Phase = ",phase 'LCDにphaseの値を表示
While phase > 158 '8(offset)+144xfiltn+6(1step)
Low rd.Bit7 '逆転:RD7にLowを出力し...
Sleep 20 '20msec保持
High rd.Bit7 'RD7にHighを出力し...
Sleep 20 '20msec保持
Adc 0,0,count '角度検出
If count < 105 Then
phase = 0
Else
phase = (count-105)*1023/918
Endif
Setpos 8,1 'LCDのカーソルを(8,1)に
Putlcd phase," " 'LCDにphaseの値を表示
Wend
While phase < 146 '8+144xfiltn-6
Low rd.Bit0 '正転:RD0にLowを出力し...
Sleep 20 '20msec保持
High rd.Bit0 'RD0にHighを出力し...
Sleep 20 '20msec保持
Adc 0,0,count '角度検出
If count < 105 Then
phase = 0
Else
phase = (count-105)*1023/918
Endif
Setpos 8,1
Putlcd phase," "
Wend
Return


filter2:
Clearlcd
Setpos 0,0
Putlcd "filter2"
For i=1 To 50 '正転25step x filtn
Low rd.Bit0
Sleep 20
High rd.Bit0
Sleep 20
Next i
Adc 0,0,count '角度検出:AN0(RA0)の入力をモード0でAD変換、phaseに代入
If count < 105 Then
phase = 0
Else
phase = (count-105)*1023/918
Endif
Setpos 0,1 'LCDのカーソルを(0,1)に
Putlcd "Phase = ",phase 'LCDにphaseの値を表示
While phase > 302 '8(offset)+144xfiltn+6(1step)
Low rd.Bit7 '逆転:RD7にLowを出力し...
Sleep 20 '20msec保持
High rd.Bit7 'RD7にHighを出力し...
Sleep 20 '20msec保持
Adc 0,0,count '角度検出
If count < 105 Then
phase = 0
Else
phase = (count-105)*1023/918
Endif
Setpos 8,1 'LCDのカーソルを(8,1)に
Putlcd phase," " 'LCDにphaseの値を表示
Wend
While phase < 290 '8+144xfiltn-6
Low rd.Bit0 '正転:RD0にLowを出力し...
Sleep 20 '20msec保持
High rd.Bit0 'RD0にHighを出力し...
Sleep 20 '20msec保持
Adc 0,0,count '角度検出
If count < 105 Then
phase = 0
Else
phase = (count-105)*1023/918
Endif
Setpos 8,1
Putlcd phase," "
Wend
Return


filter3:
Clearlcd
Setpos 0,0
Putlcd "filter3"
For i=1 To 75 '正転25step x filtn
Low rd.Bit0
Sleep 20
High rd.Bit0
Sleep 20
Next i
Adc 0,0,count '角度検出:AN0(RA0)の入力をモード0でAD変換、phaseに代入
If count < 105 Then
phase = 0
Else
phase = (count-105)*1023/918
Endif
Setpos 0,1 'LCDのカーソルを(0,1)に
Putlcd "Phase = ",phase 'LCDにphaseの値を表示
While phase > 446 '8(offset)+144xfiltn+6(1step)
Low rd.Bit7 '逆転:RD7にLowを出力し...
Sleep 20 '20msec保持
High rd.Bit7 'RD7にHighを出力し...
Sleep 20 '20msec保持
Adc 0,0,count '角度検出
If count < 105 Then
phase = 0
Else
phase = (count-105)*1023/918
Endif
Setpos 8,1 'LCDのカーソルを(8,1)に
Putlcd phase," " 'LCDにphaseの値を表示
Wend
While phase < 434 '8+144xfiltn-6
Low rd.Bit0 '正転:RD0にLowを出力し...
Sleep 20 '20msec保持
High rd.Bit0 'RD0にHighを出力し...
Sleep 20 '20msec保持
Adc 0,0,count '角度検出
If count < 105 Then
phase = 0
Else
phase = (count-105)*1023/918
Endif
Setpos 8,1
Putlcd phase," "
Wend
Return


filter4:
Clearlcd
Setpos 0,0
Putlcd "filter4"
For i=1 To 100 '正転25step x filtn
Low rd.Bit0
Sleep 20
High rd.Bit0
Sleep 20
Next i
Adc 0,0,count '角度検出:AN0(RA0)の入力をモード0でAD変換、phaseに代入
If count < 105 Then
phase = 0
Else
phase = (count-105)*1023/918
Endif
Setpos 0,1 'LCDのカーソルを(0,1)に
Putlcd "Phase = ",phase 'LCDにphaseの値を表示
While phase > 590 '8(offset)+144xfiltn+6(1step)
Low rd.Bit7 '逆転:RD7にLowを出力し...
Sleep 20 '20msec保持
High rd.Bit7 'RD7にHighを出力し...
Sleep 20 '20msec保持
Adc 0,0,count '角度検出
If count < 105 Then
phase = 0
Else
phase = (count-105)*1023/918
Endif
Setpos 8,1 'LCDのカーソルを(8,1)に
Putlcd phase," " 'LCDにphaseの値を表示
Wend
While phase < 578 '8+144xfiltn-6
Low rd.Bit0 '正転:RD0にLowを出力し...
Sleep 20 '20msec保持
High rd.Bit0 'RD0にHighを出力し...
Sleep 20 '20msec保持
Adc 0,0,count '角度検出
If count < 105 Then
phase = 0
Else
phase = (count-105)*1023/918
Endif
Setpos 8,1
Putlcd phase," "
Wend
Return


filter5:
Clearlcd
Setpos 0,0
Putlcd "filter5"
For i=1 To 125 '正転25step x filtn
Low rd.Bit0
Sleep 20
High rd.Bit0
Sleep 20
Next i
Adc 0,0,count '角度検出:AN0(RA0)の入力をモード0でAD変換、phaseに代入
If count < 105 Then
phase = 0
Else
phase = (count-105)*1023/918
Endif
Setpos 0,1 'LCDのカーソルを(0,1)に
Putlcd "Phase = ",phase 'LCDにphaseの値を表示
While phase > 734 '8(offset)+144xfiltn+6(1step)
Low rd.Bit7 '逆転:RD7にLowを出力し...
Sleep 20 '20msec保持
High rd.Bit7 'RD7にHighを出力し...
Sleep 20 '20msec保持
Adc 0,0,count '角度検出
If count < 105 Then
phase = 0
Else
phase = (count-105)*1023/918
Endif
Setpos 8,1 'LCDのカーソルを(8,1)に
Putlcd phase," " 'LCDにphaseの値を表示
Wend
While phase < 722 '8+144xfiltn-6
Low rd.Bit0 '正転:RD0にLowを出力し...
Sleep 20 '20msec保持
High rd.Bit0 'RD0にHighを出力し...
Sleep 20 '20msec保持
Adc 0,0,count '角度検出
If count < 105 Then
phase = 0
Else
phase = (count-105)*1023/918
Endif
Setpos 8,1
Putlcd phase," "
Wend
Return


filter6:
Clearlcd
Setpos 0,0
Putlcd "filter6"
For i=1 To 150 '正転25step x filtn
Low rd.Bit0
Sleep 20
High rd.Bit0
Sleep 20
Next i
Adc 0,0,count '角度検出:AN0(RA0)の入力をモード0でAD変換、phaseに代入
If count < 105 Then
phase = 0
Else
phase = (count-105)*1023/918
Endif
Setpos 0,1 'LCDのカーソルを(0,1)に
Putlcd "Phase = ",phase 'LCDにphaseの値を表示
While phase > 878 '8(offset)+144xfiltn+6(1step)
Low rd.Bit7 '逆転:RD7にLowを出力し...
Sleep 20 '20msec保持
High rd.Bit7 'RD7にHighを出力し...
Sleep 20 '20msec保持
Adc 0,0,count '角度検出
If count < 105 Then
phase = 0
Else
phase = (count-105)*1023/918
Endif
Setpos 8,1 'LCDのカーソルを(8,1)に
Putlcd phase," " 'LCDにphaseの値を表示
Wend
While phase < 866 '8+144xfiltn-6
Low rd.Bit0 '正転:RD0にLowを出力し...
Sleep 20 '20msec保持
High rd.Bit0 'RD0にHighを出力し...
Sleep 20 '20msec保持
Adc 0,0,count '角度検出
If count < 105 Then
phase = 0
Else
phase = (count-105)*1023/918
Endif
Setpos 8,1
Putlcd phase," "
Wend
Return


filter7:
Clearlcd
Setpos 0,0
Putlcd "filter7"
For i=1 To 175 '正転25step x filtn
Low rd.Bit0
Sleep 20
High rd.Bit0
Sleep 20
Next i
Adc 0,0,count '角度検出:AN0(RA0)の入力をモード0でAD変換、phaseに代入
If count < 105 Then
phase = 0
Else
phase = (count-105)*1023/918
Endif
Setpos 0,1 'LCDのカーソルを(0,1)に
Putlcd "Phase = ",phase 'LCDにphaseの値を表示
While phase >= 1022 '8(offset)+144xfiltn+6(1step)
Low rd.Bit7 '逆転:RD7にLowを出力し...
Sleep 20 '20msec保持
High rd.Bit7 'RD7にHighを出力し...
Sleep 20 '20msec保持
Adc 0,0,count '角度検出
If count < 105 Then
phase = 0
Else
phase = (count-105)*1023/918
Endif
Setpos 8,1 'LCDのカーソルを(8,1)に
Putlcd phase," " 'LCDにphaseの値を表示
Wend
While phase < 1010 '8+144xfiltn-6
Low rd.Bit0 '正転:RD0にLowを出力し...
Sleep 20 '20msec保持
High rd.Bit0 'RD0にHighを出力し...
Sleep 20 '20msec保持
Adc 0,0,count '角度検出
If count < 105 Then
phase = 0
Else
phase = (count-105)*1023/918
Endif
Setpos 8,1
Putlcd phase," "
Wend
Return

Posted: 金 - 11月 10, 2006 at 12:39 午前            


©