がたぶーのブログ

筆者の開発記録です。

Raspberry Pi3でラジコン製作(9)

本日はRaspberryPi側のプログラムの内、Bluetooth通信に関する部分について書きます。

 

ライブラリのインポート

4. import bluetooth

 

接続まわり

 9. PORT = 22

13. bl_socket=bluetooth.BluetoothSocket(bluetooth.RFCOMM)

40. bl_socket.bind*1

42. bl_socket.listen(1)

45. client_socket,address = bl_socket.accept()

82. client_socket.close()

83. bl_socket.close()

なぜ一行だけ13行目に書いているのか...(しかも、定数定義の間...)

分かりにくいのでよくないですね。これはミスです。

 

プログラムの詳細はこちらのサイトで解説されています。Python and Bluetooth

注:筆者は説明できるほどはっきりと理解できていません。

PORTは

Raspberry Pi3でラジコン製作(7)>SDPサーバの準備>2.シリアルポートの...

で設定したchannel番号と一致させる必要があるみたいです。

 

データの受け取り

52. data = client_socket.recv(1024)

54. character = data[0]

55. digit = data[1:]

52行目でデータを受け取っています。

データは文字列で、次のものを想定しています。

"r[数値]"、"l[数値]"、"e" (例えば、"r25"や"l-22")

rはrightを意味し、lはleftを、eはexitを意味しています。

例えば、r24を受け取ると

右タイヤの逆回転用のPINの出力を切り、

右タイヤの正解転用のPINのPWMを(24/50に)セットします。

 

参考にしたサイト

Python and Bluetooth

RaspberryPi同士でbluetooth通信 - Qiita

 

コードの再掲

  1. # -*- coding: utf-8 -*-
  2.  
  3. import os
  4. import bluetooth
  5. import pigpio
  6. from time import sleep
  7.  
  8. #SerialPortは22番に設定している。
  9. PORT = 22
  10. #パッケージbluetooth内のBluetoothSocketクラスのインスタンスの生成
  11. #引数はRFCOMM,L2CAP,HCI,SCOから使うプロトコルを選択する。(初期化メソッドを使用)
  12. #RFCOMMはbluetoothモジュールの中で宣言されているためbluetooth.が必要
  13. bl_socket=bluetooth.BluetoothSocket( bluetooth.RFCOMM )
  14. PIN_RF = 16 #右タイヤ前回転
  15. PIN_LF = 19 #左タイヤ前回転
  16. PIN_RR = 20 #右タイヤ後ろ回転
  17. PIN_LR = 26 #左タイヤ後ろ回転
  18. FREQ = 50
  19. RANGE = 50
  20.  
  21. pi = pigpio.pi()
  22.  
  23. def setPWM(pin, speed):
  24.         if 0 <= speed and speed <= RANGE:
  25.                 pi.set_PWM_frequency(pin, FREQ)
  26.                 pi.set_PWM_range(pin,RANGE)
  27.                 pi.set_PWM_dutycycle(pin, speed)
  28.  
  29. def stopCar():
  30.         setPWM(PIN_RF, 0)
  31.         setPWM(PIN_RR, 0)
  32.         setPWM(PIN_LF, 0)
  33.         setPWM(PIN_LR, 0)
  34.  
  35. stopCar()
  36. print "connect..."
  37.  
  38. #BluetoothSocketに定義されたbind関数を使用
  39. #bind(addrport)で使う。RFCOMMだと引数addrportは(host, channnel)
  40. bl_socket.bind( ("", PORT ))
  41. #受信可能状態にする。
  42. bl_socket.listen(1)
  43.  
  44. #接続がされるまで待ち、接続されたらそれを新しい通信として扱い、そのソケットとアドレスを返す。
  45. client_socket,adress = bl_socket.accept()
  46.  
  47. print "connection success"
  48.  
  49. while 1:
  50.               try:
  51.                 #1024バイトまでのデータを受け取る。
  52.                 data = client_socket.recv(1024)
  53.                 print "receive = %s" % data
  54.                 character = data[0]
  55.                 digit = data[1:]
  56.                 if digit.isdigit() or (digit[0] == '-' and digit[1:].isdigit()):
  57.                         speed = int(digit)
  58.                         #print "%d convert to number" % speed
  59.                         if character == 'r':
  60.                                 if speed >= 0:
  61.                                         setPWM(PIN_RR, 0)
  62.                                         setPWM(PIN_RF, speed)
  63.                                 else:
  64.                                         speed = -speed
  65.                                         setPWM(PIN_RF, 0)
  66.                                         setPWM(PIN_RR, speed)
  67.                         elif character == 'l':
  68.                                 if speed >= 0:
  69.                                         setPWM(PIN_LR, 0)
  70.                                         setPWM(PIN_LF, speed)
  71.                                 else:
  72.                                         speed = -speed
  73.                                         setPWM(PIN_LF, 0)
  74.                                         setPWM(PIN_LR, speed)
  75.                 if character == 'e':
  76.                         stopCar();
  77.                         if digit[0] == '0':
  78.                                 os.system("sudo shutdown -h now")
  79.                         break
  80.               except KeyboardInterrupt: #Ctrl+cでの中断時
  81.                 stopCar()
  82.                             client_socket.close()
  83.                             bl_socket.close()
  84.                             break
  85.               except: #何かしらのエラーが発生したとき
  86.                             print "error"
  87.                             print '\n'
  88.                 stopCar()
  89.                             client_socket.close()
  90.                             bl_socket.close()
  91.                             break

 

*1:"", PORT