3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Arduinoでステッピングモーターを指定周波数で制御するmemo

Last updated at Posted at 2020-01-10

#概要
 1年半前くらいですが、ステッピングモーターを使ったマイクロポンプを扱うことがあり、流量制御するためにポンプ周波数を5Hzなどの低周波数で変更させる必要があったのでAVRのタイマを使ってPWMを作りモーター制御した時のメモになります。

#構成
モータードライバーは駆動電圧が2.7~6VなのでArduinoから電圧を取っても駆動でき使いやすいです。ただし2個以上使用する場合は別電源推奨。

マイコン:ArduinoUnoまたはArduinonano
モータードライバ:TB6608FNG
ピッチ変換基板:SSOP20ピン(0.65mm)/SOP20ピン(1.27mm)DIP変換基板
モーター:バイポーラ4線式
抵抗:470Ω×3個、2Ω×2個
コンデンサー:220pF×1個
←リンクは秋月電子です

[回路]
図1.png

#スケッチ
AVRの8bitタイマ設定については後述の参考を見ていただくとよいかと思います。
モータードライバが正転逆転(CWCCW)やResetなどに対応しているのでそれぞれkeyを割り振り、シリアル入力したら変更されるようにしています。
任意周波数はz17xのように指定したい周波数をzとxの間に挟んでシリアル入力すると指定できます。
Node-REDのserialノードを使ってDashboardから打ち込むなど、応用が効きます。

motordrive.ino
#include <avr/io.h>
#define PWMPin 10

int frq = 100; // 周波数
float duty = 0.5; // デューティ比

unsigned int xpin4 = 1;
unsigned int xpin5 = 1;
unsigned int xpin6 = 1;
unsigned int xpin7 = 1;

void setup() {
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(PWMPin, OUTPUT);
  Serial.begin(9600);

  digitalWrite(4, HIGH);
  digitalWrite(5, HIGH);
  digitalWrite(6, HIGH);
  digitalWrite(7, HIGH);
}

void loop() {
  int input1;
  input1 = Serial.read();

  TCCR1A = 0b00100001;  // モード指定
  TCCR1B = 0b00010010;

  if (input1 == 'q') {
    Serial.write("keyq  ");
    frq = 10;
    Serial.println(frq);
    Serial.write("\n");

    OCR1A = (unsigned int)(1000000 / frq);  // TOP値指定
    OCR1B = (unsigned int)(1000000 / frq * duty); // Duty比指定

  } else if (input1 == 'w') {
    Serial.write("keyw  ");
    frq = 100;
    //  if (frq < 10) frq = 10;
    Serial.println(frq);
    Serial.write("\n");

    OCR1A = (unsigned int)(1000000 / frq);  // TOP値指定
    OCR1B = (unsigned int)(1000000 / frq * duty); // Duty比指定

  } else if (input1 == 'e') {
    Serial.write("keye  ");
    frq = frq - 10;
    if (frq < 10) frq = 10;
    Serial.println(frq);
    Serial.write("\n");

    OCR1A = (unsigned int)(1000000 / frq);  // TOP値指定
    OCR1B = (unsigned int)(1000000 / frq * duty); // Duty比指定

  } else if (input1 == 'r') {
    Serial.write("keyr  ");
    frq = frq + 10;
    if (frq > 500) frq = 500;
    Serial.println(frq);
    Serial.write("\n");

    OCR1A = (unsigned int)(1000000 / frq);  // TOP値指定
    OCR1B = (unsigned int)(1000000 / frq * duty); // Duty比指定

  } else if (input1 == 't') {
    Serial.write("keyt  ");
    frq = frq + 100;
    if (frq > 500) frq = 500;
    Serial.println(frq);
    Serial.write("\n");

    OCR1A = (unsigned int)(1000000 / frq);  // TOP値指定
    OCR1B = (unsigned int)(1000000 / frq * duty); // Duty比指定

  } else if (input1 == 'y') {
    frq = 500;
    Serial.write("keyy  ");
    Serial.println(frq);
    Serial.write("\n");

    OCR1A = (unsigned int)(1000000 / frq);  // TOP値指定
    OCR1B = (unsigned int)(1000000 / frq * duty); // Duty比指定

  } else if (input1 == 'u') {
    if (xpin4 == 1) {                   //Speed×10
      digitalWrite(4, LOW);
      xpin4 = 0;
    } else {
      digitalWrite(4, HIGH);
      xpin4 = 1;
    }
  } else if (input1 == 'i') {
    if (xpin5 == 1) {                 //CWCCW切り替え
      digitalWrite(5, LOW);  
      xpin5 = 0;
    } else {
      digitalWrite(5, HIGH);  
      xpin5 = 1;
    }

  } else if (input1 == 'o') {
    if (xpin6 == 1) {                         //ONOFF
      digitalWrite(6, LOW);
      xpin6 = 0;
    } else {
      digitalWrite(6, HIGH);
      xpin6 = 1;
    }


  } else if (input1 == 'p') {
    if (xpin7 == 1) {                         //Reset
      digitalWrite(7, LOW);
      xpin7 = 0;
    } else {
      digitalWrite(7, HIGH);
      xpin7 = 1;
    }


  } else if (input1 == 'z') {
//    String str;
    if (Serial.available() > 1) {     //任意周波数
      String str = Serial.readStringUntil('x');
      Serial.println(str);
      Serial.write("keyz  ");
      frq = str.toInt();
      Serial.println(frq);
      Serial.write("\n");

    OCR1A = (unsigned int)(1000000 / frq);  // TOP値指定
    OCR1B = (unsigned int)(1000000 / frq * duty); // Duty比指定

    }
  } else {

    Serial.write(".\n");
  }
  delay(500);
}

#参考
デジモノ覚書
http://blog.kts.jp.net/arduino-pwm-change-freq/
うしこのblog
http://usicolog.nomaki.jp/engineering/avr/avrPWM.html

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?