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

BluetoothのSPP(Serial Port Profile)サービスおよびその前提としてのSDP(Service Discovery Protocol)サーバが有効になっていないのではないでしょうか?

0Like

Your answer might help someone💌