PS3 컨트롤러로 프로그래밍 팔로 조작

16000 단어 RaspberryPimicrobit

할 일



라즈파이에 연결한 PS3 컨트롤러로, Bluetooth로 접속한 micro:bit 탑재의 프로그래밍 팔로를 조작할 수 있도록 해 보았다.

프로그래밍 팔로



우선은 프로그래밍 팔로의 조립에 대해.
조립은 이쪽

라즈파이에서 마이크로 : 비트로 블루투스로 연결



다음으로 라즈파이와 micro:bit를 Bluetooth로 연결하는 방법.
micro:bit의 프로그램도 이것을 사용한다.
방법은 여기

라즈파이에 PS3 컨트롤러를 연결



다음으로 라즈파이에 PS3의 컨트롤러를 연결하는 방법.
방법은 여기

PS3 컨트롤러의 조작으로 프로그래밍 팔로 조작



지금까지를 맞추고, PS3 컨트롤러를 조작해 프로그래밍 팔로를 조작할 수 있도록 해 보았습니다.
프로그램은 github에도

folo_control.py
from bluepy import btle
import binascii
import struct
import time

devadr           = "e4:1e:1f:1f:f4:49"
uuid_svc_iopin   = "e95d127b-251d-470a-a062-fa1922dfa9a8"
uuid_pin_io_conf = "e95db9fe-251d-470a-a062-fa1922dfa9a8"
uuid_pin_ad_conf = "e95d5899-251d-470a-a062-fa1922dfa9a8"
uuid_pin_data    = "e95d8d00-251d-470a-a062-fa1922dfa9a8"

device_path  = "/dev/input/js0"
EVENT_FORMAT = "LhBB"
EVENT_SIZE   = struct.calcsize(EVENT_FORMAT)

def main(chPin):

  with open(device_path, "rb") as device :
    event = device.read(EVENT_SIZE)

    while event :
      (ds3_time, ds3_val, ds3_type, ds3_num) = struct.unpack(EVENT_FORMAT, event)
      #print("{0}, {1}, {2}, {3}".format(ds3_time, ds3_val, ds3_type, ds3_num))

      # X button to end
      if ds3_num == 0 and ds3_type == 1:
        #print(" move stop")
        chPin.write(b"\x0d\x00")
        chPin.write(b"\x0e\x00")
        #print(" rotate stop")
        chPin.write(b"\x0f\x00")
        chPin.write(b"\x10\x00")
        per.disconnect()
        return

      # right stick to rotate
      if ds3_num == 3 and ds3_type == 2:

        if abs(ds3_val) < 4000:
          #print(" rotate stop")
          chPin.write(b"\x0f\x00")
          chPin.write(b"\x10\x00")
        elif ds3_val > 0 :
          val = ds3_val>>7
          #print(" rotate right %d" %val)
          chPin.write(b"\x0f\x00")
          chPin.write(b"\x10" + val.to_bytes(1, 'little'))
        else :
          ds3_val = -ds3_val
          val = ds3_val>>7
          #print(" rotate left  %d" %val)
          chPin.write(b"\x10\x00")
          chPin.write(b"\x0f" + val.to_bytes(1, 'little'))

      # left stick to move
      if ds3_num == 1 and ds3_type == 2:

        if abs(ds3_val) < 4000:
          #print(" move stop")
          chPin.write(b"\x0d\x00")
          chPin.write(b"\x0e\x00")
        elif ds3_val > 0 :
          val = ds3_val>>7
          #print(" move back    %d" %val)
          chPin.write(b"\x0d\x00")
          chPin.write(b"\x0e" + val.to_bytes(1, 'little'))
        else :
          ds3_val = -ds3_val
          val = ds3_val>>7
          #print(" move forward %d" %val)
          chPin.write(b"\x0e\x00")
          chPin.write(b"\x0d" + val.to_bytes(1, 'little'))

      time.sleep(0.01)
      event = device.read(EVENT_SIZE)

if __name__ == "__main__" :
  per = btle.Peripheral(devadr, btle.ADDR_TYPE_RANDOM)

  svcPinIO = per.getServiceByUUID(uuid_svc_iopin)

  #pin13-16 as Analog
  chPinAD = svcPinIO.getCharacteristics(uuid_pin_ad_conf)[0]
  chPinAD.write(b"\x00\xe0\x01\x00")

  #pin13-16 as Output
  chPinIO = svcPinIO.getCharacteristics(uuid_pin_io_conf)[0]
  chPinIO.write(b"\x00\x00\x00\x00")

  #pin
  chPin = svcPinIO.getCharacteristics(uuid_pin_data)[0]

  print("Remote control Folo by PS3 controller")
  print("  left  stick : move to forward or back")
  print("  right stick : turn left or right")
  print("  Button X    : End")

  main(chPin)


간단히 말하면,
micro : bit의 IO 단자를 아날로그 출력을 할 수 있도록하고,
PS3의 스틱 신호(-32767~0이 전진, 0~32767이 후퇴)를 보고, 움직이는 모터의 단자(전진이라면 P13)에 신호를 출력한다(0~255의 범위).
입력 신호에서 출력 신호로는 수치의 범위를 맞추기 위해 그대로 1/128(오른쪽으로 7bit 시프트)하고 있다.

실행


% python3 folo_control.py

조작은 아래에 할당되어 있습니다.


조작
동작


왼쪽 스틱 상하
전진, 후퇴

오른쪽 스틱 좌우
좌우 회전

X 버튼    
종료



전진, 후퇴, 좌우로의 회전도 제대로 움직이고, 스틱이 쓰러뜨리는 양에 따라 스피드도 바뀌도록 움직였다.

좋은 웹페이지 즐겨찾기