ラジコンカーをPWM制御して走行させる

PWM制御を使ってラジコンカーを走らせます

PWM制御を使ってラジコンカーを走らせます
 ikath
 2019-07-26

概要

Raspberry Pi の DC モータを PWM制御 することでラジコンカーを動かします。 今回は Mac から Raspberry Pi に SSH でリモート接続し手元のキーボードから操作できるようにしています。 コースを以下のように作って実際に走らせてみました。

PWM 制御のラジコンカーを走らせる自作コース

作成したコース

PWM制御とは

PWM 制御とは、スイッチのオンとオフのスイッチングを高速で行い、擬似的に出力電圧を制御するというものです。 出力電圧を制御することによってラジコンカーを右や左方向に曲がる動作を行うことができます。 例えば左の DC モータの電圧出力を右のDCモータの出力より大きくすれば、右に曲がることができます。 詳しい説明は他の方のサイトをご覧ください。私はこちらのサイトを参考にさせて頂きました。

開発環境

  1. Raspberry Pi 3B raspbian 9.4
  2. Python 3.5.3

アーキテクチャ

PWM 制御のラジコンカーのアーキテクチャ

アーキテクチャ

KeyBoard操作

Key動作
前進
右に少し移動
左に少し移動
後退
r右回転
l左回転
return停止
q終了

ソースコード

クリックしてソースコードを見る

main.py
python
# import curses and time and GPIO
import curses
import time
import RPi.GPIO as GPIO


def go_straight(rightDC, leftDC):

    GPIO.output(Lpin1, True)
    GPIO.output(Lpin2, False)
    GPIO.output(Rpin1, True)
    GPIO.output(Rpin2, False)

    pwmL.ChangeDutyCycle(leftDC)
    pwmR.ChangeDutyCycle(rightDC)

def go_back(rightDC, leftDC):

    GPIO.output(Lpin1, False)
    GPIO.output(Lpin2, True)
    GPIO.output(Rpin1, False)
    GPIO.output(Rpin2, True)

    pwmL.ChangeDutyCycle(leftDC)
    pwmR.ChangeDutyCycle(rightDC)

def turn_left(rightDC, leftDC):

    GPIO.output(Lpin1, True)
    GPIO.output(Lpin2, False)
    GPIO.output(Rpin1, True)
    GPIO.output(Rpin2, False)

    pwmL.ChangeDutyCycle(leftDC)
    pwmR.ChangeDutyCycle(rightDC)

def turn_right(rightDC, leftDC):

    GPIO.output(Lpin1, True)
    GPIO.output(Lpin2, False)
    GPIO.output(Rpin1, True)
    GPIO.output(Rpin2, False)

    pwmL.ChangeDutyCycle(leftDC)
    pwmR.ChangeDutyCycle(rightDC)

def rotation_right():

    GPIO.output(Lpin1, True)
    GPIO.output(Lpin2, False)
    GPIO.output(Rpin1, False)
    GPIO.output(Rpin2, True)

    pwmL.ChangeDutyCycle(70)
    pwmR.ChangeDutyCycle(70)

def rotation_left():

    GPIO.output(Lpin1, False)
    GPIO.output(Lpin2, True)
    GPIO.output(Rpin1, True)
    GPIO.output(Rpin2, False)

    pwmL.ChangeDutyCycle(70)
    pwmR.ChangeDutyCycle(70)

def stop():

    GPIO.output(Lpin1, False)
    GPIO.output(Lpin2, False)
    GPIO.output(Rpin1, False)
    GPIO.output(Rpin2, False)

# set GPIO numbering mode and define output pins
Lpin1 = 16
Lpin2 = 18
Lpin3 = 33
Rpin1 = 15
Rpin2 = 13
Rpin3 = 12
leftDC  = 60
rightDC = 60

GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
GPIO.setup(Lpin1,GPIO.OUT)
GPIO.setup(Lpin2,GPIO.OUT)
GPIO.setup(Lpin3,GPIO.OUT)
GPIO.setup(Rpin1,GPIO.OUT)
GPIO.setup(Rpin2,GPIO.OUT)
GPIO.setup(Rpin3,GPIO.OUT)

pwmL = GPIO.PWM(Lpin3, 100)
pwmL.start(0)
pwmR = GPIO.PWM(Rpin3, 100)
pwmR.start(0)

pwmR.ChangeDutyCycle(0)
pwmL.ChangeDutyCycle(0)

# Get the curses window, turn off echoing of keyboard to screen, turn on
# instant (no waiting) key response, and use special values for cursor keys
screen = curses.initscr()
curses.noecho()
curses.cbreak()
screen.keypad(True)

try:
    while True:
        char = screen.getch()
        if char == ord('q'):
            break

        elif char == curses.KEY_UP:
            leftDC  = 60
            rightDC = 60
            go_straight(leftDC, rightDC)

        elif char == curses.KEY_DOWN:
            leftDC  = 50
            rightDC = 50
            go_back(leftDC, rightDC)

        elif char == curses.KEY_RIGHT:
            leftDC  = leftDC  + 10
            rightDC = rightDC - 10

            if leftDC >= 100:
                leftDC = 100

            if rightDC <= 30:
                rightDC = 30

            turn_right(leftDC, rightDC)

        elif char == curses.KEY_LEFT:
            leftDC  = leftDC  - 10
            rightDC = rightDC + 10

            if leftDC <= 30:
                leftDC = 30

            if rightDC >= 100:
                rightDC = 100

            turn_right(leftDC, rightDC)

        elif char == ord('l'):
            rotation_left()
            leftDC  = 60
            rightDC = 60

        elif char == ord('r'):
            rotation_right()
            leftDC  = 60
            rightDC = 60

        # return
        elif char == 10:
            stop()
            leftDC  = 60
            rightDC = 60

finally:

    # Close down curses properly, inc turn echo back on!
    curses.nocbreak(); screen.keypad(0); curses.echo()
    curses.endwin()
    GPIO.cleanup()

結果



 公開日時: 2019-05-30
 タグ: PWM  python  IoT 
ikath icon image
 ikath

名前は ikath と言います。情報系の大学生です。

 Twitter
サイト内検索

Google カスタム検索を利用してサイト内の記事をキーワードで検索できます。

サイト内検索

Google カスタム検索を利用してサイト内の記事をキーワードで検索できます。