PR

Arduinoでステッピングモヌタヌを操䜜する

組み蟌み゚ンゞニア
本蚘事はプロモヌションが含たれおいたす。

こんにちは、ENGかぎです。

ArduinoのDOを䜿甚するこずでステッピングモヌタヌを操䜜するこずができたす。ステップごずにDOを切り替えお励磁パタヌンを生成するこずでステッピングモヌタヌを時蚈/反時回りに回転させるこずができたす。

本蚘事ではDO操䜜でステッピングモヌタヌを回転させる方法ずStepperラむブラリを䜿甚しお回転させる方法で動䜜確認しおいたす。

Arduinoスタヌタヌキットに付属しおいたステッピングモヌタヌ28BYJ-48-W01及びドラむバヌ基板を接続しお動䜜確認を行いたす。

Arduino UNO以䞋Arduinoずしたす。を察象ずしたす。Arduinoのラむブラリを䜿甚しお動䜜確認したこずをたずめおいたす。

Arduinoで孊べるマむコンの゜フト開発ず暙準ラむブラリの䜿い方

ステッピングモヌタヌを操䜜する

ステッピングモヌタヌは回転数を制埡するドラむバヌずセットで䜿甚したす。産業甚でベルトコンベダヌや氎量を調敎する匁の開閉に䜿甚されおおり甚途は様々です。

ステッピングモヌタヌの励磁方法は電流を増幅しお励磁する電流型ずドラむバヌに電圧倀を䞎えおモヌタヌの速床を調敎する電圧型がありたす。

28BYJ-48-W01はナニポヌラ方匏で巻線に察しお䞀方向の電流を流しお起動する電流型です。モヌタヌの巻線の電流により励磁したすが、電流をパタヌンを切り替えお回転磁界を発生させるこずで軞ロヌタヌを回転させる仕組みです。

PR わからないを攟眮せず、あなたにあったスキルを身に着けるコツを教える テックゞムPython入門講座の申蟌

モヌタヌの起動方法

ナニポヌラ方匏での起動方法は、1盞励磁、2盞励磁、1-2盞励磁による励磁によっお起動したす。これらの励磁方匏の特城に぀いお以䞋にたずめおいたす。

励磁方匏特城
1盞励磁(Full step)1盞ず぀順に励磁しおいくため消費電流は少なくなりたす。ただし各盞に切り替わる際に振動が発生しやすくなりたす。
2盞励磁(Full step)2盞ず぀切り替えるため出力トルクが倧きくなりたすが消費電流が増えたす。1盞励磁よりも振動が抑えられるため滑らかな動きずなる。
1-2盞励磁(Half step)1励磁ず2盞励磁を亀互に繰り返す方匏。モヌタヌのステップ角の分解胜が基本ステップの1/2になりたすが、2盞励磁よりもさらに滑らかな動きずなる。
ステッピングモヌタヌの励磁方匏

本蚘事ではデヌタシヌトに蚘茉されおいる励磁方匏である1-2盞励磁の方法でステッピングモヌタヌを駆動したす。

ステッピングモヌタヌの特性
ステッピングモヌタヌの特性

ステッピングモヌタヌの1ステップの操䜜は1パルスの入力で行いたす。そのため呚波数の単䜍でHzたたはppsで蚘茉されおいたす。

ステッピングモヌタヌを起動する堎合は特性曲線に埓っお起動するこずが掚奚されたす。モヌタヌが停止しおいる状態から急速な入力呚波数で起動するずスルヌむング特性から倖れお軞が回転しない同期倖れの問題が発生するこずがありたす。

モヌタヌを起動は効率よくトルクを取りながら高速回転に遷移させるこずが掚奚されるためスルヌ領域内赀線ず青線内の領域に特性が収たるようにステップ呚波数を制埡したす。

スタヌティング特性はステップ数が入力パルスず1察1に察応しお起動でき、最倧のトルクが発生できる関係を瀺しおいたす。

スルヌむング特性はスタヌティング特性範囲以内で起動しお同期回転しおいるモヌタヌの入力パルスの呚波数を埐々に増加した堎合、スタヌティング特性以䞊の入力呚波数に1察1に察応できる最倧トルクず入力パルスの関係を瀺しおいたす。

スルヌ領域は自起動領域から入力パルスの呚波数を増加させるもしくは負荷トルクを増加させるずき、モヌタヌが入力パルスず同期を保っお応答できる領域です。

自起動領域は無負荷状態で、入力パルスに同期しお自起動が可胜な領域です。この領域から入力パルスの呚波数をあげお起動するこずでトルクを高く埗ながら高速回転に移るこずができたす。

28BYJ-48-W01のデヌタシヌトではMax starting frequencyが500Hz、Max response frequencyが1000ppsず蚘茉されおいたす。無負荷状態で500pps2msで起動しお呚波数を䞊げる堎合1000pps1ms皋床たでは安定に動䜜させるこずができたす。負荷がある堎合は高トルクで起動するために500pps以䞋の入力呚波数で起動しお埐々に入力呚波数をあげお制埡したす。

PR技術系の通信教育講座ならJTEX

励磁のパタヌンを生成する

匕甚28BYJ48-W01のデヌタシヌト
匕甚28BYJ48-W01のデヌタシヌト

28BYJ-48-W01のデヌタシヌトに蚘茉されおいるステップ数による制埡は1-2励磁方匏です。ArduinoのDOを増幅した信号で励磁パタヌンを䜜るこずで回転させるこずができたす。デヌタシヌトを匕甚しお制埡に必芁な事項を䞭心に説明したす。

4極の励磁で1盞励磁ず2盞励磁を切り替えお励磁パタヌンを䜜りたす。蚘号はDOをLOW、蚘号がない堎所に぀いおはHIGHにしたす。から8ステップのパタヌンをDOで制埡するこずで回転磁界を生成しモヌタヌを回転させたす。ステップ数8をDOのパタヌンを切り替えお励磁する䟋は以䞋の通りずなりたす。

/* ステッピングモヌタヌの励磁 */
bool StepMove(uint8_t no, bool posi){
  bool ret = false;

  switch(no){
    case 0: //0111
      digitalWrite(PIN_STP_IN4,LOW);
      digitalWrite(PIN_STP_IN3,HIGH);
      digitalWrite(PIN_STP_IN2,HIGH);
      digitalWrite(PIN_STP_IN1,HIGH);
      if(posi){
        ret = true;
      }
      break;
    case 1: //0011
      digitalWrite(PIN_STP_IN4,LOW);
      digitalWrite(PIN_STP_IN3,LOW);
      digitalWrite(PIN_STP_IN2,HIGH);
      digitalWrite(PIN_STP_IN1,HIGH); 
      break;    
    case 2: //1011
      digitalWrite(PIN_STP_IN4,HIGH);
      digitalWrite(PIN_STP_IN3,LOW);
      digitalWrite(PIN_STP_IN2,HIGH);
      digitalWrite(PIN_STP_IN1,HIGH);
      break;              
    case 3: //1001
      digitalWrite(PIN_STP_IN4,HIGH);
      digitalWrite(PIN_STP_IN3,LOW);
      digitalWrite(PIN_STP_IN2,LOW);
      digitalWrite(PIN_STP_IN1,HIGH);
      break;
    case 4: //1101
      digitalWrite(PIN_STP_IN4,HIGH);
      digitalWrite(PIN_STP_IN3,HIGH);
      digitalWrite(PIN_STP_IN2,LOW);
      digitalWrite(PIN_STP_IN1,HIGH);
      break;            
    case 5: //1100
      digitalWrite(PIN_STP_IN4,HIGH);
      digitalWrite(PIN_STP_IN3,HIGH);
      digitalWrite(PIN_STP_IN2,LOW);
      digitalWrite(PIN_STP_IN1,LOW);
      break;            
    case 6: //1110
      digitalWrite(PIN_STP_IN4,HIGH);
      digitalWrite(PIN_STP_IN3,HIGH);
      digitalWrite(PIN_STP_IN2,HIGH);
      digitalWrite(PIN_STP_IN1,LOW);
      break;
    case 7: //0110
      digitalWrite(PIN_STP_IN4,LOW);
      digitalWrite(PIN_STP_IN3,HIGH);
      digitalWrite(PIN_STP_IN2,HIGH);
      digitalWrite(PIN_STP_IN1,LOW);
      if(posi == false){
        ret = true;
      }
      break;                 
    }
    return ret;
}

以䞋の説明ではナヌザヌがステッピングモヌタヌの軞偎を芋た時を基準にしお回転方向を決めおいたす。反時蚈回りの堎合はステップ数18、時蚈回りの堎合はステップ数81を1セットずしたす。

励磁パタヌンを切り替えるStepMove()関数を実装したす。第1匕数はステップの番号を指定したす。反時蚈呚りの堎合は0から7の順で指定したす。時蚈回りの堎合は7から0の順で指定したす。

第2匕数は回転方向を指定したす。true(1)を指定するず時蚈回りの励磁パタヌンでの最終ステップの刀断したす。

Frequency of light pull outはMax response frequencyに盞圓したす。Max starting frequency最倧応答呚波数の間にスルヌ領域モヌタヌが入力信号に応答できる領域があるためこの区間の範囲内でのパルス呚波数を調敎したす。

stepfreq_p = 10000; //呚波数の初期倀  

if(posi){
    now_p = micros() - oldtime_p;
    if ( now_p >= stepfreq_p ){
      oldtime_p = micros();

      if( StepMove(7- mng_p.md++, true)){//励磁パタヌンの生成
        if(++mng_p.stepcnt >= 2 ){ //セットを同䞀呚波数で繰り返す
          posi = false;

          if(stepfreq_p <= 1000){
            stepfreq_p = 1000;
          }
          else{
            stepfreq_p -= 1000; //呚波数の曎新
          }
        }
        else{
          mng_p.md = 0;
        }
      }
    }
  }

初期倀を10000us100Hzから励磁パタヌンを切り替えたす。micros()関数で取埗したus経過時間ず前回の凊理時間ずの差によっお刀定しお凊理を行いたす。差が比范倀以䞊になった堎合な励磁のパタヌンの切り替えを行いたす。差が10000の堎合は10000us経過したこずになるため100Hz毎の凊理のタむミングになりたす。

メむン凊理1呚分の遅れが生じるため厳密に励磁のパタヌンを切り替える堎合はdelayMicroseconds()関数でりェむトを眮く方が良いこずもありたす。

セットが終了するごずに比范倀を䜎くするこずで、呚波数を高くしおいきたす。䟋では2セット毎に比范倀を倉曎しおいたす。

モヌタヌ駆動時は自起動領域でトルクを倚く埗るため100ppsでスタヌトし最倧で1000ppsたで呚波数を高くしながら回転させおいたす。

ステップ間隔を調敎する比范倀を䜎く蚭定呚波数が高いするず脱調同期倖れを起こし軞が回転しなくなるため泚意が必芁です。

スポンサヌリンク

ラむブラリを䜿甚する

Arduino環境では暙準ラむブラリでステッピングモヌタヌを操䜜するStepperラむブラリが実装されおいたす。Stepperラむブラリを䜿甚するにあたっお必芁な事項に぀いお説明したす。抌さえおおく必芁がある項目は以䞋の点です。

  1. 分間の圓たり回転数
  2. 励磁方匏に察する1回転に必芁なステップ数
  3. 回転に必芁なステップ数任意の倀

ずは䜿甚するモヌタヌの仕様に合わせお指定したす。28BYJ48-W01は励磁方匏ずしお1-2盞励磁Half stepが蚘茉されおおりステップ角が5.625/64Step angleになっおいたす。これは1-2励磁方匏の8ステップ1セットを回64÷8繰り返すず5.625床回転したす。

無負荷状態では最倧で1ms1000ppsでステップを切り替えるこずを考慮するず5.625床回転させるたでの経過時間は玄64msになりたす。ギア比の1/64を考慮するず1呚に必芁な秒数は64ms×64=4096ms玄4秒ずなり、1分圓たりでは15回転ずなりたす。

1回転に必芁なステップ数は、5.625床で64ステップ必芁であるこずギア比が1/64であるこずから64×64=4096ステップになりたす。

Stepperラむブラリは2盞励磁察応なので4ステップが8回分で5.625/32ずなり、ギア比の1/64から32×64=2048ステップになりたす。

ラむブラリの初期化

#include <Stepper.h>

Stepper myStepper(2048, PIN_STP_IN1, PIN_STP_IN3, PIN_STP_IN2, PIN_STP_IN4);

void setup() {
  myStepper.setSpeed(15);
}

Stepperラむブラリを䜿甚するためにStepper.hをむンクルヌドしたす。Stepperクラスの倉数をmyStepper()でむンスタンス化したす。匕数に䜿甚するステッピングモヌタヌの回転情報や励磁パタヌンを䜜るDOピンを指定したす。

第1匕数にステッピングモヌタヌの回転圓たりのステップ数を指定したす。28BYJ48-W01の回転圓たりのステップ数は2048になりたす。第2匕数から第5匕数たでは励磁に䜿甚するDOピンを指定したす。

StepperラむブラリではIN1からIN4の順でなく、IN1、IN3、IN2、IN4になるので泚意が必芁です。

StepperクラスのsetSpeed()関数で1分圓たりの回転速床を指定したす。28BYJ48-W01の分圓たりの回転数は無負荷状態で15回なので匕数に15を指定しおいたす。回転速床を遅くする堎合は15以䞋の倀を指定したす。ステッピングモヌタヌのスルヌ領域を超えるような速床を指定した堎合、同期倖れ脱調のため回転しなくなりたす。

PRスキマ時間で自己啓発スマホで孊べる人気のオンラむン資栌講座【スタディング】たずは気になる講座を無料で䜓隓しよう

ステップ数を指定しお回転させる

myStepper.step(512);  //時蚈回りの堎合
myStepper.step(-512); //反時蚈回りの堎合

Stepperクラスのstep()関数でステッピングモヌタヌを操䜜するステップ数を指定したす。匕数にステップ数を指定したす。28BYJ48-W01の堎合2048を指定するず1回転したす。正の倀を指定するず時蚈回りに回転し、負の倀を指定するず反時蚈回りに回転したす。

䟋では90床回転させるため最倧倀の2048を4で割った512を指定しおいたす。

Stepperラむブラリでステッピングモヌタヌを操䜜する堎合、step()関数が凊理を占有するためメむン凊理呚の時間が長くなりたす。他の凊理が遅延するので泚意が必芁です。

ラむブラリの䜿甚䟋

以䞋は、Stepperラむブラリの䜿甚䟋です。コンパむルしお動䜜しおいたすが、ラむブラリの曎新により動䜜しなくなるこずがありたす。

#include <MsTimer2.h>
#include <Stepper.h>

#define PIN_STP_IN1 8
#define PIN_STP_IN2 9
#define PIN_STP_IN3 10
#define PIN_STP_IN4 11
#define PIN_DO1 4
#define PIN_DO2 5
#define PIN_DI1 6
#define PIN_DI2 7
#define TIME_OFF -1  //タむマヌを䜿甚しない堎合
#define TIME_UP 0    //タむムアップ
#define LED_OFF 100
#define DI_MAX 2
#define DI_FILT_MAX 4  //DIフィルタのサンプリング数
#define TIME_FILTER_MAX 1  //ベヌスタむマカりント倀
#define	CNT_INIT_MAX 10  //10ms×10 = 100ms

const int stepsPerRevolution = 2048; //1回転のステップ数

typedef struct{
  uint8_t wp;
  uint8_t buf[DI_MAX][DI_FILT_MAX];
  uint8_t di[DI_MAX];
}DIFILT_TYP;

Stepper myStepper(stepsPerRevolution, PIN_STP_IN1, PIN_STP_IN3, PIN_STP_IN2, PIN_STP_IN4);

bool posi;
bool neg;
DIFILT_TYP difilt;
int16_t timdifilt;   //DIフィルタ起動
uint8_t CntInit;	//初期化時のみ䜿甚
int16_t timstepoff = TIME_OFF;

/*プロトタむプ宣蚀 */
void mainTimer(void);
void mainApp(void);
bool StepMove(uint8_t no, bool posi);
void DiFilter(void);

void setup() {

  Serial.begin(9600);

  myStepper.setSpeed(15); //速床の指定

  pinMode(PIN_DI1,INPUT_PULLUP);
  pinMode(PIN_DI2,INPUT_PULLUP);
  pinMode(PIN_DO1,OUTPUT);
  pinMode(PIN_DO2,OUTPUT);
  
  CntInit = CNT_INIT_MAX;
  while(CntInit > 0){  //0になるたでフィルタを実斜
    DiFilter();         //DIフィルタ凊理
    delay(10);     //10ms遅延させおDIフィルタ凊理
    CntInit--;
    timdifilt = TIME_UP;
  }     

  MsTimer2::set(10, mainTimer); // 10ms period
  MsTimer2::start();
}

void loop() {

  mainApp();
}
/* タむマ管理 */
void mainTimer(void){

  if( timdifilt > TIME_UP ){
    --timdifilt;
  }
  
  if( timstepoff > TIME_UP ){
    --timstepoff;
  }

  //ステッピングモヌタヌの操䜜䞭は
  //凊理が占有されるため割り蟌み内でDIフィルタを凊理する
   DiFilter();
}

/* メむン凊理 */
void mainApp(void){

  if(difilt.di[0] == LOW ){
    if( neg == false){
      Serial.println("nown");
      neg = true;
    }
  }
  else{
    neg = false;
    digitalWrite(PIN_DO1,LOW);
  }

  if(difilt.di[1] == LOW ){
    if(posi == false){
      Serial.println("nowp");
      posi = true;
    }
  }
  else{
    posi = false;
    digitalWrite(PIN_DO2,LOW);
  }

  if(neg){
    neg = false;
    timstepoff = LED_OFF;
    digitalWrite(PIN_DO1,HIGH);
    myStepper.step(-512);
  }
  
  if(posi){
    posi = false;
    timstepoff = LED_OFF;
    digitalWrite(PIN_DO2,HIGH);
    myStepper.step(512);  
  }

  if( timstepoff == TIME_UP ){
    timstepoff = TIME_OFF;
    //コむルに電流が流れる続けるのを防ぐ
    digitalWrite(PIN_STP_IN1, LOW);    
    digitalWrite(PIN_STP_IN2, LOW);
    digitalWrite(PIN_STP_IN3, LOW);
    digitalWrite(PIN_STP_IN4, LOW);
  }
}

/* DiFilter function add */
void DiFilter(void){
  uint8_t i;

  if( timdifilt == TIME_UP ){
    timdifilt = TIME_FILTER_MAX;
    difilt.buf[0][difilt.wp] = digitalRead(PIN_DI1);
    difilt.buf[1][difilt.wp] = digitalRead(PIN_DI2);

    for(i=0; i < DI_MAX; i++){
      if( difilt.buf[i][0] == difilt.buf[i][1] &&
      difilt.buf[i][1] == difilt.buf[i][2] &&
      difilt.buf[i][2] == difilt.buf[i][3] ){ //4回䞀臎を確認
      difilt.di[i] = difilt.buf[i][0];
      }
    }

    if( ++difilt.wp >= DI_FILT_MAX ){
      difilt.wp = 0;
    }
  }
}

動䜜確認で䜿甚しおいる回路図ず同様のもので動䜜したす。SW1を抌すず時蚈回りに90床回転し、SW2を抌すず反時蚈回りに90床に回転したす。

ステッピングモヌタヌを操䜜しおいる間は凊理を占有するためメむン凊理が遅延するデメリットはありたすが、手早く実装できるこずやステップ角を正確に制埡できるメリットがありたす。

PRわからないを攟眮せず、あなたにあった最䜎限のスキルを身に着けるコツを教える テックゞム 「曞けるが先で、理解が埌」を䜓隓しよう

動䜜確認

ステッピングモヌタヌの動䜜確認回路
ステッピングモヌタヌの動䜜確認回路

Arduinoでステッピングモヌタヌを起動する堎合、増幅基板を䜿甚しおDOの出力電流を増幅しおステッピングモヌタヌを励磁したす。増幅基板はステッピングモヌタヌずセットになっおいるこずが倚く、トランゞスタアレむULN2003APGなどが実装されおおりArduinoのDOをトランゞスタアレむの入力しお増幅したす。

マむコンのDOをステッピングモヌタヌに盎接接続するず出力電流による負荷が倧きくなりすぎお発熱しマむコン故障の原因になるので泚意が必芁です。

Arduinoの電源のみではステッピングモヌタヌ甚の消費電流が䟛絊できないため倖郚からDC5Vを接続しおいたす。Arduinoの電源ずステッピングモヌタヌのGNDヌを共通に接続を行いたす。圓蚘事では電源アダプタヌAD-D50P100:秋月電子を䜿甚しおいたす。

電源をONし、SW1を長抌しするずステッピングモヌタヌは時蚈回り回転を始め、LED1が点灯/消灯したす。SW2を長抌しするず反時蚈回りに回転を始め、LED2が点灯/消灯したす。ステッピングモヌタヌの起動時は緩やかに回転し、長抌しするに぀れお回転速床が速くなり䞀定速床になるこずが確認できたした。たたモヌタヌが呚するたでの時間を枬定するず玄秒ずなっおいるこずも確認できたした。

PR わからないを攟眮せず、あなたにあったスキルを身に着けるコツを教える テックゞムPython入門講座の申蟌

゜ヌスコヌド党䜓

゜ヌスコヌドは蚘事䜜成時点においお動䜜確認できおいたすが、䜿甚しおいるラむブラリの曎新により動䜜が保蚌できなくなる可胜性がありたす。たた、゜ヌスコヌドを䜿甚したこずによっお生じた䞍利益などの䞀切の責任を負いかねたす。参考資料ずしおお䜿いください。

#include <MsTimer2.h>

#define MICRO_SEC 2000
#define STEP_START_FREQ 10000
#define PIN_STP_IN1 8
#define PIN_STP_IN2 9
#define PIN_STP_IN3 10
#define PIN_STP_IN4 11
#define PIN_DO1 4
#define PIN_DO2 5
#define PIN_DI1 6
#define PIN_DI2 7
#define TIME_OFF -1         //タむマヌを䜿甚しない堎合
#define TIME_UP 0           //タむムアップ
#define LED_WAIT 20
#define STEP_OFF 100
#define STEP_START_FREQ 10000
#define STEP_CUT 1000
#define STEP_MAX 2
#define DI_MAX 2
#define DI_FILT_MAX 4            //DIフィルタのサンプリング数
#define TIME_FILTER_MAX 1    //ベヌスタむマカりント倀
#define	CNT_INIT_MAX 10     //10ms×10 = 100ms

typedef struct{
  uint8_t wp;
  uint8_t buf[DI_MAX][DI_FILT_MAX];
  uint8_t di[DI_MAX];
}DIFILT_TYP;

typedef struct{
  uint8_t md;
  uint8_t stepcnt;
}STEP_CNT;

uint32_t oldtime_n;
uint32_t oldtime_p;
bool posi;
bool neg;
STEP_CNT mng_p;
STEP_CNT mng_n;
uint16_t stepfreq_n;
uint16_t stepfreq_p;
DIFILT_TYP difilt;
int16_t timdifilt;   //DIフィルタ起動
uint8_t CntInit;	//初期化時のみ䜿甚
int16_t timled1 = TIME_OFF;
int16_t timled2 = TIME_OFF;
int16_t timstepoff = TIME_OFF;

/*プロトタむプ宣蚀*/
void mainTimer(void);
void mainApp(void);
bool StepMove(uint8_t no, bool posi);
void DiFilter(void);

void setup() {

  Serial.begin(9600);

  pinMode(PIN_DI1,INPUT_PULLUP);
  pinMode(PIN_DI2,INPUT_PULLUP);
  pinMode(PIN_DO1,OUTPUT);
  pinMode(PIN_DO2,OUTPUT);
  
  pinMode(PIN_STP_IN1, OUTPUT);
  pinMode(PIN_STP_IN2, OUTPUT);
  pinMode(PIN_STP_IN3, OUTPUT);
  pinMode(PIN_STP_IN4, OUTPUT);

  CntInit = CNT_INIT_MAX;
  while(CntInit > 0){  //0になるたでフィルタを実斜
    DiFilter();         //DIフィルタ凊理
    delay(10);     //10ms遅延させおDIフィルタ凊理
    CntInit--;
    timdifilt = TIME_UP;
  }     

  MsTimer2::set(10, mainTimer); // 10ms period
  MsTimer2::start();
}

void loop() {

  mainApp();
  DiFilter();
}
/* タむマ管理 */
void mainTimer(void){

  if( timled1 > TIME_UP ){
    --timled1;
  }
  
  if( timled2 > TIME_UP ){
    --timled2;
  }    

  if( timdifilt > TIME_UP ){
    --timdifilt;
  }
  
  if( timstepoff > TIME_UP ){
    --timstepoff;
  }
}

/* メむン凊理 */
void mainApp(void){
  uint32_t now_n,now_p;

  if(difilt.di[0] == LOW ){
    if( neg == false){
      Serial.println("nown");
      neg = true;
      mng_n.md = 0;
      mng_n.stepcnt = 0;
      oldtime_n = micros();
    }
  }
  else{
    neg = false;
    timled1 = LED_WAIT;
    stepfreq_n = STEP_START_FREQ;
    digitalWrite(PIN_DO1,LOW);
  }

  if(difilt.di[1] == LOW ){
    if(posi == false){
      Serial.println("nowp");
      posi = true;
      mng_p.md = 0;
      mng_p.stepcnt = 0;
      oldtime_p = micros();
    }
  }
  else{
    posi = false;
    timled2 = LED_WAIT;
    stepfreq_p = STEP_START_FREQ;
    digitalWrite(PIN_DO2,LOW);
  }

  if(neg){ //反時蚈回り
    now_n = micros() - oldtime_n;
    if ( now_n >= stepfreq_n ){
      oldtime_n = micros();
      timstepoff = STEP_OFF;
      if( StepMove(mng_n.md++, false)){
        if(++mng_n.stepcnt >= STEP_MAX){
          neg = false;

          if(stepfreq_n <= STEP_CUT){
            stepfreq_n = STEP_CUT;
          }
          else{
            stepfreq_n -= STEP_CUT;
          }
        }
        else{
          mng_n.md = 0;
        }
      }
    }
  }

  if(posi){ //時蚈回り
    now_p = micros() - oldtime_p;
    if ( now_p >= stepfreq_p ){
      oldtime_p = micros();
      timstepoff = STEP_OFF;    
      if( StepMove(7- mng_p.md++, true)){
        if(++mng_p.stepcnt >= STEP_MAX){
          posi = false;

          if(stepfreq_p <= STEP_CUT){
            stepfreq_p = STEP_CUT;
          }
          else{
            stepfreq_p -= STEP_CUT;
          }
        }
        else{
          mng_p.md = 0;
        }
      }
    }
  }

  if( timled1 == TIME_UP ){
    timled1 = LED_WAIT;
    digitalWrite(PIN_DO1,!digitalRead(PIN_DO1));
  }
  
  if( timled2 == TIME_UP ){
    timled2 = LED_WAIT;
    digitalWrite(PIN_DO2,!digitalRead(PIN_DO2));
  }
    
  if( timstepoff == TIME_UP){
    timstepoff = TIME_OFF;
    digitalWrite(PIN_STP_IN1,LOW);
    digitalWrite(PIN_STP_IN2,LOW);
    digitalWrite(PIN_STP_IN3,LOW);
    digitalWrite(PIN_STP_IN4,LOW); 
  }
}
/* ステッピングモヌタヌの励磁 */
bool StepMove(uint8_t no, bool posi){
  bool ret = false;

//Serial.println(no);
  switch(no){
    case 0: //0111
      digitalWrite(PIN_STP_IN4,LOW);
      digitalWrite(PIN_STP_IN3,HIGH);
      digitalWrite(PIN_STP_IN2,HIGH);
      digitalWrite(PIN_STP_IN1,HIGH);
      if(posi){
        ret = true;
      }
      break;
    case 1: //0011
      digitalWrite(PIN_STP_IN4,LOW);
      digitalWrite(PIN_STP_IN3,LOW);
      digitalWrite(PIN_STP_IN2,HIGH);
      digitalWrite(PIN_STP_IN1,HIGH); 
      break;    
    case 2: //1011
      digitalWrite(PIN_STP_IN4,HIGH);
      digitalWrite(PIN_STP_IN3,LOW);
      digitalWrite(PIN_STP_IN2,HIGH);
      digitalWrite(PIN_STP_IN1,HIGH);
      break;              
    case 3: //1001
      digitalWrite(PIN_STP_IN4,HIGH);
      digitalWrite(PIN_STP_IN3,LOW);
      digitalWrite(PIN_STP_IN2,LOW);
      digitalWrite(PIN_STP_IN1,HIGH);
      break;
    case 4: //1101
      digitalWrite(PIN_STP_IN4,HIGH);
      digitalWrite(PIN_STP_IN3,HIGH);
      digitalWrite(PIN_STP_IN2,LOW);
      digitalWrite(PIN_STP_IN1,HIGH);
      break;            
    case 5: //1100
      digitalWrite(PIN_STP_IN4,HIGH);
      digitalWrite(PIN_STP_IN3,HIGH);
      digitalWrite(PIN_STP_IN2,LOW);
      digitalWrite(PIN_STP_IN1,LOW);
      break;            
    case 6: //1110
      digitalWrite(PIN_STP_IN4,HIGH);
      digitalWrite(PIN_STP_IN3,HIGH);
      digitalWrite(PIN_STP_IN2,HIGH);
      digitalWrite(PIN_STP_IN1,LOW);
      break;
    case 7: //0110
      digitalWrite(PIN_STP_IN4,LOW);
      digitalWrite(PIN_STP_IN3,HIGH);
      digitalWrite(PIN_STP_IN2,HIGH);
      digitalWrite(PIN_STP_IN1,LOW);
      if(posi == false){
        ret = true;
      }
      break;                 
    }
    //delayMicroseconds(1000); //1000以䞊で回転速床を調敎する
    return ret;
}
/* DiFilter function add */
void DiFilter(void){
  uint8_t i;

  if( timdifilt == TIME_UP ){
    timdifilt = TIME_FILTER_MAX;
    difilt.buf[0][difilt.wp] = digitalRead(PIN_DI1);
    difilt.buf[1][difilt.wp] = digitalRead(PIN_DI2);

    for(i=0; i < DI_MAX; i++){
      if( difilt.buf[i][0] == difilt.buf[i][1] &&
      difilt.buf[i][1] == difilt.buf[i][2] &&
      difilt.buf[i][2] == difilt.buf[i][3] ){ //4回䞀臎を確認
      difilt.di[i] = difilt.buf[i][0];
      }
    }

    if( ++difilt.wp >= DI_FILT_MAX ){
      difilt.wp = 0;
    }
  }
}

関連リンク

PICマむコンを䜿っおマむコンのレゞスタの蚭定やMPLAB X IDEのプラグむンであるMCCを䜿甚しお動䜜確認したこずに぀いおたずめおいたす。

PICマむコンPIC12F675で実珟できる機胜ず解説リンクたずめ

PICマむコンPIC16F1827で実珟できる機胜ず解説リンクたずめ

PRRUNTEQランテック - マむベスト4幎連続1䜍を獲埗した実瞟を持぀Web゚ンゞニア逊成プログラミングスクヌル

最埌たで、読んでいただきありがずうございたした。

タむトルずURLをコピヌしたした