全16件 (16件中 1-16件目)
1

月の追尾・太陽の追尾機能を加える。さて、赤道儀コントローラー互換マイコンのプログラムは95%程度の進捗のところまでに至った。最後にプログラムサイズの問題があったが、なんとかクリアできた。AVRのAT90S2313/ATtiny2313マイコンのプログラム容量は2048バイトであるが、現在のプログラムサイズも2048バイトである。これ以上の機能追加はほぼ不可能な状況である。結局のところ、以下の機能付加にとどまった。1:マイコン内蔵コンパレーターを利用する電源異常検知時のトランジスタ・モーターコイルの保護ルーチン2:ウォッチドッグ(番犬)タイマ機能を利用しての、熱暴走、夜露、水晶振動子の故障時におけるトランジスタ・モーターコイルの保護ルーチン3:4倍速ボタンを押し続けると、更に増速する機能4:ソフトウェアによる北半球・南半球の入れ替え機能5:クロックドライブでありながら、恒星追尾速度を調整可能な機能6:各種設定を保存し、次回電源オン時に前回の設定を再現する機能7:オリジナルのDK-Vの追尾速度の設定に戻すオールリセット機能8:励磁シーケンス変更機能9:月と太陽のトラッキング用の追尾機能残すは、速度の微調整である。オリジナルのA-A’間での周波数は11.97Hzであり、今回の互換マイコンでは、約5000ループに相当し、最小の調整幅は0.002Hzきざみとなるが、テスターでは小数点第2位までしか測定できないので、最終的には運用しながらの絞り込みとなる。おそらく来週末には完成しそうだ。出来あがった互換マイコンは、限定1個をオークションに出すつもりである。Binary Star Watchinng
2011.06.26
コメント(6)
プログラムサイズを小さく今までに書きあげたプログラムルーチンは多岐にわたる。1:安全対策1-1:マイコン内蔵コンパレーターを利用する電源異常検知時のトランジスタ・モーターコイルの保護ルーチン1-2:ウォッチドッグ(番犬)タイマ機能を利用しての、熱暴走、夜露、水晶振動子の故障時におけるトランジスタ・モーターコイルの保護ルーチン2:機能向上2-3:4倍速ボタンを押し続けると、更に増速する機能2-4:ソフトウェアによる北半球・南半球の入れ替え機能2-5:クロックドライブでありながら、恒星追尾速度を調整可能な機能2-6:各種設定を保存し、次回電源オン時に前回の設定を再現する機能2-7:オリジナルのDK-Vの追尾速度の設定に戻すオールリセット機能ここまで、AVRのAT90S2313/ATtiny2313の完全共通動作が得られるコードを書いてきた。ここで壁に当たってしまった。AT90S2313/ATtiny2313のプログラム格納メモリは2Kしかない。コンパイラの設定もサイズ優先にするものの、既に、2Kを超えてしまっている。あと追加したい機能は、太陽と月のトラッキングモードだ。先人の努力により、太陽は恒星の99.7%、月は恒星の96.3%にする。プログラムとしては、簡単な処理なのであるが、これが、ギリギリ収まらない。C言語で進めてきたのであるが、変数のサイズ、全体の見直しにより、無駄なコードを削減する必要がある。場合によってはアセンブラでやり直す必要もあるかもしれない。頭が回らなくなってきたので、一旦クールダウン。明日再度チャレンジする。Binary Star Watching
2011.06.25
コメント(0)
データを保存したい。さて、赤道儀コントローラー互換マイコンのプログラムもかなり進んできた。プログラムを格納するメモリも少なくなってきていて、これ以上の機能の追加はだんだん困難になってきている。さて一般的にはコントローラーの恒星追尾速度用のパルスの周波数は変更できない。設計時にはギア比が固定されていて、恒星追尾用の正確なクロックでドライブしたいからである。但し、自作派の方にとっては、ギア比の異なる赤道儀への取り付けもあり得る・その様な場合、モーターの速度を変更できれば応用範囲が広がる。様々なギア比の赤道儀に対応すべく、赤道儀モーターコントローラーの基本的な機能である恒星追尾速度をユーザーが調整することができるプログラムルーチンを加えた。しかしながら、毎回、これを調整するのはたいへんなので、マイコンに前回の設定値を保存しておきたい。AVRマイコンにはEEPROMが内蔵されていて、容量は小さいがあたかもハードディスクの様な使い方ができる不揮発メモリが内蔵されている。また、追尾速度を変更できる機能は、彗星の撮影の際に、役立つと思われる。このEEPROM不揮発メモリの利用は比較的簡単である。以下にサンプルコードを示す。Binary Star Watching//******************************************************************************************// EEPROM save/read sample for TinyTP2313 and AT90S2313// Project :// Program Name :// Programer :// Create date : 2011/6/24// History :// Laungage : GCC // Copyright : Bin-Star (Free)//******************************************************************************************// (1)Description// //******************************************************************************************#include <avr/io.h>#include <avr/eeprom.h>EEMEM unsigned char eememucStatus_of_Switch;void fSet_LED_Status(unsigned char ucPattern);/*0:消灯 1:赤 2:緑 3;オレンジ*/unsigned char fGet_Status_of_Switch(void);/*+RA X2:0b00000001 STOP:0b00000010 +RA X4:0b00000100 -RA X4 0b00001000*/int main(void){ unsigned char ucStatus_of_Switch = 0b00000000; unsigned char ucStatus_of_Switch_Buf = 0b00000000; /*各スイッチの入力設定;*/ /*=====================================================================================*/ DDRD &= (~(_BV(PD0)|_BV(PD1)|_BV(PD2)|_BV(PD3)|_BV(PD6)));/*スイッチのピンを入力に設定*/ PORTD |= (_BV(PD0)|_BV(PD1)|_BV(PD2)|_BV(PD3)|_BV(PD6));/*スイッチのプルアップ(1/High)*/ /*=====================================================================================*/ /*EEPROMからの読み込み*/ /*=====================================================================================*/ eeprom_busy_wait(); ucStatus_of_Switch = eeprom_read_byte(&eememucStatus_of_Switch); /*=====================================================================================*/ /*EEPROMからの読み込み終わり*/ ucStatus_of_Switch_Buf = ucStatus_of_Switch; switch (ucStatus_of_Switch) { case 0b00000001: fSet_LED_Status(0);/*0:消灯 1:赤 2:緑 3;オレンジ*/ break; case 0b00000010: fSet_LED_Status(1);/*0:消灯 1:赤 2:緑 3;オレンジ*/ break; case 0b00000100: fSet_LED_Status(2);/*0:消灯 1:赤 2:緑 3;オレンジ*/ break; case 0b00001000: fSet_LED_Status(3);/*0:消灯 1:赤 2:緑 3;オレンジ*/ break; } while(1) { ucStatus_of_Switch = fGet_Status_of_Switch(); if(ucStatus_of_Switch_Buf != ucStatus_of_Switch) { ucStatus_of_Switch_Buf = ucStatus_of_Switch; if( ucStatus_of_Switch != 0b00000000) { /*EEPROMへの書き込み*/ /*=====================================================================================*/ eeprom_busy_wait(); eeprom_write_byte(&eememucStatus_of_Switch, ucStatus_of_Switch); /*=====================================================================================*/ /*EEPROMへの書き込み終わり*/ } switch (ucStatus_of_Switch) { case 0b00000001: fSet_LED_Status(0);/*0:消灯 1:赤 2:緑 3;オレンジ*/ break; case 0b00000010: fSet_LED_Status(1);/*0:消灯 1:赤 2:緑 3;オレンジ*/ break; case 0b00000100: fSet_LED_Status(2);/*0:消灯 1:赤 2:緑 3;オレンジ*/ break; case 0b00001000: fSet_LED_Status(3);/*0:消灯 1:赤 2:緑 3;オレンジ*/ break; } } for(int lp=0 ; lp < 32767 ; lp++ ) { asm("nop"); } }}void fSet_LED_Status(unsigned char ucPattern){ switch(ucPattern) { case 0: DDRD |= (_BV(PD4)) ;/*PD4を出力用に設定*/ PORTD &= (~(_BV(PD4)));/*PD4を0/Lo/STK600LED点灯/コントロラーLED消灯に設定*/ DDRD |= (_BV(PD5)) ;/*PD5を出力用に設定*/ PORTD &= (~(_BV(PD5)));/*PD5を0/Lo/STK600LED点灯/コントロラーLED消灯に設定*/ break; case 1: DDRD &= (~(_BV(PD4)));/*PD4を入力用に設定*/ PORTD &= (~(_BV(PD4)));/*PD4はプルアップしないが回路内1Kオームの抵抗によりコントロラーLEDが点灯*/ DDRD |= (_BV(PD5)) ;/*PD5を出力用に設定*/ PORTD &= (~(_BV(PD5)));/*PD5を0/Lo/STK600LED点灯/コントロラーLED消灯に設定*/ break; case 2: DDRD |= (_BV(PD4)) ;/*PD4を出力用に設定*/ PORTD &= (~(_BV(PD4)));/*PD4を0/Lo/STK600LED点灯/コントロラーLED消灯に設定*/ DDRD &= (~(_BV(PD5)));/*PD5を入力用に設定*/ PORTD &= (~(_BV(PD5)));/*PD5はプルアップしないが回路内1Kオームの抵抗によりコントロラーLEDが点灯*/ break; case 3: DDRD &= (~(_BV(PD4)));/*PD4を入力用に設定*/ PORTD &= (~(_BV(PD4)));/*PD4はプルアップしないが回路内1Kオームの抵抗によりコントロラーLEDが点灯*/ DDRD &= (~(_BV(PD5)));/*PD5を入力用に設定*/ PORTD &= (~(_BV(PD5)));/*PD5はプルアップしないが回路内1Kオームの抵抗によりコントロラーLEDが点灯*/ break; } }unsigned char fGet_Status_of_Switch(void){ unsigned char PORTD_Buf; unsigned char ucSWStatus; PORTD_Buf = PIND; ucSWStatus=0b00000000; /*+RA X2 SW*/ if ( !(PORTD_Buf & _BV(PD0)) )/* +RA X2 SWが押されている PD0が0/Lo*/ { ucSWStatus |= 0b00000001; } else/* +RA X2 SWが離されている PD0が1/Hi*/ { ucSWStatus &= (~0b00000001); } /*STOP SW*/ if ( !(PORTD_Buf & _BV(PD1)) )/* +STOP SWが押されている PD1が0/Lo*/ { ucSWStatus |= 0b00000010; } else/* STOP SWが離されている PD1が1/Hi*/ { ucSWStatus &= (~0b00000010); } /*+RA X4 SW*/ if ( !(PORTD_Buf & _BV(PD2)) )/* +RA X4 SWが押されている PD2が0/Lo*/ { ucSWStatus |= 0b00000100; } else/* +RA X4 SWが離されている PD1が1/Hi*/ { ucSWStatus &= (~0b00000100); } /*-RA X4 SW*/ if ( !(PORTD_Buf & _BV(PD3)) )/* -RA X4 SWが押されている PD3が0/Lo*/ { ucSWStatus |= 0b00001000; } else/* -RA X4 SWが離されている PD1が1/Hi*/ { ucSWStatus &= (~0b00001000); } return ( ucSWStatus );}
2011.06.24
コメント(0)

更に安全な回路にさて、内蔵コンパレーターによる過電流感知によるトランジスタ保護を目的とする緊急停止のプログラムは既に正常に動作している。AVRには、ウォッチドッグタイマ(番犬タイマ)と呼ばれる面白い機能があって、プログラムが正常に走っているかを常時モニタする機能がある。そこで、この機能を用いて、万が一プログラムが正常動作しない自体に陥った際にもトランジスタ保護を目的とする緊急停止プログラムルーチンを加えた。モーターからのノイズや夜露に濡れた、またはオシレーターの故障などプログラムが停止又は暴走ということが起こりうる。ステッピングモーター回路において、ある一定の角度で停止した状態が長時間続けば、トランジスタだけでなくステッピングモーターのコイルも焼けることになる。今回のコードの追加でより安全性が増すことになる。動画は、このウォッチドッグの動作確認の様子。ステッピングモーター駆動のプログラムにおいて、プログラムの停止(又は暴走)は、正常動作が得られていた直前の状態でフリーズすることになり、モーター停止の状態であるものの、過電流の状態が続きモーターコイルが焼け、トランジスタが燃える結末とかる可能性がある。動画では、ブレッドボード上のLEDのどれかが点灯したままになること意味する。ウォッチドッグタイマーは、例えクロックが停止しても、自力でリセットをかけたり割り込みをしてくれる。今回はプログラムにウォッチドッグ機能を利用した安全対策を付加した。クロック停止後も、正常動作の最後の状態を保持することなく、全てのLEDが消灯する。なお、ネット上では、あまりウォッチドッグのサンプルを見かけない。特にAT90S2313の場合のサンプルは皆無である。サンプルプログラムを以下に示すので参考にされたい。Binary Star Watchingウォッチドッグタイマーサンプル割り込みルーチンはAT90S2313では動作しないのでAT90S2313とATtiny2313の両方で動作可能な様ウォッチドッグリセット機能のみのプログラムである。//******************************************************************************************// Watch Dog sample for AT90S2313 and TinyTP2313 // Project :// Program Name :// Programer :// Create date : Version 1.00 2011/6/19// History :// Laungage : GCC // Copyright : Bin-Star (Free)//******************************************************************************************// (1)Description// Fuse bit Ext. Clock; Start-up time: 14 CK + 65 ms//******************************************************************************************#include <avr/interrupt.h>#include <avr/io.h>#include <avr/wdt.h>void fSet_LED_Status(unsigned char ucPattern);/*0:消灯 1:赤 2:緑 3;オレンジ*/unsigned char fGet_Status_Of_Switch(void);/*+RA X2:0b00000001 STOP:0b00000010 +RA X4:0b00000100 -RA X4 0b00001000*//*ウォッチドッグによる割り込み処理 AT90S2313では無効*//*=====================================================================================*///ISR(_VECTOR(19)) //{// fSet_Position_Of_Motor(ucExciting_Sequence_Pattern_Array[0]);/*モーターを所定の回転位置にセット 4bitフィールド組み合わせ 0b00000000:緊急停止*/// //WDTCR = 0b00000111;/*ウォッチドッグ無効*/// fReset_Watch_Dog();// WDTCR = 0b00000000;/*ウォッチドッグ無効*/// ucEmergency_STOP = TRUE;// fSet_LED_Status(2);/*0:消灯 1:赤 2:緑 3;オレンジ*/// while(1)// {//}/*=====================================================================================*//*ウォッチドッグによる割り込み処理の終わり*/int main(void){ unsigned char ucInterval_Timer_Situation = 0; /*割り込み関連*/ /*=====================================================================================*/ //fInit_Interrupt(); /*各スイッチの入力設定;*/ /*=====================================================================================*/ DDRD &= (~(_BV(PD0)|_BV(PD1)|_BV(PD2)|_BV(PD3)|_BV(PD6)));/*スイッチのピンを入力に設定*/ PORTD |= (_BV(PD0)|_BV(PD1)|_BV(PD2)|_BV(PD3)|_BV(PD6));/*スイッチのプルアップ(1/High)*/ cli();/*全割り込みの禁止*/ /*ウォッチドッグタイマー*/ _SFR_IO8(0x21) = 0b00001111; sei();/*全割り込みの許可*/ fSet_LED_Status(ucInterval_Timer_Situation); /*0:消灯 1:赤 2:緑 3;オレンジ*/ for (int i=0 ; i < 2000 ; i++) { for (int j=0 ; j < 100 ; j++) { asm("nop"); } } while (1) { if(fGet_Status_Of_Switch() != 0b00000000) { wdt_reset(); break; } asm("nop"); } /*=====================================================================================*/ while(1) { wdt_reset(); fSet_LED_Status(ucInterval_Timer_Situation); /*0:消灯 1:赤 2:緑 3;オレンジ*/ if(ucInterval_Timer_Situation >= 3) { ucInterval_Timer_Situation = 0; } for (int i=0 ; i < 20000 ; i++) { asm("nop"); } ucInterval_Timer_Situation ++; }}void fSet_LED_Status(unsigned char ucPattern){ switch(ucPattern) { case 0: DDRD |= (_BV(PD4)) ;/*PD4を出力用に設定*/ PORTD &= (~(_BV(PD4)));/*PD4を0/Lo/STK600LED点灯/コントロラーLED消灯に設定*/ DDRD |= (_BV(PD5)) ;/*PD5を出力用に設定*/ PORTD &= (~(_BV(PD5)));/*PD5を0/Lo/STK600LED点灯/コントロラーLED消灯に設定*/ break; case 1: DDRD &= (~(_BV(PD4)));/*PD4を入力用に設定*/ PORTD &= (~(_BV(PD4)));/*PD4はプルアップしないが回路内1Kオームの抵抗によりコントロラーLEDが点灯*/ DDRD |= (_BV(PD5)) ;/*PD5を出力用に設定*/ PORTD &= (~(_BV(PD5)));/*PD5を0/Lo/STK600LED点灯/コントロラーLED消灯に設定*/ break; case 2: DDRD |= (_BV(PD4)) ;/*PD4を出力用に設定*/ PORTD &= (~(_BV(PD4)));/*PD4を0/Lo/STK600LED点灯/コントロラーLED消灯に設定*/ DDRD &= (~(_BV(PD5)));/*PD5を入力用に設定*/ PORTD &= (~(_BV(PD5)));/*PD5はプルアップしないが回路内1Kオームの抵抗によりコントロラーLEDが点灯*/ break; case 3: DDRD &= (~(_BV(PD4)));/*PD4を入力用に設定*/ PORTD &= (~(_BV(PD4)));/*PD4はプルアップしないが回路内1Kオームの抵抗によりコントロラーLEDが点灯*/ DDRD &= (~(_BV(PD5)));/*PD5を入力用に設定*/ PORTD &= (~(_BV(PD5)));/*PD5はプルアップしないが回路内1Kオームの抵抗によりコントロラーLEDが点灯*/ break; } }unsigned char fGet_Status_Of_Switch(void){ unsigned char PORTD_Buf; unsigned char ucSWStatus; PORTD_Buf = PIND; ucSWStatus=0b00000000; /*+RA X2 SW*/ if ( !(PORTD_Buf & _BV(PD0)) )/* +RA X2 SWが押されている PD0が0/Lo*/ { ucSWStatus |= 0b00000001; } else/* +RA X2 SWが離されている PD0が1/Hi*/ { ucSWStatus &= (~0b00000001); } /*STOP SW*/ if ( !(PORTD_Buf & _BV(PD1)) )/* +STOP SWが押されている PD1が0/Lo*/ { ucSWStatus |= 0b00000010; } else/* STOP SWが離されている PD1が1/Hi*/ { ucSWStatus &= (~0b00000010); } /*+RA X4 SW*/ if ( !(PORTD_Buf & _BV(PD2)) )/* +RA X4 SWが押されている PD2が0/Lo*/ { ucSWStatus |= 0b00000100; } else/* +RA X4 SWが離されている PD1が1/Hi*/ { ucSWStatus &= (~0b00000100); } /*-RA X4 SW*/ if ( !(PORTD_Buf & _BV(PD3)) )/* -RA X4 SWが押されている PD3が0/Lo*/ { ucSWStatus |= 0b00001000; } else/* -RA X4 SWが離されている PD1が1/Hi*/ { ucSWStatus &= (~0b00001000); } return ( ucSWStatus & 0b00001111 );}
2011.06.19
コメント(0)

のM社とC社の赤道儀1軸コントローラーの互換マイコンもようやく8割程度の進捗まで来た。現時点では、各ボタン、北半球/南半球の切り替えなどオリジナルのマイコンの機能は網羅できている。電源異常時のトランジスタ保護を目的とする、緊急停止の機能については割り込み処理のプログラムを書き、何か異常があれば、最優先で緊急停止する。しかし、これだけでは面白くない。せっかくの互換マイコンなのだからオリジナルを上回る機能が必要だろう。そこで、4倍速ボタンの機能を変更した。4倍速ボタンを押し続けることにより約3秒間隔で4倍速=>8倍速=>16倍速まで増速する機能を持たせた。AVRマイコンを使用しての互換マイコンはオリジナルのマイコンに比べ処理能力が高く、ステッピングモーターを1-2相励磁(フルステップ)駆動できることから、より高速な回転も可能となる。互換マイコンの機能付加はまだまだ続く!Binary Star Watching
2011.06.13
コメント(0)
ステッピングモーター駆動プログラム本体のコーディングをタイマー割り込み処理で書くか、ループで書くかが悩みどころ。この企画を開始してから、ステッピング励磁シーケンスに続いて2つ目の悩みどころである。ステッピングモーター駆動プログラム本体のコーディング:========================================タイマー割り込み処理のメリット: ・より正確な時間タイマー割り込み処理のデメリット: ・多重割り込み時の処理が複雑になる ・電源異常をコンパレーターの割り込みの処理で書いているが、割り込み優先順位がタイマー割り込みの方が高く、電源異常時の緊急停止の割り込み処理が遅延またはできなくなる。 ・マイコンの機種依存性が高まる ・プログラムがより複雑になる========================================ループ処理のメリット ・プログラムが簡単 ・電源異常をコンパレーターの緊急停止割り込み処理が確実ループ処理のデメリット ・ループ時間がの予測が難しい(必ずしも不正確ではない)う~ん!悩む。Binary Star Watching
2011.06.12
コメント(0)

ATtiny2313、AT90S2313のアナログコンパレーターからの割り込み処理を行うプログラムを書く。M社とC社の赤道儀1軸コントローラー互換マイコンの作成を進めている。(引用元:くっしー様ブログ)オリジナルの回路には、どうやら電源異常を監視する回路が組み込んであるらしい。またオリジナルのマイコンであるAT89C2051にもアナログコンパレーターが内蔵されていて、どうやら基準電圧と比較している様だ。マイコンの12-13番ピンはレジスタの設定によりオリジナルマイコンのAT89C2051、ATtiny2313、AT90S2313に共通してアナログインプット入力ピンに設定できる。ここで非常に不可解に思うのは私だけかもしれないが、ダイオードの向きだ。この様な回路を組む際の基準電圧を取るのであれば、普通はツェーナダイオードを使用する。その場合は、アノード側にマイナスとカソード側にプラスと整流用ダイオードとは逆向きにつけるのが普通である。くっしー氏の情報によれば、1N4148の可能性が高い。整流用ダイオードから参照用の定電圧をとることができることを初めて知った。さて、オリジナルの回路設計からして、感知できる電源異常は、電池消耗をはじめ、短絡・トランジスタ回路での過電流による一過性の電圧降下だろうと推察される。短絡・トランジスタ回路での過電流の際に、回路設計者ならおそらく、トランジスタを発火させずに緊急停止させるのではないだとうか?その様なプログラムを書くには、通常のプログラムより優先して実行される割り込み処理で対応する方法が望まれる。そこで、C言語で、アナログコンパレーターからの割り込み処理を行うプログラムを書いた。ここではATtiny2313とAT90S2313の両方で利用可能なコードを書いたが、AT90S2313ではデータシートどおりの動きが得られず、プログラム側の工夫により対応した。また、ATtiny2313とAT90S2313ともに、アナログコンパレーターからの割り込みのプログラムについて、判り易く解説した書籍や先人のブログも存在しないことから、トライアンドエラーで進めることになった。サンプルコードを最後に示す。また、この参照電圧を変化させコンパレーターの出力を確認するには、STK600が極めて役立った。今まではこんな高い評価ボードは不要と書いてきたが役立つこともある。AVR StudioからSTK600を接続するダイアログのHW Settingタブには2つの可変可能な参照電圧を設定する画面がある。AVR Studioで設定した電圧の出力はSTK600のボード上の写真の端子(AREF0 AREF1)に出力される。ボード上の端子(AREF0 AREF1)から、PORTBのPB0とPB1にテストリードを用いて接続する。この様にして、コンパレーターの動作を確認することができる。以下にC言語によるサンプルソースを示す。Binary Star Watching//******************************************************************************************// Project :Analog Comparator Interrupt Sample Program for ATtiny2313 / AT90S2313// Program Name :AnalogComparatorInterrupt.bin// Programer :Bin-Star// Version :Version 1.0// Create date :2011/6/12// History :// Laungage :WinAVR GCC // Copyright :Bin-Star (Free) //******************************************************************************************// (1)Description//******************************************************************************************#define TRUE 0b11111111#define FALSE 0b00000000#include <avr/io.h>#include <avr/interrupt.h>void fInit_Interrupt(void);/*割り込みの初期化*/void fSet_LED_Status(unsigned char ucPattern);/*0:消灯 1:赤 2:緑 3;オレンジ*/unsigned char fCheckComparator(void);int main (void){ fInit_Interrupt();/*割り込みの初期化*/ /*リセット直後は割り込みかからないので手動でコンパレータの状況を確認*/ if(fCheckComparator()==TRUE) { fSet_LED_Status(1); } else { fSet_LED_Status(2); } while(1);}void fInit_Interrupt(void)/*割り込みの初期化*/{ cli();/*全割り込みの禁止*/ DDRB &= (~(_BV(PB0)|_BV(PB1)));/*PB0-1(AIN0-1)を入力用に設定*/ PORTB &= (~(_BV(PB0)|_BV(PB1)));/*PB0-1(AIN0-1)をプルアップしない*/ /*ACSRのビットの説明*/ /*Bit7 1:コンパレーターへの電源OFF*/ /*Bit6 ATTiny2313: 0:AIN0 1:内部基準電圧 AT90S2313 0;常時 予約*/ /*Bit5 出力*/ /*Bit4 1:割り込み要求リセット*/ /*Bit3 0:割り込み禁止 1:割り込み有効*/ /*Bit2 1:タイマ/カウンタの機能を利用*/ /*Bit1-0 比較条件(AT90S2313ではうまく動作しない)*/ ACSR = 0b00000000;/*Analog Comparator Interruppt Enable オフ*/ ACSR |= 0b00001000;/*Analog Comparator Interruppt Enable オン*/ sei();/*全割り込みの許可*/}unsigned char fCheckComparator(void){ if((ACSR & 0b00100000)==0b00100000) { return TRUE; } else { return FALSE; }}//ISR(ANA_COMP_vect)/*(AT90S2313ではうまく動作せず以下のISR(_VECTOR(10))を利用する)*/ISR(_VECTOR(10)) { if(fCheckComparator()==TRUE) { fSet_LED_Status(1); } else { fSet_LED_Status(2); } asm("nop"); ACSR |= 0b00001000;/*Bit4 1:割り込み要求リセット*/}void fSet_LED_Status(unsigned char ucPattern){ switch(ucPattern) { case 0: DDRD |= (_BV(PD4)) ;/*PD4を出力用に設定*/ PORTD &= (~(_BV(PD4)));/*PD4を0/Lo/STK600LED点灯/コントロラーLED消灯に設定*/ DDRD |= (_BV(PD5)) ;/*PD5を出力用に設定*/ PORTD &= (~(_BV(PD5)));/*PD5を0/Lo/STK600LED点灯/コントロラーLED消灯に設定*/ break; case 1: DDRD &= (~(_BV(PD4)));/*PD4を入力用に設定*/ PORTD &= (~(_BV(PD4)));/*PD4はプルアップしないが回路内1Kオームの抵抗によりコントロラーLEDが点灯*/ DDRD |= (_BV(PD5)) ;/*PD5を出力用に設定*/ PORTD &= (~(_BV(PD5)));/*PD5を0/Lo/STK600LED点灯/コントロラーLED消灯に設定*/ break; case 2: DDRD |= (_BV(PD4)) ;/*PD4を出力用に設定*/ PORTD &= (~(_BV(PD4)));/*PD4を0/Lo/STK600LED点灯/コントロラーLED消灯に設定*/ DDRD &= (~(_BV(PD5)));/*PD5を入力用に設定*/ PORTD &= (~(_BV(PD5)));/*PD5はプルアップしないが回路内1Kオームの抵抗によりコントロラーLEDが点灯*/ break; case 3: DDRD &= (~(_BV(PD4)));/*PD4を入力用に設定*/ PORTD &= (~(_BV(PD4)));/*PD4はプルアップしないが回路内1Kオームの抵抗によりコントロラーLEDが点灯*/ DDRD &= (~(_BV(PD5)));/*PD5を入力用に設定*/ PORTD &= (~(_BV(PD5)));/*PD5はプルアップしないが回路内1Kオームの抵抗によりコントロラーLEDが点灯*/ break; } }
2011.06.12
コメント(0)

AT90S2313にプログラムを書きこみたい。C社とM社の1軸赤道儀コントローラーの電源は6Vであり、レギュレターを介さずにマイコンにも供給される。よって、少しでも動作電圧の高いマイコンを使いたい。ATtiny2313はAT90S2313の後継品で、クロックを内蔵したり、ポートの数が増え、より高機能になっている共によりMAXの供給電圧が低くなった。MAXの供給電圧はオリジナルのAT89C2051が6.0V、AT90S2313が6.0V、ATTiny2313が5.5Vである。よって、互換マイコンとしては、AT89C2051を利用したいところである。私の所有するAVRライタは、STK600とAVRISP mkIIの2機種だが、実は標準ではAT90S2313へのプログラムの書きこみが行えない。先人の努力によりAVRISP mkIIに関しては、C:\ Program Files\Atmel\AVR Tools\Partdescriptionfiles\AT90S2313.xmlを編集することにより扱うことが出来る様になる。ICE_SETTINGSというタグを検索して、MODULE_LISTにAVRISPmkIIを追加する<ICE_SETTINGS> <MODULE_LIST>[ICEPRO:SIMULATOR:STK500:STK500_2:AVRISPmkII]</MODULE_LIST></ICE_SETTINGS>というタグを検索して、このタグの直前に<AVRISPmkII/>を加える。 <AVRISPmkII/></ICE_SETTINGS>保存後、DeviceとしてAT90S2313が選択可能になり、プログラムを書き込むことが可能になる。一方STK600については、AT90S2313が利用可能であったとする過去の報告はない様であるが、AVR.JPにてSTK600通信規約が公開されているので、これを参考にxmlを編集可能であるかもしれないが定かではない。現在のところ、私の環境では合理的とは言えないが、STK600にAVRISPmkIIを接続してAT90S2313にプログラムを書き込む方法をとっている。上記写真の様に結線すれば、STK600上のAT90S2313に、AVRISPmkIIからプログラムを書き込める。以上Binary Star Watching
2011.06.11
コメント(0)

ATtiny2313/AT90S2313のPORT出力をオープン方式にしたい。ATtiny2313/AT90S2313のPORTを出力に設定した場合、そのままLEDドライブが可能なくらい電流をとれることがAVRの特徴の1つである。またPORTを入力設定にした場合、レジスタにより、プルアップの有無の設定を行えるが、出力設定の場合には、オープンにすることが出来ない。この特徴は、新たに回路設計を行う際にメリットがあるが、出力が0の場合Groundレベル、1の場合オープンになることを前提に設計された回路にて、マイコンの置き換えを行う様な際には、問題が生じる。おそらくは互換マイコンを作成しようとする様な場合に生じる特殊なケースではないかと思う。(引用元:くっしー様ブログ)上の回路図はM社及びC社の1軸赤道儀モーターコントローラの回路図をLED点灯の回路の部分のみを抽出し簡略化したものである。オリジナルで使用されているマイコンはAT89C2051でかなり古いMCS-51互換である。PORTの出力は0がGround、1がオープンになり、それに対応して回路設計されている。マイコンのPORTが0に設定され、LEDのアノード側がGroundレベルまでプルダウンされるとLEDは消灯する。逆にマイコンのPORTが1に設定され、オープンになるとLEDのアノード側は1kオームの抵抗を介してVCCに接続されLEDが点灯する。さてこのマイコンを最新のATTiny2313やAT90S2313に置き換えると何がおきるかである。マイコンの動作として異なるのが、PORTが1に設定された場合にAT89C2051ではオープン、ATTiny2313/AT90S2313ではVCCレベルである。すなわち、ATTiny2313/AT90S2313ではVCCレベルとなり、抵抗を介さない状態でLEDに電流を送り込むことになる。私はLEDを破壊するだけで済んだが、マイコンを破壊する可能性も高い。なので、ATTiny2313/AT90S2313のPORTが0の時にGround、1の時にオープンになる様なプログラムを書きたい。プログラムではPORTをGroundレベルにしたい場合は、出力設定で0として、オープンにしたい時は入力設定として0(プルアップしない)とすれば、古いAT89C2051と同じ動作が得られる。例)PORTをGroundレベルにする。DDRD |= (_BV(PD4)) ;/*PD4を出力用に設定*/PORTD &= (~(_BV(PD4)));/*PD4を0/Lo/STK600LED点灯/コントロラーLED消灯に設定*/例)PORTをオープンにする。DDRD &= (~(_BV(PD4)));/*PD4を入力用に設定*/ PORTD &= (~(_BV(PD4)));/*PD4はプルアップしないが回路内1Kオームの抵抗によりコントロラーLEDが点灯*/サブルーチンを組み込んだサンプル(C言語)を以下に示す。Binary Star Watching//******************************************************************************************// Open Collector TinyTP2313 and AT90S2313// Project :// Program Name :// Programer :// Create date : 2011/6/11// History :// Laungage : GCC // Copyright : Bin-Star (Free)//******************************************************************************************// (1)Description// //******************************************************************************************#include <avr/io.h>unsigned char fWait_for_Stepping(unsigned int uiStandard_Spped, unsigned int uiMultiple_Of_Spped, unsigned char ucDynamic_Increase);/*標準ループ数:uiStandard_Spped, 倍数:uiMultiple_Of_Sppe, 増速:Dynamic_Increase*/void fSet_LED_Status(unsigned char ucPattern);/*0:消灯 1:赤 2:緑 3;オレンジ*/ int main(void){ int lp,lp1 ; unsigned char LED=0; while(1) { /*LED出力用*/ fSet_LED_Status(LED);/*0:消灯 1:赤 2:緑 3;オレンジ*/ if (LED==3) { LED=0; } else { LED++; } for(lp=0 ; lp < 32767 ; lp++ ) { asm("nop"); } }} void fSet_LED_Status(unsigned char ucPattern){ switch(ucPattern) { case 0: DDRD |= (_BV(PD4)) ;/*PD4を出力用に設定*/ PORTD &= (~(_BV(PD4)));/*PD4を0/Lo/STK600LED点灯/コントロラーLED消灯に設定*/ DDRD |= (_BV(PD5)) ;/*PD5を出力用に設定*/ PORTD &= (~(_BV(PD5)));/*PD5を0/Lo/STK600LED点灯/コントロラーLED消灯に設定*/ break; case 1: DDRD &= (~(_BV(PD4)));/*PD4を入力用に設定*/ PORTD &= (~(_BV(PD4)));/*PD4はプルアップしないが回路内1Kオームの抵抗によりコントロラーLEDが点灯*/ DDRD |= (_BV(PD5)) ;/*PD5を出力用に設定*/ PORTD &= (~(_BV(PD5)));/*PD5を0/Lo/STK600LED点灯/コントロラーLED消灯に設定*/ break; case 2: DDRD |= (_BV(PD4)) ;/*PD4を出力用に設定*/ PORTD &= (~(_BV(PD4)));/*PD4を0/Lo/STK600LED点灯/コントロラーLED消灯に設定*/ DDRD &= (~(_BV(PD5)));/*PD5を入力用に設定*/ PORTD &= (~(_BV(PD5)));/*PD5はプルアップしないが回路内1Kオームの抵抗によりコントロラーLEDが点灯*/ break; case 3: DDRD &= (~(_BV(PD4)));/*PD4を入力用に設定*/ PORTD &= (~(_BV(PD4)));/*PD4はプルアップしないが回路内1Kオームの抵抗によりコントロラーLEDが点灯*/ DDRD &= (~(_BV(PD5)));/*PD5を入力用に設定*/ PORTD &= (~(_BV(PD5)));/*PD5はプルアップしないが回路内1Kオームの抵抗によりコントロラーLEDが点灯*/ break; } }
2011.06.11
コメント(0)
字数制限により分割投稿続き //==================== unsigned char fWait_for_Stepping(unsigned int uiStandard_Spped, unsigned int uiMultiple_Of_Spped, unsigned char ucDynamic_Increase)/*標準ループ数:uiStandard_Spped, 倍数:uiMultiple_Of_Sppe, 増速:Dynamic_Increase*/{ unsigned int uiCounter=0; if (uiMultiple_Of_Spped ==0 || (uiStandard_Spped / uiMultiple_Of_Spped <= 1)) { while(uiCounter <= uiStandard_Spped) { uiCounter++; } return FALSE; } else { while(uiCounter <= (uiStandard_Spped / uiMultiple_Of_Spped)) { uiCounter++; } }return TRUE; // int lp,lp1 ;// for(lp=0 ; lp < TIM ; lp++ ) //for(lp1=0 ; lp1 < 20000 ; lp1++ );//1-2相で40が最速 2相では120が最速 1相では130が限界// for(lp1=0 ; lp1 < 10000 ; lp1++ );//1-2相で40が最速 2相では120が最速 1相では130が限界// return 1;}void fSet_Position_Of_Motor(unsigned char ucPosition)/*モーターを所定の回転位置にセット 4bitフィールド組み合わせ 0b00000000:緊急停止*/{ unsigned char ucPBSetting; ucPBSetting = ucPosition << 4; PORTB |= ((~ucPBSetting) & 0b11110000);/*PB4-7で該当しないビットを(1/Hi/STK600LED消灯)に設定*/ PORTB &= ((~ucPBSetting) | 0b00001111);/*PB4-7で該当するビットを0/Lo/STK600LED点灯に設定*/}void fSet_LED_Status(unsigned char ucPattern){ switch(ucPattern) { case 0: DDRD |= (_BV(PD4)) ;/*PD4を出力用に設定*/ PORTD &= (~(_BV(PD4)));/*PD4を0/Lo/STK600LED点灯/コントロラーLED消灯に設定*/ DDRD |= (_BV(PD5)) ;/*PD5を出力用に設定*/ PORTD &= (~(_BV(PD5)));/*PD5を0/Lo/STK600LED点灯/コントロラーLED消灯に設定*/ break; case 1: DDRD &= (~(_BV(PD4)));/*PD4を入力用に設定*/ PORTD &= (~(_BV(PD4)));/*PD4はプルアップしないが回路内1Kオームの抵抗によりコントロラーLEDが点灯*/ DDRD |= (_BV(PD5)) ;/*PD5を出力用に設定*/ PORTD &= (~(_BV(PD5)));/*PD5を0/Lo/STK600LED点灯/コントロラーLED消灯に設定*/ break; case 2: DDRD |= (_BV(PD4)) ;/*PD4を出力用に設定*/ PORTD &= (~(_BV(PD4)));/*PD4を0/Lo/STK600LED点灯/コントロラーLED消灯に設定*/ DDRD &= (~(_BV(PD5)));/*PD5を入力用に設定*/ PORTD &= (~(_BV(PD5)));/*PD5はプルアップしないが回路内1Kオームの抵抗によりコントロラーLEDが点灯*/ break; case 3: DDRD &= (~(_BV(PD4)));/*PD4を入力用に設定*/ PORTD &= (~(_BV(PD4)));/*PD4はプルアップしないが回路内1Kオームの抵抗によりコントロラーLEDが点灯*/ DDRD &= (~(_BV(PD5)));/*PD5を入力用に設定*/ PORTD &= (~(_BV(PD5)));/*PD5はプルアップしないが回路内1Kオームの抵抗によりコントロラーLEDが点灯*/ break; } }unsigned char fGet_Status_Of_Switch(void){ unsigned char PORTD_Buf; unsigned char ucSWStatus; PORTD_Buf = PIND; ucSWStatus=0b00000000; /*+RA X2 SW*/ if ( !(PORTD_Buf & _BV(PD0)) )/* +RA X2 SWが押されている PD0が0/Lo*/ { ucSWStatus |= 0b00000001; } else/* +RA X2 SWが離されている PD0が1/Hi*/ { ucSWStatus &= (~0b00000001); } /*STOP SW*/ if ( !(PORTD_Buf & _BV(PD1)) )/* +STOP SWが押されている PD1が0/Lo*/ { ucSWStatus |= 0b00000010; } else/* STOP SWが離されている PD1が1/Hi*/ { ucSWStatus &= (~0b00000010); } /*+RA X4 SW*/ if ( !(PORTD_Buf & _BV(PD2)) )/* +RA X4 SWが押されている PD2が0/Lo*/ { ucSWStatus |= 0b00000100; } else/* +RA X4 SWが離されている PD1が1/Hi*/ { ucSWStatus &= (~0b00000100); } /*-RA X4 SW*/ if ( !(PORTD_Buf & _BV(PD3)) )/* -RA X4 SWが押されている PD3が0/Lo*/ { ucSWStatus |= 0b00001000; } else/* -RA X4 SWが離されている PD1が1/Hi*/ { ucSWStatus &= (~0b00001000); } return ucSWStatus;}unsigned char fGet_North_Hemisphere_or_Not(void){ unsigned char PORTD_Buf; PORTD_Buf = PIND; if ( !(PORTD_Buf & _BV(PD6)) )/* North SWの設定 PD6が0/Lo*/ { return ~ucRev_North_South_Hemisphere; } else/* South SWの設定 PD6が1/Hi*/ { return ucRev_North_South_Hemisphere; }}void fSet_Exciting_Sequence(unsigned char ucNum_of_Exciting_Sequence)/*励磁方式 0:緊急停止 1:1相 2:2相 3:1-2相 拡張可能*/{ switch(ucNum_of_Exciting_Sequence) { /*ucExciting_Sequence_Pattern_Array[10]は励磁方式によりコイルへの電源供給パターンを設定したもの 拡張可能*/ case 0: ucExciting_Sequence_Pattern_Array[0]=0b00000000;/*緊急停止*/ ucExciting_Sequence_Pattern_Array[1]=0b00000000;/*緊急停止*/ ucExciting_Sequence_Pattern_Array[2]=0b00000000;/*緊急停止*/ ucExciting_Sequence_Pattern_Array[3]=0b00000000;/*緊急停止*/ ucExciting_Sequence_Pattern_Array[4]=0b00000000;/*緊急停止*/ ucExciting_Sequence_Pattern_Array[5]=0b00000000;/*緊急停止*/ ucExciting_Sequence_Pattern_Array[6]=0b00000000;/*緊急停止*/ ucExciting_Sequence_Pattern_Array[7]=0b00000000;/*緊急停止*/ ucExciting_Sequence_Pattern_Array[8]=0b00000000;/*緊急停止*/ ucExciting_Sequence_Pattern_Array[9]=0b00000000;/*緊急停止*/ break; case 1:/*1相*/ ucExciting_Sequence_Pattern_Array[0]=0b00000000;/*緊急停止*/ ucExciting_Sequence_Pattern_Array[1]=0b00000001; ucExciting_Sequence_Pattern_Array[2]=0b00000010; ucExciting_Sequence_Pattern_Array[3]=0b00001000; ucExciting_Sequence_Pattern_Array[4]=0b00000100; ucExciting_Sequence_Pattern_Array[5]=0b00000001; ucExciting_Sequence_Pattern_Array[6]=0b00000010; ucExciting_Sequence_Pattern_Array[7]=0b00001000; ucExciting_Sequence_Pattern_Array[8]=0b00000100; ucExciting_Sequence_Pattern_Array[9]=0b00000000;/*緊急停止*/ break; case 2:/*2相*/ ucExciting_Sequence_Pattern_Array[0]=0b00000000;/*緊急停止*/ ucExciting_Sequence_Pattern_Array[1]=0b00000011; ucExciting_Sequence_Pattern_Array[2]=0b00001010; ucExciting_Sequence_Pattern_Array[3]=0b00001100; ucExciting_Sequence_Pattern_Array[4]=0b00000101; ucExciting_Sequence_Pattern_Array[5]=0b00000011; ucExciting_Sequence_Pattern_Array[6]=0b00001010; ucExciting_Sequence_Pattern_Array[7]=0b00001100; ucExciting_Sequence_Pattern_Array[8]=0b00000101; ucExciting_Sequence_Pattern_Array[9]=0b00000000;/*緊急停止*/ break; case 3:/*1-2相*/ ucExciting_Sequence_Pattern_Array[0]=0b00000000;/*緊急停止*/ ucExciting_Sequence_Pattern_Array[1]=0b00000001; ucExciting_Sequence_Pattern_Array[2]=0b00000011; ucExciting_Sequence_Pattern_Array[3]=0b00000010; ucExciting_Sequence_Pattern_Array[4]=0b00001010; ucExciting_Sequence_Pattern_Array[5]=0b00001000; ucExciting_Sequence_Pattern_Array[6]=0b00001100; ucExciting_Sequence_Pattern_Array[7]=0b00000100; ucExciting_Sequence_Pattern_Array[8]=0b00000101; ucExciting_Sequence_Pattern_Array[9]=0b00000000;/*緊急停止*/ break; default: ucExciting_Sequence_Pattern_Array[0]=0b00000000;/*緊急停止*/ ucExciting_Sequence_Pattern_Array[1]=0b00000000;/*緊急停止*/ ucExciting_Sequence_Pattern_Array[2]=0b00000000;/*緊急停止*/ ucExciting_Sequence_Pattern_Array[3]=0b00000000;/*緊急停止*/ ucExciting_Sequence_Pattern_Array[4]=0b00000000;/*緊急停止*/ ucExciting_Sequence_Pattern_Array[5]=0b00000000;/*緊急停止*/ ucExciting_Sequence_Pattern_Array[6]=0b00000000;/*緊急停止*/ ucExciting_Sequence_Pattern_Array[7]=0b00000000;/*緊急停止*/ ucExciting_Sequence_Pattern_Array[8]=0b00000000;/*緊急停止*/ ucExciting_Sequence_Pattern_Array[9]=0b00000000;/*緊急停止*/ break; }}
2011.06.06
コメント(0)

M社とC社の1軸赤道儀御コントローラーの互換マイコンのプログラミングを進めている。ようやくオリジナルの動作を再現するプログラムが書けた。現在の進捗率は70%程度である。現時点では、割り込み処理を一切使用しておらず、低電圧対応のプログラムは書けていない。また、追尾速度は合わせておらず、目視確認用の低速での動作になっている。この後、低電圧対応、速度微調整機能速度、月追尾、惑星追尾速度などの機能を付加していく。現時点で、問題となっているのは、分岐処理などの制御のせいか、モーター回転1ステップに時間がかかっており、空ループでウェイトをかけるにしては、マイコンのクロック数をもう少し高めたいところである。オリジナルのAT89C2051は3.58MHzの水晶によるクロックであるが、おそらくは、クロック数が低くて、1-2相励磁プログラムを物理的にかけなかったのではないかと推測する。現時点での互換マイコンは内蔵8MHz校正クロックを使用しているが、更に高速な外部クロックに置き換える必要があるかを検証する必要がある。以下に現時点でのプログラムを示す。Binary Star Watching//******************************************************************************************// Motor Driver Program for TinyTP2313 // Project :// Program Name :// Programer :// Create date : Version 1.01 2011/6/5// History :// Laungage : GCC // Copyright : Bin-Star (Free)//******************************************************************************************// (1)Description// Fuse bit int. RC Osc. 8MHz, Start-up time: 14 CK + 65 ms//******************************************************************************************#include <avr/io.h>//#define TIM 1#define TRUE 0b11111111#define FALSE 0b00000000static unsigned char ucExciting_Sequence_Pattern_Array[10];/*励磁方式によりコイルへの電源供給パターンを変更できる 拡張可能*/static unsigned char ucRev_North_South_Hemisphere= FALSE;/*北半球・南半球切り替えスイッチのソフトウェア入れ替え*/static unsigned char ucRA_Plus_Direction = TRUE;/*RA+方向を示すフラグ*/static unsigned char ucDirection = TRUE;/*回転方向を示すフラグ(+/-)*/static unsigned char ucEmergency_STOP = FALSE;static unsigned int uiStandard_Spped=36;/*調整可能なスピード 実測値18*///static unsigned int uiMultiple_Of_Spped=1;/*0: STOP 2-254:2-255倍速*/unsigned char fWait_for_Stepping(unsigned int uiStandard_Spped, unsigned int uiMultiple_Of_Spped, unsigned char ucDynamic_Increase);/*標準ループ数:uiStandard_Spped, 倍数:uiMultiple_Of_Sppe, 増速:Dynamic_Increase*/void fSet_Position_Of_Motor( unsigned char ucPosition);/*モーターを所定の回転位置にセット 4bitフィールド組み合わせ 0b00000000:緊急停止*/void fSet_LED_Status(unsigned char ucPattern);/*0:消灯 1:赤 2:緑 3;オレンジ*/unsigned char fGet_Status_Of_Switch(void);/*+RA X2:0b00000001 STOP:0b00000010 +RA X4:0b00000100 -RA X4 0b00001000*/unsigned char fGet_North_Hemisphere_or_Not(void);/*北半球/南半球かでRAプラス方向がどちらの回転かを判断する*/void fSet_Exciting_Sequence(unsigned char ucNum_of_Exciting_Sequence);/*励磁方式 0:緊急停止 1:1相 2:2相 3:1-2相 拡張可能*/int main(void){ unsigned char ucStep_Num_of_Exciting_Sequence;/*ステップの位置*/ unsigned int uiMultiple_Of_Spped;/*スピードの倍数*/ //unsigned char ucStatusOfSwitch; /*ステッピングモーター用変数*/ fSet_Exciting_Sequence(3);/*励磁方式 0:緊急停止 1:1相 2:2相 3:1-2相 拡張可能*/ /*リセットピン対策*/ //DDRA &= (~_BV(PA2)); //PORTA |= _BV(PA2);//RESETピン対策として、PA2をプルアップ(1/High) /*ステッピングパルス出力\初期設定*/ DDRB |= (_BV(PB4)|_BV(PB5)|_BV(PB6)|_BV(PB7));/*出力用に設定*/ PORTB |= (_BV(PB4)|_BV(PB5)|_BV(PB6)|_BV(PB7));/*PB4-7を(1/Hi/STK600LED消灯)に設定*/ /*各スイッチの入力設定;*/ DDRD &= (~(_BV(PD0)|_BV(PD1)|_BV(PD2)|_BV(PD3)|_BV(PD6)));/*スイッチのピンを入力に設定*/ PORTD |= (_BV(PD0)|_BV(PD1)|_BV(PD2)|_BV(PD3)|_BV(PD6));/*スイッチのプルアップ(1/High)*/ ucRA_Plus_Direction = fGet_North_Hemisphere_or_Not();/*北半球/南半球かでRAプラス方向がどちらの回転かを判断する*/ /*LED出力用*/ fSet_LED_Status(1);/*0:消灯 1:赤 2:緑 3;オレンジ*/ ucStep_Num_of_Exciting_Sequence=1; while(1) { if(ucEmergency_STOP) { fSet_Position_Of_Motor(ucExciting_Sequence_Pattern_Array[0]);/*モーターを所定の回転位置にセット 4bitフィールド組み合わせ 0b00000000:緊急停止*/ break; } else { //ucStatusOfSwitch = fGet_Status_Of_Switch(); //switch ( ucStatusOfSwitch & 0b00001111 ) switch ( fGet_Status_Of_Switch() & 0b00001111 )/*+RA X2:0b00000001 STOP:0b00000010 +RA X4:0b00000100 -RA X4 0b00001000*/ { case 0b00000001:/*+RA X2*/ fSet_LED_Status(2);/*0:消灯 1:赤 2:緑 3;オレンジ*/ ucDirection = ucRA_Plus_Direction;/*回転方向を示すフラグ(+/-)*/ uiMultiple_Of_Spped=2;/*0: STOP 2-254:2-255倍速*/ break; case 0b00000010:/*STOP*/ fSet_LED_Status(2);/*0:消灯 1:赤 2:緑 3;オレンジ*/ ucDirection = ~ucRA_Plus_Direction;/*回転方向を示すフラグ(+/-)*/ uiMultiple_Of_Spped=0;/*0: STOP 2-254:2-255倍速*/ break; case 0b00000100:/*+RA X4*/ fSet_LED_Status(2);/*0:消灯 1:赤 2:緑 3;オレンジ*/ ucDirection = ucRA_Plus_Direction;/*回転方向を示すフラグ(+/-)*/ uiMultiple_Of_Spped=16;/*0: STOP 2-254:2-255倍速*/ break; case 0b00001000:/*-RA X4*/ fSet_LED_Status(2);/*0:消灯 1:赤 2:緑 3;オレンジ*/ ucDirection = ~ucRA_Plus_Direction;/*回転方向を示すフラグ(+/-)*/ uiMultiple_Of_Spped=4;/*0: STOP 2-254:2-255倍速*/ break; default: fSet_LED_Status(1);/*0:消灯 1:赤 2:緑 3;オレンジ*/ ucDirection = ucRA_Plus_Direction;/*回転方向を示すフラグ(+/-)*/ uiMultiple_Of_Spped=1;/*0: STOP 2-254:2-255倍速*/ break; } if(uiMultiple_Of_Spped==0)/*ストップボタンが押されていた場合*/ { fSet_Position_Of_Motor(ucExciting_Sequence_Pattern_Array[0]);/*停止*/ } else { fSet_Position_Of_Motor(ucExciting_Sequence_Pattern_Array[ucStep_Num_of_Exciting_Sequence]); /*モーターを所定の回転位置にセット 4bitフィールド組み合わせ 0b00000000:緊急停止*/ if(ucDirection == TRUE)/*回転方向を示すフラグ(+/-)*/ { if(ucStep_Num_of_Exciting_Sequence>=8) { ucStep_Num_of_Exciting_Sequence=1; } else { ucStep_Num_of_Exciting_Sequence++; } } else { if(ucStep_Num_of_Exciting_Sequence<=1) { ucStep_Num_of_Exciting_Sequence=8; } else { ucStep_Num_of_Exciting_Sequence--; } } } if(fWait_for_Stepping(uiStandard_Spped, uiMultiple_Of_Spped, FALSE) == FALSE ) { fSet_LED_Status(3);/*0:消灯 1:赤 2:緑 3;オレンジ*/ } } }}
2011.06.06
コメント(0)

ステッピングモーターの励磁シークエンスが適切でなければ、ステッピングモーターは回転しない。それどころか、このシークエンスを誤ると、トランジスタが燃える結末に至る。ステッピングモーターの励磁シークエンスとして適切なものを検証するために、LEDによる目視でのシークエンステスタをブレッドボード上に作成した。とはいってもLED8個と2.2Kオームび抵抗8本のみの簡単なものだ。一方のLEDのカソードを2.2Kオームの抵抗を介してGroundへ、アノードにICテストクリップへ、もう一方のLEDはアノードを2.2Kオームの抵抗を介してVCCへ、カソードを同一のICテストクリップと同じラインへ接続する。ICテストクリップがGroudレベルになると一方のLEDが光り、VCCレベルになるともう一方のLEDが光る様にする。ステッピングモーター出力のA,A',B,B'の端子として、ダイオードが並ぶ上記写真の部分から、ICテストクリップを用いて信号線を取り出した。テストリードのそれぞれの箇所は、白がA、黄色がB、青がB'、緑がA'、赤がVCC、黒がGroundである。励磁シークエンスが適切であるかを確認する為、目視で判断できる程度まで、ステッピングの周波数をプログラム上で落とした。以下の動画に1相、2相、1-2相の励磁シークエンスの確認状況を示す。なお、1相励磁方式と2相励磁方式では48ステップでモーターが1回転、1-2相励磁方式では96ステップでモーターが1回転し、1-2相励磁方式の方が細かく回転角度を制御できる。また、同一ICテストクリップに繋がる(隣接する)赤と緑のLEDが同時点灯することがあればトランジスタが燃えるシークエンスであることを示す。また高速回転性能については、以下のとおりであった。高速回転には、1相か2相励磁方式が向いている様に思えるが、実際には1-2相励磁方式が1相又は2相励磁方式に比しステップ数で3倍、角度で1.5倍高速の高速回転が可能であることが判った。1-2相励磁方式は、回転角度の制御をより細かく行え、高速回転についても有利である。また1-2相励磁方式は振動が少ないことも大きな特徴になる。但し1相励磁方式に比し、電池の消耗が1.5倍早まる。M社やC社オリジナルのコントローラーは1相励磁方式であるが、この企画での互換マイコンは1-2相励磁方式(フルステップ)による制御をおこなう仕様でプログラムの作成を進めたいと考えている。Binary Star Watching
2011.06.05
コメント(0)
ステッピングモーターの駆動方式ステッピングモーターのステッピングパターンも様々あるらしいという事で、調査。Web上で技術情報を判り易く説明してくれているページがある。メカトロアイデア新日本無線モーター自体は、M社のものは、ユニポーラのモーターのコイルを半分だけ使ってバイポーラで駆動(もったいない)。C社のものは、バイポーラのタイプである。また、スッテピングのは励磁シーケンス(順序)は、M社・C社ともに1相励磁方式である。励磁シーケンス(順序)には、1相、2相、1-2相の方式があり、それぞれ特徴があるらしい。・1相は低電力・2相は高トルク・1-2相は高角度精度である。今回の企画においても、プログラム上で、いずれの方法も可能である。ここで、とても大きな葛藤状態となる。どれも1長1短である。果たして赤道儀に向いている励磁シーケンス(順序)はどの方法なのか。。。。?一晩中動かすには、低電力の方がいいし、大型機材を積むなら高トルク、追尾精度を追及するなら、高角度制御が選択できる。オリジナルは、1相の低電力を採用している。互換マイコンではあえて、別の方法をとるか?ここに来られた方のコメントがあれば幸いです。あなたなら赤道儀モータドライバに何を求めますか。・1相:低電力を重視する。・2相:高トルクで回転角度が正確だが、電池の消耗が倍・1-2相:微細な回転角度でよりなめらかで、モーターの振動が少ないが、電池の消耗が1.5倍Binary Star Watching
2011.06.05
コメント(4)

あいた!しまったインジケーター用のLEDが死んだ。プログラムの書き方だけで回路部品が壊れる。結構チャレンジングなことをしているなあと自分自身思う。突然LEDが光らなくなり、インジケーター用のLEDの足をテスタで確認。LEDの足までは正常である。LEDが死んだのである。なぜ、この様な減少が起きたかは回路図を見れば判る。オリジナルのMCS-51互換のAT89C2051は、LED出力としては、プルダウンで消灯し、点灯は1Kオームの抵抗により保護される。昔のマイコンなので、オープンコレクタ仕様である様だ。しかしながら、RISCのAVRであるAT90S2313/ATtiny2313ともにICピンは高出力でそのままでLEDがドライブできる性能を持つ。AT90S2313/ATtiny2313の信号がHiになりLEDは保護抵抗なしに電流が流れ出ることになる。しまったなあ!トランジスタにばかり気を取られてしまってLED側のことはノーマークであった。まあLEDくらい取り換えれば済むこと。また、この様なことを想定したプログラムに作り替えなければならない。(追記:AT90S2313はSTK600では正常な書きこみが行えない。AT90S2313.xmlのクロック関連を編集すれば動作できそうであるが、過去に成功した人はいない様である。2011/6/8)引用許可済:くっしー様ブログ
2011.06.04
コメント(8)
前回の投稿では、トランジスタを燃やすケースを紹介した。誤ったプログラムを書けば、トランジスタを燃やすことになる。今回は、ステッピングモーターがちゃんと動作してくれるかを見る為、単純に回るだけのプログラムを書いた。割り込み処理もしていないし、恒星追尾速度とか、4倍速ボタンの対応等は全くない。単純にモーターが回るだけのプログラムである。このプログラムでトランジスタが燃えないかについて事前にSTK600上で動作に問題ないことを確認した。動画参照その後、コントローラーのマイコンと交換し、無事トランジスタが燃えないプログラムであることが実証できた。動画参照以下のAVR Studio / WinAVRのC言語のソースコードを示す。//******************************************************************************************// Motor Driver Program// Project :// Program Name :// Programer :// Create date : Version 1.0 2011/6/3// History :// Laungage : GCC // Copyright : Bin-Star (Free)//******************************************************************************************// (1)Description// Fuse bit 外部クロック 3.58MHz//******************************************************************************************//******************************************************************************************// Motor Driver Program// Project :// Program Name :// Programer :// Create date : Version 1.0 2011/6/3// History :// Laungage : GCC // Copyright : Bin-Star (Free)//******************************************************************************************// (1)Description// Fuse bit 外部クロック 3.58MHz//******************************************************************************************#include <avr/io.h>#define TIM 10int ArrayPosition[8];int MotorRotatePosition( int nPosition);int wait();int main(void){unsigned char PORTB_Buf;unsigned char PORTD_Buf;int iArrayNum;iArrayNum=0;ArrayPosition[0]=0;ArrayPosition[1]=1;ArrayPosition[2]=2;ArrayPosition[3]=4;ArrayPosition[4]=3;ArrayPosition[5]=0;ArrayPosition[6]=0;ArrayPosition[7]=0;DDRA =0x00;//PORTA = _BV(PA0)|_BV(PA1)|_BV(PA2);//RESETピン対策として、プルアップ(1/High)DDRB = _BV(PB4)|_BV(PB5)|_BV(PB6)|_BV(PB7);//出力用に設定:パルスPORTB_Buf = _BV(PB4)|_BV(PB5)|_BV(PB6)|_BV(PB7);//PB4-7を(1/Hi/STK600LED消灯)に設定PORTB = PORTB_Buf;DDRD = _BV(PD4)|_BV(PD5);//出力用に設定 ステータスLEDPORTD_Buf=0x00;PORTD = _BV(PD0)|_BV(PD1)|_BV(PD2)|_BV(PD3)|_BV(PD6);//スイッチのプルアップ(1/High)PORTD |= (_BV(PD4)|_BV(PD5));//PD4-5を(1/Hi/STK600LED消灯)に設定iArrayNum=0;while(1) {iArrayNum++;MotorRotatePosition(ArrayPosition[iArrayNum]);if(iArrayNum==4){iArrayNum=0;}PORTD_Buf = PIND;if ( !(PORTD_Buf & _BV(PD0)) )// +RA X2 SWが押されている PD0が0/Lo{//PORTB &= (~_BV(PB4));//PORTBのPB4を0/Lo/STK600LED点灯にする。PORTD &= (~_BV(PD4));//PORTBのPB4を0/Lo/STK600LED点灯にする。}else// +RA X2 SWが離されている PD0が1/Hi{//PORTB |= _BV(PB4);//PORTBのPB4を1/Hi/STK600LED消灯にする。PORTD |= _BV(PD4);//PORTBのPB4を1/Hi/STK600LED消灯にする。}if ( !(PORTD_Buf & _BV(PD1)) )// +STOP SWが押されている PD1が0/Lo{//PORTB &= (~_BV(PB4));//PORTBのPB4を0/Lo/STK600LED点灯にする。PORTD &= (~_BV(PD5));//PORTBのPB4を0/Lo/STK600LED点灯にする。}else// STOP SWが離されている PD1が1/Hi{//PORTB |= _BV(PB4);//PORTBのPB4を1/Hi/STK600LED消灯にする。PORTD |= _BV(PD5);//PORTBのPB4を1/Hi/STK600LED消灯にする。}}}//******************************************************************************************// Function Name : MotorRotatePosition// Title : MotorRotatePosition function// Input :// Output ://******************************************************************************************int MotorRotatePosition(int nPosition){PORTB |= (_BV(PB4)|_BV(PB5)|_BV(PB6)|_BV(PB7));//PB4-7を(1/Hi/STK600LED消灯)に設定switch (nPosition){case 1:PORTB &= (~_BV(PB4));//PORTBのPB4を0/Lo/STK600LED点灯にする。break;case 2:PORTB &= (~_BV(PB5));//PORTBのPB5を0/Lo/STK600LED点灯にする。break;case 3:PORTB &= (~_BV(PB6));//PORTBのPB6を0/Lo/STK600LED点灯にする。break;case 4:PORTB &= (~_BV(PB7));//PORTBのPB7を0/Lo/STK600LED点灯にする。break;default:break;}wait();//PORTB |= (_BV(PB4)|_BV(PB5)|_BV(PB6)|_BV(PB7));//PB4-7を(1/Hi/STK600LED消灯)に設定return 1;}//******************************************************************************************// Function Name : wait// Title : wait function// Input :// Output ://******************************************************************************************int wait(){int lp,lp1 ;for(lp=0 ; lp < TIM ; lp++ )for(lp1=0 ; lp1 < 1000 ; lp1++ );//return 1;}Binary Star Watching
2011.06.03
コメント(0)

さて、互換マイコンのプログラムを始める前によく回路図を理解しておく必要がある。引用許可済:くっしー様ブログ上手のV1からV8の動作を良く検討する必要がある。例えばV1のエミッタがVCCに直結、V8のエミッタがグランドに直結されていて、コレクタがブリッジしている。この状態でマイコンの16ピンと19ピンが共にLo(Ground)レベルになった場合、V1のVCCレベルのエミッタから、V8のグランドレベルのエミッタ間で短絡が起きて、V1とV8が燃える。この状況はV4とV5でも同時に発生する。一方、マイコンの17ピンと18ピンが共にLo(Ground)レベルになった場合、同様にV2,V7, V3, V6のトランジスタが燃える。プログラムを書く立場から考えると、マイコンのプログラム起動時に直ぐに、16から19ピンをHi(VCC)レベルにセットして、いずれかの1本のピンのみを順次Lowにして、モーターを回転させることになるわけであるが、製造物責任法の観点からすれば、回路上に過電流が流れてトランジスタが燃える状況になれば、火事の原因にもなりかねない。ここで、色々な自体をシミュレーションしておく必要がある。マイコンプログラムがRUNして、初期化にまで処理が至らなかった場合どうなるかである。オリジナルのAT89C2051であってもAVRであっても、これらの16から19ピンのデフォルトの出力はLo(Ground)レベルに設定され、全てのトランジスタが燃えだすことになる。実際にマイコンのプログラムが起動しないことがあり得るについてもよく検討する必要がある。高電圧破壊(12V供給)を想定する。1:マイコンやロジックICが12Vに耐えた場合:オリジナルのマイコンのAT89C2051はプロググラムの書き換えに1番ピンに12Vが供給された場合にマイコンの機能はプログラミンングモードに変更され、7番ピンがLo、8、9番ピンはプルアップされているのでHi、11番ピンは北半球設定スイッチの設定によりHiになった場合、マイコンの動作は、コードライトとなり、無意味なプログラムをマイコンが自己で書き込んでしまう。その結果、初期設定ルーチンのプログラム領域を破壊する。結局のところプログラムはRUNしなくなり、16から19ピンはデフォルトのLoのまま、全てのトランジスタが燃える。この現象は、マイコンやインバーターが物理的破壊を免れた場合のことであり、こうなると全てのトランジスタが破壊される結末に至る。2:マイコンICのみが1高電圧により壊れた場合:状況は前述の1にお状態と変わりない。3:ロジックICのみが高電圧により壊れた場合:偶然にもインバーターのロジックICが12V過電圧により壊れて、全ての出力が同時にHigh、Loとなった場合はトランジスタの破壊は免れ、破壊部品は、インバーターのロジックICのみで済む。4:低電圧破壊:マイコン又はロジックICは、Hiを感知する電圧の閾値があり、これらの参照電圧よりも電池消耗により電圧が下降している様な場合である。電源をつないだまま長期間放置したり、放電状態に近いバッテリーがもたらす低電圧は、マイコンやロジックICを破壊することはあまり考えられないが、インバータICの動作反応下限値より電圧が下回った場合、1と同様の理由によりトランジスタへの過電流が流れ、トランジスタのみ破壊される。この場合、マイコンとロジックICは破壊を免れる。これらのことを想定して緊急停止の機能をプログラムに組み込む必要があるBinary Star Watching
2011.06.01
コメント(0)
全16件 (16件中 1-16件目)
1