制御回路を作ることにします。
テストでは、CNC2418のWoodpeckerでやってて
これは、1号機の時ですが、こんなんじゃ組み込めませんからね~
組み込めるよう、小さいDigisparkか、ATTINY85にしようかな!
Digisparkは、ここでちょっと噛じって
Windowsに専用のUSB DriverとArduino IDEの開発環境Installして
ここで、一発スクリーンショットを作って、
その後、キャパシティブセンサーもやって以来であります。
このDigispark Cloneが在庫ってます。
US$ 2.68/2個
やっぱ、この元祖タイプの直挿Digispark Cloneだな!
USBの差し込みが甘く、ちょっと押すと接触不良起こすので
PCで抜き差しする用途には向かないと思います。
USBの差し込みが甘く、ちょっと押すと接触不良起こすので
PCで抜き差しする用途には向かないと思います。
今回は、スケッチ書込時だけで、後は、スタンドアローンで動かすので
こっちを使うことにします。
一時、売り切れでしたが、今見ると、$1.3で復活してます。
Digisparkに乗っているATtiny85の機能は、GitHubのここにあります。
こっちを使うことにします。
一時、売り切れでしたが、今見ると、$1.3で復活してます。
Digisparkに乗っているATtiny85の機能は、GitHubのここにあります。
「AVR 8bit Microcontroller」なのです。
カメラスライダーを作られていますので
参考にさせていただきましたm(_ _)m
まずは、ボタンで上下させるだけ
その後、Limit SWを付けることにします。
Digisparkボード内には、色々パーツがぶら下がっているので注意です。
PB5は、RESET専用にしなければなりません。
PB1にもLチカ確認用のLEDがあるので要注意です。
Digistump Createdの回路図は、このPDFです。
で、ピンアサインは、これ。
PIN0:Direction
PIN1:Step(ボード内のLEDは問題ないでしょう)
PIN2:UP BUTTON
PIN3:DOWN BUTTON
PIN4:Limit SW(PullUP、Normal Open)(ボードにPullUP抵抗あり)
PIN5:NC(RESET専用)
では、スケッチを設計していきます。
まず、STEP PLUSEの周期は、
20step/回転、3mmリード=ピッチ、1/4 Microstepなので
20 ÷ 1/4 ÷ 3 = 26.667step/mm
F500 = 500mm/minだと
1分間に
26.667 x 500 = 13333step/min
1秒間のSTEP数が、A4988のStepパルス周期になるので
13333 ÷ 60 = 222.22step/sec = 222.22Hz
= 4.5 msec(HIGH/LOWの1周期)
Arduinoのスケッチは、昨年6月以来、久々です。
すっかり忘れてるので、過去のブログを覗きます。
ブログ書いてて良かっと感じる時です^^;
実体配線図を作っておかないと確実に間違えるので(-_-;)
久しぶりにFritzingを立ち上げます。
「A4988」を検索すると
おっ!Pololu A4988がありますね~
Digisparkのライブラリは、この時、
ここから直挿DigisparkのFritzing PartsをImportしてます。
ステッピングモーターの電源は、定格 3~6Vなのですが
A4988(定格 8V~)の実力でも 6.2V~しか動かないので
6.2Vで動かしています。
MS2だけHIGHでいいでしょう。
A4988のDatasheetには、SLEEPとRESETを直結する記述がないけど
CNC2418のWoodpeckerで動いてるので、直結でいくとして...
A4988のENABLEは、どうしようか?
このステッピングモーター、静止状態で電流を流し続けたくないし
PB5(RESET)をOUTPUTで使えるだろうか?
ATTINY85のDatasheetは、このPDF。
有志の方々で作成された日本語訳は、これです。
それを見ると、
PB5を使うには、RESETをDISABLEすればできるのですが、
Datasheetの10.3.1に
RESETをINPUT/OUTPUTとして使う場合は、
RSTDISBL Fuse(非プログラミング領域)を変更しないといけないのです。
Table 20-4 にありました。
一番上の「RSTDISBL」です。
(2)の注釈が下にあり、書換は、高電圧シリアルプログラミングだけ。と
どうもこれをやると弊害の方が大きいので止めておきます(T_T)
A4988のENABLEは、取り敢えずGNDに落としとくしかないな~
後で考えることにしよっと^^;
Arduino IDE v.1.8.3を起動します。
「Digisparkの製作元Digistump LLC(合同会社)のパッケージ」は
この前インストールしています。
まだ、Digispark(ATtiny85)は、接続しないで
[ツール]-[ボード]-[Digispark(Default - 16.5mhz)]を選択します。
Fusion360の3Dの後にソフト考えるのは、頭が~
切り替えるのに時間がかかります(-_-;)
...
できたみたいなので、書き込みです。
切り替えるのに時間がかかります(-_-;)
...
できたみたいなので、書き込みです。
まだ、Digisparkは接続しません!つい、先に繋ぎそうになるんですよね~
[スケッチ]-[マイコンボードに書き込む]します。
「ボードへの書き込みが完了しました。」と
[スケッチ]-[マイコンボードに書き込む]します。
コンパイルが終わり、下の欄に
「Plug in device now...(will timeout in 60 seconds)」とでたら
Digispark(ATtiny85)をUSBに接続します。
書き込み時は、Digisparkは、何も配線していない方がいいかと思われます。「ボードへの書き込みが完了しました。」と
「Micronucleus done. Thank you!」の表示がでます。
まずは、上下だけ
動いたけど、モーターから変なキュイ~んって音が出て、ややぎこちない動き
OPENしているMS1、MS3がノイズを拾っているのかなあ?
***最初に動いたスケッチ**
// CO2 Laser Cutter Z-Axis Controller
// DigiSpark
// 基本動作の確認
const int Direction = 0; // PB0 for Direction
const int Step = 1; // PB1 for STEP
const int UpBtn = 2; // PB2 for UP Button
const int DownBtn = 3; // PB3 for DOWN Button
const int LimitSW = 4; // PB4 for Limit Switch
void setup() {
// initialize the digital pin as an output.
pinMode(0, OUTPUT); //DIRECTION
pinMode(1, OUTPUT); //STEP
pinMode(2, INPUT_PULLUP); //UP Button
pinMode(3, INPUT_PULLUP); //DOWN Button
pinMode(4, INPUT_PULLUP); //LimitSW
pinMode(5, INPUT); //Reset
}
void loop() {
// UP & DOWN
if (digitalRead(UpBtn) == LOW) { // UP Button
digitalWrite(Direction, HIGH); // DIRECTION UP
move();
}
if (digitalRead(DownBtn) == LOW) { // DOWN Button検出
digitalWrite(Direction, LOW); // DIRECTION DOWN
move();
}
}
// STEP信号を1Step Pluse送出 F500固定
// 20step/回転、3mmリード=ピッチ、1/4 Microstepなので
// 20 ÷ 1/4 ÷ 3 = 26.667step/mm
// F500 = 500mm/min
// 26.667 x 500 = 13333step/min(1分間)
// 1秒間のSTEP数が、A4988のStepパルス周期になるので
// 13333 ÷ 60 = 222.22step/sec = 222.22Hz = 4.5 msec(HIGH/LOWの1周期)
// 4.5msec ÷ 2 = 2250μsec
void move() {
digitalWrite(Step, HIGH);
delayMicroseconds(2250);
digitalWrite(Step, LOW);
delayMicroseconds(2250);
}
*****
少し動かしていると、動かなくなりました(T_T)
UP/DOWN SWを押すと点灯していたDigispark内のLED(PB1:Step)が
点灯しなくなったのです。
Digisparkからの空中配線ケーブルの接触不良っぽいな~
配線し直そうかな~
そうだ!
ATTINY85のソケット付きのDigisparkボードと
DIPの単体チップを持ってるのすっかり忘れてました!
US$ 0.49
このDIPのATTINY85を乗せて書き込みするのです。
これをブレッドボードに直挿しすれば、空中配線がスッキリするハズです。
Digisparkボード内のパーツも気にしなくてよくなります。
(後でATTINY85に振り回されることになるとは、知る由もないマーティー)
US$ 1.15(15% OFF)
ATTINY85のDIPタイプのピンアサイン
VBB(Mortor系)、VDD(Logic系)の立上げも
サンケン電気のDatasheet 8.16に、この記述がありました。
つまりどっちを電源ON/OFFでの順番は気にしなくていいようです。
今回は、Step UP Converterしか持ってないので
VBB:6.2Vは、VDD:5Vから作ることにします。
Friztingで実体配線図!
早速、書き込んでみます。
忘れてました~
これは、生チップなのでブートローダーが入ってないですね~(T_T)
所が、そう簡単にはいかず、長~いATTINY85地獄の始まりだったのです(-_-;)
この後、
ATTINY85(Digispark)との格闘に陥るわけであります。
すでに投稿してますが、格闘三部作になっております(-_-;)
・格闘Ⅰ(生チップへBootloader書込)
・格闘Ⅱ(謎のPULL-UP)
・格闘Ⅲ(妙なパルス)
<教訓>
① 内部PULL-UPは、信用しないこと!
Digisparkでは「pinMode(INPUT_PULLUP);」でPULL-UPされない
「digitalWrite(x, HIGH);」でPULL-UPされるが、されないPINがある
なので、必ず、外部PULL-UP抵抗をつける。
② DigisparkボードのPB1、PB3、PB4にぶら下がっているパーツに注意!
・PB1:GND間に「LED+1KΩ」あるので
LED 2Vとすると4.7KΩでPULL-UPしても2.5Vまでしか上がらない。
2KΩ以下でPULL-UPしないとHIGHレベルにならないでしょう。
・PB3:66.5Ωを挟んで3.6Vツェナー ~ GND、と1.5KΩ PULL-UP
・PB4:66.5Ωを挟んで3.6Vツェナー ~ GND
これだけでATTINY85から20mAも出すことになる。
実際にはドライブ不足でHIGHレベルが大きく低下する。
③ 単体のATTINY85は、挙動不審なので何が起こるかわからない。
動作が変な時は、必ずオシロで波形確認する。
ということで、思わぬ所でATTINY85地獄に落ちました(T_T)
抜け出すのに数日、とても苦労しました(-_-;)
さて、ATTINY85との格闘に三連勝して^^;
上下の基本動作がや~~~っと動いた所で
どうしてもA4988のENABLEが気になるのであります。
ADCを使って1pinでUP、DOWN、
折角なので、もう一つKEYを増やして、HOMEを追加!
1pin空くので、ENABLEに当てようと思いつきました!
このモーターは、常時電流流すのはキツそうなのです。
ENABLEでモーター電流OFFしても、ほとんど位置がズレそうにないし、
CO2レーザーなので1mm位ズレても問題ないでしょう。
1pinで3KEYに対応するには、
抵抗分割してADCで電圧を読むという手があります。
まあ、解像度が数段階のジョイスティックってところです。
しばし頭を捻って、このタイプA
同時押ししても高優先順位のが有効になりますが、
抵抗値の選定が面倒(まあExcelとかで計算すればいいですが)
と、このタイプB
SW2とSW3の同時押しで中間の電圧になりますが
抵抗値選定は、とても簡単!
ということで、後者のタイプBに!
UPはGNDで変動せず、±20%の変動を見ても、
DOWN: 1.76V±20% ・・・ 1.4~2.2V
HOME: 3.0V±20% ・・・ 2.4~3.6V
まあ、範囲が被らないから大丈夫でしょう。
というか、被らないように抵抗値を決めた結果ですが...
現時点の実体配線図!
できたスケッチです。
・Limit SWは、まだ使いません。
・KEY無操作が2sec続くと、ENABLE HIGHでモーター電流OFFにします。
・ADCを使った、1pinで3 Buttonの検出も動きました!
・Limit SWは、まだ使いません。
・KEY無操作が2sec続くと、ENABLE HIGHでモーター電流OFFにします。
・ADCを使った、1pinで3 Buttonの検出も動きました!
***CO2_Z-Axis_Move_E.ino***
// CO2 Laser Cutter Z-Axis Controller
// DigiSpark (ATTINY85)
// 抵抗分割して3-KEYをADCで検出
// PB1(Step):470KΩ+Diode(Pluse 立下りなまり対策)
// PB4(LimitSW):4.7KΩ程度のPullUp必須(内部Pull-Up不安定対策)
// 注意 see https://digistump.com/wiki/digispark/quickref
// Digital 2 is analog (ADC channel) 1
// Digital 3 is analog (ADC channel) 3
// Digital 4 is analog (ADC channel) 2
// Digital 5 is analog (ADC channel) 0
#define Direction 0 // PB0 for Direction HIGH: UP、LOW: DOWN
#define Step 1 // PB1 for Step Pluse
#define KEY_Detect 1 // For Analog ch1 = digital ch2(PB2)
#define nENABLE 3 // PB3 for nENABLE
#define LimitSW 4 // PB4 for Limit-SW(Upper & Lower)
#define nRESET 5 // PB5 for nRESET
int DontMoveCount = 0; // 非動作期間カウント
int MaxDontMoveCount = 2000; // これで約2秒
void setup() {
// initialize the digital pin as an output.
pinMode(Direction, OUTPUT); // DIRECTION
pinMode(Step, OUTPUT); // STEP
pinMode(KEY_Detect, INPUT); // ADC ch1(PB2)でKEY検出
pinMode(nENABLE, OUTPUT); // nENABLE
pinMode(LimitSW, INPUT); // LimitSW ("_PULLUP"は効かない)
digitalWrite(LimitSW, HIGH); // 一応これで内蔵PullUpをActiveにする
pinMode(nRESET, INPUT); // Reset(固定だが覚書)
// 初期値設定
digitalWrite(Direction, HIGH); // UP
digitalWrite(Step, LOW);
digitalWrite(nENABLE, HIGH); // Motor Disable
analogReference(DEFAULT); // Reference = VCC(5V) (念の為)
}
// 抵抗分割のKEYは、ADCで検出(1pinキー回路)
// UP : 0.0V(0~1.0V)
// DOWN: 1.76V±20% (1.4~2.2V)
// HOME: 3.0V±20% (2.4~3.6V) ・・・ 最上部に移動
// INPUT: 5V ・・・ ADC: 1023 なので
// UP : 0 to 205
// DOWN: 286 to 451
// HOME: 491 to 738
void loop() {
// 0 以上 ~ 205以下:UP
if ( (0 <= analogRead(KEY_Detect)) && (analogRead(KEY_Detect) <= 205)) {
DontMoveCount = 0;
digitalWrite(nENABLE, LOW); // ENABLEをACTIVEする
digitalWrite(Direction, HIGH);
// ここにLimit SW判定
move();
}
// 286 以上 ~ 451以下:DOWN
if ( (286 <= analogRead(KEY_Detect)) && (analogRead(KEY_Detect) <= 451)) {
DontMoveCount = 0;
digitalWrite(nENABLE, LOW); // ENABLEをACTIVEする
digitalWrite(Direction, LOW);
// ここにLimit SW判定
move();
}
// 491 以上 ~ 738以下:HOME ・・・ Limit SW 直前まで上がる
if ( (491 <= analogRead(KEY_Detect)) && (analogRead(KEY_Detect) <= 738)) {
DontMoveCount = 0;
digitalWrite(nENABLE, LOW); // ENABLEをACTIVEする
digitalWrite(Direction, HIGH);
// ここにHoming動作が入る
}
// KEYを押してない時は、5V(VCC)になる
// 一定カウント超えたらnENABLEをHIGHにしてモーター電流停止
// SW ALL OFF 739~1023
if ((739 <= analogRead(KEY_Detect)) && (analogRead(KEY_Detect) <= 1023)) {
// 非動作期間カウントUP処理
DontMoveCount = ++DontMoveCount;
if ( DontMoveCount >= MaxDontMoveCount ) {
digitalWrite(nENABLE, HIGH); // ENABLEをDISABLEする
DontMoveCount = 0; // カウントリセット
}
}
}
void move() {
digitalWrite(1, HIGH);
delayMicroseconds(2250);
digitalWrite(1, LOW);
delayMicroseconds(2250);
}
*****
が、SWを素早く押しても1mm程動き、微妙な操作ができません。
素早く押すといっても、100msec位は、押してるので、
1step 4.5msecが22 Pluseも出て、0.0375 x 22=0.825mm
動いてしまうというわけです。
「短押し:チョン」と「長押し:0.3sec以上」で
動きを変えることにします。
0.1sec未満のKEY押しは、ノイズとみなして無視することにして、
<短押し>
これは、この時にとても苦労して作った
ATTINY85にかなりもて遊ばれました~(-_-;)
やっとLimit Switchに行けそうです。
PICに乗り換えたくなってきましたが
一旦、最後までATTINY85で頑張ってみるつもりですが...^^;0.1sec未満のKEY押しは、ノイズとみなして無視することにして、
<短押し>
・0.1~0.3sec 同じKEYを押すとSTEP信号を出す
・1STEP毎に0.1secのDelayを入れる。
<長押し>
・0.3sec以上 同じKEYを押してるとDelayをなくして連続移動にします。
・0.3sec以上 同じKEYを押してるとDelayをなくして連続移動にします。
これは、この時にとても苦労して作った
JOYSTICKで上下左右3段階検出のスケッチが役立ちました^^;
0.1secに比べ十分無視できます。
やや格闘したスケッチ「CO2_Z-Axis_Move_F」バージョンは、
動作したけど、ちとゴチャゴチャなので整理してます。
動作したけど、ちとゴチャゴチャなので整理してます。
チョンチョンで1step、長押しで連続移動
時間は正確ではないけど、動作は、良い感じです\(^o^)/
***CO2_Z-Axis_Move_G.ino***
// CO2 Laser Cutter Z-Axis Controller
// DigiSpark (ATTINY85)
// 抵抗分割して3-KEYをADCで検出
// PB1(Step):470KΩ+Diode(Pluse 立下りなまり対策)
// PB4(LimitSW):4.7KΩ程度のPullUp必須(内部Pull-Up不安定対策)
// 1 PUSHで1mm以上移動するので
// 0.1~0.3sec同一KEY押下で、1STEP送出
// 0.3sec以上の同一KEY押下で連続移動
// 注意 see https://digistump.com/wiki/digispark/quickref
// Digital 2 is analog (ADC channel) 1 今回は、これ
// Digital 3 is analog (ADC channel) 3
// Digital 4 is analog (ADC channel) 2
// Digital 5 is analog (ADC channel) 0
#define Direction 0 // PB0 for Direction HIGH: UP、LOW: DOWN
#define Step 1 // PB1 for Step Pluse
#define KEY_Detect 1 // For Analog ch1 = digital ch2(PB2)
#define nENABLE 3 // PB3 for nENABLE
#define LimitSW 4 // PB4 for Limit-SW(Upper & Lower)
#define nRESET 5 // PB5 for nRESET
int DontMoveCount = 0; // 非動作期間カウント
int MaxDontMoveCount = 500; // これで約0.5秒
short ContenuousMode = 0; // 0:シングル動作、1:連続動作
#define None_Key 4
#define UP_Key 1
#define DOWN_Key 2
#define HOME_Key 3
short KeyPosition = None_Key; // 今押したKEY 4:None Key、1:UP、2:DOWN、3:Home
short last_KeyPosition = None_Key; // 前押したKEY 4:None Key、1:UP、2:DOWN、3:Home
int SameKeyCount = 0; // 同一KEY押下時間カウント
short WaitCount = 0; // Single Step移動時の無効化時間カウント
short WaitCountIncrease = 10; // 1LOOPの時間が約10msecになるようにする
void setup() {
// initialize
pinMode(Direction, OUTPUT); // DIRECTION
pinMode(Step, OUTPUT); // STEP
pinMode(KEY_Detect, INPUT); // ADC ch1(PB2)でKEY検出
pinMode(nENABLE, OUTPUT); // nENABLE
pinMode(LimitSW, INPUT); // LimitSW ("_PULLUP"は効かない)
digitalWrite(LimitSW, HIGH); // 一応これで内蔵PullUpをActiveにする
pinMode(nRESET, INPUT); // Reset(固定だが覚書)
// 初期値設定
digitalWrite(Direction, HIGH); // UP
digitalWrite(Step, LOW);
digitalWrite(nENABLE, HIGH); // Motor Disable
analogReference(DEFAULT); // Reference = VCC(5V) (念の為)
}
void loop() {
KeyDetect(); // ADCのKEY状態をScan
MoveProcess(); // KEY押下時間判定して移動処理
}
// 抵抗分割のKEYは、ADCで検出(1pinキー回路)
// UP : 0.0V(0~1.0V)
// DOWN: 1.76V±20% (1.4~2.2V)
// HOME: 3.0V±20% (2.4~3.6V) ・・・ 最上部に移動
// INPUT: 5V ・・・ ADC: 1024 なので
// UP : 0 to 205
// DOWN: 286 to 451
// HOME: 491 to 738
void KeyDetect() {
// 0 以上 ~ 205以下:UP
if ( (0 <= analogRead(KEY_Detect)) && (analogRead(KEY_Detect) <= 205)) {
KeyPosition = UP_Key;
}
// 286 以上 ~ 451以下:DOWN
if ( (286 <= analogRead(KEY_Detect)) && (analogRead(KEY_Detect) <= 451)) {
KeyPosition = DOWN_Key;
}
// 491 以上 ~ 738以下:HOME ・・・ Limit SW 直前まで上がる
if ( (491 <= analogRead(KEY_Detect)) && (analogRead(KEY_Detect) <= 738)) {
KeyPosition = HOME_Key;
}
// KEYを押してない時は、5V(VCC)になる
// 一定カウント超えたらnENABLEをHIGHにしてモーター電流停止
// キーを押してもカウントリセット必要
// SW ALL OFF 739~1023
if ((739 <= analogRead(KEY_Detect)) && (analogRead(KEY_Detect) <= 1023)) {
KeyPosition = None_Key;
}
}
void MoveProcess(){
if (last_KeyPosition == KeyPosition) { // 前KEYと同一KEY押下の場合
SameKeyCount = SameKeyCount + WaitCountIncrease; // ① 1loop分増加
// 同一Positionに最低閾値~300msec定位していればシングルstep移動命令
// 同一KEY押下が約100~300msecであれば、シングルstep動作
if ( 1000 <= SameKeyCount && SameKeyCount < 3000 ) {
if ( WaitCount == 0 ) { // KEY変化の最初
ContenuousMode = 0; // 連続モードOFF
MoveControl(); //
WaitCount = WaitCount + WaitCountIncrease; // 1loop分増加
} else { // 2回めに同一KEY検出したら290 Wait
// 一定期間(300msec弱)不感時間を設ける為のカウンタ
WaitCount = WaitCount + WaitCountIncrease; // 1loop分増加
if( WaitCount > 2900) {
WaitCount = 0;
}
}
// KEY押下時間SameCountが100未満の場合、①のカウントUPのみ
}
// 同一Positionに約300msec以上定位していれば連続移動命令
if (SameKeyCount >= 3000) {
// 一定間隔で出力する連続モード
ContenuousMode = 1;
MoveControl(); // delayなしでMoveする
}
} else { // 前KEYと異なるKEY押下の場合
// 初めてのKeyScan時の初期化処理
// ノイズも含め全ての検出は、最初にここを通る
last_KeyPosition = KeyPosition;
SameKeyCount = 0;
WaitCount = 0;
}
}
void MoveControl() {
switch ( KeyPosition ) { // KEYに応じて処理
case 1: // UP
DontMoveCount = 0;
// UP処理
// ここにLimit SW判定
digitalWrite(nENABLE, LOW); // ENABLEをACTIVEする
digitalWrite(Direction, HIGH);
SendStepPluse();
break;
case 2: // DOWN
DontMoveCount = 0;
// DOWN処理
// ここにLimit SW判定
digitalWrite(nENABLE, LOW); // ENABLEをACTIVEする
digitalWrite(Direction, LOW);
SendStepPluse();
break;
case 3: // HOME・・・上側Limit SWまでUP
DontMoveCount = 0;
digitalWrite(nENABLE, LOW); // ENABLEをACTIVEする
digitalWrite(Direction, HIGH);
// ここにHOMING処理
delay(1000); // HOMEの後は、少しDelayした方がいいだろう
break;
case 4: // None KEY(KEY押下なし)
// nENABLEをDISABLEしてMOTOR OFF処理
// 非動作期間カウントUP処理
DontMoveCount = ++DontMoveCount;
if ( DontMoveCount >= MaxDontMoveCount ) {
digitalWrite(nENABLE, HIGH); // ENABLEをDISABLEする
DontMoveCount = 0; // カウントリセット
}
break;
}
}
void SendStepPluse() {
digitalWrite(1, HIGH);
delayMicroseconds(2250);
digitalWrite(1, LOW);
delayMicroseconds(2250);
}
***
やっとLimit Switchに行けそうです。
PICに乗り換えたくなってきましたが
0 件のコメント:
コメントを投稿