質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.32%

Q&A

解決済

2回答

576閲覧

シリアル通信で200Bの文字を受信できません。

Sheep

総合スコア1

0グッド

2クリップ

投稿2023/09/11 07:27

実現したいこと

ここに実現したいことを箇条書きで書いてください。

  • シリアル通信で200B以上を受信できるようにしたい!

前提

ラズパイZero と LoRa HATを2台ずつ使ったシリアル通信を行っています。
Pythonでプログラムを書いています。
送信側のプログラム(send.py)ではファイルの内容を送信できるようなプログラムを作りました。
受信側のプログラム(receive.py)では受信した文字を表示するプログラムを作りました。

送信側・受信側それぞれのプログラムにエラーはなく、正常に動作しています。
しかし、198文字(198B)以上を送信すると、197Bまでしか受信できません。
どうすれば200B以上を受信することができますか?

該当のソースコード(send.py)

Python

1import serial 2import sys 3import argparse 4import hexdump 5 6 7def get_args(): 8 parser = argparse.ArgumentParser() 9 10 parser.add_argument("serial_port") 11 parser.add_argument("-b", "--baud", default="9600") 12 parser.add_argument("-m", "--model", default="E220-900JP") 13 parser.add_argument("-p", "--payload_length") 14 parser.add_argument("-a", "--ascii_text") 15 parser.add_argument("-f", "--fixed_mode", action="store_true") 16 parser.add_argument("--target_address") 17 parser.add_argument("--target_channel") 18 19 args = parser.parse_args() 20 21 return args 22 23 24def main(): 25 args = get_args() 26 27 if args.model == "E220-900JP": 28 if args.fixed_mode: 29 if (args.target_address != None) and (args.target_channel != None): 30 t_addr = int(args.target_address) 31 t_addr_H = t_addr >> 8 32 t_addr_L = t_addr & 0xFF 33 t_ch = int(args.target_channel) 34 payload = bytes([t_addr_H, t_addr_L, t_ch]) 35 else: 36 print("INVALID") 37 return 38 else: 39 payload = bytes([]) 40 41 if args.payload_length != None: 42 count = int(args.payload_length) // 256 43 if count > 0: 44 payload = payload + bytes(range(256)) 45 for i in range(count - 1): 46 payload = payload + bytes(range(256)) 47 payload = payload + bytes(range(int(args.payload_length) % 256)) 48 else: 49 payload = payload + bytes(range(int(args.payload_length))) 50 elif args.ascii_text != None: 51 payload = payload + args.ascii_text.encode() 52 else: 53 payload = payload + sys.stdin.buffer.read() 54 55 print("serial port:") 56 print(args.serial_port) 57 58 print("send data hex dump:") 59 hexdump.hexdump(payload) 60 61 with serial.Serial(args.serial_port, int(args.baud), timeout=None) as ser: 62 while True: 63 if ser.out_waiting == 0: 64 break 65 ser.write(payload) 66 ser.flush() 67 print("SENT") 68 else: 69 print("INVALID") 70 return 71 72 73if __name__ == "__main__": 74 main() 75

該当のソースコード(reveive.py)

Python

1import serial 2import time 3import argparse 4import hexdump 5 6 7def get_args(): 8 parser = argparse.ArgumentParser() 9 10 parser.add_argument("serial_port") 11 parser.add_argument("-b", "--baud", default="9600") 12 parser.add_argument("-m", "--model", default="E220-900JP") 13 parser.add_argument("--rssi", action="store_true") 14 15 args = parser.parse_args() 16 17 return args 18 19 20def main(): 21 args = get_args() 22 23 if args.model == "E220-900JP": 24 print("serial port:") 25 print(args.serial_port) 26 27 print("receive waiting...") 28 with serial.Serial(args.serial_port, int(args.baud), timeout=None) as ser: 29 payload = bytes() 30 while True: 31 if ser.in_waiting != 0: 32 payload = payload + ser.read() 33 elif ser.in_waiting == 0 and len(payload) != 0: 34 time.sleep(0.030) 35 if ser.in_waiting == 0: 36 print("recv data hex dump:") 37 hexdump.hexdump(payload) 38 if args.rssi: 39 rssi = int(payload[-1]) - 256 40 print(f"RSSI: {rssi} dBm") 41 print("RECEIVED\n") 42 payload = bytes() 43 else: 44 print("INVALID") 45 return 46 47 48if __name__ == "__main__": 49 main()

送るファイルの内容(ascii_data.txt)

送る文字列はascii_data.txtに記されている内容です。198文字です。

txt

1JRxuqEn1wp8YPGcBGPm8OpIbt81t8Dtf01nFXsnC3KTup7xta7ibn8QDespYmlCum47Whli5ekuGA4YhKPn3hRVvnlicaFKrSRVGhiNi2qD62oPRniPMPQq3kjP4kX5Ua5X3TQwbOdwUYLLH8sQqjvNRhvJUNfsBXTufHsy5mrdAA1jqO8JUHRE2KY2k6ynK7anSSS

試したこと

以下のようにsend.pyを実行しました。ascii_data.txtには198文字分が記述されています。

$ python3 send.py /dev/ttyS0 -f --target_address 0 --target_channel 0 < ascii_data.txt

上の実行結果です。ファイルの内容すべてが送信されています。

serial port: /dev/ttyS0 send data hex dump: 00000000: 00 00 00 4A 52 78 75 71 45 6E 31 77 70 38 59 50 ...JRxuqEn1wp8YP 00000010: 47 63 42 47 50 6D 38 4F 70 49 62 74 38 31 74 38 GcBGPm8OpIbt81t8 00000020: 44 74 66 30 31 6E 46 58 73 6E 43 33 4B 54 75 70 Dtf01nFXsnC3KTup 00000030: 37 78 74 61 37 69 62 6E 38 51 44 65 73 70 59 6D 7xta7ibn8QDespYm 00000040: 6C 43 75 6D 34 37 57 68 6C 69 35 65 6B 75 47 41 lCum47Whli5ekuGA 00000050: 34 59 68 4B 50 6E 33 68 52 56 76 6E 6C 69 63 61 4YhKPn3hRVvnlica 00000060: 46 4B 72 53 52 56 47 68 69 4E 69 32 71 44 36 32 FKrSRVGhiNi2qD62 00000070: 6F 50 52 6E 69 50 4D 50 51 71 33 6B 6A 50 34 6B oPRniPMPQq3kjP4k 00000080: 58 35 55 61 35 58 33 54 51 77 62 4F 64 77 55 59 X5Ua5X3TQwbOdwUY 00000090: 4C 4C 48 38 73 51 71 6A 76 4E 52 68 76 4A 55 4E LLH8sQqjvNRhvJUN 000000A0: 66 73 42 58 54 75 66 48 73 79 35 6D 72 64 41 41 fsBXTufHsy5mrdAA 000000B0: 31 6A 71 4F 38 4A 55 48 52 45 32 4B 59 32 6B 36 1jqO8JUHRE2KY2k6 000000C0: 79 6E 4B 37 61 6E 53 53 53 0A ynK7anSSS. SENT

  

次に受信側(reveive.py)です。以下のように実行しました。

python3 receive.py /dev/ttyS0 --rssi

上の実行結果です。sendでは末尾がSSSだったのですが、最後のSが受信されていません。

serial port: /dev/ttyS0 receive waiting... recv data hex dump: 00000000: 4A 52 78 75 71 45 6E 31 77 70 38 59 50 47 63 42 JRxuqEn1wp8YPGcB 00000010: 47 50 6D 38 4F 70 49 62 74 38 31 74 38 44 74 66 GPm8OpIbt81t8Dtf 00000020: 30 31 6E 46 58 73 6E 43 33 4B 54 75 70 37 78 74 01nFXsnC3KTup7xt 00000030: 61 37 69 62 6E 38 51 44 65 73 70 59 6D 6C 43 75 a7ibn8QDespYmlCu 00000040: 6D 34 37 57 68 6C 69 35 65 6B 75 47 41 34 59 68 m47Whli5ekuGA4Yh 00000050: 4B 50 6E 33 68 52 56 76 6E 6C 69 63 61 46 4B 72 KPn3hRVvnlicaFKr 00000060: 53 52 56 47 68 69 4E 69 32 71 44 36 32 6F 50 52 SRVGhiNi2qD62oPR 00000070: 6E 69 50 4D 50 51 71 33 6B 6A 50 34 6B 58 35 55 niPMPQq3kjP4kX5U 00000080: 61 35 58 33 54 51 77 62 4F 64 77 55 59 4C 4C 48 a5X3TQwbOdwUYLLH 00000090: 38 73 51 71 6A 76 4E 52 68 76 4A 55 4E 66 73 42 8sQqjvNRhvJUNfsB 000000A0: 58 54 75 66 48 73 79 35 6D 72 64 41 41 31 6A 71 XTufHsy5mrdAA1jq 000000B0: 4F 38 4A 55 48 52 45 32 4B 59 32 6B 36 79 6E 4B O8JUHRE2KY2k6ynK 000000C0: 37 61 6E 53 53 E9 7anSS. RSSI: -23 dBm RECEIVED

同様に、300Bとかを送っても197文字までしか受信できません。
どなたか解決お願いします。

補足情報(FW/ツールのバージョンなど)

OSはBullseyeです。Pythonは3.9です。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

can110

2023/09/11 08:32 編集

LoRa通信については門外漢ですが 単純に末尾だけが受信できないわけではなく - 送信データ先頭3byteは00であり末尾は0Aである - 受信データ末尾はE9である ようですが、それに心当たりなどないでしょうか。(先頭は宛先とチャンネル?) また以下には https://dragon-torch.tech/cat-components/rf-modules/e220-900t22s-jp/ LoRaパケットあたり最大200バイトのペイロードをサポート のような記述がありますが、これに関して心当たりなどないでしょうか?
tmp

2023/09/11 08:31

初めに、pySerialは、使ったことありませんので、 さっとpySerialのドキュメントを見てみました。 write(データ) パラメーター: データ– 送信するデータ。 戻り値: 書き込まれたバイト数。 戻り値の型: 整数 とあり、 まずは、戻り値を見ていないので確認してください。 恐らく送ろうとしているサイズよりすくないのではないでしょうか? だとすれば、受信側でなく送信側を修正する必要があります。 また、送信プログラムで表示されてる送信のデータは、送ったデータではなく 送ろうとしたデータです。
Sheep

2023/09/11 09:27

can110さん、コメントありがとうございます! おっしゃる通り、冒頭3Byteは宛先とチャネルです。私のLoRaモジュールを確認したところ、型番がURLと同じものでした。そのため、200Byteより大きいデータ数は送れないことが分かりました。この情報は大変役に立ちました!解決しました。ありがとうございます! tmpさん、コメントありがとうございます! writeメソッドの戻り値は確認したことが無かったので、今後プログラムを改良していく上での参考にさせていただきます。ありがとうございます!
guest

回答2

0

まず、明らかに不味いところを。

if ser.in_waiting != 0:

ループ中に一度でもser.in_waitingが0になってしまうと、そこで受信を中断してしまいますね。

投稿2023/09/11 08:13

編集2023/09/11 08:13
y_waiwai

総合スコア88163

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Sheep

2023/09/11 09:22

回答ありがとうございます! 今後、プログラムを改良していく予定なのでとても助かりました!
guest

0

自己解決

結論から、200Byteより大きいサイズのデータ数は送れないことが分かりました。最初の3byteは宛先とチャネルのため、197byteのみの受信となっていることもわかりました。

私の使用しているLoRaモジュールE220-900T22S(JP)の仕様上、200Byteより大きいサイズ数を送ることができないことが判明しました!
送信するデータに注意していきたいと思います。
https://dragon-torch.tech/cat-components/rf-modules/e220-900t22s-jp/

投稿2023/09/11 09:29

編集2023/09/11 09:31
Sheep

総合スコア1

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.32%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問