忍者ブログ

Azukish

消えゆく世界と流れる未来に最後の灯を since 2006/4/3

2024/04/29

[PR]

×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

コメント

ただいまコメントを受けつけておりません。

2021/01/10

M5Stackでステッパーモーターを回す

年末年始がコロナの関係で非常に暇だった。皆様あけましておめでとうございます。
当ブログは今年で15年?になるらしいです。昔の記事とかはもう読みたくもない・・・
よさそうなおもちゃを手に入れたので、さっそく遊んでみた。
2021/1/10現在、MCPWM.hをいじる必要があり。
mcpwm_sync_signal_t missing enums (IDFGH-3469)とあるので、多分エラッタだと思う。



接続はGPIO1と3をそれぞれIN1とIN3へ、GPIO16と17をIN2とIN4へ。
まず、ソースコード
#include <M5Stack.h>
#include "driver/mcpwm.h"
#include "soc/mcpwm_reg.h"
#include "soc/mcpwm_struct.h"

uint32_t time_on=0;
boolean clockwise=false;
boolean button_on=false;
boolean button_on_complete=false;

void setup() {
  // put your setup code here, to run once:
  M5.begin();

  mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM0A, GPIO_NUM_3);
  mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM0B, GPIO_NUM_1);
  mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM1A, GPIO_NUM_16);
  mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM1B, GPIO_NUM_17);

  mcpwm_config_t pwm_config;
  pwm_config.frequency = 50;
  pwm_config.cmpr_a = 50;
  pwm_config.cmpr_b = pwm_config.cmpr_a;
  pwm_config.counter_mode = MCPWM_UP_DOWN_COUNTER;
  pwm_config.duty_mode = MCPWM_DUTY_MODE_0;
  
  mcpwm_init(MCPWM_UNIT_0, MCPWM_TIMER_0, &pwm_config);
  mcpwm_init(MCPWM_UNIT_0, MCPWM_TIMER_1, &pwm_config);

  mcpwm_deadtime_enable(MCPWM_UNIT_0, MCPWM_TIMER_0, MCPWM_ACTIVE_HIGH_COMPLIMENT_MODE, 80, 80);
  mcpwm_deadtime_enable(MCPWM_UNIT_0, MCPWM_TIMER_1, MCPWM_ACTIVE_HIGH_COMPLIMENT_MODE, 80, 80);

  //mcpwm.h line 144-147 added
  mcpwm_sync_enable(MCPWM_UNIT_0, MCPWM_TIMER_0, MCPWM_SELECT_INT1, 0);
  mcpwm_sync_enable(MCPWM_UNIT_0, MCPWM_TIMER_1, MCPWM_SELECT_INT1, 500);

  MCPWM0.timer[0].sync.out_sel = 1;  
}

// M5.BtnB.wasPressed()使えば簡単に再現できたので、下側のloop()はコメントアウトした。
void loop() {
  // put your main code here, to run repeatedly:
  M5.update();

  if (M5.BtnA.wasPressed()) {
    if (motorMoving) {
      M5.Lcd.println("Motor Stops");
      mcpwm_stop(MCPWM_UNIT_0, MCPWM_TIMER_0);
      mcpwm_stop(MCPWM_UNIT_0, MCPWM_TIMER_1);
    } else {
      M5.Lcd.println("Motor Starts");
      mcpwm_start(MCPWM_UNIT_0, MCPWM_TIMER_0);
      mcpwm_start(MCPWM_UNIT_0, MCPWM_TIMER_1);
    }
    motorMoving = !motorMoving;
  }
  if (M5.BtnB.wasPressed()) {
    if (clockwise) {
      M5.Lcd.println("to counterwise");
      mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM0A, GPIO_NUM_3);
      mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM0B, GPIO_NUM_1);
    } else {
      M5.Lcd.println("to clockwise");
      mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM0A, GPIO_NUM_1);
      mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM0B, GPIO_NUM_3);
    }
    clockwise = !clockwise;
    MCPWM0.timer[0].sync.out_sel = 1;
  }
}
/*void loop() {
  // put your main code here, to run repeatedly:
  if (digitalRead(39)==0) {
    if (!button_on) {
      button_on = true;
      button_on_complete = false;
      time_on = millis();
    } else {
      if (!button_on_complete) {
        if (millis()-time_on>30) {
            button_on_complete=true;
            if (clockwise) {
                M5.Lcd.printf("to counterwise\n");
                  mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM0A, GPIO_NUM_3);
                  mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM0B, GPIO_NUM_1);
                clockwise=false;
            } else {
                M5.Lcd.printf("to clockwise\n");
                  mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM0A, GPIO_NUM_1);
                  mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM0B, GPIO_NUM_3);
                clockwise=true;
            }
            MCPWM0.timer[0].sync.out_sel = 1;  
        }
      }
    }
  } else {
    button_on = false;
  }
}*/

んで、mcpwm.hのmcpwm_sync_signal_tを変更する。
mcpwm.hはC:\Users\ユーザ名\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4\tools\sdk\include\driver\driver\mcpwm.hにあると思う。
typedef enum {
    MCPWM_SELECT_INT0 =0,
    MCPWM_SELECT_INT1,
    MCPWM_SELECT_INT2,
    MCPWM_SELECT_INT3,	
    MCPWM_SELECT_SYNC0,  /*!<Select SYNC0 as input*/
    MCPWM_SELECT_SYNC1,      /*!<Select SYNC1 as input*/
    MCPWM_SELECT_SYNC2,      /*!<Select SYNC2 as input*/
} mcpwm_sync_signal_t;

ざっくりと解説

まず、ステッパーモーターに関しての制御方法は過去やったので過去記事参照

MCPWMの使い方はHackday.io ESP-32 BLDC Robot Actuator Controller: MCPWM with deadbandをそのまま丸パクリしつつ、
公式Programming Guide
公式のQA: mcpwm basic config - no synchronization happening, why? (IDFGH-1036)あたりを見た。

mcpwm_gpio_init()でGPIOに紐づけるMCPWMのペリフェラルを選択し(ESP32ではなんとすべてのGPIOピンに任意のPWMペリフェラルが割り当てられるらしい!)、
mcpwm_config_tでPWMの仕様を規定し、
mcpwm_init()でmcpwm_config_tをPWMペリフェラルに割り当て、
mcpwm_deadtime_enable()で貫通電流防止のデッドタイムとPWMAとBが反転動作するように設定し、
mcpwm_sync_enable()でPWMの0と1の位相が50%ずれるように設定し、
MCPWM0.timer[0].sync.out_sel=1;でPWM出力とPWM設定の更新を行ってる、はず。
(各関数とテクニカルリファレンスマニュアルをきちんと見比べてないので、認識が合ってるか微妙)

void loop()内はボタンを押したときに逆回転するようなプログラムが記述してある。無くても回る。
チャタリング防止のために引用: mgo-tec電子工作 M5stack ボタンスイッチの、チャタリング、誤作動防止、感度調整、長押し設定を考えてみる

拍手

コメント













カレンダー

03 2024/04 05
S M T W T F S
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30

アーカイブ

AD

Azkishはamazon.co.jpを宣伝しリンクすることによって サイトが紹介料を獲得できる手段を提供することを目的に設定されたアフィリエイト宣伝プログラムである、 Amazonアソシエイト・プログラムの参加者です。