質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Arduino

Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

Q&A

2回答

5905閲覧

Arduino nano 外部割込みピンの増やし方

kujir

総合スコア0

Arduino

Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

0グッド

0クリップ

投稿2021/11/08 08:38

Arduino nanoを用いてロータリー付きエンコーダー2つを制御したいです.
制御の要件としましては2つのモーターの位相を同じにしたいです.
回転数か回転を表す値をシリアルモニターに表示しその値によって電流を制御してほしいです.
片方のモーターのCount値をArduino nanoの2,3番ピンで割り込みはできたのですが,もう片方のモーターが表示できません.
Arduino nanoの外部割込みピンは2,3の2つしかないと調べていたら出てきたのですがArduino UNOのようにPinChangeInterruptなどのプログラムで外部割込みピンを増やせないでしょうか.
'''Arduino nano
コード
'''#include <Rotary.h>

Rotary r1 = Rotary(2, 3); //モーター①用エンコーダー
Rotary r2 = Rotary(4, 5); //モーター②用エンコーダー

//モーター①用エンコーダー入力カウンター
int motor1_count = 0;
//モーター②用エンコーダー入力カウンター
int motor2_count = 0;

//モーター①用PWM信号
int motor1_pwm=0;
//モーター②用PWM信号
int motor2_pwm=0;

//モーター①出力ピン
const int motor1_B_IA = 10; //正転
const int motor1_B_IB = 11; //逆転

//モーター②出力ピン
const int motor2_A_IA = 9; //正転
const int motor2_A_IB = 6; //逆転

//モーター①駆動トリガー
int motor1_on = 1;
//モーター②駆動トリガー
int motor2_on = 1;

//モーター正転・逆転を決定する変数
int motor1_LR = 0; //モーター①:初期値は正転
int motor2_LR = 0; //モーター②:初期値は正転

//モーター用カウンター値表示用変数
String motor1_monitor="";
String motor2_monitor="";

void setup() {
Serial.begin(9600);

//モーター①用エンコーダー入力割り込み
attachInterrupt(digitalPinToInterrupt(2), motor1, CHANGE);
attachInterrupt(digitalPinToInterrupt(3), motor1, CHANGE);

//モーター②用エンコーダー入力割り込み
attachInterrupt(digitalPinToInterrupt(4), motor2, CHANGE);
attachInterrupt(digitalPinToInterrupt(5), motor2, CHANGE);

//モーター①②出力ピン準備
pinMode(motor1_B_IA,OUTPUT); //モーター①
pinMode(motor1_B_IB,OUTPUT); //モーター①
pinMode(motor2_A_IA,OUTPUT); //モーター②
pinMode(motor2_A_IB,OUTPUT); //モーター②

}

void loop() {

//モーター①ON・OFF制御
if (motor1_on == 1){
motor1_pwm = 250;
} else if (motor1_on == 0){
motor1_pwm = 0;
}

//モーター②ON・OFF制御
if (motor2_on == 1){
motor2_pwm = 250;
} else if (motor2_on == 0){
motor2_pwm = 0;
}

//モーター①駆動ON:正転・逆転制御
if (motor1_LR == 0){
analogWrite(motor1_B_IA,motor1_pwm); //正転
}else if(motor2_LR == 1){
analogWrite(motor1_B_IB,motor1_pwm); //逆転
}

//モーター②駆動ON:正転・逆転制御
if (motor2_LR == 0){
analogWrite(motor2_A_IA,motor2_pwm); //正転
}else if(motor2_LR == 1){
analogWrite(motor2_A_IB,motor2_pwm); //逆転
}

}

//
void motor1() {
//エンコーダー状態入力
unsigned char result1 = r1.process();

if (result1 == DIR_NONE) {
// do nothing
}
else if (result1 == DIR_CW) {
motor1_count++;
motor1_monitor = "Motor1【Right】:Count = " + String(motor1_count);
Serial.println(motor1_monitor);
}
else if (result1 == DIR_CCW) {
motor1_count++;
motor1_monitor = "Motor1【Left】:Count = " + String(motor1_count);
Serial.println(motor1_monitor);
}

if (motor1_count > 200){
motor1_on = 0;
motor1_count = 0;
motor1_monitor = "Motor1 CountMAX:Return to zero:Count = " + String(motor1_count);
Serial.println(motor1_monitor);
}
}

void motor2() {
//エンコーダー状態入力
unsigned char result2 = r2.process();

if (result2 == DIR_NONE) {
// do nothing
}
else if (result2 == DIR_CW) {
motor2_count++;
motor2_monitor = "Motor2【Right】:Count = " + String(motor2_count);
Serial.println(motor2_monitor);
}
else if (result2 == DIR_CCW) {
motor2_count++;
motor2_monitor = "Motor2【Left】:Count = " + String(motor2_count);
Serial.println(motor2_monitor);
}

if (motor2_count > 50){
motor2_on = 0;
motor2_count = 0;
motor2_monitor = "Motor2 CountMAX:Return to zero:Count = " + String(motor2_count);
Serial.println(motor2_monitor);
}

}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

thkana

2021/11/08 13:21

前の質問( https://teratail.com/questions/367908 )で反応がなかったのですが、「位相」という言葉をあなたと私が同じ意味で捉えているかとても不安です。 あなたがいう「位相が同じ」とは、2つのエンコーダーの出力がどうなることか、できれば「位相」という言葉を使わずに説明してみていただけますか?
kujir

2021/11/09 09:23

質問ありがとうございます. 二つのモーターそれぞれに楕円型の車輪を付け,二つの車輪が全く同じ挙動を描くようにしたいです.
thkana

2021/11/09 13:49

一応伺いますが、一回転何パルスのエンコーダでしょうか? > 二つのモーターそれぞれに楕円型の車輪を付け,二つの車輪が全く同じ挙動を描くようにしたいです. ということなら、一回転1パルス? あるいはZ相(原点/1回転1パルス)が必要になるかと思いますが、そういう仕組みはあるのでしょうか? で、モーターの回転(ギアなどを含んで車輪の回転)はそういうレベルの制御がまともにできるほど低速なのですね?
guest

回答2

0

前の質問は放置ですか?

Arduino UNOのようにPinChangeInterruptなどのプログラムで外部割込みピンを増やせないでしょうか.

できるはずですが。UNOとNANOはマイコンチップは同じATMEGA328ですから。歴史的な事情でファームが違ったりサイズの関係で外に出てるピンが違う、とかはあるようですけれど本質的には同じです。
なにかNanoではできないという情報があったのですか?

投稿2021/11/08 13:13

thkana

総合スコア7703

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kujir

2021/11/09 09:29

前の質問でのPinChangeInterruptをArduinon nanoに対してインクルードし実行してみたのですが2,3番ピンに入力したものはにはシリアルモニタに表示されたのですが4,5番ピンに入力したものは改善されなかったためできないと判断してしまっていました.
thkana

2021/11/09 13:42

当然ながら、PinChangeInterruptをインクルードしたらそれだけで前の質問のプログラムが(インクルード以外)なにも変えずに突如動き出す...なんていうことは(UNOであっても)ないですが、それを以てNanoではできない、と言っているのではないですね?
guest

0

外部割り込みピンってのはCPUで使えるピンはきまっているため、増やすことはできません

ましかし、そんなに早く回さないのであれば、1ms程度のタイマ割り込みでエンコーダのピン状態をサンプルしてカウントさせれば、GPIOの許す限りいくつでも増やせます


制御の要件としましては2つのモーターの位相を同じにしたいです.

という要求仕様であるなら、DCモータではなく、ステッピングモータを使うのが筋じゃないでしょうか

投稿2021/11/08 08:52

編集2021/11/08 08:57
y_waiwai

総合スコア88042

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問