Raspberry Piと無線IMUをシリアル通信で接続させたいです
Q&A
Closed
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();
以上、よろしくお願いいたします。