Python §82 : シリアル通信(エンコードとデコード) | hitochan007のブログ(Pythonの勉強ブログ)

hitochan007のブログ(Pythonの勉強ブログ)

★Pythonの勉強記録を中心に●pomera DM200、●パソコン、●グルメ、●愛犬(トイプードル) などについてのブログです

テーマ:

ブログランキング参加しました。下のバナーをポチッとしていただけると助かります。↓

Python ブログランキングへ




■シリアル通信(エンコードとデコード)■
●1.送信するときに文字列をバイト型に変換する方法
●2.受信するときにバイト型から文字列に変換する方法



●1.送信するときに文字列をバイト型に変換する方法


■通信関連の記事のバックナンバー

§79.通信リアルタイムモニター 構想段階
§80.シリアル通信
§81.シリアル通信(通信ポートの自動サーチ)



シリアル通信の送信、受信にはPython3の場合はバイト型で行う必要がありました。

こんな感じです。


コード:バイト型で送信

ser1.write(b"Hello\r\n")


文字列の前にbを付けることでバイト型となることはわかりました。

しかし、この方法だと動的に文字を送る場合には困ってしまします。変数の先頭にbを付けることはできないからです。

そこで、使うのがencode関数です。

以下は、encode関数を用いて、以下のように送信まで行っています。

1
2
3
4
5
6
moji='Hello\r\n'            #文字列を変数の格納。文字列の最後は改行文字を入れる
print('1',moji) #改行されることを確認(改行文字があるため)
moji2=moji.encode('utf-8') #文字列をバイト型に変換
print('2',moji2) #バイト型の変数を確認

ser1.write(moji2) #エンコードしたデータを送信する

syntax2html


1行目は、moji='Hello\r\n' として、mojiという文字列変数にデータを格納しています。行末コードは\r\nとしています。これは、受信のときにreadline()関数での区切り文字として\nが必要でしたね。

3行目は、moji2=moji.encode('utf-8') とここで、encode関数が出てきました。引数のutf-8が通常使用しているutf-8のコードを意味しています。この関数でバイト型に変換することができます。

6行目は、ser1.write(moji2) とエンコードしたバイト型のデータを送信しています。


●2.受信するときにバイト型から文字列に変換する方法


次は、受信の方法ですが、さきほどの送信したデータを受け取るのは、次のようにreadline()関数を用いるとできます。

コード:1行を受信(\nまで読み取る)

r=ser2.readline()


受信した内容を表示してみると b'Hello\r\n' となります。
ここで、bはバイトコードで、''の文字列も処理するには邪魔ですね。

ここで登場するのはdecode()関数です。以下が、decode()を使って、通常のutf-8の文字列に変換したコードです。

1
2
3
4
5
print('受信テスト')
r=ser2.readline() #行末コードまでを1行読み込む
print('1',r) #バイト型のまま表示
print('2',r.strip()) #バイト型末端の改行文字を除外する
print('3',r.strip().decode('utf-8')) #バイト型を文字列変数に変換

syntax2html


2行目で受信したデータを3行目でそのまま表示します。
4行目は、strip()関数を使って、文字列データの両端のスペースなどを除去します。ここでは、行末コードである\r\nを取り除きます。
そして、5行目は、両端のスペースを取り除いたあとにdecoe()関数を用いて、文字列に変換しています。

出力結果も参考まで、示します。


出力結果

受信テスト
1 b'Hello\r\n'
2 b'Hello'
3 Hello



本日のコードと出力を以下にすべて掲載します。

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
'''
(1)まずはポートのopenからはじめる
(2)送信テスト バイト型にして送る
(3)受信テスト バイト型で受信して、通常の文字列に変換する
'''
import serial #シリアル通信モジュールをインポート
ser1 = serial.Serial(2) #送信用ポートをOpen
ser2 = serial.Serial(3) #受信用ポートをOpen
print ('送信用ポート番号:',ser1.portstr) #送信用ポート番号を確認
print ('受信用ポート番号:',ser2.portstr) #受信用ポート番号を確認

#ser1.write('Hello') #これではエラーになる。serialモジュールではバイト列でないとだめ
#ser1.write(b'Hello\r\n') #bをつけることでバイト列になる

print('通信時のデータのエンコードとデコード\n')
print('送信テスト')

moji='Hello\r\n' #文字列を変数の格納。文字列の最後は改行文字を入れる
print('1',moji) #改行されることを確認(改行文字があるため)
moji2=moji.encode('utf-8') #文字列をバイト型に変換
print('2',moji2) #バイト型の変数を確認

ser1.write(moji2) #エンコードしたデータを送信する

print('受信テスト')
r=ser2.readline() #行末コードまでを1行読み込む
print('1',r) #バイト型のまま表示
print('2',r.strip()) #バイト型末端の改行文字を除外する
print('3',r.strip().decode('utf-8')) #バイト型を文字列変数に変換


ser1.close() #送信側のポートをclose
ser2.close() #受信型のポートをopen

syntax2html


 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Python 3.4.2 (v3.4.2:ab2c023a9432, Oct  6 2014, 22:15:05) [MSC v.1600 32 bit (Intel)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> ================================ RESTART ================================
>>>
送信用ポート番号 COM3
受信用ポート番号 COM4
通信時のデータのエンコードとデコード

送信テスト
1 Hello


2 b'Hello\r\n'
受信テスト
1 b'Hello\r\n'
2 b'Hello'
3 Hello
>>>

syntax2html







●シリアル通信(エンコードとデコード)●

encode()とdecode()関数で、バイト型という文字列処理のやっかいな作業から解放されます。
もし、この関数がなかったら b'abcd' という文字列をbや'のコードを除去したりしなければなりませんでした。

これで、バイト型を気にせず、通常の文字列処理が行えます。









Python ブログランキングへ 
クリックしてね


新しいブログをはじめました。pythonの初級者から中級者まで、役に立つ記事を掲載していますので、ご覧ください。

特にカスタム関数(ユーザー定義関数)は、便利に使えると思います。

ぜひぜひこのリンクをクリックしてください 

 Pythonを勉強して株で儲けるブログ