ここから本文です

arduinoでステッピングモータを制御しています。 #define INTERVAL 169 #defi...

アバター

ID非公開さん

2018/3/2109:48:41

arduinoでステッピングモータを制御しています。

#define INTERVAL 169
#define MICRO 256/256

void setup(){

}

void loop(){

int ii;

for(ii=0;ii<=255;ii=ii+MICRO

){
analogWrite(5,0);
analogWrite(6,ii);
delay(INTERVAL*MICRO);
}

for(ii=0;ii<=255;ii=ii+MICRO){
analogWrite(5,ii);
analogWrite(6,255);
delay(INTERVAL*MICRO);
}

for(ii=255;0<=ii;ii=ii-MICRO){
analogWrite(5,255);
analogWrite(6,ii);
delay(INTERVAL*MICRO);
}

for(ii=255;0<=ii;ii=ii-MICRO){
analogWrite(5,ii);
analogWrite(6,0);
delay(INTERVAL*MICRO);
}
}

intervalをもっと小さくすると正常に動くのですが、ここまで大きくすると動きません。オーバーフローしているそうです。
このスピードでどうにかして動かせないでしょうか。
滑らかさはあまり犠牲にしたくありません。
何方か詳しい方お教えください。

閲覧数:
83
回答数:
3
お礼:
100枚

違反報告

ベストアンサーに選ばれた回答

プロフィール画像

カテゴリマスター

qui********さん

2018/3/2111:03:33

INTERVALが登場するのは
delay(INTERVAL*MICRO);
だけなのでそこの話ですか。

C/C++でのマクロ(#define)は、単に文字列の置換を行うだけです。なので、マクロ中に式を書いたりする時は注意深くしなければいけません。

#define MICRO 256/256
とありますが、これは、プログラム中のMICROという語を単純に256/256に置き換えます。すると、
INTERVAL*MICROは
192*256/256
に置き換えられます。192*256を計算しその結果を256で割る...のですが。C/C++の整数計算は、特に指定しなければint型の範囲で行われます。Arduino UNOではintは16ビットの符号付き、つまり-32768~32767の間の値しか表せませんが
192*256を計算した時点でこの範囲を逸脱してしまい、49152にはなりません... -16384、かな。もうこの時点で駄目ですね。
(Arduinoと言ってもいろいろあります。Arduino M0等ではintが32bitなのでこの程度では問題は起こりません)

その他にも、そのマクロでは(今回のプログラムの使い方ではありませんが)
512/MICRO
はどうなるかというと
512/256/256
に置き換えられるので、512/256は2。2/256は...整数演算としては0になっちゃいます。(こちらは整数演算である以上他のArduinoでも起こります)

で、どうするかというと。
1.
Arduino言語はC++をベースにしています。なので、constをつけるとちゃんと定数として扱われます(Cではconstが変更禁止というだけで「定数」ではなかった)。
なので、
const int INTERVAL=192;
const float MICRO=256./256;
とすると、MICROには計算済の値が入りますので、オーバーフローは起こりません。なお、256/256という書き方は当然どちらかの値が変わる可能性があるからですよね? であれば、どちらかの値を浮動小数点型にしておかないと、先程の話と同様整数同士の演算で整数型として扱われますから、255/256だと0、256/255は1という計算結果になります。どちらかの値に小数点をつければ、浮動小数点型として扱われるようになります。

2.
どうしてもマクロで扱いたいのなら
#define MICRO (256./256)
とでもしましょうか。カッコで括ることによって256/MICROみたな除数に使ったときでも期待する動作をするようになります。また、先程と同様、浮動小数点型として扱われるように小数点をつけます。

3.
浮動小数点は処理が重いので使いたくない...で、除数に使うこともこのプログラムだからやらない、といい切るのなら
#define INTERVAL 192l
#define MICRO 256/256
として、lをつけることでlong型の値に拡張してやる手もあります。そうすると、192l*256が49152として扱われるので期待する結果が得られるでしょう。


マクロの数式については
#define MACRO 1+2
とかでも注意しなければいけません。
3*MACRO

3*1+2
なので5になります。決して9にはなりません。
const int MACRO=1+2;
あるいは
#define MACRO (1+2)
とすべきところです。

  • qui********さん

    2018/3/2111:14:37

    それはそれとして、
    ステッピングモーターを動かすプログラムにも見えないし、マイクロステップっていうのとは違う話に思えるけどなぁ?
    普通のDCモーターをTA7291辺りのHドライバで回しているかのような...?

  • その他の返信(1件)を表示

返信を取り消しますが
よろしいですか?

  • 取り消す
  • キャンセル

ベストアンサー以外の回答

1〜2件/2件中

並び替え:回答日時の
新しい順
|古い順

kaw********さん

2018/3/2209:42:31

■そのモータ 1Pulseで1Step動く物ですから
「低速でも滑らかに回れ!」は無理難題 パワハラです。

■そのモータ 1Pulseで1Step動く物ですから
「低速でも滑らかに回れ!」は無理難題 パワハラです。

プロフィール画像

カテゴリマスター

fri********さん

2018/3/2118:59:33

ソフトウエアだけの問題なら、
#define MICRO 256/256

#define MICRO 1
に修正すれば上手くいくはずです。

次のように書き直せばもっとすっきりします。
#define INTERVAL 169
void setup(){}
void loop(){
int i, j, p, q;
for (i=0; i<4; i++){
for(j=0; j<256; j++){
switch(i){
case 0: p=0; q=j; break;
case 1: p=j; q=255; break;
case 2: p=255; q=255-j; break;
case 3: p=255-j; q=0; break;
}
analogWrite(5, p);
analogWrite(6, q);
delay(INTERVAL);
}
}
}


しかし、これほど遅いマイクロステップが
ちゃんと機能するかどうかは疑問です。

目的に対してモーターの選定が適切で無い
のではありませんか。要検討だと思います。

あわせて知りたい

この質問につけられたタグ

みんなで作る知恵袋 悩みや疑問、なんでも気軽にきいちゃおう!

Q&Aをキーワードで検索:

Yahoo! JAPANは、回答に記載された内容の信ぴょう性、正確性を保証しておりません。
お客様自身の責任と判断で、ご利用ください。
本文はここまでです このページの先頭へ

「追加する」ボタンを押してください。

閉じる

※知恵コレクションに追加された質問は選択されたID/ニックネームのMy知恵袋で確認できます。

不適切な投稿でないことを報告しました。

閉じる