daigouin
@daigouin

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

Raspberry Piと無線IMUをシリアル通信で接続させたいです

Raspberry Piと無線IMUをシリアル通信で接続させたいです

質問を見てくださりありがとうございます。
お力添えいただけますと幸いです。

Bluetoothで接続する無線IMUで測定した角速度をシリアル通信でラズベリーパイに送信し、
その角速度をもとにモータを回転させる機械を開発したいと考えています。
windosPCではシリアル通信ができたのですが、
LINUXのラズベリーパイではシリアル通信ができず、研究が行き詰まっている状態です。

発生している問題・エラー

例外が発生しました: SerialException
device reports readiness to read but returned no data (device disconnected or multiple access on port?)
  File "/home/osumi/Desktop/program09_2024/AMWS.py", line 43, in <module>
    ser.read(1000)
serial.serialutil.SerialException: device reports readiness to read but returned no data (device disconnected or multiple access on port?)

上記のエラーコードが以下のプログラムで実行した際に発生してしまいます。
エラーの内容を調べたところ、シリアルポートデバイスが通信可能な状態であるにもかかわらず、
IMUからデータが送られてきていないことを示しているようです。
プログラムコードを最後に記載しますので、解決の参考にしていただければと思います。

該当するソースコード

ser.read(1000)

自分で試したこと

まず、rfcommのバインドの確認を行いました。
rfcommコマンドを用いて、Bluetoothデバイスの仮想的なシリアルポートとしてシステムにバウンドし、
バインドが成功したか確認すると、

rfcomm0: C9:0B:89:87:CC:4C channel 1 closed [tty-attached]

と表示されました。
このclosedは、バインドが成功していてもBluetooth接続ができていないことから、
通信が開始されていない状態を示しているようです。

先程のエラーから、IMUのBluetooth通信の確認を行いました。
Bluetoothctlより確認すると、正常にペアリングし、接続されていることが確認できました。
このように、Bluetoothの接続がされていないと表示される場合と、
接続がされているという矛盾した結果が出ており、
調べても解決方法が出てこないことから、皆様のお力添えをいただきたいです。

一応、タイムアウト時間を延長しましたが、変わらず通信はできませんでした。

また、試しにワイヤレスイヤホンBluetooth接続させたところ、正常に音声が聞こえたため、
ラズベリーパイのBluetoothが使用できないというわけではないようです。

プログラムコード

import os
import sys
import serial
import time
import struct
import binascii
import ctypes

if __name__ == '__main__':

        # Serial port 
        ser = serial.Serial()
        ser.port = "/dev/rfcomm0"  # 
        ser.timeout=9.0                                
        ser.baudrate = 115200                          

        # Serial port Open
        ser.open() 
        
        #加/角速度計測設定
        header = 0x9A
        cmd = 0x16              #加/角速度計測設定コマンド
        data = 0x01             #計測周期 1ms
        data1 = 0x0A            #計測データ送信の平均回数 10回
        data2 = 0x00            #計測データ記録の平均回数
        
        check = header ^ cmd
        check = check ^ data
        check = check ^ data1
        check = check ^ data2

        print(ser)
	
        list = bytearray([header,  cmd,  data,  data1, data2 , check])

        ser.read(1000)
        ser.write(list)

        str = ser.readline()

        print('CmdRes:' + repr(str))
	
        # 計測開始/計測予約
        header = 0x9A
        cmd    = 0x13           #計測開始/計測予約コマンド
        smode  = 0x00           #計測時刻の設定状態(0:未設定,1:設定あり)
        syear  = 0x00           #開始年
        smonth = 0x01           #開始月
        sday   = 0x01           #開始日
        shour  = 0x00           #開始時
        smin   = 0x00           #開始分
        ssec   = 0x00           #開始秒
        emode  = 0x00
        eyear  = 0x00           #終了年
        emonth = 0x01           #終了月
        eday   = 0x01           #終了日        
        ehour  = 0x00           #終了時
        emin   = 0x00           #終了分
        esec   = 0x00           #終了秒

        #チェックサム
        check = header ^ cmd
        check = check ^ smode
        check = check ^ syear
        check = check ^ smonth
        check = check ^ sday
        check = check ^ shour
        check = check ^ smin
        check = check ^ ssec
        check = check ^ emode
        check = check ^ eyear
        check = check ^ emonth
        check = check ^ eday
        check = check ^ ehour
        check = check ^ emin
        check = check ^ esec
	
        list = bytearray([header,  cmd, smode, syear, smonth, sday, shour, smin, ssec, emode, eyear, emonth, eday, ehour, emin, esec, check])
  
        ser.read(100)
        ser.write(list)
	
        str = ser.readline()
	
        str =ser.read(1)
	
        while ord(str) != 0x9A:
                str = ser.read(1)

        str = ser.read(1)
	
        if ord(str) == 0x80:            #加速度角速度計測データ通知
                
                str = ser.read(4)
                
                data1 = ser.read(1)
                data2 = ser.read(1)
                data3 = ser.read(1)

                if ord(data3) & 0x80:   #加速度角速度計測データ通知
                        data4 = b'\xFF'
                else:
                        data4 = b'\x00'
		
                print(binascii.b2a_hex(data1))
                print(binascii.b2a_hex(data2))
                print(binascii.b2a_hex(data3))
                print(binascii.b2a_hex(data4))
		
                accx = ord(data1)
                accx += ord(data2)<<8
                accx += ord(data3)<<16
                accx += ord(data4)<<24

                print("accx = %d" % (ctypes.c_int(accx).value))
	
        ser.close();

以上、よろしくお願いいたします。

0

1Answer

windosPCではシリアル通信ができたのですが、
LINUXのラズベリーパイではシリアル通信ができず

↑ 全く同じPythonコードを試された結果でしょうか?
 

rfcommコマンドを用いて、Bluetoothデバイスの仮想的なシリアルポートとしてシステムにバウンドし、・・・

バインドは、次のコマンドでしょうか?
sudo rfcomm bind 0 C9:0B:89:87:CC:4C


以下のコマンドの結果から何かわかりませんか?

sudo hciconfig

sudo l2ping -c 3 C9:0B:89:87:CC:4C

sudo hcitool info C9:0B:89:87:CC:4C

sudo sdptool browse

sudo sdptool records C9:0B:89:87:CC:4C

sudo rfcomm -a

sudo cat /dev/rfcomm0

なお、接続や確認のために投入したコマンドは、省略せずにすべて掲示してもらえると切り分けしやすいです。

1Like

Comments

  1. @daigouin

    Questioner

    コメントありがとうございます。

    ・全く同じPythonコードを試された結果でしょうか?

    ser.port = "/dev/rfcomm0"
    

    上記のコードはwindowsとLINUXとで割り振るポートが異なるため、
    変更していますが、それ以外は変更しておりません。

    ・バインドは、次のコマンドでしょうか?
    sudo rfcomm bind 0 C9:0B:89:87:CC:4C
    →以下のコマンドを用いて行いました。

    sudo rfcomm bind /dev/rfcomm0 C9:0B:89:87:CC:4C 1
    

    ・以下のコマンドの結果から何かわかりませんか?
    コマンドを教えていただきありがとうございます。
    私が勉強不足であるため、教えていただいたコマンドについて勉強した上で、
    コマンドの結果を考察したいと考えております。
    一応、以下に出力結果を記載しますので、何かお気づきになったことがありましたら、
    再度コメントいただけますと幸いです。

    osumi@raspberrypi:~ $ sudo hciconfig
    hci0:	Type: Primary  Bus: UART
    	BD Address: D8:3A:DD:0F:81:66  ACL MTU: 1021:8  SCO MTU: 64:1
    	UP RUNNING PSCAN 
    	RX bytes:9620 acl:84 sco:0 events:528 errors:0
    	TX bytes:390511 acl:704 sco:0 commands:136 errors:0
    
    osumi@raspberrypi:~ $ sudo l2ping -c 3 C9:0B:89:87:CC:4C
    Ping: C9:0B:89:87:CC:4C from D8:3A:DD:0F:81:66 (data size 44) ...
    0 bytes from C9:0B:89:87:CC:4C id 0 time 8.90ms
    0 bytes from C9:0B:89:87:CC:4C id 1 time 26.72ms
    0 bytes from C9:0B:89:87:CC:4C id 2 time 4.83ms
    3 sent, 3 received, 0% loss
    osumi@raspberrypi:~ $ sudo hcitool info C9:0B:89:87:CC:4C
    Requesting information ...
    	BD Address:  C9:0B:89:87:CC:4C
    	Device Name: AMWS020_RP1B002597
    	LMP Version: 4.2 (0x8) LMP Subversion: 0x220b
    	Manufacturer: Cypress Semiconductor (305)
    	Features page 0: 0xbf 0xfe 0xcf 0xfe 0xdb 0xff 0x7b 0x87
    		<3-slot packets> <5-slot packets> <encryption> <slot offset> 
    		<timing accuracy> <role switch> <sniff mode> <RSSI> 
    		<channel quality> <SCO link> <HV2 packets> <HV3 packets> 
    		<u-law log> <A-law log> <CVSD> <paging scheme> <power control> 
    		<transparent SCO> <broadcast encrypt> <EDR ACL 2 Mbps> 
    		<EDR ACL 3 Mbps> <enhanced iscan> <interlaced iscan> 
    		<interlaced pscan> <inquiry with RSSI> <extended SCO> 
    		<EV4 packets> <EV5 packets> <AFH cap. slave> 
    		<AFH class. slave> <LE support> <3-slot EDR ACL> 
    		<5-slot EDR ACL> <sniff subrating> <pause encryption> 
    		<AFH cap. master> <AFH class. master> <EDR eSCO 2 Mbps> 
    		<EDR eSCO 3 Mbps> <3-slot EDR eSCO> <extended inquiry> 
    		<LE and BR/EDR> <simple pairing> <encapsulated PDU> 
    		<err. data report> <non-flush flag> <LSTO> <inquiry TX power> 
    		<EPC> <extended features> 
    	Features page 1: 0x0f 0x00 0x00 0x00 0x00 0x00 0x00 0x00
    	Features page 2: 0x30 0x0b 0x00 0x00 0x00 0x00 0x00 0x00
    osumi@raspberrypi:~ $ sudo sdptool browse
    Inquiring ...
    Failed to connect to SDP server on 38:FC:98:46:9C:D5: Host is down
    Failed to connect to SDP server on 10:F6:0A:82:CF:A2: Host is down
    Browsing C9:0B:89:87:CC:4C ...
    Service Name: Device Identification
    Service RecHandle: 0x10001
    Service Class ID List:
      "PnP Information" (0x1200)
    
    Browsing C9:0B:89:87:CC:4C ...
    Service Search failed: Invalid argument
    Service Name: SPP SERVER
    Service RecHandle: 0x10002
    Service Class ID List:
      "Serial Port" (0x1101)
    Protocol Descriptor List:
      "L2CAP" (0x0100)
      "RFCOMM" (0x0003)
        Channel: 2
    Profile Descriptor List:
      "Serial Port" (0x1101)
        Version: 0x0102
    
    Service Name: A2DP Sink
    Service RecHandle: 0x10006
    Service Class ID List:
      "Audio Sink" (0x110b)
    
    Service Name: AVRCP Controller
    Service RecHandle: 0x10007
    Service Class ID List:
      "AV Remote" (0x110e)
      "AV Remote Controller" (0x110f)
    
    Service Name: Human Interface Device
    Service RecHandle: 0x10008
    Service Class ID List:
      "Human Interface Device" (0x1124)
    
    osumi@raspberrypi:~ $ sudo sdptool records C9:0B:89:87:CC:4C
    Service Name: Device Identification
    Service RecHandle: 0x10001
    Service Class ID List:
      "PnP Information" (0x1200)
    
    Service Name: SPP SERVER
    Service RecHandle: 0x10002
    Service Class ID List:
      "Serial Port" (0x1101)
    Protocol Descriptor List:
      "L2CAP" (0x0100)
      "RFCOMM" (0x0003)
        Channel: 2
    Profile Descriptor List:
      "Serial Port" (0x1101)
        Version: 0x0102
    
    Service Name: A2DP Sink
    Service RecHandle: 0x10006
    Service Class ID List:
      "Audio Sink" (0x110b)
    
    Service Name: AVRCP Controller
    Service RecHandle: 0x10007
    Service Class ID List:
      "AV Remote" (0x110e)
      "AV Remote Controller" (0x110f)
    
    Service Name: Human Interface Device
    Service RecHandle: 0x10008
    Service Class ID List:
      "Human Interface Device" (0x1124)
    
    osumi@raspberrypi:~ $ sudo rfcomm -a
    rfcomm0: C9:0B:89:87:CC:4C channel 1 closed 
    osumi@raspberrypi:~ $ sudo cat /dev/rfcomm0
    
  2. bluetoothd-Cオプションが必要という記事があったので、試しに以下のコマンドを試してもらえないでしょうか?

    sudo rfcomm release all
    sudo systemctl stop bluetooth
    sudo bluetoothd -C & #for background
    sudo hciconfig hci0 up
    sudo sdptool add SP
    sudo rfcomm bind 0 C9:0B:89:87:CC:4C
    sudo rfcomm -a
    sudo cat /dev/rfcomm0
    
  3. @daigouin

    Questioner

    コメントありがとうございます。

    コメントに頂いたコマンドを試したですが、
    sudo rfcomm -a の結果は変わらず、closedとなっていました。
    以下にコマンドの結果を添付いたしますので、ご確認いただけますと幸いです。

    osumi@raspberrypi:~ $ sudo rfcomm release all
    osumi@raspberrypi:~ $ sudo systemctl stop bluetooth
    osumi@raspberrypi:~ $ sudo bluetoothd -C &
    [1] 2216
    osumi@raspberrypi:~ $ sudo hciconfig hci0 up
    osumi@raspberrypi:~ $ sudo sdptool add SP
    Serial Port service registered
    osumi@raspberrypi:~ $ sudo rfcomm bind 0 C9:0B:89:87:CC:4C
    osumi@raspberrypi:~ $ sudo rfcomm -a
    rfcomm0: C9:0B:89:87:CC:4C channel 1 closed 
    osumi@raspberrypi:~ $ sudo cat /dev/rfcomm0
    

Your answer might help someone💌