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

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

新規登録して質問してみよう
ただいま回答率
85.44%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Raspberry Pi

Raspberry Piは、ラズベリーパイ財団が開発した、名刺サイズのLinuxコンピュータです。 学校で基本的なコンピュータ科学の教育を促進することを意図しています。

Q&A

解決済

1回答

650閲覧

ラズパイでモーターを動かす為のプログラムをclass化しようとして失敗しています。このプログラムで何で動かないのでしょうか?

Aki1000

総合スコア78

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Raspberry Pi

Raspberry Piは、ラズベリーパイ財団が開発した、名刺サイズのLinuxコンピュータです。 学校で基本的なコンピュータ科学の教育を促進することを意図しています。

0グッド

0クリップ

投稿2023/01/31 18:06

ラズパイでモーターを制御するプログラムをつくろうとしています。
ラズパイ3 model B モータードライバーはL293Dを使っています。

まず、下のプログラムでは問題なくモーターが動きました。

Python

1import RPi.GPIO as GPIO 2from time import sleep 3 4# Set up pins 5MotorPin1 = 17 6MotorPin2 = 27 7MotorEnable = 22 8 9# ~ GPIO.setmode(GPIO.BOARD) 10GPIO.setmode(GPIO.BCM) 11 12GPIO.setup(MotorPin1, GPIO.OUT) 13GPIO.setup(MotorPin2, GPIO.OUT) 14GPIO.setup(MotorEnable, GPIO.OUT) 15 16pwm = GPIO.PWM(MotorEnable, 100) 17 18#dutycycle 0% 矩形波を出力 19pwm.start(0) 20 21try: 22 while True: 23 dcycle = 100 24 # Set direction Clockwise 25 GPIO.output(MotorPin1, True) 26 GPIO.output(MotorPin2, False) 27 pwm.ChangeDutyCycle(dcycle) 28 GPIO.output(MotorEnable, True) 29 sleep(2) 30 GPIO.output(MotorEnable, False) 31 32 dcycle = 50 33 # Set direction Counterclockwise 34 GPIO.output(MotorPin1, False) 35 GPIO.output(MotorPin2, True) 36 pwm.ChangeDutyCycle(dcycle) 37 GPIO.output(MotorEnable, True) 38 sleep(2) 39 GPIO.output(MotorEnable, False) 40 41 42 pwm.stop() 43 GPIO.cleanup() 44 45except KeyboardInterrupt: 46 pwm.stop() 47 GPIO.cleanup() 48 49 print("KeyboardInterrupt") 50 pass

多分何度も使う事になるだろうからと、このモーター制御部をclassにしようとして失敗しています。下記のようにclass化したのですが、まったくモーターが動きません。

Python

1import RPi.GPIO as GPIO 2from time import sleep 3 4 5class motor_with_L293D: 6 def __init__(self): 7 self.Motor1Pin1 = 17 8 self.Motor1Pin2 = 27 9 self.Motor1Enable = 22 10 11 def setup(self): 12 GPIO.setmode(GPIO.BCM) 13 # Set pins to output 14 GPIO.setup(self.Motor1Pin1, GPIO.OUT) 15 GPIO.setup(self.Motor1Pin2, GPIO.OUT) 16 GPIO.setup(self.Motor1Enable, GPIO.OUT, initial=False) 17 18 19 def motor1(self, direction, dutycycle1=100): 20 21 pwm1 = GPIO.PWM(self.Motor1Enable, 100) 22 pwm1.start(0) 23 24 if direction == 0: 25 GPIO.output(self.Motor1Enable, False) 26 print("Stop") 27 28 elif direction == 1: 29 GPIO.output(self.Motor1Pin1, True) 30 GPIO.output(self.Motor1Pin2, False) 31 pwm1.ChangeDutyCycle(dutycycle1) 32 GPIO.output(self.Motor1Enable, True) 33 print("Clockwise, dutycycle:", dutycycle1) 34 35 elif direction == -1: 36 GPIO.output(self.Motor1Pin1, False) 37 GPIO.output(self.Motor1Pin2, True) 38 pwm1.ChangeDutyCycle(dutycycle1) 39 GPIO.output(self.Motor1Enable, True) 40 print("CounterClockwise, dutycycle:", dutycycle1) 41 42 43if __name__ == '__main__': 44 45 motor = motor_with_L293D() 46 motor.setup() 47 48 try: 49 while True: 50 51 motor.motor1(1, 100) 52 sleep(5) 53 motor.motor1(0) 54 sleep(1) 55 motor.motor1(-1, 100) 56 sleep(5) 57 motor.motor1(0) 58 59 60 except KeyboardInterrupt: 61 GPIO.cleanup() 62

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

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

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

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

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

can110

2023/02/01 00:48

コードを見た目だけで比べると pwm.start(0)が無限ループ内、外にある、などの違いがあるようです。 このあたりの違いは意図したもの(違っても問題ない)でしょうか。
thkana

2023/02/01 03:58

仕込んであるprintの表示は出るのですか? (多分出ているのだと思うけど) もとのプログラムでもやっているので「動かない」原因ではありませんが、 PWMに設定したピンに対して GPIO.output(MotorEnable, True) なんてやるとただのGPIO(PWMなし)にオーバーライドされてしまいませんか? (いまRaspberryPiをセットアップしてないので確認できない) 気になるのは、motor1()に入るたびの pwm1 = GPIO.PWM(self.Motor1Enable, 100) pwm1.start(0) の「重ねがけ」ですが、それが問題だとしても「最初の一回」は動くはずだし。 気がついたら線が一本外れていた...なんてないですか? (実際時々あるので)
Aki1000

2023/02/01 09:48

仕込んであるprintは表示されます。時々前のプログラム動かすとちゃんと動くので配線ではないです。 重ねがけのところ、今晩もう少しいじって見てみます。
guest

回答1

0

ベストアンサー

Raspberry Pi 2Bを引っ張り出していじってみました。
つまるところ、
pwmオブジェクトが「生きて」いないと信号が出なくなる、ということのようです。

非クラス版では、pwmオブジェクトはプログラム実行中ずっと生きていますから信号が出続けます。
クラス版では、motor_with_L293D.motor1()関数を出るとpwmオブジェクトが寿命を終えますから、そこで信号が止まります。止まった状態でsleep()で時間つぶしします。

以下、本題以外

GPIO.output(self.Motor1Enable, val)はpwmに対してなにも影響を及ぼさないようです。つまり、そのstop機能は働きません。

・コンストラクタとsetup()関数を分けている意味はなにかあるのですか?

・モーターを反転する際はメカ的電気的負担を和らげるために一旦止める時間を設けたほうがいいです。クラス版の最後のmotor.motor1(0)の後にもsleep()を少し入れてやったほうがよいでしょう。

投稿2023/02/01 10:54

thkana

総合スコア7667

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

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

Aki1000

2023/02/02 10:28

コンストラクタとsetup()関数を分けている意味はないですね。始めにコンストラクタに入れても動かなかったので、分けてみただけです。setup()関数の部分をコンストラクタに入れようが、motor1()の冒頭に入れようが動かなかったです。 ありがとうございます。なんで、動かないのかは分かりました。 コンストラクトの部分に self.pwm1 = GPIO.PWM(self.Motor1Enable, init_dutycycle) self.pwm1.start(0) として、以後self.pwm1を操作してやることで動くようになりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.44%

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

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

質問する

関連した質問